Merge pull request #19748 from briansull/evalop-specialized
authorBrian Sullivan <briansul@microsoft.com>
Fri, 7 Sep 2018 17:40:48 +0000 (10:40 -0700)
committerGitHub <noreply@github.com>
Fri, 7 Sep 2018 17:40:48 +0000 (10:40 -0700)
Rework the EvalOp generic-template methods

230 files changed:
Documentation/botr/clr-abi.md
build.sh
src/.nuget/Microsoft.NET.Sdk.IL/targets/Microsoft.NET.Sdk.IL.targets
src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
src/System.Private.CoreLib/shared/System/Number.Formatting.cs
src/System.Private.CoreLib/shared/System/Number.NumberBuffer.cs
src/System.Private.CoreLib/shared/System/Reflection/SignatureConstructedGenericType.cs
src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.PlatformNotSupported.cs
src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.cs
src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.PlatformNotSupported.cs
src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.cs
src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs
src/System.Private.CoreLib/shared/System/Type.cs
src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs
src/ToolBox/SOS/Strike/CMakeLists.txt
src/ToolBox/SOS/Strike/eeheap.cpp
src/ToolBox/SOS/Strike/gcroot.cpp
src/ToolBox/SOS/Strike/sos.cpp
src/ToolBox/SOS/Strike/sos.h
src/ToolBox/SOS/Strike/util.h
src/classlibnative/bcltype/grisu3.cpp
src/classlibnative/bcltype/grisu3.h
src/classlibnative/bcltype/number.cpp
src/classlibnative/bcltype/number.h
src/corefx/System.Globalization.Native/icushim.cpp
src/debug/createdump/crashinfo.cpp
src/debug/daccess/daccess.cpp
src/debug/daccess/dacimpl.h
src/debug/daccess/request.cpp
src/debug/inc/dbgipcevents.h
src/dlls/mscorrc/mscorrc.rc
src/dlls/mscorrc/resource.h
src/inc/corprof.idl
src/inc/dacprivate.h
src/inc/regdisp.h
src/inc/sospriv.idl
src/inc/stdmacros.h
src/jit/codegen.h
src/jit/codegenarm.cpp
src/jit/codegenarm64.cpp
src/jit/codegenarmarch.cpp
src/jit/codegencommon.cpp
src/jit/codegenlinear.cpp
src/jit/codegenxarch.cpp
src/jit/compiler.cpp
src/jit/compiler.h
src/jit/compiler.hpp
src/jit/ee_il_dll.cpp
src/jit/emit.cpp
src/jit/emit.h
src/jit/emitarm.cpp
src/jit/emitarm.h
src/jit/emitarm64.cpp
src/jit/emitarm64.h
src/jit/emitfmtsxarch.h
src/jit/emitxarch.cpp
src/jit/emitxarch.h
src/jit/gentree.cpp
src/jit/gentree.h
src/jit/hwintrinsiccodegenxarch.cpp
src/jit/hwintrinsiclistxarch.h
src/jit/hwintrinsicxarch.cpp
src/jit/hwintrinsicxarch.h
src/jit/importer.cpp
src/jit/instrsxarch.h
src/jit/jitconfigvalues.h
src/jit/lower.cpp
src/jit/lower.h
src/jit/lowerxarch.cpp
src/jit/lsra.h
src/jit/lsraarm.cpp
src/jit/lsraarm64.cpp
src/jit/lsraarmarch.cpp
src/jit/lsraxarch.cpp
src/jit/morph.cpp
src/jit/namedintrinsiclist.h
src/jit/valuenum.cpp
src/pal/inc/pal.h
src/pal/inc/unixasmmacrosarm64.inc
src/pal/prebuilt/idl/sospriv_i.cpp
src/pal/prebuilt/inc/corprof.h
src/pal/prebuilt/inc/sospriv.h
src/pal/src/CMakeLists.txt
src/pal/src/cruntime/math.cpp
src/scripts/genEventPipe.py
src/scripts/genLttngProvider.py
src/vm/CMakeLists.txt
src/vm/amd64/jithelpers_fast.S
src/vm/amd64/unixstubs.cpp
src/vm/arm/cgencpu.h
src/vm/arm/stubs.cpp
src/vm/arm64/stubs.cpp
src/vm/callingconvention.h
src/vm/ceeload.cpp
src/vm/ceeload.h
src/vm/domainfile.cpp
src/vm/eetoprofinterfaceimpl.cpp
src/vm/i386/asmhelpers.S
src/vm/i386/fptext.asm [deleted file]
src/vm/i386/unixstubs.cpp
src/vm/jitinterface.h
src/vm/methodtablebuilder.cpp
src/vm/peimage.cpp
src/vm/peimage.h
src/vm/profilinghelper.cpp
src/vm/stublink.cpp
tests/CoreFX/CoreFX.issues.json
tests/arm/Tests.lst
tests/arm64/Tests.lst
tests/issues.targets
tests/src/Interop/CMakeLists.txt
tests/src/Interop/IJW/FakeMscoree/mscoree.cpp
tests/src/Interop/IJW/ManagedCallingNative/IjwNativeDll/CMakeLists.txt
tests/src/Interop/IJW/ManagedCallingNative/IjwNativeDll/IjwNativeDll.cpp
tests/src/Interop/IJW/NativeCallingManaged/IjwNativeCallingManagedDll/CMakeLists.txt [new file with mode: 0644]
tests/src/Interop/IJW/NativeCallingManaged/IjwNativeCallingManagedDll/IjwNativeCallingManagedDll.cpp [new file with mode: 0644]
tests/src/Interop/IJW/NativeCallingManaged/NativeCallingManaged.cs [new file with mode: 0644]
tests/src/Interop/IJW/NativeCallingManaged/NativeCallingManaged.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar_r.csproj with 61% similarity]
tests/src/Interop/StructMarshalling/PInvoke/Helper.cs
tests/src/JIT/Directed/arglist/CMakeLists.txt [new file with mode: 0644]
tests/src/JIT/Directed/arglist/vararg.cs [new file with mode: 0644]
tests/src/JIT/Directed/arglist/vararg.csproj [new file with mode: 0644]
tests/src/JIT/Directed/arglist/varargmanaged.cs [new file with mode: 0644]
tests/src/JIT/Directed/arglist/varargnative.c [new file with mode: 0644]
tests/src/JIT/Directed/arglist/varargtypes.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_r.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar_r.csproj with 86% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_ro.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar_ro.csproj with 86% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_r.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar_r.csproj with 86% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_ro.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar_ro.csproj with 86% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_r.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar_r.csproj with 85% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_ro.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar_ro.csproj with 85% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_r.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar_r.csproj with 85% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_ro.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar_ro.csproj with 85% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar.Boolean.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
tests/src/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs [new file with mode: 0644]
tests/src/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar_ro.csproj with 80% similarity]
tests/testsUnsupportedOutsideWindows.txt

index ea5a49e..0a40b41 100644 (file)
@@ -599,6 +599,8 @@ For AMD64, all probes receive a second parameter (passed in `RDX` according to t
 
 TODO: describe ARM64 tail call convention.
 
+On Linux/x86 the profiling hooks are declared with the ```__cdecl``` attribute.  In cdecl (which stands for C declaration), subroutine arguments are passed on the stack. Integer values and memory addresses are returned in the EAX register, floating point values in the ST0 x87 register. Registers EAX, ECX, and EDX are caller-saved, and the rest are callee-saved. The x87 floating point registers ST0 to ST7 must be empty (popped or freed) when calling a new function, and ST1 to ST7 must be empty on exiting a function. ST0 must also be empty when not used for returning a value. Returned values of managed-code are formed before the leave/tailcall profiling hooks, so they should be saved in these hooks and restored on returning from them. The instruction ```ret``` for assembler implementations of profiling hooks should be without a parameter.
+
 JIT32 only generates one epilog (and causes all returns to branch to it) when there are profiler hooks.
 
 # Synchronized Methods
index 95e21b5..6c40251 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -416,20 +416,23 @@ build_CoreLib_ni()
 {
     local __CrossGenExec=$1
 
-    echo "Generating native image for System.Private.CoreLib.dll"
+    if [ -e $__CrossGenCoreLibLog ]; then
+        rm $__CrossGenCoreLibLog
+    fi
+    echo "Generating native image of System.Private.CoreLib.dll for $__BuildOS.$__BuildArch.$__BuildType. Logging to \"$__CrossGenCoreLibLog\"."
     echo "$__CrossGenExec /Platform_Assemblies_Paths $__BinDir/IL $__IbcTuning /out $__BinDir/System.Private.CoreLib.dll $__BinDir/IL/System.Private.CoreLib.dll"
-    $__CrossGenExec /Platform_Assemblies_Paths $__BinDir/IL $__IbcTuning /out $__BinDir/System.Private.CoreLib.dll $__BinDir/IL/System.Private.CoreLib.dll
+    $__CrossGenExec /Platform_Assemblies_Paths $__BinDir/IL $__IbcTuning /out $__BinDir/System.Private.CoreLib.dll $__BinDir/IL/System.Private.CoreLib.dll >> $__CrossGenCoreLibLog 2>&1
     if [ $? -ne 0 ]; then
-        echo "Failed to generate native image for System.Private.CoreLib."
+        echo "Failed to generate native image for System.Private.CoreLib. Refer to $__CrossGenCoreLibLog"
         exit 1
     fi
 
     if [ "$__BuildOS" == "Linux" ]; then
         echo "Generating symbol file for System.Private.CoreLib.dll"
         echo "$__CrossGenExec /Platform_Assemblies_Paths $__BinDir /CreatePerfMap $__BinDir $__BinDir/System.Private.CoreLib.dll"
-        $__CrossGenExec /Platform_Assemblies_Paths $__BinDir /CreatePerfMap $__BinDir $__BinDir/System.Private.CoreLib.dll
+        $__CrossGenExec /Platform_Assemblies_Paths $__BinDir /CreatePerfMap $__BinDir $__BinDir/System.Private.CoreLib.dll >> $__CrossGenCoreLibLog 2>&1
         if [ $? -ne 0 ]; then
-            echo "Failed to generate symbol file for System.Private.CoreLib."
+            echo "Failed to generate symbol file for System.Private.CoreLib. Refer to $__CrossGenCoreLibLog"
             exit 1
         fi
     fi
@@ -960,7 +963,7 @@ fi
 if [ $__CrossBuild == 1 ]; then
     __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
 fi
-__CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
+__CrossGenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$__BuildArch.$__BuildType.log"
 __CrossgenExe="$__CrossComponentBinDir/crossgen"
 
 # Init if MSBuild for .NET Core is supported for this platform
index b5998a2..677015a 100644 (file)
@@ -77,6 +77,7 @@ Copyright (c) .NET Foundation. All rights reserved.
       <_IlasmSwitches Condition="'$(DebugType)' == 'Impl'">$(_IlasmSwitches) -DEBUG=IMPL</_IlasmSwitches>
       <_IlasmSwitches Condition="'$(DebugType)' == 'PdbOnly'">$(_IlasmSwitches) -DEBUG=OPT</_IlasmSwitches>
       <_IlasmSwitches Condition="'$(Optimize)' == 'True'">$(_IlasmSwitches) -OPTIMIZE</_IlasmSwitches>
+      <_IlasmSwitches Condition="'$(IlasmResourceFile)' != ''">$(_IlasmSwitches) -RESOURCES=$(IlasmResourceFile)</_IlasmSwitches>
     </PropertyGroup>
 
     <!-- Having to copy these binaries is really inefficient. https://github.com/dotnet/coreclr/issues/18892 tracks making the ilasm tool self-contained  -->
index 69765a4..b2db71d 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.OutputDebugString.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.ReadFile_SafeHandle_IntPtr.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.ReadFile_SafeHandle_NativeOverlapped.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.RegistryView.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SECURITY_ATTRIBUTES.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SecurityOptions.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetEndOfFile.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Internal\IO\File.Windows.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFindHandle.Windows.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryValueKind.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryView.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Windows.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Windows.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Windows.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
   <ItemGroup Condition="$(TargetsWindows) and '$(EnableWinRT)' != 'true'">
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\NtDll\NtQueryInformationFile.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegistryConstants.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.RegistryView.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Win32.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.Win32.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\Registry.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryHive.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryValueKind.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryView.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeRegistryHandle.Windows.cs" />
index 106fd15..3d3c15b 100644 (file)
@@ -301,7 +301,7 @@ namespace System
 
             if (fmt != 0)
             {
-                NumberToString(ref sb, ref number, fmt, digits, info, isDecimal:true);
+                NumberToString(ref sb, ref number, fmt, digits, info);
             }
             else
             {
@@ -327,7 +327,7 @@ namespace System
 
             if (fmt != 0)
             {
-                NumberToString(ref sb, ref number, fmt, digits, info, isDecimal: true);
+                NumberToString(ref sb, ref number, fmt, digits, info);
             }
             else
             {
@@ -342,6 +342,7 @@ namespace System
             char* buffer = number.digits;
             number.precision = DecimalPrecision;
             number.sign = d.IsNegative;
+            number.kind = NumberBufferKind.Decimal;
 
             char* p = buffer + DecimalPrecision;
             while ((d.Mid | d.High) != 0)
@@ -388,6 +389,7 @@ namespace System
             char fmt = ParseFormatSpecifier(format, out int digits);
             int precision = DoublePrecision;
             NumberBuffer number = default;
+            number.kind = NumberBufferKind.Double;
 
             switch (fmt)
             {
@@ -409,12 +411,12 @@ namespace System
 
                         if (NumberToDouble(ref number) == value)
                         {
-                            NumberToString(ref sb, ref number, 'G', DoublePrecision, info, isDecimal: false);
+                            NumberToString(ref sb, ref number, 'G', DoublePrecision, info);
                         }
                         else
                         {
                             DoubleToNumber(value, 17, ref number);
-                            NumberToString(ref sb, ref number, 'G', 17, info, isDecimal: false);
+                            NumberToString(ref sb, ref number, 'G', 17, info);
                         }
 
                         return null;
@@ -451,7 +453,7 @@ namespace System
 
             if (fmt != 0)
             {
-                NumberToString(ref sb, ref number, fmt, digits, info, isDecimal: false);
+                NumberToString(ref sb, ref number, fmt, digits, info);
             }
             else
             {
@@ -488,6 +490,7 @@ namespace System
             char fmt = ParseFormatSpecifier(format, out int digits);
             int precision = FloatPrecision;
             NumberBuffer number = default;
+            number.kind = NumberBufferKind.Double;
 
             switch (fmt)
             {
@@ -509,12 +512,12 @@ namespace System
 
                         if ((float)NumberToDouble(ref number) == value)
                         {
-                            NumberToString(ref sb, ref number, 'G', FloatPrecision, info, isDecimal: false);
+                            NumberToString(ref sb, ref number, 'G', FloatPrecision, info);
                         }
                         else
                         {
                             DoubleToNumber(value, 9, ref number);
-                            NumberToString(ref sb, ref number, 'G', 9, info, isDecimal: false);
+                            NumberToString(ref sb, ref number, 'G', 9, info);
                         }
                         return null;
                     }
@@ -550,7 +553,7 @@ namespace System
 
             if (fmt != 0)
             {
-                NumberToString(ref sb, ref number, fmt, digits, info, false);
+                NumberToString(ref sb, ref number, fmt, digits, info);
             }
             else
             {
@@ -608,7 +611,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -653,7 +656,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -696,7 +699,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -739,7 +742,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -785,7 +788,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -831,7 +834,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -875,7 +878,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -919,7 +922,7 @@ namespace System
                 }
                 if (fmt != 0)
                 {
-                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                    NumberToString(ref sb, ref number, fmt, digits, info);
                 }
                 else
                 {
@@ -949,6 +952,7 @@ namespace System
             int i = (int)(buffer + Int32Precision - p);
 
             number.scale = i;
+            number.kind = NumberBufferKind.Integer;
 
             char* dst = number.digits;
             while (--i >= 0)
@@ -1065,6 +1069,7 @@ namespace System
             char* p = UInt32ToDecChars(buffer + UInt32Precision, value, 0);
             int i = (int)(buffer + UInt32Precision - p);
             number.scale = i;
+            number.kind = NumberBufferKind.Integer;
 
             char* dst = number.digits;
             while (--i >= 0)
@@ -1184,6 +1189,7 @@ namespace System
             int i = (int)(buffer + Int64Precision - p);
 
             number.scale = i;
+            number.kind = NumberBufferKind.Integer;
 
             char* dst = number.digits;
             while (--i >= 0)
@@ -1325,6 +1331,7 @@ namespace System
             int i = (int)(buffer + UInt64Precision - p);
 
             number.scale = i;
+            number.kind = NumberBufferKind.Integer;
 
             char* dst = number.digits;
             while (--i >= 0)
@@ -1453,8 +1460,10 @@ namespace System
                 '\0';
         }
 
-        internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info, bool isDecimal)
+        internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info)
         {
+            Debug.Assert(number.kind != NumberBufferKind.Unknown);
+
             switch (format)
             {
                 case 'C':
@@ -1522,14 +1531,9 @@ namespace System
                         bool noRounding = false;
                         if (nMaxDigits < 1)
                         {
-                            if (isDecimal && (nMaxDigits == -1))
+                            if ((number.kind == NumberBufferKind.Decimal) && (nMaxDigits == -1))
                             {
                                 noRounding = true;  // Turn off rounding for ECMA compliance to output trailing 0's after decimal as significant
-                                if (number.digits[0] == 0)
-                                {
-                                    // Minus zero should be formatted as 0
-                                    goto SkipSign;
-                                }
                                 goto SkipRounding;
                             }
                             else
@@ -1539,13 +1543,12 @@ namespace System
                             }
                         }
 
-                        RoundNumber(ref number, nMaxDigits); // This also fixes up the minus zero case
+                        RoundNumber(ref number, nMaxDigits);
 
 SkipRounding:
                         if (number.sign)
                             sb.Append(info.NegativeSign);
 
-SkipSign:
                         FormatGeneral(ref sb, ref number, nMaxDigits, info, (char)(format - ('G' - 'E')), noRounding);
 
                         break;
@@ -1572,6 +1575,8 @@ SkipSign:
 
         internal static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref NumberBuffer number, ReadOnlySpan<char> format, NumberFormatInfo info)
         {
+            Debug.Assert(number.kind != NumberBufferKind.Unknown);
+
             int digitCount;
             int decimalPos;
             int firstDigit;
@@ -1694,7 +1699,6 @@ SkipSign:
                 }
                 else
                 {
-                    number.sign = false;   // We need to format -0 without the sign set.
                     number.scale = 0;      // Decimals with scale ('0.00') should be rounded.
                 }
 
@@ -2220,7 +2224,11 @@ SkipSign:
             if (i == 0)
             {
                 number.scale = 0;
-                number.sign = false;
+
+                if (number.kind == NumberBufferKind.Integer)
+                {
+                    number.sign = false;
+                }
             }
             dig[i] = '\0';
         }
index 2316f99..1730cf1 100644 (file)
@@ -15,17 +15,27 @@ namespace System
         [StructLayout(LayoutKind.Sequential, Pack = 1)]
         internal unsafe ref struct NumberBuffer // needs to match layout of NUMBER in coreclr's src/classlibnative/bcltype/number.h
         {
-            public int precision;
-            public int scale;
-            private int _sign;
-            private DigitsAndNullTerminator _digits;
-            private char* _allDigits;
+            public int precision;                       //  0
+            public int scale;                           //  4
+            private int _sign;                          //  8
+            private NumberBufferKind _kind;             // 12
+            private char* _allDigits;                   // 16
+            private DigitsAndNullTerminator _digits;    // 20 or 24
 
             public bool sign { get => _sign != 0; set => _sign = value ? 1 : 0; }
             public char* digits => (char*)Unsafe.AsPointer(ref _digits);
+            public NumberBufferKind kind { get => _kind; set => _kind = value; }
 
             [StructLayout(LayoutKind.Sequential, Size = (NumberMaxDigits + 1) * sizeof(char))]
             private struct DigitsAndNullTerminator { }
         }
+
+        internal enum NumberBufferKind // needs to match NUMBER_KIND in coreclr's src/classlibnative/bcltype/number.h
+        {
+            Unknown = 0,
+            Integer = 1,
+            Decimal = 2,
+            Double = 3
+        }
     }
 }
index cd97ffa..d3d8852 100644 (file)
@@ -10,11 +10,25 @@ namespace System.Reflection
 {
     internal sealed class SignatureConstructedGenericType : SignatureType
     {
-        internal SignatureConstructedGenericType(Type genericTypeDefinition, Type[] genericTypeArguments)
+        // The exception-visible name "typeArguments" is chosen to match the parameter name to Type.MakeGenericType() since that's the
+        // intended user of this constructor.
+        internal SignatureConstructedGenericType(Type genericTypeDefinition, Type[] typeArguments)
         {
-            Debug.Assert(genericTypeDefinition != null && genericTypeArguments != null);
+            if (genericTypeDefinition == null)
+                throw new ArgumentNullException(nameof(genericTypeDefinition));
+
+            if (typeArguments == null)
+                throw new ArgumentNullException(nameof(typeArguments));
+
+            typeArguments = (Type[])(typeArguments.Clone());
+            for (int i = 0; i < typeArguments.Length; i++)
+            {
+                if (typeArguments[i] == null)
+                    throw new ArgumentNullException(nameof(typeArguments));
+            }
+
             _genericTypeDefinition = genericTypeDefinition;
-            _genericTypeArguments = (Type[])(genericTypeArguments.Clone());
+            _genericTypeArguments = typeArguments;
         }
     
         public sealed override bool IsTypeDefinition => false;
index ee07f09..a4b5680 100644 (file)
@@ -539,242 +539,290 @@ namespace System.Runtime.Intrinsics.X86
         /// <summary>
         /// __m128i _mm_i32gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i32gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128 _mm_i32gather_ps (float const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERDPS xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128d _mm_i32gather_pd (double const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERDPD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i64gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i64gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i64gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_i64gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128 _mm_i64gather_ps (float const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERQPS xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128d _mm_i64gather_pd (double const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERQPD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<int> GatherVector256(int* baseAddress, Vector256<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<uint> GatherVector256(uint* baseAddress, Vector256<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256 _mm256_i32gather_ps (float const* base_addr, __m256i vindex, const int scale)
         ///   VGATHERDPS ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<float> GatherVector256(float* baseAddress, Vector256<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256d _mm256_i32gather_pd (double const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERDPD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector128<int> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm256_i64gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
-        ///   VPGATHERQD ymm, vm64y, ymm
+        ///   VPGATHERQD xmm, vm64y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector256<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm256_i64gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
-        ///   VPGATHERQD ymm, vm64y, ymm
+        ///   VPGATHERQD xmm, vm64y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector256<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_i64gather_epi64 (__int64 const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERQQ ymm, vm64y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector256<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_i64gather_epi64 (__int64 const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERQQ ymm, vm64y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector256<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128 _mm256_i64gather_ps (float const* base_addr, __m256i vindex, const int scale)
-        ///   VGATHERQPS ymm, vm64y, ymm
+        ///   VGATHERQPS xmm, vm64y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector256<long> index, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256d _mm256_i64gather_pd (double const* base_addr, __m256i vindex, const int scale)
         ///   VGATHERQPD ymm, vm64y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector256<long> index, byte scale) { throw new PlatformNotSupportedException(); }
 
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<int> index, Vector128<int> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<int> index, Vector128<uint> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<int> index, Vector128<long> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<int> index, Vector128<ulong> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128 _mm_mask_i32gather_ps (__m128 src, float const* base_addr, __m128i vindex, __m128 mask, const int scale)
         ///   VGATHERDPS xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<int> index, Vector128<float> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128d _mm_mask_i32gather_pd (__m128d src, double const* base_addr, __m128i vindex, __m128d mask, const int scale)
         ///   VGATHERDPD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<int> index, Vector128<double> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<long> index, Vector128<int> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<long> index, Vector128<uint> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<long> index, Vector128<long> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<long> index, Vector128<ulong> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128 _mm_mask_i64gather_ps (__m128 src, float const* base_addr, __m128i vindex, __m128 mask, const int scale)
-        ///   VPGATHERQPS xmm, vm64x, xmm
+        ///   VGATHERQPS xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<long> index, Vector128<float> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128d _mm_mask_i64gather_pd (__m128d src, double const* base_addr, __m128i vindex, __m128d mask, const int scale)
-        ///   VPGATHERQPD xmm, vm64x, xmm
+        ///   VGATHERQPD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<long> index, Vector128<double> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi32 (__m256i src, int const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<int> GatherMaskVector256(Vector256<int> source, int* baseAddress, Vector256<int> index, Vector256<int> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi32 (__m256i src, int const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<uint> GatherMaskVector256(Vector256<uint> source, uint* baseAddress, Vector256<int> index, Vector256<uint> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi64 (__m256i src, __int64 const* base_addr, __m128i vindex, __m256i mask, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector128<int> index, Vector256<long> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi64 (__m256i src, __int64 const* base_addr, __m128i vindex, __m256i mask, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector128<int> index, Vector256<ulong> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256 _mm256_mask_i32gather_ps (__m256 src, float const* base_addr, __m256i vindex, __m256 mask, const int scale)
         ///   VPGATHERDPS ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<float> GatherMaskVector256(Vector256<float> source, float* baseAddress, Vector256<int> index, Vector256<float> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256d _mm256_mask_i32gather_pd (__m256d src, double const* base_addr, __m128i vindex, __m256d mask, const int scale)
         ///   VPGATHERDPD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector128<int> index, Vector256<double> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm256_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m256i vindex, __m128i mask, const int scale)
-        ///   VPGATHERQD ymm, vm32y, ymm
+        ///   VPGATHERQD xmm, vm32y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector256<long> index, Vector128<int> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm256_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m256i vindex, __m128i mask, const int scale)
-        ///   VPGATHERQD ymm, vm32y, ymm
+        ///   VPGATHERQD xmm, vm32y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector256<long> index, Vector128<uint> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_mask_i64gather_epi64 (__m256i src, __int64 const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERQQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector256<long> index, Vector256<long> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256i _mm256_mask_i64gather_epi64 (__m256i src, __int64 const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERQQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector256<long> index, Vector256<ulong> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128 _mm256_mask_i64gather_ps (__m128 src, float const* base_addr, __m256i vindex, __m128 mask, const int scale)
-        ///   VPGATHERQPS ymm, vm32y, ymm
+        ///   VGATHERQPS xmm, vm32y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector256<long> index, Vector128<float> mask, byte scale) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m256d _mm256_mask_i64gather_pd (__m256d src, double const* base_addr, __m256i vindex, __m256d mask, const int scale)
-        ///   VPGATHERQPD ymm, vm32y, ymm
+        ///   VGATHERQPD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
         public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector256<long> index, Vector256<double> mask, byte scale) { throw new PlatformNotSupportedException(); }
 
index 1f92cbf..2e949dc 100644 (file)
@@ -545,244 +545,1012 @@ namespace System.Runtime.Intrinsics.X86
         /// <summary>
         /// __m128i _mm_i32gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<int> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i32gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<int> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<int> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<int> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128 _mm_i32gather_ps (float const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERDPS xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<int> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128d _mm_i32gather_pd (double const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERDPD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<int> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i64gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i64gather_epi32 (int const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i64gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_i64gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128 _mm_i64gather_ps (float const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERQPS xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128d _mm_i64gather_pd (double const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERQPD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<int> GatherVector256(int* baseAddress, Vector256<int> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<int> GatherVector256(int* baseAddress, Vector256<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<uint> GatherVector256(uint* baseAddress, Vector256<int> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<uint> GatherVector256(uint* baseAddress, Vector256<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector128<int> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_i32gather_epi64 (__int64 const* base_addr, __m128i vindex, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector128<int> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256 _mm256_i32gather_ps (float const* base_addr, __m256i vindex, const int scale)
         ///   VGATHERDPS ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<float> GatherVector256(float* baseAddress, Vector256<int> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<float> GatherVector256(float* baseAddress, Vector256<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256d _mm256_i32gather_pd (double const* base_addr, __m128i vindex, const int scale)
         ///   VGATHERDPD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector128<int> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector128<int> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm256_i64gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
-        ///   VPGATHERQD ymm, vm64y, ymm
+        ///   VPGATHERQD xmm, vm64y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector256<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector256<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm256_i64gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
-        ///   VPGATHERQD ymm, vm64y, ymm
+        ///   VPGATHERQD xmm, vm64y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector256<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector256<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_i64gather_epi64 (__int64 const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERQQ ymm, vm64y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector256<long> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector256<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_i64gather_epi64 (__int64 const* base_addr, __m256i vindex, const int scale)
         ///   VPGATHERQQ ymm, vm64y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector256<long> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector256<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128 _mm256_i64gather_ps (float const* base_addr, __m256i vindex, const int scale)
-        ///   VGATHERQPS ymm, vm64y, ymm
+        ///   VGATHERQPS xmm, vm64y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector256<long> index, byte scale) => GatherVector128(baseAddress, index, scale);
+        public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector256<long> index, byte scale) 
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector128(baseAddress, index, 1);
+                case 2:
+                    return GatherVector128(baseAddress, index, 2);
+                case 4:
+                    return GatherVector128(baseAddress, index, 4);
+                case 8:
+                    return GatherVector128(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256d _mm256_i64gather_pd (double const* base_addr, __m256i vindex, const int scale)
         ///   VGATHERQPD ymm, vm64y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector256<long> index, byte scale) => GatherVector256(baseAddress, index, scale);
+        public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector256<long> index, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherVector256(baseAddress, index, 1);
+                case 2:
+                    return GatherVector256(baseAddress, index, 2);
+                case 4:
+                    return GatherVector256(baseAddress, index, 4);
+                case 8:
+                    return GatherVector256(baseAddress, index, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
 
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<int> index, Vector128<int> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<int> index, Vector128<int> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<int> index, Vector128<uint> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<int> index, Vector128<uint> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<int> index, Vector128<long> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<int> index, Vector128<long> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i32gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERDQ xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<int> index, Vector128<ulong> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<int> index, Vector128<ulong> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128 _mm_mask_i32gather_ps (__m128 src, float const* base_addr, __m128i vindex, __m128 mask, const int scale)
         ///   VGATHERDPS xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<int> index, Vector128<float> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<int> index, Vector128<float> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128d _mm_mask_i32gather_pd (__m128d src, double const* base_addr, __m128i vindex, __m128d mask, const int scale)
         ///   VGATHERDPD xmm, vm32x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<int> index, Vector128<double> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<int> index, Vector128<double> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<long> index, Vector128<int> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<long> index, Vector128<int> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<long> index, Vector128<uint> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<long> index, Vector128<uint> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<long> index, Vector128<long> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<long> index, Vector128<long> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm_mask_i64gather_epi64 (__m128i src, __int64 const* base_addr, __m128i vindex, __m128i mask, const int scale)
         ///   VPGATHERQQ xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<long> index, Vector128<ulong> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<long> index, Vector128<ulong> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128 _mm_mask_i64gather_ps (__m128 src, float const* base_addr, __m128i vindex, __m128 mask, const int scale)
-        ///   VPGATHERQPS xmm, vm64x, xmm
+        ///   VGATHERQPS xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<long> index, Vector128<float> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<long> index, Vector128<float> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128d _mm_mask_i64gather_pd (__m128d src, double const* base_addr, __m128i vindex, __m128d mask, const int scale)
-        ///   VPGATHERQPD xmm, vm64x, xmm
+        ///   VGATHERQPD xmm, vm64x, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<long> index, Vector128<double> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<long> index, Vector128<double> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi32 (__m256i src, int const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<int> GatherMaskVector256(Vector256<int> source, int* baseAddress, Vector256<int> index, Vector256<int> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<int> GatherMaskVector256(Vector256<int> source, int* baseAddress, Vector256<int> index, Vector256<int> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi32 (__m256i src, int const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERDD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<uint> GatherMaskVector256(Vector256<uint> source, uint* baseAddress, Vector256<int> index, Vector256<uint> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<uint> GatherMaskVector256(Vector256<uint> source, uint* baseAddress, Vector256<int> index, Vector256<uint> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi64 (__m256i src, __int64 const* base_addr, __m128i vindex, __m256i mask, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector128<int> index, Vector256<long> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector128<int> index, Vector256<long> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_mask_i32gather_epi64 (__m256i src, __int64 const* base_addr, __m128i vindex, __m256i mask, const int scale)
         ///   VPGATHERDQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector128<int> index, Vector256<ulong> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector128<int> index, Vector256<ulong> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256 _mm256_mask_i32gather_ps (__m256 src, float const* base_addr, __m256i vindex, __m256 mask, const int scale)
         ///   VPGATHERDPS ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<float> GatherMaskVector256(Vector256<float> source, float* baseAddress, Vector256<int> index, Vector256<float> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<float> GatherMaskVector256(Vector256<float> source, float* baseAddress, Vector256<int> index, Vector256<float> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256d _mm256_mask_i32gather_pd (__m256d src, double const* base_addr, __m128i vindex, __m256d mask, const int scale)
         ///   VPGATHERDPD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector128<int> index, Vector256<double> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector128<int> index, Vector256<double> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm256_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m256i vindex, __m128i mask, const int scale)
-        ///   VPGATHERQD ymm, vm32y, ymm
+        ///   VPGATHERQD xmm, vm32y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector256<long> index, Vector128<int> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector256<long> index, Vector128<int> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128i _mm256_mask_i64gather_epi32 (__m128i src, int const* base_addr, __m256i vindex, __m128i mask, const int scale)
-        ///   VPGATHERQD ymm, vm32y, ymm
+        ///   VPGATHERQD xmm, vm32y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector256<long> index, Vector128<uint> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector256<long> index, Vector128<uint> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_mask_i64gather_epi64 (__m256i src, __int64 const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERQQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector256<long> index, Vector256<long> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector256<long> index, Vector256<long> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256i _mm256_mask_i64gather_epi64 (__m256i src, __int64 const* base_addr, __m256i vindex, __m256i mask, const int scale)
         ///   VPGATHERQQ ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector256<long> index, Vector256<ulong> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector256<long> index, Vector256<ulong> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m128 _mm256_mask_i64gather_ps (__m128 src, float const* base_addr, __m256i vindex, __m128 mask, const int scale)
-        ///   VPGATHERQPS ymm, vm32y, ymm
+        ///   VGATHERQPS xmm, vm32y, xmm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector256<long> index, Vector128<float> mask, byte scale) => GatherMaskVector128(source, baseAddress, index, mask, scale);
+        public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector256<long> index, Vector128<float> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector128(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
         /// <summary>
         /// __m256d _mm256_mask_i64gather_pd (__m256d src, double const* base_addr, __m256i vindex, __m256d mask, const int scale)
-        ///   VPGATHERQPD ymm, vm32y, ymm
+        ///   VGATHERQPD ymm, vm32y, ymm
+        /// The scale parameter should be 1, 2, 4 or 8, otherwise, ArgumentOutOfRangeException will be thrown.
         /// </summary>
-        public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector256<long> index, Vector256<double> mask, byte scale) => GatherMaskVector256(source, baseAddress, index, mask, scale);
+        public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector256<long> index, Vector256<double> mask, byte scale)
+        {
+            switch (scale)
+            {
+                case 1:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 1);
+                case 2:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 2);
+                case 4:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 4);
+                case 8:
+                    return GatherMaskVector256(source, baseAddress, index, mask, 8);
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(scale));
+            }
+        }
 
         /// <summary>
         /// __m256i _mm256_hadd_epi16 (__m256i a, __m256i b)
index a1ec168..b79e50a 100644 (file)
@@ -21,11 +21,11 @@ namespace System.Runtime.Intrinsics.X86
         /// __m128i _mm_clmulepi64_si128 (__m128i a, __m128i b, const int imm8)
         ///   PCLMULQDQ xmm, xmm/m128, imm8
         /// </summary>
-        public static Vector128<long> CarryLessMultiply(Vector128<long> left, Vector128<long> right, byte control) { throw new PlatformNotSupportedException(); }
+        public static Vector128<long> CarrylessMultiply(Vector128<long> left, Vector128<long> right, byte control) { throw new PlatformNotSupportedException(); }
         /// <summary>
         /// __m128i _mm_clmulepi64_si128 (__m128i a, __m128i b, const int imm8)
         ///   PCLMULQDQ xmm, xmm/m128, imm8
         /// </summary>
-        public static Vector128<ulong> CarryLessMultiply(Vector128<ulong> left, Vector128<ulong> right, byte control) { throw new PlatformNotSupportedException(); }
+        public static Vector128<ulong> CarrylessMultiply(Vector128<ulong> left, Vector128<ulong> right, byte control) { throw new PlatformNotSupportedException(); }
     }
 }
index c2ed5bf..c108e65 100644 (file)
@@ -21,11 +21,11 @@ namespace System.Runtime.Intrinsics.X86
         /// __m128i _mm_clmulepi64_si128 (__m128i a, __m128i b, const int imm8)
         ///   PCLMULQDQ xmm, xmm/m128, imm8
         /// </summary>
-        public static Vector128<long> CarryLessMultiply(Vector128<long> left, Vector128<long> right, byte control) => CarryLessMultiply(left, right, control);
+        public static Vector128<long> CarrylessMultiply(Vector128<long> left, Vector128<long> right, byte control) => CarrylessMultiply(left, right, control);
         /// <summary>
         /// __m128i _mm_clmulepi64_si128 (__m128i a, __m128i b, const int imm8)
         ///   PCLMULQDQ xmm, xmm/m128, imm8
         /// </summary>
-        public static Vector128<ulong> CarryLessMultiply(Vector128<ulong> left, Vector128<ulong> right, byte control) => CarryLessMultiply(left, right, control);
+        public static Vector128<ulong> CarrylessMultiply(Vector128<ulong> left, Vector128<ulong> right, byte control) => CarrylessMultiply(left, right, control);
     }
 }
index 21cc3dc..74b5dac 100644 (file)
@@ -50,9 +50,20 @@ namespace System.Text
 
         /// <summary>
         /// Get a pinnable reference to the builder.
+        /// Does not ensure there is a null char after <see cref="Length"/>
+        /// This overload is pattern matched in the C# 7.3+ compiler so you can omit
+        /// the explicit method call, and write eg "fixed (char* c = builder)"
+        /// </summary>
+        public ref char GetPinnableReference()
+        {
+            return ref MemoryMarshal.GetReference(_chars);
+        }
+
+        /// <summary>
+        /// Get a pinnable reference to the builder.
         /// </summary>
         /// <param name="terminate">Ensures that the builder has a null char after <see cref="Length"/></param>
-        public ref char GetPinnableReference(bool terminate = false)
+        public ref char GetPinnableReference(bool terminate)
         {
             if (terminate)
             {
index 79f6b6f..c78d988 100644 (file)
@@ -346,6 +346,8 @@ namespace System
         public virtual Type MakeGenericType(params Type[] typeArguments) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
         public virtual Type MakePointerType() { throw new NotSupportedException(); }
 
+        public static Type MakeGenericSignatureType(Type genericTypeDefinition, params Type[] typeArguments) => new SignatureConstructedGenericType(genericTypeDefinition, typeArguments);
+
         public static Type MakeGenericMethodParameter(int position)
         {
             if (position < 0)
index 767fadf..c1c6e4f 100644 (file)
@@ -500,7 +500,7 @@ namespace System.Reflection
         #endregion
 
         #region Public Members
-        public Type AttributeType { get { return Constructor.DeclaringType; } }
+        public virtual Type AttributeType { get { return Constructor.DeclaringType; } }
 
         public virtual ConstructorInfo Constructor { get { return m_ctor; } }
 
index bd34ff9..e1673bc 100644 (file)
@@ -220,5 +220,5 @@ target_link_libraries(sos ${SOS_LIBRARY})
 install_clr(sos)
 
 if(NOT WIN32)
-  install(FILES sosdocsunix.txt DESTINATION .)
+  _install(FILES sosdocsunix.txt DESTINATION .)
 endif(NOT WIN32)
index 5a5680f..c28c964 100644 (file)
@@ -868,8 +868,7 @@ DWORD GetNumComponents(TADDR obj)
     return Value;
 }
 
-BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj, 
-    DWORD_PTR dwAddrMethTable, BOOL bLarge, size_t& s, BOOL& bContainsPointers)
+static MethodTableInfo* GetMethodTableInfo(DWORD_PTR dwAddrMethTable)
 {
     // Remove lower bits in case we are in mark phase
     dwAddrMethTable = dwAddrMethTable & ~3;
@@ -880,12 +879,34 @@ BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
         // from the target
         DacpMethodTableData dmtd;
         // see code:ClrDataAccess::RequestMethodTableData for details
-        if (dmtd.Request(g_sos,dwAddrMethTable) != S_OK)
-            return FALSE;
+        if (dmtd.Request(g_sos, dwAddrMethTable) != S_OK)
+            return NULL;
+
 
         info->BaseSize = dmtd.BaseSize;
         info->ComponentSize = dmtd.ComponentSize;
         info->bContainsPointers = dmtd.bContainsPointers;
+
+        // The following request doesn't work on older runtimes. For those, the
+        // objects would just look like non-collectible, which is acceptable.
+        DacpMethodTableCollectibleData dmtcd;
+        if (SUCCEEDED(dmtcd.Request(g_sos, dwAddrMethTable)))
+        {
+            info->bCollectible = dmtcd.bCollectible;
+            info->LoaderAllocatorObjectHandle = TO_TADDR(dmtcd.LoaderAllocatorObjectHandle);
+        }
+    }
+
+    return info;
+}
+
+BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj, 
+    DWORD_PTR dwAddrMethTable, BOOL bLarge, size_t& s, BOOL& bContainsPointers)
+{
+    MethodTableInfo* info = GetMethodTableInfo(dwAddrMethTable);
+    if (info == NULL)
+    {
+        return FALSE;
     }
         
     bContainsPointers = info->bContainsPointers;
@@ -911,6 +932,20 @@ BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
     return TRUE;
 }
 
+BOOL GetCollectibleDataEfficient(DWORD_PTR dwAddrMethTable, BOOL& bCollectible, TADDR& loaderAllocatorObjectHandle)
+{
+    MethodTableInfo* info = GetMethodTableInfo(dwAddrMethTable);
+    if (info == NULL)
+    {
+        return FALSE;
+    }
+
+    bCollectible = info->bCollectible;
+    loaderAllocatorObjectHandle = info->LoaderAllocatorObjectHandle;
+
+    return TRUE;
+}
+
 // This function expects stat to be valid, and ready to get statistics.
 void GatherOneHeapFinalization(DacpGcHeapDetails& heapDetails, HeapStat *stat, BOOL bAllReady, BOOL bShort)
 {
index e426220..cd13719 100644 (file)
@@ -1009,7 +1009,7 @@ GCRootImpl::RootNode *GCRootImpl::GetGCRefs(RootNode *path, RootNode *node)
 
     // Only calculate the size if we need it.
     size_t objSize = 0;
-    if (mSize || node->MTInfo->ContainsPointers)
+    if (mSize || node->MTInfo->ContainsPointers || node->MTInfo->Collectible)
     {
         objSize = GetSizeOfObject(obj, node->MTInfo);
         
@@ -1027,7 +1027,7 @@ GCRootImpl::RootNode *GCRootImpl::GetGCRefs(RootNode *path, RootNode *node)
     }
     
     // Early out:  If the object doesn't contain any pointers, return.
-    if (!node->MTInfo->ContainsPointers)
+    if (!node->MTInfo->ContainsPointers && !node->MTInfo->Collectible)
         return NULL;
     
     // Make sure we have the object's data in the cache.
@@ -1139,6 +1139,15 @@ GCRootImpl::MTInfo *GCRootImpl::GetMTInfo(TADDR mt)
     curr->ComponentSize = (size_t)dmtd.ComponentSize;
     curr->ContainsPointers = dmtd.bContainsPointers ? true : false;
 
+    // The following request doesn't work on older runtimes. For those, the
+    // objects would just look like non-collectible, which is acceptable.
+    DacpMethodTableCollectibleData dmtcd;
+    if (SUCCEEDED(dmtcd.Request(g_sos, mt)))
+    {
+        curr->Collectible = dmtcd.bCollectible ? true : false;
+        curr->LoaderAllocatorObjectHandle = TO_TADDR(dmtcd.LoaderAllocatorObjectHandle);
+    }
+
     // If this method table contains pointers, fill out and cache the GCDesc.
     if (curr->ContainsPointers)
     {
index 64ee4b9..5ff77a9 100644 (file)
@@ -180,6 +180,15 @@ namespace sos
             info->BaseSize = mMTData->BaseSize;
             info->ComponentSize = mMTData->ComponentSize;
             info->bContainsPointers = mMTData->bContainsPointers;
+
+            // The following request doesn't work on older runtimes. For those, the
+            // objects would just look like non-collectible, which is acceptable.
+            DacpMethodTableCollectibleData mtcd;
+            if (SUCCEEDED(mtcd.Request(g_sos, GetMT())))
+            {
+                info->bCollectible = mtcd.bCollectible;
+                info->LoaderAllocatorObjectHandle = TO_TADDR(mtcd.LoaderAllocatorObjectHandle);
+            }
         }
         
         if (mSize == (size_t)~0)
@@ -380,14 +389,14 @@ namespace sos
 
 
     RefIterator::RefIterator(TADDR obj, LinearReadCache *cache)
-        : mCache(cache), mGCDesc(0), mArrayOfVC(false), mDone(false), mBuffer(0), mCurrSeries(0),
+        : mCache(cache), mGCDesc(0), mArrayOfVC(false), mDone(false), mBuffer(0), mCurrSeries(0), mLoaderAllocatorObjectHandle(0),
           i(0), mCount(0), mCurr(0), mStop(0), mObject(obj), mObjSize(0)
     {
         Init();
     }
 
     RefIterator::RefIterator(TADDR obj, CGCDesc *desc, bool arrayOfVC, LinearReadCache *cache)
-        : mCache(cache), mGCDesc(desc), mArrayOfVC(arrayOfVC), mDone(false), mBuffer(0), mCurrSeries(0),
+        : mCache(cache), mGCDesc(desc), mArrayOfVC(arrayOfVC), mDone(false), mBuffer(0), mCurrSeries(0), mLoaderAllocatorObjectHandle(0),
           i(0), mCount(0), mCurr(0), mStop(0), mObject(obj), mObjSize(0)
     {
         Init();
@@ -403,6 +412,13 @@ namespace sos
     {
         if (mDone)
             Throw<Exception>("Attempt to move past the end of the iterator.");
+
+        if (mCurr == mLoaderAllocatorObjectHandle)
+        {
+            // The mLoaderAllocatorObjectHandle is always the last reference returned
+            mDone = true;
+            return *this;
+        }
         
         if (!mArrayOfVC)
         {
@@ -440,6 +456,14 @@ namespace sos
                 mDone = true;
         }
         
+        if (mDone && mLoaderAllocatorObjectHandle != NULL)
+        {
+            // The iteration over all regular object references is done, but there is one more
+            // reference for collectible types - the LoaderAllocator for GC
+            mCurr = mLoaderAllocatorObjectHandle;
+            mDone = false;
+        }
+
         return *this;
     }
     
@@ -457,66 +481,89 @@ namespace sos
     {
         TADDR mt = ReadPointer(mObject);
         BOOL bContainsPointers = FALSE;
-        
+        BOOL bCollectible = FALSE;
+        TADDR loaderAllocatorObjectHandle;
+
         if (!GetSizeEfficient(mObject, mt, FALSE, mObjSize, bContainsPointers))
             Throw<DataRead>("Failed to get size of object.");
-        
-        if (!bContainsPointers)
+
+        if (!GetCollectibleDataEfficient(mt, bCollectible, loaderAllocatorObjectHandle))
+            Throw<DataRead>("Failed to get collectible info of object.");
+
+        if (!bContainsPointers && !bCollectible)
         {
             mDone = true;
             return;
         }
-        
-        if (!mGCDesc)
+
+        if (bContainsPointers)
         {
-            int entries = 0;
-            
-            if (FAILED(MOVE(entries, mt-sizeof(TADDR))))
-                Throw<DataRead>("Failed to request number of entries.");
-            
-            // array of vc?
-            if (entries < 0)
+            if (!mGCDesc)
             {
-                entries = -entries;
-                mArrayOfVC = true;
+                int entries = 0;
+
+                if (FAILED(MOVE(entries, mt-sizeof(TADDR))))
+                    Throw<DataRead>("Failed to request number of entries.");
+
+                // array of vc?
+                if (entries < 0)
+                {
+                    entries = -entries;
+                    mArrayOfVC = true;
+                }
+                else
+                {
+                    mArrayOfVC = false;
+                }
+
+                size_t slots = 1 + entries * sizeof(CGCDescSeries)/sizeof(TADDR);
+
+                ArrayHolder<TADDR> buffer = new TADDR[slots];
+
+                ULONG fetched = 0;
+                CLRDATA_ADDRESS address = TO_CDADDR(mt - slots*sizeof(TADDR));
+                if (FAILED(g_ExtData->ReadVirtual(address, buffer, (ULONG)(slots*sizeof(TADDR)), &fetched)))
+                    Throw<DataRead>("Failed to request GCDesc.");
+
+                mBuffer = buffer.Detach();
+                mGCDesc = (CGCDesc*)(mBuffer + slots);
+            }
+
+            mCurrSeries = mGCDesc->GetHighestSeries();
+
+            if (!mArrayOfVC)
+            {
+                mCurr = mObject + mCurrSeries->GetSeriesOffset();
+                mStop = mCurr + mCurrSeries->GetSeriesSize() + mObjSize;
             }
             else
             {
-                mArrayOfVC = false;
+                i = 0;
+                mCurr = mObject + mCurrSeries->startoffset;
+                mStop = mCurr + mCurrSeries->val_serie[i].nptrs * sizeof(TADDR);
+                mCount = (int)mGCDesc->GetNumSeries();
             }
-            
-            size_t slots = 1 + entries * sizeof(CGCDescSeries)/sizeof(TADDR);
-            
-            ArrayHolder<TADDR> buffer = new TADDR[slots];
-            
-            ULONG fetched = 0;
-            CLRDATA_ADDRESS address = TO_CDADDR(mt - slots*sizeof(TADDR));
-            if (FAILED(g_ExtData->ReadVirtual(address, buffer, (ULONG)(slots*sizeof(TADDR)), &fetched)))
-                Throw<DataRead>("Failed to request GCDesc.");
-            
-            mBuffer = buffer.Detach();
-            mGCDesc = (CGCDesc*)(mBuffer + slots);
+
+            if (mCurr == mStop)
+                operator++();
+            else if (mCurr >= mObject + mObjSize - plug_skew)
+                mDone = true;
         }
-        
-        mCurrSeries = mGCDesc->GetHighestSeries();
-        
-        if (!mArrayOfVC)
+        else
         {
-            mCurr = mObject + mCurrSeries->GetSeriesOffset();
-            mStop = mCurr + mCurrSeries->GetSeriesSize() + mObjSize;
+            mDone = true;
         }
-        else
+
+        if (bCollectible)
         {
-            i = 0;
-            mCurr = mObject + mCurrSeries->startoffset;
-            mStop = mCurr + mCurrSeries->val_serie[i].nptrs * sizeof(TADDR);
-            mCount = (int)mGCDesc->GetNumSeries();
+            mLoaderAllocatorObjectHandle = loaderAllocatorObjectHandle;
+            if (mDone)
+            {
+                // There are no object references, but there is still a reference for 
+                // collectible types - the LoaderAllocator for GC
+                mCurr = mLoaderAllocatorObjectHandle;
+            }
         }
-        
-        if (mCurr == mStop)
-          operator++();
-        else if (mCurr >= mObject + mObjSize - plug_skew)
-          mDone = true;
     }
 
 
index 3778235..ff5b53a 100644 (file)
@@ -501,6 +501,8 @@ namespace sos
         TADDR *mBuffer;
         CGCDescSeries *mCurrSeries;
         
+        TADDR mLoaderAllocatorObjectHandle;
+
         int i, mCount;
         
         TADDR mCurr, mStop, mObject;
index 7851654..ebad2e4 100644 (file)
@@ -1660,9 +1660,11 @@ struct MethodTableInfo
     DWORD BaseSize;           // Caching BaseSize and ComponentSize for a MethodTable
     DWORD ComponentSize;      // here has HUGE perf benefits in heap traversals.
     BOOL  bContainsPointers;
+    BOOL  bCollectible;
     DWORD_PTR* GCInfoBuffer;  // Start of memory of GC info
     CGCDesc* GCInfo;    // Just past GC info (which is how it is stored)
     bool  ArrayOfVC;
+    TADDR LoaderAllocatorObjectHandle;
 };
 
 class MethodTableCache
@@ -1680,9 +1682,11 @@ protected:
             info.BaseSize = 0;
             info.ComponentSize = 0;
             info.bContainsPointers = false;
+            info.bCollectible = false;
             info.GCInfo = NULL;
             info.ArrayOfVC = false;
             info.GCInfoBuffer = NULL;
+            info.LoaderAllocatorObjectHandle = NULL;
         }
     };
     Node *head;
@@ -1948,6 +1952,8 @@ size_t NextOSPageAddress (size_t addr);
 BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj, 
     DWORD_PTR dwAddrMethTable, BOOL bLarge, size_t& s, BOOL& bContainsPointers);
 
+BOOL GetCollectibleDataEfficient(DWORD_PTR dwAddrMethTable, BOOL& bCollectible, TADDR& loaderAllocatorObjectHandle);
+
 // ObjSize now uses the methodtable cache for its work too.
 size_t ObjectSize (DWORD_PTR obj, BOOL fIsLargeObject=FALSE);
 size_t ObjectSize(DWORD_PTR obj, DWORD_PTR mt, BOOL fIsValueClass, BOOL fIsLargeObject=FALSE);
@@ -2856,8 +2862,10 @@ private:
         TADDR *Buffer;
         CGCDesc *GCDesc;
 
+        TADDR LoaderAllocatorObjectHandle;
         bool ArrayOfVC;
         bool ContainsPointers;
+        bool Collectible;
         size_t BaseSize;
         size_t ComponentSize;
         
@@ -2874,7 +2882,7 @@ private:
 
         MTInfo()
             : MethodTable(0), TypeName(0), Buffer(0), GCDesc(0),
-              ArrayOfVC(false), ContainsPointers(false), BaseSize(0), ComponentSize(0)
+              ArrayOfVC(false), ContainsPointers(false), Collectible(false), BaseSize(0), ComponentSize(0)
         {
         }
 
index 0fc9e88..e0138f6 100644 (file)
@@ -44,7 +44,7 @@ bool Grisu3::Run(double value, int count, int* dec, int* sign, wchar_t* digits)
     // kappa: A factor used for generating digits. See step 5 of the Grisu3 procedure in the paper.
 
     // Handle sign bit.
-    if (value < 0)
+    if (_signbit(value) != 0)
     {
         value = -value;
         *sign = 1;
@@ -378,4 +378,4 @@ void Grisu3::BiggestPowerTenLessThanOrEqualTo(UINT32 number,
         *exponent = 0;
         UNREACHABLE();
     }
-}
\ No newline at end of file
+}
index b3c5a40..7f8ec82 100644 (file)
 
 #include "diyfp.h"
 
+#ifdef _MSC_VER
+#define _signbit signbit
+#define _signbitf signbit
+#endif
+
 struct PowerOfTen
 {
     UINT64 significand;
index b20044e..e8db5ab 100644 (file)
@@ -18,13 +18,6 @@ typedef wchar_t wchar;
 #define SCALE_NAN 0x80000000
 #define SCALE_INF 0x7FFFFFFF
 
-#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
-
-extern "C" void _cdecl /*__stdcall*/ DoubleToNumber(double value, int precision, NUMBER* number);
-extern "C" void _cdecl /*__stdcall*/ NumberToDouble(NUMBER* number, double* value);
-
-#else // _TARGET_X86_ && !FEATURE_PAL
-
 void Dragon4( double value, int count, int* dec, int* sign, wchar_t* digits )
 {
     // ========================================================================================================================================
@@ -288,7 +281,7 @@ void DoubleToNumberWorker( double value, int count, int* dec, int* sign, wchar_t
     if (value == 0.0)
     {
         *dec = 0;
-        *sign = 0;
+        *sign = _signbit(value);
 
         // Instead of zeroing digits, we just make it as an empty string due to performance reason.
         *digits = 0;
@@ -740,8 +733,6 @@ done:
     if (number->sign) *(UINT64*)value |= I64(0x8000000000000000);
 }
 
-#endif // _TARGET_X86_ && !FEATURE_PAL
-
 FCIMPL3_VII(void, COMNumber::DoubleToNumberFC, double value, int precision, NUMBER* number)
 {
     FCALL_CONTRACT;
index 22c74ca..480e6ad 100644 (file)
@@ -19,13 +19,21 @@ static const double LOG10V2 = 0.30102999566398119521373889472449;
 // DRIFT_FACTOR = 1 - LOG10V2 - epsilon (a small number account for drift of floating point multiplication)
 static const double DRIFT_FACTOR = 0.69;
 
+enum NUMBER_KIND : int {
+    NUMBER_KIND_Unknown = 0,
+    NUMBER_KIND_Integer = 1,
+    NUMBER_KIND_Decimal = 2,
+    NUMBER_KIND_Double = 3
+};
+
 struct NUMBER {
-    int precision;
-    int scale;
-    int sign;
-    wchar_t digits[NUMBER_MAXDIGITS + 1];
-    wchar_t* allDigits;
-    NUMBER() : precision(0), scale(0), sign(0), allDigits(NULL) {}
+    int precision;                          //  0
+    int scale;                              //  4
+    int sign;                               //  8
+    NUMBER_KIND kind;                       // 12
+    wchar_t* allDigits;                     // 16
+    wchar_t digits[NUMBER_MAXDIGITS + 1];   // 20 or 24
+    NUMBER() : precision(0), scale(0), sign(0), kind(NUMBER_KIND_Unknown), allDigits(NULL) {}
 };
 
 class COMNumber
index b02bd49..e250238 100644 (file)
@@ -19,12 +19,15 @@ FOR_ALL_ICU_FUNCTIONS
 static void* libicuuc = nullptr;
 static void* libicui18n = nullptr;
 
-// .x.x.x, considering the max number of decimal digits for each component
-static const int MaxICUVersionStringLength = 33;
+#define VERSION_PREFIX_NONE ""
+#define VERSION_PREFIX_SUSE "suse"
+
+// .[suse]x.x.x, considering the max number of decimal digits for each component
+static const int MaxICUVersionStringLength = sizeof(VERSION_PREFIX_SUSE) + 33;
 
 #ifdef __APPLE__
 
-bool FindICULibs(char* symbolName, char* symbolVersion)
+bool FindICULibs(const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
 #ifndef OSX_ICU_LIBRARY_PATH
     static_assert(false, "The ICU Library path is not defined");
@@ -63,11 +66,11 @@ static const int MaxSubICUVersion = 5;
 // 1. Only majorVer is not equal to -1 => result is baseFileName.majorver
 // 2. Only majorVer and minorVer are not equal to -1 => result is baseFileName.majorver.minorVer
 // 3. All components are not equal to -1 => result is baseFileName.majorver.minorVer.subver
-void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVer, int subVer, char* result)
+void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVer, int subVer, const char* versionPrefix, char* result)
 {
     assert(majorVer != -1);
 
-    int nameLen = sprintf(result, "%s.%d", baseFileName, majorVer);
+    int nameLen = sprintf(result, "%s.%s%d", baseFileName, versionPrefix, majorVer);
 
     if (minorVer != -1)
     {
@@ -110,16 +113,16 @@ bool FindSymbolVersion(int majorVer, int minorVer, int subVer, char* symbolName,
 }
 
 // Try to open the necessary ICU libraries
-bool OpenICULibraries(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion)
+bool OpenICULibraries(int majorVer, int minorVer, int subVer, const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
     char libicuucName[64];
     char libicui18nName[64];
 
     static_assert(sizeof("libicuuc.so") + MaxICUVersionStringLength <= sizeof(libicuucName), "The libicuucName is too small");
-    GetVersionedLibFileName("libicuuc.so", majorVer, minorVer, subVer, libicuucName);
+    GetVersionedLibFileName("libicuuc.so", majorVer, minorVer, subVer, versionPrefix, libicuucName);
 
     static_assert(sizeof("libicui18n.so") + MaxICUVersionStringLength <= sizeof(libicui18nName), "The libicui18nName is too small");
-    GetVersionedLibFileName("libicui18n.so", majorVer, minorVer, subVer, libicui18nName);
+    GetVersionedLibFileName("libicui18n.so", majorVer, minorVer, subVer, versionPrefix, libicui18nName);
 
     libicuuc = dlopen(libicuucName, RTLD_LAZY);
     if (libicuuc != nullptr)
@@ -142,7 +145,7 @@ bool OpenICULibraries(int majorVer, int minorVer, int subVer, char* symbolName,
 // environment variable.
 // The format of the string in this variable is majorVer[.minorVer[.subVer]] (the brackets
 // indicate optional parts).
-bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
+bool FindLibUsingOverride(const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
     char* versionOverride = getenv("CLR_ICU_VERSION_OVERRIDE");
     if (versionOverride != nullptr)
@@ -154,7 +157,7 @@ bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
         int matches = sscanf(versionOverride, "%d.%d.%d", &first, &second, &third);
         if (matches > 0)
         {
-            if (OpenICULibraries(first, second, third, symbolName, symbolVersion))
+            if (OpenICULibraries(first, second, third, versionPrefix, symbolName, symbolVersion))
             {
                 return true;
             }
@@ -165,13 +168,13 @@ bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
 }
 
 // Search for library files with names including the major version.
-bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
+bool FindLibWithMajorVersion(const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
     // ICU packaging documentation (http://userguide.icu-project.org/packaging)
     // describes applications link against the major (e.g. libicuuc.so.54).
 
     // Select the version of ICU present at build time.
-    if (OpenICULibraries(MinICUVersion, -1, -1, symbolName, symbolVersion))
+    if (OpenICULibraries(MinICUVersion, -1, -1, versionPrefix, symbolName, symbolVersion))
     {
         return true;
     }
@@ -179,7 +182,7 @@ bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
     // Select the highest supported version of ICU present on the local machine
     for (int i = MaxICUVersion; i > MinICUVersion; i--)
     {
-        if (OpenICULibraries(i, -1, -1, symbolName, symbolVersion))
+        if (OpenICULibraries(i, -1, -1, versionPrefix, symbolName, symbolVersion))
         {
             return true;
         }
@@ -190,13 +193,13 @@ bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
 
 // Select the highest supported version of ICU present on the local machine
 // Search for library files with names including the major and minor version.
-bool FindLibWithMajorMinorVersion(char* symbolName, char* symbolVersion)
+bool FindLibWithMajorMinorVersion(const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
     for (int i = MaxICUVersion; i >= MinICUVersion; i--)
     {
         for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
         {
-            if (OpenICULibraries(i, j, -1, symbolName, symbolVersion))
+            if (OpenICULibraries(i, j, -1, versionPrefix, symbolName, symbolVersion))
             {
                 return true;
             }
@@ -208,7 +211,7 @@ bool FindLibWithMajorMinorVersion(char* symbolName, char* symbolVersion)
 
 // Select the highest supported version of ICU present on the local machine
 // Search for library files with names including the major, minor and sub version.
-bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
+bool FindLibWithMajorMinorSubVersion(const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
     for (int i = MaxICUVersion; i >= MinICUVersion; i--)
     {
@@ -216,7 +219,7 @@ bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
         {
             for (int k = MaxSubICUVersion; k >= MinSubICUVersion; k--)
             {
-                if (OpenICULibraries(i, j, k, symbolName, symbolVersion))
+                if (OpenICULibraries(i, j, k, versionPrefix, symbolName, symbolVersion))
                 {
                     return true;
                 }
@@ -227,12 +230,13 @@ bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
     return false;
 }
 
-bool FindICULibs(char* symbolName, char* symbolVersion)
+
+bool FindICULibs(const char* versionPrefix, char* symbolName, char* symbolVersion)
 {
-    return FindLibUsingOverride(symbolName, symbolVersion) ||
-           FindLibWithMajorVersion(symbolName, symbolVersion) ||
-           FindLibWithMajorMinorVersion(symbolName, symbolVersion) ||
-           FindLibWithMajorMinorSubVersion(symbolName, symbolVersion);
+    return FindLibUsingOverride(versionPrefix, symbolName, symbolVersion) ||
+           FindLibWithMajorVersion(versionPrefix, symbolName, symbolVersion) ||
+           FindLibWithMajorMinorVersion(versionPrefix, symbolName, symbolVersion) ||
+           FindLibWithMajorMinorSubVersion(versionPrefix, symbolName, symbolVersion);
 }
 
 #endif // __APPLE__
@@ -246,8 +250,15 @@ extern "C" int32_t GlobalizationNative_LoadICU()
     char symbolName[128];
     char symbolVersion[MaxICUVersionStringLength + 1] = "";
 
-    if (!FindICULibs(symbolName, symbolVersion))
-        return 0;
+    if (!FindICULibs(VERSION_PREFIX_NONE, symbolName, symbolVersion))
+    {
+#ifndef __APPLE__
+        if (!FindICULibs(VERSION_PREFIX_SUSE, symbolName, symbolVersion))
+#endif
+        {
+            return 0;
+        }
+    }
 
     // Get pointers to all the ICU functions that are needed
 #define PER_FUNCTION_BLOCK(fn, lib) \
@@ -290,4 +301,4 @@ void ShutdownICUShim()
         dlclose(libicui18n);
         libicui18n = nullptr;
     }
-}
\ No newline at end of file
+}
index 8064691..6de6b94 100644 (file)
@@ -197,6 +197,10 @@ CrashInfo::GatherCrashInfo(MINIDUMP_TYPE minidumpType)
     // Add all the heap (read/write) memory regions (m_otherMappings contains the heaps)
     else if (minidumpType & MiniDumpWithPrivateReadWriteMemory)
     {
+        for (const MemoryRegion& region : m_moduleMappings)
+        {
+            InsertMemoryBackedRegion(region);
+        }
         for (const MemoryRegion& region : m_otherMappings)
         {
             if (region.Permissions() == (PF_R | PF_W))
index 1ce452b..e7bef87 100644 (file)
@@ -3278,6 +3278,10 @@ ClrDataAccess::QueryInterface(THIS_
     {
         ifaceRet = static_cast<ISOSDacInterface5*>(this);
     }
+    else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface6)))
+    {
+        ifaceRet = static_cast<ISOSDacInterface6*>(this);
+    }
     else
     {
         *iface = NULL;
index 6147de3..e05575c 100644 (file)
@@ -862,7 +862,8 @@ class ClrDataAccess
       public ISOSDacInterface2,
       public ISOSDacInterface3,
       public ISOSDacInterface4,
-      public ISOSDacInterface5
+      public ISOSDacInterface5,
+      public ISOSDacInterface6
 {
 public:
     ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0);
@@ -1208,6 +1209,9 @@ public:
     // ISOSDacInterface5
     virtual HRESULT STDMETHODCALLTYPE GetTieredVersions(CLRDATA_ADDRESS methodDesc, int rejitId, struct DacpTieredVersionData *nativeCodeAddrs, int cNativeCodeAddrs, int *pcNativeCodeAddrs);
 
+    // ISOSDacInterface6
+    virtual HRESULT STDMETHODCALLTYPE GetMethodTableCollectibleData(CLRDATA_ADDRESS mt, struct DacpMethodTableCollectibleData *data);
+
     //
     // ClrDataAccess.
     //
index 12864e7..3a497b1 100644 (file)
@@ -1955,6 +1955,33 @@ ClrDataAccess::GetMethodTableFieldData(CLRDATA_ADDRESS mt, struct DacpMethodTabl
 }
 
 HRESULT
+ClrDataAccess::GetMethodTableCollectibleData(CLRDATA_ADDRESS mt, struct DacpMethodTableCollectibleData *data)
+{
+    if (mt == 0 || data == NULL)
+        return E_INVALIDARG;
+
+    SOSDacEnter();
+
+    MethodTable* pMT = PTR_MethodTable(TO_TADDR(mt));
+    BOOL bIsFree = FALSE;
+    if (!pMT || !DacValidateMethodTable(pMT, bIsFree))
+    {
+        hr = E_INVALIDARG;
+    }
+    else
+    {
+        data->bCollectible = pMT->Collectible();
+        if (data->bCollectible)
+        {
+            data->LoaderAllocatorObjectHandle = pMT->GetLoaderAllocatorObjectHandle();
+        }
+    }
+
+    SOSDacLeave();
+    return hr;
+}
+
+HRESULT
 ClrDataAccess::GetMethodTableTransparencyData(CLRDATA_ADDRESS mt, struct DacpMethodTableTransparencyData *pTransparencyData)
 {
     if (mt == 0 || pTransparencyData == NULL)
index b91bb5b..653ec0d 100644 (file)
@@ -179,7 +179,11 @@ struct MSLAYOUT DebuggerIPCRuntimeOffsets
 // aren't any embedded buffers in the DebuggerIPCControlBlock).
 
 #if defined(DBG_TARGET_X86) || defined(DBG_TARGET_ARM)
+#ifdef _WIN64
+#define CorDBIPC_BUFFER_SIZE (2096)
+#else
 #define CorDBIPC_BUFFER_SIZE (2088) // hand tuned to ensure that ipc block in IPCHeader.h fits in 1 page.
+#endif
 #else  // !_TARGET_X86_ && !_TARGET_ARM_
 // This is the size of a DebuggerIPCEvent.  You will hit an assert in Cordb::Initialize() (DI\process.cpp)
 // if this is not defined correctly.  AMD64 actually has a page size of 0x1000, not 0x2000.
index a298563..713d7e0 100644 (file)
@@ -1086,6 +1086,7 @@ BEGIN
         BFA_BAD_CA_HEADER                       "Malformed custom attribute header."
         BFA_BAD_STRING_TOKEN                    "Bad string token."
         BFA_BAD_STRING_TOKEN_RANGE              "No string associated with token."
+        BFA_FIXUP_WRONG_PLATFORM                "Image has a platform-specific fixup type that is not compatible with this platform."
         BFA_UNEXPECTED_GENERIC_TOKENTYPE        "Token specifying generic type must be either a typeref or typedef."
         BFA_MDARRAY_BADRANK                     "Array rank may not be zero."
         BFA_SDARRAY_BADRANK                     "Single-dimensional array rank must be one."
index d58780f..0a42dad 100644 (file)
 #define BFA_BAD_CA_HEADER                       0x2050
 #define BFA_BAD_STRING_TOKEN                    0x2052
 #define BFA_BAD_STRING_TOKEN_RANGE              0x2053
+#define BFA_FIXUP_WRONG_PLATFORM                0x2054
 #define BFA_UNEXPECTED_GENERIC_TOKENTYPE        0x2055
 #define BFA_MDARRAY_BADRANK                     0x2056
 #define BFA_SDARRAY_BADRANK                     0x2057
index 7766bf9..feeac08 100644 (file)
@@ -125,6 +125,8 @@ import "wtypes.idl";
 import "unknwn.idl";
 #endif
 
+#define STDMETHODCALLTYPE
+
 typedef UINT_PTR ProcessID;
 typedef UINT_PTR AssemblyID;
 typedef UINT_PTR AppDomainID;
@@ -303,13 +305,13 @@ typedef struct _COR_PRF_METHOD
  * bits cleared for COR_PRF_ENABLE_FRAME_INFO, COR_PRF_ENABLE_FUNCTION_RETVAL
  * and COR_PRF_ENABLE_FUNCTION_ARGS.
  */
-typedef void __stdcall FunctionEnter(
+typedef void STDMETHODCALLTYPE FunctionEnter(
                 FunctionID funcID);
                 
-typedef void __stdcall FunctionLeave(
+typedef void STDMETHODCALLTYPE FunctionLeave(
                 FunctionID funcID);
                 
-typedef void __stdcall FunctionTailcall(
+typedef void STDMETHODCALLTYPE FunctionTailcall(
                 FunctionID funcID);
 
 /*
@@ -320,19 +322,19 @@ typedef void __stdcall FunctionTailcall(
  * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks.
  */
 
-typedef void __stdcall FunctionEnter2(
+typedef void STDMETHODCALLTYPE FunctionEnter2(
                 FunctionID funcId, 
                 UINT_PTR clientData, 
                 COR_PRF_FRAME_INFO func, 
                 COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo);
                 
-typedef void __stdcall FunctionLeave2(
+typedef void STDMETHODCALLTYPE FunctionLeave2(
                 FunctionID funcId, 
                 UINT_PTR clientData, 
                 COR_PRF_FRAME_INFO func, 
                 COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange);
                 
-typedef void __stdcall FunctionTailcall2(
+typedef void STDMETHODCALLTYPE FunctionTailcall2(
                 FunctionID funcId, 
                 UINT_PTR clientData, 
                 COR_PRF_FRAME_INFO func);
@@ -348,13 +350,13 @@ typedef void __stdcall FunctionTailcall2(
  * true FunctionID of the function.
  */
 
-typedef void __stdcall FunctionEnter3(
+typedef void STDMETHODCALLTYPE FunctionEnter3(
                 FunctionIDOrClientID functionIDOrClientID);
  
-typedef void __stdcall FunctionLeave3(
+typedef void STDMETHODCALLTYPE FunctionLeave3(
                 FunctionIDOrClientID functionIDOrClientID);
  
-typedef void __stdcall FunctionTailcall3(
+typedef void STDMETHODCALLTYPE FunctionTailcall3(
                 FunctionIDOrClientID functionIDOrClientID);
 
 /*
@@ -371,15 +373,15 @@ typedef void __stdcall FunctionTailcall3(
  * It is only valid during the callback to which it is passed.
  */
 
-typedef void __stdcall FunctionEnter3WithInfo(
+typedef void STDMETHODCALLTYPE FunctionEnter3WithInfo(
                 FunctionIDOrClientID functionIDOrClientID,
                 COR_PRF_ELT_INFO eltInfo);
  
-typedef void __stdcall FunctionLeave3WithInfo(
+typedef void STDMETHODCALLTYPE FunctionLeave3WithInfo(
                 FunctionIDOrClientID functionIDOrClientID,
                 COR_PRF_ELT_INFO eltInfo);
  
-typedef void __stdcall FunctionTailcall3WithInfo(
+typedef void STDMETHODCALLTYPE FunctionTailcall3WithInfo(
                 FunctionIDOrClientID functionIDOrClientID,
                 COR_PRF_ELT_INFO eltInfo);
 
index 2f74826..47e79a1 100644 (file)
@@ -177,6 +177,25 @@ struct MSLAYOUT DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
     }
 };
 
+struct MSLAYOUT DacpMethodTableCollectibleData : ZeroInit<DacpMethodTableCollectibleData>
+{
+    CLRDATA_ADDRESS LoaderAllocatorObjectHandle;
+    BOOL bCollectible;
+
+    HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
+    {
+        HRESULT hr;
+        ISOSDacInterface6 *pSOS6 = NULL;
+        if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface6), (void**)&pSOS6)))
+        {
+            hr = pSOS6->GetMethodTableCollectibleData(addr, this);
+            pSOS6->Release();
+        }
+
+        return hr;
+    }
+};
+
 struct MSLAYOUT DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData>
 {
     BOOL bHasCriticalTransparentInfo;
@@ -1043,5 +1062,6 @@ static_assert(sizeof(DacpGetModuleAddress) == 0x8, "Dacp structs cannot be modif
 static_assert(sizeof(DacpFrameData) == 0x8, "Dacp structs cannot be modified due to backwards compatibility.");
 static_assert(sizeof(DacpJitCodeHeapInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
 static_assert(sizeof(DacpExceptionObjectData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
+static_assert(sizeof(DacpMethodTableCollectibleData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility.");
 
 #endif  // _DACPRIVATE_H_
index 06ceaf2..7875edf 100644 (file)
@@ -250,7 +250,7 @@ struct REGDISPLAY : public REGDISPLAY_BASE {
     ArmVolatileContextPointer     volatileCurrContextPointers;
 
     DWORD *  pPC;                // processor neutral name
-
+#ifndef CROSSGEN_COMPILE
     REGDISPLAY()
     {
         // Initialize regdisplay
@@ -259,6 +259,10 @@ struct REGDISPLAY : public REGDISPLAY_BASE {
         // Setup the pointer to ControlPC field
         pPC = &ControlPC;
     }
+#else
+private:
+    REGDISPLAY();
+#endif
 };
 
 // This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame
index 5b71821..5896426 100644 (file)
@@ -367,3 +367,13 @@ interface ISOSDacInterface5 : IUnknown
 {
     HRESULT GetTieredVersions(CLRDATA_ADDRESS methodDesc, int rejitId, struct DacpTieredVersionData *nativeCodeAddrs, int cNativeCodeAddrs, int *pcNativeCodeAddrs);
 };
+
+[
+    object,
+    local,
+    uuid(11206399-4B66-4EDB-98EA-85654E59AD45)
+]
+interface ISOSDacInterface6 : IUnknown
+{
+    HRESULT GetMethodTableFieldData(CLRDATA_ADDRESS mt, struct DacpMethodTableFieldData *data);
+};
index d60abf5..6a7f286 100644 (file)
 
 
 #ifndef ALLOC_ALIGN_CONSTANT
-#define ALLOC_ALIGN_CONSTANT ((1<<LOG2_PTRSIZE)-1)
+#define ALLOC_ALIGN_CONSTANT (sizeof(void*)-1)
 #endif
 
 
index 9eb1ba3..695c284 100644 (file)
@@ -425,8 +425,7 @@ protected:
                      MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
                      IL_OFFSETX            ilOffset,
                      regNumber             base   = REG_NA,
-                     bool                  isJump = false,
-                     bool                  isNoGC = false);
+                     bool                  isJump = false);
     // clang-format on
 
     // clang-format off
@@ -789,7 +788,78 @@ protected:
     void genLongToIntCast(GenTree* treeNode);
 #endif
 
-    void genIntToIntCast(GenTree* treeNode);
+    struct GenIntCastDesc
+    {
+        enum CheckKind
+        {
+            CHECK_NONE,
+            CHECK_SMALL_INT_RANGE,
+            CHECK_POSITIVE,
+#ifdef _TARGET_64BIT_
+            CHECK_UINT_RANGE,
+            CHECK_POSITIVE_INT_RANGE,
+            CHECK_INT_RANGE,
+#endif
+        };
+
+        enum ExtendKind
+        {
+            COPY,
+            ZERO_EXTEND_SMALL_INT,
+            SIGN_EXTEND_SMALL_INT,
+#ifdef _TARGET_64BIT_
+            ZERO_EXTEND_INT,
+            SIGN_EXTEND_INT,
+#endif
+        };
+
+    private:
+        CheckKind  m_checkKind;
+        unsigned   m_checkSrcSize;
+        int        m_checkSmallIntMin;
+        int        m_checkSmallIntMax;
+        ExtendKind m_extendKind;
+        unsigned   m_extendSrcSize;
+
+    public:
+        GenIntCastDesc(GenTreeCast* cast);
+
+        CheckKind CheckKind() const
+        {
+            return m_checkKind;
+        }
+
+        unsigned CheckSrcSize() const
+        {
+            assert(m_checkKind != CHECK_NONE);
+            return m_checkSrcSize;
+        }
+
+        int CheckSmallIntMin() const
+        {
+            assert(m_checkKind == CHECK_SMALL_INT_RANGE);
+            return m_checkSmallIntMin;
+        }
+
+        int CheckSmallIntMax() const
+        {
+            assert(m_checkKind == CHECK_SMALL_INT_RANGE);
+            return m_checkSmallIntMax;
+        }
+
+        ExtendKind ExtendKind() const
+        {
+            return m_extendKind;
+        }
+
+        unsigned ExtendSrcSize() const
+        {
+            return m_extendSrcSize;
+        }
+    };
+
+    void genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& desc, regNumber reg);
+    void genIntToIntCast(GenTreeCast* cast);
     void genFloatToFloatCast(GenTree* treeNode);
     void genFloatToIntCast(GenTree* treeNode);
     void genIntToFloatCast(GenTree* treeNode);
index 63ef942..fadc9a5 100644 (file)
@@ -1615,19 +1615,17 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
                                    BAD_IL_OFFSET, // ilOffset
                                    callTargetReg, // ireg
                                    REG_NA, 0, 0,  // xreg, xmul, disp
-                                   false,         // isJump
-                                   emitter::emitNoGChelper(helper),
-                                   (CorInfoHelpFunc)helper == CORINFO_HELP_PROF_FCN_LEAVE);
+                                   false          // isJump
+                                   );
     }
     else
     {
         getEmitter()->emitIns_Call(emitter::EC_FUNC_TOKEN, compiler->eeFindHelper(helper),
                                    INDEBUG_LDISASM_COMMA(nullptr) addr, argSize, retSize, gcInfo.gcVarPtrSetCur,
                                    gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur, BAD_IL_OFFSET, REG_NA, REG_NA, 0,
-                                   0,     /* ilOffset, ireg, xreg, xmul, disp */
-                                   false, /* isJump */
-                                   emitter::emitNoGChelper(helper),
-                                   (CorInfoHelpFunc)helper == CORINFO_HELP_PROF_FCN_LEAVE);
+                                   0,    /* ilOffset, ireg, xreg, xmul, disp */
+                                   false /* isJump */
+                                   );
     }
 
     regSet.verifyRegistersUsed(RBM_CALLEE_TRASH);
index e95a192..44e92e2 100644 (file)
@@ -3712,8 +3712,8 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
                                gcInfo.gcRegByrefSetCur, BAD_IL_OFFSET, /* IL offset */
                                callTarget,                             /* ireg */
                                REG_NA, 0, 0,                           /* xreg, xmul, disp */
-                               false,                                  /* isJump */
-                               emitter::emitNoGChelper(helper));
+                               false                                   /* isJump */
+                               );
 
     regMaskTP killMask = compiler->compHelperCallKillSet((CorInfoHelpFunc)helper);
     regSet.verifyRegistersUsed(killMask);
index eb53d2b..746636a 100644 (file)
@@ -2850,202 +2850,150 @@ void CodeGen::genJmpMethod(GenTree* jmp)
 }
 
 //------------------------------------------------------------------------
-// genIntToIntCast: Generate code for an integer cast
+// genIntCastOverflowCheck: Generate overflow checking code for an integer cast.
 //
 // Arguments:
-//    treeNode - The GT_CAST node
-//
-// Return Value:
-//    None.
+//    cast - The GT_CAST node
+//    desc - The cast description
+//    reg  - The register containing the value to check
 //
-// Assumptions:
-//    The treeNode must have an assigned register.
-//    For a signed convert from byte, the source must be in a byte-addressable register.
-//    Neither the source nor target type can be a floating point type.
-//
-// TODO-ARM64-CQ: Allow castOp to be a contained node without an assigned register.
-//
-void CodeGen::genIntToIntCast(GenTree* treeNode)
+void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& desc, regNumber reg)
 {
-    assert(treeNode->OperGet() == GT_CAST);
-
-    GenTree* castOp = treeNode->gtCast.CastOp();
-    emitter* emit   = getEmitter();
-
-    var_types dstType = treeNode->CastToType();
-    var_types srcType = genActualType(castOp->TypeGet());
-
-    assert(genTypeSize(srcType) <= genTypeSize(TYP_I_IMPL));
-
-    regNumber targetReg = treeNode->gtRegNum;
-    regNumber sourceReg = castOp->gtRegNum;
-
-    // For Long to Int conversion we will have a reserved integer register to hold the immediate mask
-    regNumber tmpReg = (treeNode->AvailableTempRegCount() == 0) ? REG_NA : treeNode->GetSingleTempReg();
-
-    assert(genIsValidIntReg(targetReg));
-    assert(genIsValidIntReg(sourceReg));
-
-    genConsumeReg(castOp);
-    Lowering::CastInfo castInfo;
+    switch (desc.CheckKind())
+    {
+        case GenIntCastDesc::CHECK_POSITIVE:
+            getEmitter()->emitIns_R_I(INS_cmp, EA_ATTR(desc.CheckSrcSize()), reg, 0);
+            genJumpToThrowHlpBlk(EJ_lt, SCK_OVERFLOW);
+            break;
 
-    // Get information about the cast.
-    Lowering::getCastDescription(treeNode, &castInfo);
+#ifdef _TARGET_64BIT_
+        case GenIntCastDesc::CHECK_UINT_RANGE:
+            // We need to check if the value is not greater than 0xFFFFFFFF but this value
+            // cannot be encoded in the immediate operand of CMP. Use TST instead to check
+            // if the upper 32 bits are zero.
+            getEmitter()->emitIns_R_I(INS_tst, EA_8BYTE, reg, 0xFFFFFFFF00000000LL);
+            genJumpToThrowHlpBlk(EJ_ne, SCK_OVERFLOW);
+            break;
 
-    if (castInfo.requiresOverflowCheck)
-    {
-        bool     movRequired = (sourceReg != targetReg);
-        emitAttr movSize     = emitActualTypeSize(dstType);
-        emitAttr cmpSize     = EA_ATTR(genTypeSize(srcType));
+        case GenIntCastDesc::CHECK_POSITIVE_INT_RANGE:
+            // We need to check if the value is not greater than 0x7FFFFFFF but this value
+            // cannot be encoded in the immediate operand of CMP. Use TST instead to check
+            // if the upper 33 bits are zero.
+            getEmitter()->emitIns_R_I(INS_tst, EA_8BYTE, reg, 0xFFFFFFFF80000000LL);
+            genJumpToThrowHlpBlk(EJ_ne, SCK_OVERFLOW);
+            break;
 
-        if (castInfo.signCheckOnly)
+        case GenIntCastDesc::CHECK_INT_RANGE:
         {
-            // We only need to check for a negative value in sourceReg
-            emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, 0);
-            emitJumpKind jmpLT = genJumpKindForOper(GT_LT, CK_SIGNED);
-            genJumpToThrowHlpBlk(jmpLT, SCK_OVERFLOW);
-            noway_assert(genTypeSize(srcType) == 4 || genTypeSize(srcType) == 8);
-            // This is only interesting case to ensure zero-upper bits.
-            if ((srcType == TYP_INT) && (dstType == TYP_ULONG))
-            {
-                // cast to TYP_ULONG:
-                // We use a mov with size=EA_4BYTE
-                // which will zero out the upper bits
-                movSize     = EA_4BYTE;
-                movRequired = true;
-            }
+            const regNumber tempReg = cast->GetSingleTempReg();
+            assert(tempReg != reg);
+            instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, INT32_MAX);
+            getEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, tempReg);
+            genJumpToThrowHlpBlk(EJ_gt, SCK_OVERFLOW);
+            instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, INT32_MIN);
+            getEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, tempReg);
+            genJumpToThrowHlpBlk(EJ_lt, SCK_OVERFLOW);
         }
-        else if (castInfo.unsignedSource || castInfo.unsignedDest)
+        break;
+#endif
+
+        default:
         {
-            // When we are converting from/to unsigned,
-            // we only have to check for any bits set in 'typeMask'
+            assert(desc.CheckKind() == GenIntCastDesc::CHECK_SMALL_INT_RANGE);
+            const int castMaxValue = desc.CheckSmallIntMax();
+            const int castMinValue = desc.CheckSmallIntMin();
 
-            noway_assert(castInfo.typeMask != 0);
-#if defined(_TARGET_ARM_)
-            if (arm_Valid_Imm_For_Instr(INS_tst, castInfo.typeMask, INS_FLAGS_DONT_CARE))
+            // Values greater than 255 cannot be encoded in the immediate operand of CMP.
+            // Replace (x > max) with (x >= max + 1) where max + 1 (a power of 2) can be
+            // encoded. We could do this for all max values but on ARM32 "cmp r0, 255"
+            // is better than "cmp r0, 256" because it has a shorter encoding.
+            if (castMaxValue > 255)
             {
-                emit->emitIns_R_I(INS_tst, cmpSize, sourceReg, castInfo.typeMask);
+                assert((castMaxValue == 32767) || (castMaxValue == 65535));
+                getEmitter()->emitIns_R_I(INS_cmp, EA_SIZE(desc.CheckSrcSize()), reg, castMaxValue + 1);
+                genJumpToThrowHlpBlk((castMinValue == 0) ? EJ_hs : EJ_ge, SCK_OVERFLOW);
             }
             else
             {
-                noway_assert(tmpReg != REG_NA);
-                instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMask);
-                emit->emitIns_R_R(INS_tst, cmpSize, sourceReg, tmpReg);
+                getEmitter()->emitIns_R_I(INS_cmp, EA_SIZE(desc.CheckSrcSize()), reg, castMaxValue);
+                genJumpToThrowHlpBlk((castMinValue == 0) ? EJ_hi : EJ_gt, SCK_OVERFLOW);
             }
-#elif defined(_TARGET_ARM64_)
-            emit->emitIns_R_I(INS_tst, cmpSize, sourceReg, castInfo.typeMask);
-#endif // _TARGET_ARM*
-            emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_SIGNED);
-            genJumpToThrowHlpBlk(jmpNotEqual, SCK_OVERFLOW);
-        }
-        else
-        {
-            // For a narrowing signed cast
-            //
-            // We must check the value is in a signed range.
-
-            // Compare with the MAX
-
-            noway_assert((castInfo.typeMin != 0) && (castInfo.typeMax != 0));
 
-#if defined(_TARGET_ARM_)
-            if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, INS_FLAGS_DONT_CARE))
-#elif defined(_TARGET_ARM64_)
-            if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, cmpSize))
-#endif // _TARGET_*
-            {
-                emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, castInfo.typeMax);
-            }
-            else
+            if (castMinValue != 0)
             {
-                noway_assert(tmpReg != REG_NA);
-                instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMax);
-                emit->emitIns_R_R(INS_cmp, cmpSize, sourceReg, tmpReg);
+                getEmitter()->emitIns_R_I(INS_cmp, EA_SIZE(desc.CheckSrcSize()), reg, castMinValue);
+                genJumpToThrowHlpBlk(EJ_lt, SCK_OVERFLOW);
             }
+        }
+        break;
+    }
+}
 
-            emitJumpKind jmpGT = genJumpKindForOper(GT_GT, CK_SIGNED);
-            genJumpToThrowHlpBlk(jmpGT, SCK_OVERFLOW);
+//------------------------------------------------------------------------
+// genIntToIntCast: Generate code for an integer cast, with or without overflow check.
+//
+// Arguments:
+//    cast - The GT_CAST node
+//
+// Assumptions:
+//    The cast node is not a contained node and must have an assigned register.
+//    Neither the source nor target type can be a floating point type.
+//
+// TODO-ARM64-CQ: Allow castOp to be a contained node without an assigned register.
+//
+void CodeGen::genIntToIntCast(GenTreeCast* cast)
+{
+    genConsumeRegs(cast->gtGetOp1());
 
-// Compare with the MIN
+    const regNumber srcReg = cast->gtGetOp1()->gtRegNum;
+    const regNumber dstReg = cast->gtRegNum;
 
-#if defined(_TARGET_ARM_)
-            if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, INS_FLAGS_DONT_CARE))
-#elif defined(_TARGET_ARM64_)
-            if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, cmpSize))
-#endif // _TARGET_*
-            {
-                emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, castInfo.typeMin);
-            }
-            else
-            {
-                noway_assert(tmpReg != REG_NA);
-                instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMin);
-                emit->emitIns_R_R(INS_cmp, cmpSize, sourceReg, tmpReg);
-            }
+    assert(genIsValidIntReg(srcReg));
+    assert(genIsValidIntReg(dstReg));
 
-            emitJumpKind jmpLT = genJumpKindForOper(GT_LT, CK_SIGNED);
-            genJumpToThrowHlpBlk(jmpLT, SCK_OVERFLOW);
-        }
+    GenIntCastDesc desc(cast);
 
-        if (movRequired)
-        {
-            emit->emitIns_R_R(INS_mov, movSize, targetReg, sourceReg);
-        }
+    if (desc.CheckKind() != GenIntCastDesc::CHECK_NONE)
+    {
+        genIntCastOverflowCheck(cast, desc, srcReg);
     }
-    else // Non-overflow checking cast.
+
+    if ((desc.ExtendKind() != GenIntCastDesc::COPY) || (srcReg != dstReg))
     {
-        const unsigned srcSize = genTypeSize(srcType);
-        const unsigned dstSize = genTypeSize(dstType);
-        instruction    ins;
-        emitAttr       insSize;
+        instruction ins;
+        unsigned    insSize;
 
-        if (dstSize < 4)
+        switch (desc.ExtendKind())
         {
-            // Casting to a small type really means widening from that small type to INT/LONG.
-            ins     = ins_Move_Extend(dstType, true);
-            insSize = emitActualTypeSize(treeNode->TypeGet());
-        }
+            case GenIntCastDesc::ZERO_EXTEND_SMALL_INT:
+                ins     = (desc.ExtendSrcSize() == 1) ? INS_uxtb : INS_uxth;
+                insSize = 4;
+                break;
+            case GenIntCastDesc::SIGN_EXTEND_SMALL_INT:
+                ins     = (desc.ExtendSrcSize() == 1) ? INS_sxtb : INS_sxth;
+                insSize = 4;
+                break;
 #ifdef _TARGET_64BIT_
-        // dstType cannot be a long type on 32 bit targets, such casts should have been decomposed.
-        // srcType cannot be a small type since it's the "actual type" of the cast operand.
-        // This means that widening casts do not occur on 32 bit targets.
-        else if (dstSize > srcSize)
-        {
-            // (U)INT to (U)LONG widening cast
-            assert((srcSize == 4) && (dstSize == 8));
-            // Make sure the node type has the same size as the destination type.
-            assert(genTypeSize(treeNode->TypeGet()) == dstSize);
-
-            ins = treeNode->IsUnsigned() ? INS_mov : INS_sxtw;
-            // SXTW requires EA_8BYTE but MOV requires EA_4BYTE in order to zero out the upper 32 bits.
-            insSize = (ins == INS_sxtw) ? EA_8BYTE : EA_4BYTE;
-        }
+            case GenIntCastDesc::ZERO_EXTEND_INT:
+                ins     = INS_mov;
+                insSize = 4;
+                break;
+            case GenIntCastDesc::SIGN_EXTEND_INT:
+                ins     = INS_sxtw;
+                insSize = 8;
+                break;
 #endif
-        else
-        {
-            // Sign changing cast or narrowing cast
-            assert(dstSize <= srcSize);
-            // Note that narrowing casts are possible only on 64 bit targets.
-            assert(srcSize <= genTypeSize(TYP_I_IMPL));
-            // Make sure the node type has the same size as the destination type.
-            assert(genTypeSize(treeNode->TypeGet()) == dstSize);
-
-            // This cast basically does nothing, even when narrowing it is the job of the
-            // consumer of this node to use the appropiate register size (32 or 64 bit)
-            // and not rely on the cast to set the upper 32 bits in a certain manner.
-            // Still, we will need to generate a MOV instruction if the source and target
-            // registers are different.
-            ins     = (sourceReg != targetReg) ? INS_mov : INS_none;
-            insSize = EA_SIZE(dstSize);
+            default:
+                assert(desc.ExtendKind() == GenIntCastDesc::COPY);
+                ins     = INS_mov;
+                insSize = desc.ExtendSrcSize();
+                break;
         }
 
-        if (ins != INS_none)
-        {
-            emit->emitIns_R_R(ins, insSize, targetReg, sourceReg);
-        }
+        getEmitter()->emitIns_R_R(ins, EA_ATTR(insSize), dstReg, srcReg);
     }
 
-    genProduceReg(treeNode);
+    genProduceReg(cast);
 }
 
 //------------------------------------------------------------------------
index e4ba8e6..72fa3c7 100644 (file)
@@ -506,9 +506,7 @@ void CodeGenInterface::genUpdateRegLife(const LclVarDsc* varDsc, bool isBorn, bo
 }
 
 //----------------------------------------------------------------------
-// compNoGCHelperCallKillSet:
-//
-// Gets a register mask that represents the kill set for a helper call.
+// compHelperCallKillSet: Gets a register mask that represents the kill set for a helper call.
 // Not all JIT Helper calls follow the standard ABI on the target architecture.
 //
 // TODO-CQ: Currently this list is incomplete (not all helpers calls are
@@ -639,6 +637,19 @@ regMaskTP Compiler::compNoGCHelperCallKillSet(CorInfoHelpFunc helper)
 
     switch (helper)
     {
+        case CORINFO_HELP_ASSIGN_BYREF:
+#if defined(_TARGET_X86_)
+            // This helper only trashes ECX.
+            return RBM_ECX;
+#elif defined(_TARGET_AMD64_)
+            // This uses and defs RDI and RSI.
+            return RBM_CALLEE_TRASH_NOGC & ~(RBM_RDI | RBM_RSI);
+#elif defined(_TARGET_ARMARCH_)
+            return RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF;
+#else
+            assert(!"unknown arch");
+#endif
+
 #if defined(_TARGET_XARCH_)
         case CORINFO_HELP_PROF_FCN_ENTER:
             return RBM_PROFILER_ENTER_TRASH;
@@ -650,19 +661,13 @@ regMaskTP Compiler::compNoGCHelperCallKillSet(CorInfoHelpFunc helper)
             return RBM_PROFILER_TAILCALL_TRASH;
 #endif // defined(_TARGET_XARCH_)
 
-#if defined(_TARGET_X86_)
-        case CORINFO_HELP_ASSIGN_BYREF:
-            // This helper only trashes ECX.
-            return RBM_ECX;
-#endif // defined(_TARGET_X86_)
-
 #if defined(_TARGET_ARMARCH_)
-        case CORINFO_HELP_ASSIGN_BYREF:
-            return RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF;
-
         case CORINFO_HELP_ASSIGN_REF:
         case CORINFO_HELP_CHECKED_ASSIGN_REF:
             return RBM_CALLEE_GCTRASH_WRITEBARRIER;
+        case CORINFO_HELP_PROF_FCN_LEAVE:
+            // In case of Leave profiler callback, we need to preserve liveness of REG_PROFILER_RET_SCRATCH on ARMARCH.
+            return RBM_CALLEE_TRASH_NOGC & ~RBM_PROFILER_RET_SCRATCH;
 #endif
 
 #if defined(_TARGET_X86_)
@@ -2432,16 +2437,20 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
 #endif
 
 #if EMIT_TRACK_STACK_DEPTH
-    /* Check our max stack level. Needed for fgAddCodeRef().
-       We need to relax the assert as our estimation won't include code-gen
-       stack changes (which we know don't affect fgAddCodeRef()) */
+    // Check our max stack level. Needed for fgAddCodeRef().
+    // We need to relax the assert as our estimation won't include code-gen
+    // stack changes (which we know don't affect fgAddCodeRef()).
+    // NOTE: after emitEndCodeGen (including here), emitMaxStackDepth is a
+    // count of DWORD-sized arguments, NOT argument size in bytes.
     {
         unsigned maxAllowedStackDepth = compiler->fgPtrArgCntMax +    // Max number of pointer-sized stack arguments.
                                         compiler->compHndBBtabCount + // Return address for locally-called finallys
                                         genTypeStSz(TYP_LONG) +       // longs/doubles may be transferred via stack, etc
                                         (compiler->compTailCallUsed ? 4 : 0); // CORINFO_HELP_TAILCALL args
 #if defined(UNIX_X86_ABI)
-        maxAllowedStackDepth += maxNestedAlignment;
+        // Convert maxNestedAlignment to DWORD count before adding to maxAllowedStackDepth.
+        assert(maxNestedAlignment % sizeof(int) == 0);
+        maxAllowedStackDepth += maxNestedAlignment / sizeof(int);
 #endif
         noway_assert(getEmitter()->emitMaxStackDepth <= maxAllowedStackDepth);
     }
@@ -6922,8 +6931,13 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
     unsigned saveStackLvl2 = genStackLevel;
 
 #if defined(_TARGET_X86_)
-    // Important note: when you change enter probe layout, you must also update SKIP_ENTER_PROF_CALLBACK()
-    // for x86 stack unwinding
+// Important note: when you change enter probe layout, you must also update SKIP_ENTER_PROF_CALLBACK()
+// for x86 stack unwinding
+
+#if defined(UNIX_X86_ABI)
+    // Manually align the stack to be 16-byte aligned. This is similar to CodeGen::genAlignStackBeforeCall()
+    getEmitter()->emitIns_R_I(INS_sub, EA_4BYTE, REG_SPBASE, 0xC);
+#endif // UNIX_X86_ABI
 
     // Push the profilerHandle
     if (compiler->compProfilerMethHndIndirected)
@@ -6934,6 +6948,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
     {
         inst_IV(INS_push, (size_t)compiler->compProfilerMethHnd);
     }
+
 #elif defined(_TARGET_ARM_)
     // On Arm arguments are prespilled on stack, which frees r0-r3.
     // For generating Enter callout we would need two registers and one of them has to be r0 to pass profiler handle.
@@ -6970,6 +6985,12 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
 #if defined(_TARGET_X86_)
     // Check that we have place for the push.
     assert(compiler->fgPtrArgCntMax >= 1);
+
+#if defined(UNIX_X86_ABI)
+    // Restoring alignment manually. This is similar to CodeGen::genRemoveAlignmentAfterCall
+    getEmitter()->emitIns_R_I(INS_add, EA_4BYTE, REG_SPBASE, 0x10);
+#endif // UNIX_X86_ABI
+
 #elif defined(_TARGET_ARM_)
     if (initReg == argReg)
     {
@@ -7144,6 +7165,13 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
 
 #elif defined(_TARGET_X86_)
 
+#if defined(UNIX_X86_ABI)
+    // Manually align the stack to be 16-byte aligned. This is similar to CodeGen::genAlignStackBeforeCall()
+    getEmitter()->emitIns_R_I(INS_sub, EA_4BYTE, REG_SPBASE, 0xC);
+    AddStackLevel(0xC);
+    AddNestedAlignment(0xC);
+#endif // UNIX_X86_ABI
+
     //
     // Push the profilerHandle
     //
@@ -7158,13 +7186,23 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
     }
     genSinglePush();
 
-    genEmitHelperCall(helper,
-                      sizeof(int) * 1, // argSize
-                      EA_UNKNOWN);     // retSize
+#if defined(UNIX_X86_ABI)
+    int argSize = -REGSIZE_BYTES; // negative means caller-pop (cdecl)
+#else
+    int argSize = REGSIZE_BYTES;
+#endif
+    genEmitHelperCall(helper, argSize, EA_UNKNOWN /* retSize */);
 
     // Check that we have place for the push.
     assert(compiler->fgPtrArgCntMax >= 1);
 
+#if defined(UNIX_X86_ABI)
+    // Restoring alignment manually. This is similar to CodeGen::genRemoveAlignmentAfterCall
+    getEmitter()->emitIns_R_I(INS_add, EA_4BYTE, REG_SPBASE, 0x10);
+    SubtractStackLevel(0x10);
+    SubtractNestedAlignment(0xC);
+#endif // UNIX_X86_ABI
+
 #elif defined(_TARGET_ARM_)
     //
     // Push the profilerHandle
@@ -9102,7 +9140,8 @@ void CodeGen::genFnEpilog(BasicBlock* block)
                                        gcInfo.gcRegGCrefSetCur,
                                        gcInfo.gcRegByrefSetCur,
                                        BAD_IL_OFFSET, REG_NA, REG_NA, 0, 0,  /* iloffset, ireg, xreg, xmul, disp */
-                                       true); /* isJump */
+                                       true /* isJump */
+            );
             // clang-format on
         }
 #if FEATURE_FASTTAILCALL
index 9962a62..9647600 100644 (file)
@@ -1849,8 +1849,7 @@ void CodeGen::genEmitCall(int                   callType,
                           MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
                           IL_OFFSETX            ilOffset,
                           regNumber             base,
-                          bool                  isJump,
-                          bool                  isNoGC)
+                          bool                  isJump)
 {
 #if !defined(_TARGET_X86_)
     int argSize = 0;
@@ -1865,8 +1864,7 @@ void CodeGen::genEmitCall(int                   callType,
                                gcInfo.gcVarPtrSetCur,
                                gcInfo.gcRegGCrefSetCur,
                                gcInfo.gcRegByrefSetCur,
-                               ilOffset, base, REG_NA, 0, 0, isJump,
-                               emitter::emitNoGChelper(compiler->eeGetHelperNum(methHnd)));
+                               ilOffset, base, REG_NA, 0, 0, isJump);
 }
 // clang-format on
 
@@ -1943,11 +1941,129 @@ void CodeGen::genCodeForCast(GenTreeOp* tree)
     else
     {
         // Casts int <--> int
-        genIntToIntCast(tree);
+        genIntToIntCast(tree->AsCast());
     }
     // The per-case functions call genProduceReg()
 }
 
+CodeGen::GenIntCastDesc::GenIntCastDesc(GenTreeCast* cast)
+{
+    const var_types srcType      = genActualType(cast->gtGetOp1()->TypeGet());
+    const bool      srcUnsigned  = cast->IsUnsigned();
+    const unsigned  srcSize      = genTypeSize(srcType);
+    const var_types castType     = cast->gtCastType;
+    const bool      castUnsigned = varTypeIsUnsigned(castType);
+    const unsigned  castSize     = genTypeSize(castType);
+    const var_types dstType      = genActualType(cast->TypeGet());
+    const unsigned  dstSize      = genTypeSize(dstType);
+    const bool      overflow     = cast->gtOverflow();
+
+    assert((srcSize == 4) || (srcSize == genTypeSize(TYP_I_IMPL)));
+    assert((dstSize == 4) || (dstSize == genTypeSize(TYP_I_IMPL)));
+
+    assert(dstSize == genTypeSize(genActualType(castType)));
+
+    if (castSize < 4) // Cast to small int type
+    {
+        if (overflow)
+        {
+            m_checkKind    = CHECK_SMALL_INT_RANGE;
+            m_checkSrcSize = srcSize;
+            // Since these are small int types we can compute the min and max
+            // values of the castType without risk of integer overflow.
+            const int castNumBits = (castSize * 8) - (castUnsigned ? 0 : 1);
+            m_checkSmallIntMax    = (1 << castNumBits) - 1;
+            m_checkSmallIntMin    = (castUnsigned | srcUnsigned) ? 0 : (-m_checkSmallIntMax - 1);
+
+            m_extendKind    = COPY;
+            m_extendSrcSize = dstSize;
+        }
+        else
+        {
+            m_checkKind = CHECK_NONE;
+
+            // Casting to a small type really means widening from that small type to INT/LONG.
+            m_extendKind    = castUnsigned ? ZERO_EXTEND_SMALL_INT : SIGN_EXTEND_SMALL_INT;
+            m_extendSrcSize = castSize;
+        }
+    }
+#ifdef _TARGET_64BIT_
+    // castType cannot be (U)LONG on 32 bit targets, such casts should have been decomposed.
+    // srcType cannot be a small int type since it's the "actual type" of the cast operand.
+    // This means that widening casts do not occur on 32 bit targets.
+    else if (castSize > srcSize) // (U)INT to (U)LONG widening cast
+    {
+        assert((srcSize == 4) && (castSize == 8));
+
+        if (overflow && !srcUnsigned && castUnsigned)
+        {
+            // Widening from INT to ULONG, check if the value is positive
+            m_checkKind    = CHECK_POSITIVE;
+            m_checkSrcSize = 4;
+
+            // This is the only overflow checking cast that requires changing the
+            // source value (by zero extending), all others copy the value as is.
+            assert((srcType == TYP_INT) && (castType == TYP_ULONG));
+            m_extendKind    = ZERO_EXTEND_INT;
+            m_extendSrcSize = 4;
+        }
+        else
+        {
+            m_checkKind = CHECK_NONE;
+
+            m_extendKind    = srcUnsigned ? ZERO_EXTEND_INT : SIGN_EXTEND_INT;
+            m_extendSrcSize = 4;
+        }
+    }
+    else if (castSize < srcSize) // (U)LONG to (U)INT narrowing cast
+    {
+        assert((srcSize == 8) && (castSize == 4));
+
+        if (overflow)
+        {
+            if (castUnsigned) // (U)LONG to UINT cast
+            {
+                m_checkKind = CHECK_UINT_RANGE;
+            }
+            else if (srcUnsigned) // ULONG to INT cast
+            {
+                m_checkKind = CHECK_POSITIVE_INT_RANGE;
+            }
+            else // LONG to INT cast
+            {
+                m_checkKind = CHECK_INT_RANGE;
+            }
+
+            m_checkSrcSize = 8;
+        }
+        else
+        {
+            m_checkKind = CHECK_NONE;
+        }
+
+        m_extendKind    = COPY;
+        m_extendSrcSize = 4;
+    }
+#endif
+    else // if (castSize == srcSize) // Sign changing or same type cast
+    {
+        assert(castSize == srcSize);
+
+        if (overflow && (srcUnsigned != castUnsigned))
+        {
+            m_checkKind    = CHECK_POSITIVE;
+            m_checkSrcSize = srcSize;
+        }
+        else
+        {
+            m_checkKind = CHECK_NONE;
+        }
+
+        m_extendKind    = COPY;
+        m_extendSrcSize = srcSize;
+    }
+}
+
 #if !defined(_TARGET_64BIT_)
 //------------------------------------------------------------------------
 // genStoreLongLclVar: Generate code to store a non-enregistered long lclVar
index caccf47..81b0871 100644 (file)
@@ -6345,269 +6345,134 @@ void CodeGen::genLongToIntCast(GenTree* cast)
 #endif
 
 //------------------------------------------------------------------------
-// genIntToIntCast: Generate code for an integer cast
-//    This method handles integer overflow checking casts
-//    as well as ordinary integer casts.
+// genIntCastOverflowCheck: Generate overflow checking code for an integer cast.
 //
 // Arguments:
-//    treeNode - The GT_CAST node
-//
-// Return Value:
-//    None.
-//
-// Assumptions:
-//    The treeNode is not a contained node and must have an assigned register.
-//    For a signed convert from byte, the source must be in a byte-addressable register.
-//    Neither the source nor target type can be a floating point type.
-//
-// TODO-XArch-CQ: Allow castOp to be a contained node without an assigned register.
-// TODO: refactor to use getCastDescription
+//    cast - The GT_CAST node
+//    desc - The cast description
+//    reg  - The register containing the value to check
 //
-void CodeGen::genIntToIntCast(GenTree* treeNode)
+void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& desc, regNumber reg)
 {
-    assert(treeNode->OperGet() == GT_CAST);
-
-    GenTree*  castOp  = treeNode->gtCast.CastOp();
-    var_types srcType = genActualType(castOp->TypeGet());
-    noway_assert(genTypeSize(srcType) >= 4);
-    assert(genTypeSize(srcType) <= genTypeSize(TYP_I_IMPL));
-
-    regNumber targetReg     = treeNode->gtRegNum;
-    regNumber sourceReg     = castOp->gtRegNum;
-    var_types dstType       = treeNode->CastToType();
-    bool      isUnsignedDst = varTypeIsUnsigned(dstType);
-    bool      isUnsignedSrc = varTypeIsUnsigned(srcType);
-
-    // if necessary, force the srcType to unsigned when the GT_UNSIGNED flag is set
-    if (!isUnsignedSrc && treeNode->IsUnsigned())
+    switch (desc.CheckKind())
     {
-        srcType       = genUnsignedType(srcType);
-        isUnsignedSrc = true;
-    }
-
-    bool requiresOverflowCheck = false;
-
-    assert(genIsValidIntReg(targetReg));
-    assert(genIsValidIntReg(sourceReg));
+        case GenIntCastDesc::CHECK_POSITIVE:
+            getEmitter()->emitIns_R_R(INS_test, EA_SIZE(desc.CheckSrcSize()), reg, reg);
+            genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW);
+            break;
 
-    instruction ins     = INS_invalid;
-    emitAttr    srcSize = EA_ATTR(genTypeSize(srcType));
-    emitAttr    dstSize = EA_ATTR(genTypeSize(dstType));
+#ifdef _TARGET_64BIT_
+        case GenIntCastDesc::CHECK_UINT_RANGE:
+        {
+            // We need to check if the value is not greater than 0xFFFFFFFF but this value
+            // cannot be encoded in an immediate operand. Use a right shift to test if the
+            // upper 32 bits are zero. This requires a temporary register.
+            const regNumber tempReg = cast->GetSingleTempReg();
+            assert(tempReg != reg);
+            getEmitter()->emitIns_R_R(INS_mov, EA_8BYTE, tempReg, reg);
+            getEmitter()->emitIns_R_I(INS_shr_N, EA_8BYTE, tempReg, 32);
+            genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW);
+        }
+        break;
 
-    if (srcSize < dstSize)
-    {
-#ifdef _TARGET_X86_
-        // dstType cannot be a long type on x86, such casts should have been decomposed.
-        // srcType cannot be a small type since it's the "actual type" of the cast operand.
-        // This means that widening casts do not actually occur on x86.
-        unreached();
-#else
-        // This is a widening cast from TYP_(U)INT to TYP_(U)LONG.
-        assert(dstSize == EA_8BYTE);
-        assert(srcSize == EA_4BYTE);
+        case GenIntCastDesc::CHECK_POSITIVE_INT_RANGE:
+            getEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MAX);
+            genJumpToThrowHlpBlk(EJ_ja, SCK_OVERFLOW);
+            break;
 
-        // When widening, overflows can only happen if the source type is signed and the
-        // destination type is unsigned. Since the overflow check ensures that the value
-        // is positive a cheaper mov instruction can be used instead of movsxd.
-        if (treeNode->gtOverflow() && !isUnsignedSrc && isUnsignedDst)
-        {
-            requiresOverflowCheck = true;
-            ins                   = INS_mov;
-        }
-        else
-        {
-            ins = isUnsignedSrc ? INS_mov : INS_movsxd;
-        }
+        case GenIntCastDesc::CHECK_INT_RANGE:
+            getEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MAX);
+            genJumpToThrowHlpBlk(EJ_jg, SCK_OVERFLOW);
+            getEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MIN);
+            genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW);
+            break;
 #endif
-    }
-    else
-    {
-        // Narrowing cast, or sign-changing cast
-        noway_assert(srcSize >= dstSize);
 
-        // Is this an Overflow checking cast?
-        if (treeNode->gtOverflow())
-        {
-            requiresOverflowCheck = true;
-            ins                   = INS_mov;
-        }
-        else
+        default:
         {
-            ins = ins_Move_Extend(dstType, false);
-        }
-    }
+            assert(desc.CheckKind() == GenIntCastDesc::CHECK_SMALL_INT_RANGE);
+            const int castMaxValue = desc.CheckSmallIntMax();
+            const int castMinValue = desc.CheckSmallIntMin();
 
-    noway_assert(ins != INS_invalid);
+            getEmitter()->emitIns_R_I(INS_cmp, EA_SIZE(desc.CheckSrcSize()), reg, castMaxValue);
+            genJumpToThrowHlpBlk((castMinValue == 0) ? EJ_ja : EJ_jg, SCK_OVERFLOW);
 
-    genConsumeReg(castOp);
+            if (castMinValue != 0)
+            {
+                getEmitter()->emitIns_R_I(INS_cmp, EA_SIZE(desc.CheckSrcSize()), reg, castMinValue);
+                genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW);
+            }
+        }
+        break;
+    }
+}
 
-    if (requiresOverflowCheck)
-    {
-        ssize_t typeMin        = 0;
-        ssize_t typeMax        = 0;
-        ssize_t typeMask       = 0;
-        bool    needScratchReg = false;
-        bool    signCheckOnly  = false;
+//------------------------------------------------------------------------
+// genIntToIntCast: Generate code for an integer cast, with or without overflow check.
+//
+// Arguments:
+//    cast - The GT_CAST node
+//
+// Assumptions:
+//    The cast node is not a contained node and must have an assigned register.
+//    Neither the source nor target type can be a floating point type.
+//    On x86 casts to (U)BYTE require that the source be in a byte register.
+//
+// TODO-XArch-CQ: Allow castOp to be a contained node without an assigned register.
+//
+void CodeGen::genIntToIntCast(GenTreeCast* cast)
+{
+    genConsumeRegs(cast->gtGetOp1());
 
-        /* Do we need to compare the value, or just check masks */
+    const regNumber srcReg = cast->gtGetOp1()->gtRegNum;
+    const regNumber dstReg = cast->gtRegNum;
 
-        switch (dstType)
-        {
-            case TYP_BYTE:
-                typeMask = ssize_t((int)0xFFFFFF80);
-                typeMin  = SCHAR_MIN;
-                typeMax  = SCHAR_MAX;
-                break;
+    assert(genIsValidIntReg(srcReg));
+    assert(genIsValidIntReg(dstReg));
 
-            case TYP_UBYTE:
-                typeMask = ssize_t((int)0xFFFFFF00L);
-                break;
+    GenIntCastDesc desc(cast);
 
-            case TYP_SHORT:
-                typeMask = ssize_t((int)0xFFFF8000);
-                typeMin  = SHRT_MIN;
-                typeMax  = SHRT_MAX;
-                break;
+    if (desc.CheckKind() != GenIntCastDesc::CHECK_NONE)
+    {
+        genIntCastOverflowCheck(cast, desc, srcReg);
+    }
 
-            case TYP_USHORT:
-                typeMask = ssize_t((int)0xFFFF0000L);
-                break;
+    if ((desc.ExtendKind() != GenIntCastDesc::COPY) || (srcReg != dstReg))
+    {
+        instruction ins;
+        unsigned    insSize;
 
-            case TYP_INT:
-                if (srcType == TYP_UINT)
-                {
-                    signCheckOnly = true;
-                }
-                else
-                {
-                    typeMask = ssize_t((int)0x80000000);
-                    typeMin  = INT_MIN;
-                    typeMax  = INT_MAX;
-                }
+        switch (desc.ExtendKind())
+        {
+            case GenIntCastDesc::ZERO_EXTEND_SMALL_INT:
+                ins     = INS_movzx;
+                insSize = desc.ExtendSrcSize();
                 break;
-
-            case TYP_UINT:
-                if (srcType == TYP_INT)
-                {
-                    signCheckOnly = true;
-                }
-                else
-                {
-                    needScratchReg = true;
-                }
+            case GenIntCastDesc::SIGN_EXTEND_SMALL_INT:
+                ins     = INS_movsx;
+                insSize = desc.ExtendSrcSize();
                 break;
-
-            case TYP_LONG:
-                noway_assert(srcType == TYP_ULONG);
-                signCheckOnly = true;
+#ifdef _TARGET_64BIT_
+            case GenIntCastDesc::ZERO_EXTEND_INT:
+                ins     = INS_mov;
+                insSize = 4;
                 break;
-
-            case TYP_ULONG:
-                noway_assert((srcType == TYP_LONG) || (srcType == TYP_INT));
-                signCheckOnly = true;
+            case GenIntCastDesc::SIGN_EXTEND_INT:
+                ins     = INS_movsxd;
+                insSize = 4;
                 break;
-
+#endif
             default:
-                NO_WAY("Unknown type");
-                return;
-        }
-
-        if (signCheckOnly)
-        {
-            // We only need to check for a negative value in sourceReg
-            inst_RV_RV(INS_test, sourceReg, sourceReg, srcType, srcSize);
-            genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW);
-        }
-        else
-        {
-            // When we are converting from unsigned or to unsigned, we
-            // will only have to check for any bits set using 'typeMask'
-            if (isUnsignedSrc || isUnsignedDst)
-            {
-                if (needScratchReg)
-                {
-                    regNumber tmpReg = treeNode->GetSingleTempReg();
-                    inst_RV_RV(INS_mov, tmpReg, sourceReg, TYP_LONG); // Move the 64-bit value to a writable temp reg
-                    inst_RV_SH(INS_SHIFT_RIGHT_LOGICAL, srcSize, tmpReg, 32); // Shift right by 32 bits
-                    genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW);               // Throw if result shift is non-zero
-                }
-                else
-                {
-                    noway_assert(typeMask != 0);
-                    inst_RV_IV(INS_TEST, sourceReg, typeMask, srcSize);
-                    genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW);
-                }
-            }
-            else
-            {
-                // For a narrowing signed cast
-                //
-                // We must check the value is in a signed range.
-
-                // Compare with the MAX
-
-                noway_assert((typeMin != 0) && (typeMax != 0));
-
-                inst_RV_IV(INS_cmp, sourceReg, typeMax, srcSize);
-                genJumpToThrowHlpBlk(EJ_jg, SCK_OVERFLOW);
-
-                // Compare with the MIN
-
-                inst_RV_IV(INS_cmp, sourceReg, typeMin, srcSize);
-                genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW);
-            }
-        }
-
-        if (targetReg != sourceReg
-#ifdef _TARGET_AMD64_
-            // On amd64, we can hit this path for a same-register
-            // 4-byte to 8-byte widening conversion, and need to
-            // emit the instruction to set the high bits correctly.
-            || (dstSize == EA_8BYTE && srcSize == EA_4BYTE)
-#endif // _TARGET_AMD64_
-                )
-            inst_RV_RV(ins, targetReg, sourceReg, srcType, srcSize);
-    }
-    else // non-overflow checking cast
-    {
-        // We may have code transformations that result in casts where srcType is the same as dstType.
-        // e.g. Bug 824281, in which a comma is split by the rationalizer, leaving an assignment of a
-        // long constant to a long lclVar.
-        if (srcType == dstType)
-        {
-            ins = INS_mov;
-        }
-
-        if (ins == INS_mov)
-        {
-            if (targetReg != sourceReg
-#ifdef _TARGET_AMD64_
-                // On amd64, 'mov' is the opcode used to zero-extend from
-                // 4 bytes to 8 bytes.
-                || (dstSize == EA_8BYTE && srcSize == EA_4BYTE)
-#endif // _TARGET_AMD64_
-                    )
-            {
-                inst_RV_RV(ins, targetReg, sourceReg, srcType, srcSize);
-            }
-        }
-#ifdef _TARGET_AMD64_
-        else if (ins == INS_movsxd)
-        {
-            inst_RV_RV(ins, targetReg, sourceReg, srcType, srcSize);
+                assert(desc.ExtendKind() == GenIntCastDesc::COPY);
+                ins     = INS_mov;
+                insSize = desc.ExtendSrcSize();
+                break;
         }
-#endif // _TARGET_AMD64_
-        else
-        {
-            noway_assert(ins == INS_movsx || ins == INS_movzx);
-            noway_assert(srcSize >= dstSize);
 
-            /* Generate "mov targetReg, castOp->gtReg */
-            inst_RV_RV(ins, targetReg, sourceReg, srcType, dstSize);
-        }
+        getEmitter()->emitIns_R_R(ins, EA_ATTR(insSize), dstReg, srcReg);
     }
 
-    genProduceReg(treeNode);
+    genProduceReg(cast);
 }
 
 //------------------------------------------------------------------------
@@ -8625,8 +8490,8 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
                                BAD_IL_OFFSET, // IL offset
                                callTarget,    // ireg
                                REG_NA, 0, 0,  // xreg, xmul, disp
-                               false,         // isJump
-                               emitter::emitNoGChelper(helper));
+                               false         // isJump
+                               );
     // clang-format on
 
     regSet.verifyRegistersUsed(killMask);
index b89bda3..69bb7e9 100644 (file)
@@ -3264,6 +3264,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
     opts.disDiffable     = false;
     opts.dspCode         = false;
     opts.dspEHTable      = false;
+    opts.dspDebugInfo    = false;
     opts.dspGCtbls       = false;
     opts.disAsm2         = false;
     opts.dspUnwind       = false;
@@ -3312,6 +3313,11 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
             {
                 opts.dspEHTable = true;
             }
+
+            if (JitConfig.NgenDebugDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
+            {
+                opts.dspDebugInfo = true;
+            }
         }
         else
         {
@@ -3373,6 +3379,12 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
                 {
                     opts.dspEHTable = true;
                 }
+
+                if (JitConfig.JitDebugDump().contains(info.compMethodName, info.compClassName,
+                                                      &info.compMethodInfo->args))
+                {
+                    opts.dspDebugInfo = true;
+                }
             }
         }
 
@@ -9207,11 +9219,6 @@ int cTreeFlagsIR(Compiler* comp, GenTree* tree)
                 break;
 
             case GT_FIELD:
-
-                if (tree->gtFlags & GTF_FLD_NULLCHECK)
-                {
-                    chars += printf("[FLD_NULLCHECK]");
-                }
                 if (tree->gtFlags & GTF_FLD_VOLATILE)
                 {
                     chars += printf("[FLD_VOLATILE]");
@@ -9263,10 +9270,6 @@ int cTreeFlagsIR(Compiler* comp, GenTree* tree)
                 {
                     chars += printf("[IND_INVARIANT]");
                 }
-                if (tree->gtFlags & GTF_IND_ARR_LEN)
-                {
-                    chars += printf("[IND_ARR_INDEX]");
-                }
                 break;
 
             case GT_CLS_VAR:
index d46e571..131fe7d 100644 (file)
@@ -2304,8 +2304,7 @@ public:
 
     GenTree* gtNewCodeRef(BasicBlock* block);
 
-    GenTree* gtNewFieldRef(
-        var_types typ, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj = nullptr, DWORD offset = 0, bool nullcheck = false);
+    GenTree* gtNewFieldRef(var_types typ, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj = nullptr, DWORD offset = 0);
 
     GenTree* gtNewIndexRef(var_types typ, GenTree* arrayOp, GenTree* indexOp);
 
@@ -8165,6 +8164,7 @@ public:
         bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH
         bool dspCode;                  // Display native code generated
         bool dspEHTable;               // Display the EH table reported to the VM
+        bool dspDebugInfo;             // Display the Debug info reported to the VM
         bool dspInstrs;                // Display the IL instructions intermixed with the native code output
         bool dspEmit;                  // Display emitter output
         bool dspLines;                 // Display source-code lines intermixed with native code output
index 3b3cea2..ec09c9d 100644 (file)
@@ -1204,8 +1204,7 @@ inline GenTree* Compiler::gtNewCodeRef(BasicBlock* block)
  *  A little helper to create a data member reference node.
  */
 
-inline GenTree* Compiler::gtNewFieldRef(
-    var_types typ, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj, DWORD offset, bool nullcheck)
+inline GenTree* Compiler::gtNewFieldRef(var_types typ, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj, DWORD offset)
 {
 #if SMALL_TREE_NODES
     /* 'GT_FIELD' nodes may later get transformed into 'GT_IND' */
@@ -1223,11 +1222,6 @@ inline GenTree* Compiler::gtNewFieldRef(
     tree->gtField.gtFieldLookup.addr = nullptr;
 #endif
 
-    if (nullcheck)
-    {
-        tree->gtFlags |= GTF_FLD_NULLCHECK;
-    }
-
     // If "obj" is the address of a local, note that a field of that struct local has been accessed.
     if (obj != nullptr && obj->OperGet() == GT_ADDR && varTypeIsStruct(obj->gtOp.gtOp1) &&
         obj->gtOp.gtOp1->OperGet() == GT_LCL_VAR)
index 85f9606..c7f0658 100644 (file)
@@ -657,7 +657,7 @@ void Compiler::eeSetLVdone()
     assert(opts.compScopeInfo);
 
 #ifdef DEBUG
-    if (verbose)
+    if (verbose || opts.dspDebugInfo)
     {
         eeDispVars(info.compMethodHnd, eeVarsCount, (ICorDebugInfo::NativeVarInfo*)eeVars);
     }
@@ -943,7 +943,7 @@ void Compiler::eeSetLIdone()
     assert(opts.compDbgInfo);
 
 #if defined(DEBUG)
-    if (verbose)
+    if (verbose || opts.dspDebugInfo)
     {
         eeDispLineInfos();
     }
index 46726f4..f320596 100644 (file)
@@ -2222,17 +2222,22 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn
     }
 }
 
-/*****************************************************************************
- *
- *  Returns true if garbage-collection won't happen within the helper call.
- *  Don't need to record live pointers for such call sites.
- */
-
-bool emitter::emitNoGChelper(unsigned IHX)
+//------------------------------------------------------------------------
+// emitNoGChelper: Returns true if garbage collection won't happen within the helper call.
+//
+// Notes:
+//  There is no need to record live pointers for such call sites.
+//
+// Arguments:
+//   helpFunc - a helper signature for the call, can be CORINFO_HELP_UNDEF, that means that the call is not a helper.
+//
+// Return value:
+//   true if GC can't happen within this call, false otherwise.
+bool emitter::emitNoGChelper(CorInfoHelpFunc helpFunc)
 {
     // TODO-Throughput: Make this faster (maybe via a simple table of bools?)
 
-    switch (IHX)
+    switch (helpFunc)
     {
         case CORINFO_HELP_UNDEF:
             return false;
@@ -2276,11 +2281,32 @@ bool emitter::emitNoGChelper(unsigned IHX)
         case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR:
 
         case CORINFO_HELP_INIT_PINVOKE_FRAME:
-
             return true;
+
+        default:
+            return false;
     }
+}
 
-    return false;
+//------------------------------------------------------------------------
+// emitNoGChelper: Returns true if garbage collection won't happen within the helper call.
+//
+// Notes:
+//  There is no need to record live pointers for such call sites.
+//
+// Arguments:
+//   methHnd - a method handle for the call.
+//
+// Return value:
+//   true if GC can't happen within this call, false otherwise.
+bool emitter::emitNoGChelper(CORINFO_METHOD_HANDLE methHnd)
+{
+    CorInfoHelpFunc helpFunc = Compiler::eeGetHelperNum(methHnd);
+    if (helpFunc == CORINFO_HELP_UNDEF)
+    {
+        return false;
+    }
+    return emitNoGChelper(helpFunc);
 }
 
 /*****************************************************************************
@@ -7277,3 +7303,46 @@ const char* emitter::emitOffsetToLabel(unsigned offs)
 }
 
 #endif // DEBUG
+
+//------------------------------------------------------------------------
+// emitGetGCRegsSavedOrModified: Returns the set of registers that keeps gcrefs and byrefs across the call.
+//
+// Notes: it returns union of two sets:
+//        1) registers that could contain GC/byRefs before the call and call doesn't touch them;
+//        2) registers that contain GC/byRefs before the call and call modifies them, but they still
+//           contain GC/byRefs.
+//
+// Arguments:
+//   methHnd - the method handler of the call.
+//
+// Return value:
+//   the saved set of registers.
+//
+regMaskTP emitter::emitGetGCRegsSavedOrModified(CORINFO_METHOD_HANDLE methHnd)
+{
+    // Is it a helper with a special saved set?
+    bool isNoGCHelper = emitNoGChelper(methHnd);
+    if (isNoGCHelper)
+    {
+        CorInfoHelpFunc helpFunc = Compiler::eeGetHelperNum(methHnd);
+
+        // Get the set of registers that this call kills and remove it from the saved set.
+        regMaskTP savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(helpFunc);
+
+#ifdef DEBUG
+        if (emitComp->verbose)
+        {
+            printf("NoGC Call: savedSet=");
+            printRegMaskInt(savedSet);
+            emitDispRegSet(savedSet);
+            printf("\n");
+        }
+#endif
+        return savedSet;
+    }
+    else
+    {
+        // This is the saved set of registers after a normal call.
+        return RBM_CALLEE_SAVED;
+    }
+}
index fcab878..261302a 100644 (file)
@@ -1909,7 +1909,8 @@ public:
     /*    The following is used to distinguish helper vs non-helper calls   */
     /************************************************************************/
 
-    static bool emitNoGChelper(unsigned IHX);
+    static bool emitNoGChelper(CorInfoHelpFunc helpFunc);
+    static bool emitNoGChelper(CORINFO_METHOD_HANDLE methHnd);
 
     /************************************************************************/
     /*         The following logic keeps track of live GC ref values        */
@@ -1919,6 +1920,8 @@ public:
     bool emitFullGCinfo;  // full GC pointer maps?
     bool emitFullyInt;    // fully interruptible code?
 
+    regMaskTP emitGetGCRegsSavedOrModified(CORINFO_METHOD_HANDLE methHnd);
+
 #if EMIT_TRACK_STACK_DEPTH
     unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere
     unsigned emitMaxStackDepth; // actual computed max. stack depth
index ac6239d..1b8d2af 100644 (file)
@@ -4415,9 +4415,7 @@ void emitter::emitIns_Call(EmitCallType          callType,
                            regNumber        xreg /* = REG_NA */,
                            unsigned         xmul /* = 0     */,
                            ssize_t          disp /* = 0     */,
-                           bool             isJump /* = false */,
-                           bool             isNoGC /* = false */,
-                           bool             isProfLeaveCB /* = false */)
+                           bool             isJump /* = false */)
 {
     /* Sanity check the arguments depending on callType */
 
@@ -4434,44 +4432,8 @@ void emitter::emitIns_Call(EmitCallType          callType,
     // a sanity test.
     assert((unsigned)abs(argSize) <= codeGen->genStackLevel);
 
-    int        argCnt;
-    instrDesc* id;
-
-    /* This is the saved set of registers after a normal call */
-    regMaskTP savedSet = RBM_CALLEE_SAVED;
-
-    /* some special helper calls have a different saved set registers */
-
-    if (isNoGC)
-    {
-        assert(emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
-
-        // Get the set of registers that this call kills and remove it from the saved set.
-        savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(Compiler::eeGetHelperNum(methHnd));
-
-        // In case of Leave profiler callback, we need to preserve liveness of REG_PROFILER_RET_SCRATCH
-        if (isProfLeaveCB)
-        {
-            savedSet |= RBM_PROFILER_RET_SCRATCH;
-        }
-
-#ifdef DEBUG
-        if (emitComp->verbose)
-        {
-            printf("NOGC Call: savedSet=");
-            printRegMaskInt(savedSet);
-            emitDispRegSet(savedSet);
-            printf("\n");
-        }
-#endif
-    }
-    else
-    {
-        assert(!emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
-    }
-
-    /* Trim out any callee-trashed registers from the live set */
-
+    // Trim out any callee-trashed registers from the live set.
+    regMaskTP savedSet = emitGetGCRegsSavedOrModified(methHnd);
     gcrefRegs &= savedSet;
     byrefRegs &= savedSet;
 
@@ -4490,9 +4452,6 @@ void emitter::emitIns_Call(EmitCallType          callType,
     }
 #endif
 
-    assert(argSize % REGSIZE_BYTES == 0);
-    argCnt = argSize / REGSIZE_BYTES;
-
     /* Managed RetVal: emit sequence point for the call */
     if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
     {
@@ -4512,6 +4471,10 @@ void emitter::emitIns_Call(EmitCallType          callType,
             Direct call with GC vars          9,440
             Indir. call with GC vars          5,768
      */
+    instrDesc* id;
+
+    assert(argSize % REGSIZE_BYTES == 0);
+    int argCnt = argSize / REGSIZE_BYTES;
 
     if (callType >= EC_INDIR_R)
     {
@@ -4537,12 +4500,12 @@ void emitter::emitIns_Call(EmitCallType          callType,
     emitThisGCrefRegs = gcrefRegs;
     emitThisByrefRegs = byrefRegs;
 
+    id->idSetIsNoGC(emitNoGChelper(methHnd));
+
     /* Set the instruction - special case jumping a function */
     instruction ins;
     insFormat   fmt = IF_NONE;
 
-    id->idSetIsNoGC(isNoGC);
-
     /* Record the address: method, indirection, or funcptr */
 
     if (callType > EC_FUNC_ADDR)
index b7f2337..fe24007 100644 (file)
@@ -334,14 +334,12 @@ void emitIns_Call(EmitCallType          callType,
                   VARSET_VALARG_TP ptrVars,
                   regMaskTP        gcrefRegs,
                   regMaskTP        byrefRegs,
-                  IL_OFFSETX       ilOffset      = BAD_IL_OFFSET,
-                  regNumber        ireg          = REG_NA,
-                  regNumber        xreg          = REG_NA,
-                  unsigned         xmul          = 0,
-                  ssize_t          disp          = 0,
-                  bool             isJump        = false,
-                  bool             isNoGC        = false,
-                  bool             isProfLeaveCB = false);
+                  IL_OFFSETX       ilOffset = BAD_IL_OFFSET,
+                  regNumber        ireg     = REG_NA,
+                  regNumber        xreg     = REG_NA,
+                  unsigned         xmul     = 0,
+                  ssize_t          disp     = 0,
+                  bool             isJump   = false);
 
 /*****************************************************************************
  *
index 851085a..a87d496 100644 (file)
@@ -7392,9 +7392,7 @@ void emitter::emitIns_Call(EmitCallType          callType,
                            regNumber        xreg /* = REG_NA */,
                            unsigned         xmul /* = 0     */,
                            ssize_t          disp /* = 0     */,
-                           bool             isJump /* = false */,
-                           bool             isNoGC /* = false */,
-                           bool             isProfLeaveCB /* = false */)
+                           bool             isJump /* = false */)
 {
     /* Sanity check the arguments depending on callType */
 
@@ -7411,44 +7409,8 @@ void emitter::emitIns_Call(EmitCallType          callType,
     // a sanity test.
     assert((unsigned)abs(argSize) <= codeGen->genStackLevel);
 
-    int        argCnt;
-    instrDesc* id;
-
-    /* This is the saved set of registers after a normal call */
-    regMaskTP savedSet = RBM_CALLEE_SAVED;
-
-    /* some special helper calls have a different saved set registers */
-
-    if (isNoGC)
-    {
-        assert(emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
-
-        // Get the set of registers that this call kills and remove it from the saved set.
-        savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(Compiler::eeGetHelperNum(methHnd));
-
-        // In case of Leave profiler callback, we need to preserve liveness of REG_PROFILER_RET_SCRATCH
-        if (isProfLeaveCB)
-        {
-            savedSet |= RBM_PROFILER_RET_SCRATCH;
-        }
-
-#ifdef DEBUG
-        if (emitComp->verbose)
-        {
-            printf("NOGC Call: savedSet=");
-            printRegMaskInt(savedSet);
-            emitDispRegSet(savedSet);
-            printf("\n");
-        }
-#endif
-    }
-    else
-    {
-        assert(!emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
-    }
-
-    /* Trim out any callee-trashed registers from the live set */
-
+    // Trim out any callee-trashed registers from the live set.
+    regMaskTP savedSet = emitGetGCRegsSavedOrModified(methHnd);
     gcrefRegs &= savedSet;
     byrefRegs &= savedSet;
 
@@ -7467,9 +7429,6 @@ void emitter::emitIns_Call(EmitCallType          callType,
     }
 #endif
 
-    assert(argSize % REGSIZE_BYTES == 0);
-    argCnt = (int)(argSize / (int)REGSIZE_BYTES);
-
     /* Managed RetVal: emit sequence point for the call */
     if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
     {
@@ -7481,6 +7440,10 @@ void emitter::emitIns_Call(EmitCallType          callType,
         on whether this is a direct/indirect call, and whether we need to
         record an updated set of live GC variables.
      */
+    instrDesc* id;
+
+    assert(argSize % REGSIZE_BYTES == 0);
+    int argCnt = (int)(argSize / (int)REGSIZE_BYTES);
 
     if (callType >= EC_INDIR_R)
     {
@@ -7506,12 +7469,12 @@ void emitter::emitIns_Call(EmitCallType          callType,
     emitThisGCrefRegs = gcrefRegs;
     emitThisByrefRegs = byrefRegs;
 
+    id->idSetIsNoGC(emitNoGChelper(methHnd));
+
     /* Set the instruction - special case jumping a function */
     instruction ins;
     insFormat   fmt = IF_NONE;
 
-    id->idSetIsNoGC(isNoGC);
-
     /* Record the address: method, indirection, or funcptr */
 
     if (callType > EC_FUNC_ADDR)
index bf22738..fefee04 100644 (file)
@@ -816,14 +816,12 @@ void emitIns_Call(EmitCallType          callType,
                   VARSET_VALARG_TP ptrVars,
                   regMaskTP        gcrefRegs,
                   regMaskTP        byrefRegs,
-                  IL_OFFSETX       ilOffset      = BAD_IL_OFFSET,
-                  regNumber        ireg          = REG_NA,
-                  regNumber        xreg          = REG_NA,
-                  unsigned         xmul          = 0,
-                  ssize_t          disp          = 0,
-                  bool             isJump        = false,
-                  bool             isNoGC        = false,
-                  bool             isProfLeaveCB = false);
+                  IL_OFFSETX       ilOffset = BAD_IL_OFFSET,
+                  regNumber        ireg     = REG_NA,
+                  regNumber        xreg     = REG_NA,
+                  unsigned         xmul     = 0,
+                  ssize_t          disp     = 0,
+                  bool             isJump   = false);
 
 BYTE* emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i);
 unsigned emitOutputCall(insGroup* ig, BYTE* dst, instrDesc* i, code_t code);
index b070b3d..371023b 100644 (file)
@@ -188,6 +188,7 @@ IF_DEF(RRW_ARD_CNS, IS_AM_RD|IS_R1_RW,          AMD_CNS)  // r/w    reg , read [
 
 IF_DEF(RWR_RRD_ARD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD )     // write  reg , read  reg2, read [adr]
 IF_DEF(RWR_ARD_CNS, IS_AM_RD|IS_R1_WR,          AMD_CNS)  // write  reg , read [adr], const
+IF_DEF(RWR_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD)      // write  reg , read [adr], read reg2
 IF_DEF(RWR_RRD_ARD_CNS, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD_CNS) // write  reg , read  reg2, read [adr], const
 IF_DEF(RWR_RRD_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, AMD_CNS) // write  reg , read  reg2, read [adr], read reg3
 
index 5be69db..9a6d63f 100644 (file)
@@ -334,6 +334,10 @@ bool TakesRexWPrefix(instruction ins, emitAttr attr)
         case INS_vfnmsub213sd:
         case INS_vfnmsub231sd:
         case INS_vpmaskmovq:
+        case INS_vpgatherdq:
+        case INS_vpgatherqq:
+        case INS_vgatherdpd:
+        case INS_vgatherqpd:
             return true;
         default:
             break;
@@ -2901,8 +2905,8 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
     if (dst->isContained() || (dst->isLclField() && (dst->gtRegNum == REG_NA)) || dst->isUsedFromSpillTemp())
     {
         // dst can only be a modrm
-        assert(dst->isUsedFromMemory() || (dst->gtRegNum == REG_NA) ||
-               instrIs3opImul(ins)); // dst on 3opImul isn't really the dst
+        // dst on 3opImul isn't really the dst
+        assert(dst->isUsedFromMemory() || (dst->gtRegNum == REG_NA) || instrIs3opImul(ins));
         assert(!src->isUsedFromMemory());
 
         memOp = dst;
@@ -4123,6 +4127,74 @@ void emitter::emitIns_R_R_AR(instruction ins, emitAttr attr, regNumber reg1, reg
     emitCurIGsize += sz;
 }
 
+//------------------------------------------------------------------------
+// IsAVX2GatherInstruction: return true if the instruction is AVX2 Gather
+//
+// Arguments:
+//    ins - the instruction to check
+// Return Value:
+//    true if the instruction is AVX2 Gather
+//
+bool IsAVX2GatherInstruction(instruction ins)
+{
+    switch (ins)
+    {
+        case INS_vpgatherdd:
+        case INS_vpgatherdq:
+        case INS_vpgatherqd:
+        case INS_vpgatherqq:
+        case INS_vgatherdps:
+        case INS_vgatherdpd:
+        case INS_vgatherqps:
+        case INS_vgatherqpd:
+            return true;
+        default:
+            return false;
+    }
+}
+
+//------------------------------------------------------------------------
+// emitIns_R_AR_R: Emits an AVX2 Gather instructions
+//
+// Arguments:
+//    ins - the instruction to emit
+//    attr - the instruction operand size
+//    reg1 - the destination and first source operand
+//    reg2 - the mask operand (encoded in VEX.vvvv)
+//    base - the base register of address to load
+//    index - the index register of VSIB
+//    scale - the scale number of VSIB
+//    offs - the offset added to the memory address from base
+//
+void emitter::emitIns_R_AR_R(instruction ins,
+                             emitAttr    attr,
+                             regNumber   reg1,
+                             regNumber   reg2,
+                             regNumber   base,
+                             regNumber   index,
+                             int         scale,
+                             int         offs)
+{
+    assert(IsAVX2GatherInstruction(ins));
+
+    instrDesc* id = emitNewInstrAmd(attr, offs);
+
+    id->idIns(ins);
+    id->idReg1(reg1);
+    id->idReg2(reg2);
+
+    id->idInsFmt(IF_RWR_ARD_RRD);
+    id->idAddr()->iiaAddrMode.amBaseReg = base;
+    id->idAddr()->iiaAddrMode.amIndxReg = index;
+    id->idAddr()->iiaAddrMode.amScale   = emitEncodeSize((emitAttr)scale);
+
+    UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
+    id->idCodeSize(sz);
+
+    dispIns(id);
+    emitCurIGsize += sz;
+}
+
 void emitter::emitIns_R_R_C(
     instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, CORINFO_FIELD_HANDLE fldHnd, int offs)
 {
@@ -6752,8 +6824,7 @@ void emitter::emitIns_Call(EmitCallType          callType,
                            regNumber             xreg,     // = REG_NA
                            unsigned              xmul,     // = 0
                            ssize_t               disp,     // = 0
-                           bool                  isJump,   // = false
-                           bool                  isNoGC)   // = false
+                           bool                  isJump)   // = false
 // clang-format on
 {
     /* Sanity check the arguments depending on callType */
@@ -6858,28 +6929,8 @@ void emitter::emitIns_Call(EmitCallType          callType,
     }
 #endif // STACK_PROBES
 
-    int argCnt;
-
-    UNATIVE_OFFSET sz;
-    instrDesc*     id;
-
-    /* This is the saved set of registers after a normal call */
-    unsigned savedSet = RBM_CALLEE_SAVED;
-
-    /* some special helper calls have a different saved set registers */
-
-    if (isNoGC)
-    {
-        // Get the set of registers that this call kills and remove it from the saved set.
-        savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(Compiler::eeGetHelperNum(methHnd));
-    }
-    else
-    {
-        assert(!emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
-    }
-
-    /* Trim out any callee-trashed registers from the live set */
-
+    // Trim out any callee-trashed registers from the live set.
+    regMaskTP savedSet = emitGetGCRegsSavedOrModified(methHnd);
     gcrefRegs &= savedSet;
     byrefRegs &= savedSet;
 
@@ -6898,9 +6949,6 @@ void emitter::emitIns_Call(EmitCallType          callType,
     }
 #endif
 
-    assert(argSize % REGSIZE_BYTES == 0);
-    argCnt = (int)(argSize / (int)REGSIZE_BYTES); // we need a signed-divide
-
     /* Managed RetVal: emit sequence point for the call */
     if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
     {
@@ -6921,6 +6969,11 @@ void emitter::emitIns_Call(EmitCallType          callType,
             Indir. call with GC vars          5,768
      */
 
+    instrDesc* id;
+
+    assert(argSize % REGSIZE_BYTES == 0);
+    int argCnt = (int)(argSize / (int)REGSIZE_BYTES); // we need a signed-divide
+
     if (callType >= EC_FUNC_VIRTUAL)
     {
         /* Indirect call, virtual calls */
@@ -6965,7 +7018,9 @@ void emitter::emitIns_Call(EmitCallType          callType,
     }
     id->idIns(ins);
 
-    id->idSetIsNoGC(isNoGC);
+    id->idSetIsNoGC(emitNoGChelper(methHnd));
+
+    UNATIVE_OFFSET sz;
 
     // Record the address: method, indirection, or funcptr
     if (callType >= EC_FUNC_VIRTUAL)
@@ -8341,6 +8396,17 @@ void emitter::emitDispIns(
             emitDispAddrMode(id);
             break;
 
+        case IF_RWR_ARD_RRD:
+            if (ins == INS_vpgatherqd || ins == INS_vgatherqps)
+            {
+                attr = EA_16BYTE;
+            }
+            sstr = codeGen->genSizeStr(EA_ATTR(4));
+            printf("%s, %s", emitRegName(id->idReg1(), attr), sstr);
+            emitDispAddrMode(id);
+            printf(", %s", emitRegName(id->idReg2(), attr));
+            break;
+
         case IF_RWR_RRD_ARD_CNS:
         {
             printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr);
@@ -9223,6 +9289,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
             switch (id->idInsFmt())
             {
                 case IF_RWR_RRD_ARD:
+                case IF_RWR_ARD_RRD:
                 case IF_RWR_RRD_ARD_CNS:
                 case IF_RWR_RRD_ARD_RRD:
                 {
@@ -12884,6 +12951,15 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
             break;
         }
 
+        case IF_RWR_ARD_RRD:
+        {
+            assert(IsAVX2GatherInstruction(ins));
+            code = insCodeRM(ins);
+            dst  = emitOutputAM(dst, id, code);
+            sz   = emitSizeOfInsDsc(id);
+            break;
+        }
+
         case IF_RWR_RRD_ARD_CNS:
         case IF_RWR_RRD_ARD_RRD:
         {
index 3ec962f..a3e25de 100644 (file)
@@ -335,6 +335,15 @@ void emitIns_R_R_A(instruction ins, emitAttr attr, regNumber reg1, regNumber reg
 
 void emitIns_R_R_AR(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber base, int offs);
 
+void emitIns_R_AR_R(instruction ins,
+                    emitAttr    attr,
+                    regNumber   reg1,
+                    regNumber   reg2,
+                    regNumber   base,
+                    regNumber   index,
+                    int         scale,
+                    int         offs);
+
 void emitIns_R_R_C(
     instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, CORINFO_FIELD_HANDLE fldHnd, int offs);
 
@@ -503,22 +512,6 @@ enum EmitCallType
 // clang-format off
 void emitIns_Call(EmitCallType          callType,
                   CORINFO_METHOD_HANDLE methHnd,
-                  CORINFO_SIG_INFO*     sigInfo, // used to report call sites to the EE
-                  void*                 addr,
-                  ssize_t               argSize,
-                  emitAttr              retSize
-                  MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
-                  VARSET_VALARG_TP      ptrVars,
-                  regMaskTP             gcrefRegs,
-                  regMaskTP             byrefRegs,
-                  GenTreeIndir*         indir,
-                  bool                  isJump = false,
-                  bool                  isNoGC = false);
-// clang-format on
-
-// clang-format off
-void emitIns_Call(EmitCallType          callType,
-                  CORINFO_METHOD_HANDLE methHnd,
                   INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE
                   void*                 addr,
                   ssize_t               argSize,
@@ -532,8 +525,7 @@ void emitIns_Call(EmitCallType          callType,
                   regNumber             xreg     = REG_NA,
                   unsigned              xmul     = 0,
                   ssize_t               disp     = 0,
-                  bool                  isJump   = false,
-                  bool                  isNoGC   = false);
+                  bool                  isJump   = false);
 // clang-format on
 
 #ifdef _TARGET_AMD64_
index 620087a..39fee9c 100644 (file)
@@ -16727,10 +16727,10 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* isExact, bo
 void GenTree::ParseArrayAddress(
     Compiler* comp, ArrayInfo* arrayInfo, GenTree** pArr, ValueNum* pInxVN, FieldSeqNode** pFldSeq)
 {
-    *pArr                = nullptr;
-    ValueNum      inxVN  = ValueNumStore::NoVN;
-    ssize_t       offset = 0;
-    FieldSeqNode* fldSeq = nullptr;
+    *pArr                 = nullptr;
+    ValueNum       inxVN  = ValueNumStore::NoVN;
+    target_ssize_t offset = 0;
+    FieldSeqNode*  fldSeq = nullptr;
 
     ParseArrayAddressWork(comp, 1, pArr, &inxVN, &offset, &fldSeq);
 
@@ -16782,20 +16782,21 @@ void GenTree::ParseArrayAddress(
     }
 
     // Is there some portion of the "offset" beyond the first-elem offset and the struct field suffix we just computed?
-    if (!FitsIn<ssize_t>(fieldOffsets + arrayInfo->m_elemOffset) || !FitsIn<ssize_t>(arrayInfo->m_elemSize))
+    if (!FitsIn<target_ssize_t>(fieldOffsets + arrayInfo->m_elemOffset) ||
+        !FitsIn<target_ssize_t>(arrayInfo->m_elemSize))
     {
         // This seems unlikely, but no harm in being safe...
         *pInxVN = comp->GetValueNumStore()->VNForExpr(nullptr, TYP_INT);
         return;
     }
     // Otherwise...
-    ssize_t offsetAccountedFor = static_cast<ssize_t>(fieldOffsets + arrayInfo->m_elemOffset);
-    ssize_t elemSize           = static_cast<ssize_t>(arrayInfo->m_elemSize);
+    target_ssize_t offsetAccountedFor = static_cast<target_ssize_t>(fieldOffsets + arrayInfo->m_elemOffset);
+    target_ssize_t elemSize           = static_cast<target_ssize_t>(arrayInfo->m_elemSize);
 
-    ssize_t constIndOffset = offset - offsetAccountedFor;
+    target_ssize_t constIndOffset = offset - offsetAccountedFor;
     // This should be divisible by the element size...
     assert((constIndOffset % elemSize) == 0);
-    ssize_t constInd = constIndOffset / elemSize;
+    target_ssize_t constInd = constIndOffset / elemSize;
 
     ValueNumStore* vnStore = comp->GetValueNumStore();
 
@@ -16814,7 +16815,7 @@ void GenTree::ParseArrayAddress(
         // which has been scaled by element size. We need to recover the array index from that offset
         if (vnStore->IsVNConstant(inxVN))
         {
-            ssize_t index = vnStore->CoercedConstantValue<ssize_t>(inxVN);
+            target_ssize_t index = vnStore->CoercedConstantValue<target_ssize_t>(inxVN);
             noway_assert(elemSize > 0 && ((index % elemSize) == 0));
             *pInxVN = vnStore->VNForPtrSizeIntCon((index / elemSize) + constInd);
         }
@@ -16863,8 +16864,12 @@ void GenTree::ParseArrayAddress(
     }
 }
 
-void GenTree::ParseArrayAddressWork(
-    Compiler* comp, ssize_t inputMul, GenTree** pArr, ValueNum* pInxVN, ssize_t* pOffset, FieldSeqNode** pFldSeq)
+void GenTree::ParseArrayAddressWork(Compiler*       comp,
+                                    target_ssize_t  inputMul,
+                                    GenTree**       pArr,
+                                    ValueNum*       pInxVN,
+                                    target_ssize_t* pOffset,
+                                    FieldSeqNode**  pFldSeq)
 {
     if (TypeGet() == TYP_REF)
     {
@@ -16878,7 +16883,10 @@ void GenTree::ParseArrayAddressWork(
         {
             case GT_CNS_INT:
                 *pFldSeq = comp->GetFieldSeqStore()->Append(*pFldSeq, gtIntCon.gtFieldSeq);
-                *pOffset += (inputMul * gtIntCon.gtIconVal);
+                assert(!gtIntCon.ImmedValNeedsReloc(comp));
+                // TODO-CrossBitness: we wouldn't need the cast below if GenTreeIntCon::gtIconVal had target_ssize_t
+                // type.
+                *pOffset += (inputMul * (target_ssize_t)(gtIntCon.gtIconVal));
                 return;
 
             case GT_ADD:
@@ -16894,8 +16902,8 @@ void GenTree::ParseArrayAddressWork(
             case GT_MUL:
             {
                 // If one op is a constant, continue parsing down.
-                ssize_t  subMul   = 0;
-                GenTree* nonConst = nullptr;
+                target_ssize_t subMul   = 0;
+                GenTree*       nonConst = nullptr;
                 if (gtOp.gtOp1->IsCnsIntOrI())
                 {
                     // If the other arg is an int constant, and is a "not-a-field", choose
@@ -16903,18 +16911,27 @@ void GenTree::ParseArrayAddressWork(
                     if (gtOp.gtOp2->OperGet() == GT_CNS_INT &&
                         gtOp.gtOp2->gtIntCon.gtFieldSeq == FieldSeqStore::NotAField())
                     {
-                        subMul   = gtOp.gtOp2->gtIntConCommon.IconValue();
+                        assert(!gtOp.gtOp2->gtIntCon.ImmedValNeedsReloc(comp));
+                        // TODO-CrossBitness: we wouldn't need the cast below if GenTreeIntConCommon::gtIconVal had
+                        // target_ssize_t type.
+                        subMul   = (target_ssize_t)gtOp.gtOp2->gtIntConCommon.IconValue();
                         nonConst = gtOp.gtOp1;
                     }
                     else
                     {
-                        subMul   = gtOp.gtOp1->gtIntConCommon.IconValue();
+                        assert(!gtOp.gtOp1->gtIntCon.ImmedValNeedsReloc(comp));
+                        // TODO-CrossBitness: we wouldn't need the cast below if GenTreeIntConCommon::gtIconVal had
+                        // target_ssize_t type.
+                        subMul   = (target_ssize_t)gtOp.gtOp1->gtIntConCommon.IconValue();
                         nonConst = gtOp.gtOp2;
                     }
                 }
                 else if (gtOp.gtOp2->IsCnsIntOrI())
                 {
-                    subMul   = gtOp.gtOp2->gtIntConCommon.IconValue();
+                    assert(!gtOp.gtOp2->gtIntCon.ImmedValNeedsReloc(comp));
+                    // TODO-CrossBitness: we wouldn't need the cast below if GenTreeIntConCommon::gtIconVal had
+                    // target_ssize_t type.
+                    subMul   = (target_ssize_t)gtOp.gtOp2->gtIntConCommon.IconValue();
                     nonConst = gtOp.gtOp1;
                 }
                 if (nonConst != nullptr)
@@ -16930,7 +16947,10 @@ void GenTree::ParseArrayAddressWork(
                 // If one op is a constant, continue parsing down.
                 if (gtOp.gtOp2->IsCnsIntOrI())
                 {
-                    ssize_t subMul = ssize_t{1} << gtOp.gtOp2->gtIntConCommon.IconValue();
+                    assert(!gtOp.gtOp2->gtIntCon.ImmedValNeedsReloc(comp));
+                    // TODO-CrossBitness: we wouldn't need the cast below if GenTreeIntCon::gtIconVal had target_ssize_t
+                    // type.
+                    target_ssize_t subMul = target_ssize_t{1} << (target_ssize_t)gtOp.gtOp2->gtIntConCommon.IconValue();
                     gtOp.gtOp1->ParseArrayAddressWork(comp, inputMul * subMul, pArr, pInxVN, pOffset, pFldSeq);
                     return;
                 }
@@ -17501,13 +17521,18 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad()
     {
         // Some AVX instructions here also have MemoryLoad sematics
 
-        // Do we have 3 operands?
-        if (HWIntrinsicInfo::lookupNumArgs(this) != 3)
+        // Do we have less than 3 operands?
+        if (HWIntrinsicInfo::lookupNumArgs(this) < 3)
         {
             return false;
         }
-        else // We have 3 operands/args
+        else // We have 3 or more operands/args
         {
+            if (HWIntrinsicInfo::isAVX2GatherIntrinsic(gtHWIntrinsicId))
+            {
+                return true;
+            }
+
             GenTreeArgList* argList = gtOp.gtOp1->AsArgList();
 
             if ((gtHWIntrinsicId == NI_AVX_InsertVector128 || gtHWIntrinsicId == NI_AVX2_InsertVector128) &&
@@ -17558,38 +17583,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore()
 bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore()
 {
 #ifdef _TARGET_XARCH_
-    // Some xarch instructions have MemoryLoad sematics
-    HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(gtHWIntrinsicId);
-    if ((category == HW_Category_MemoryLoad) || (category == HW_Category_MemoryStore))
-    {
-        return true;
-    }
-    else if (category == HW_Category_IMM)
-    {
-        // Some AVX instructions here also have MemoryLoad or MemoryStore sematics
-
-        // Do we have 3 operands?
-        if (HWIntrinsicInfo::lookupNumArgs(this) != 3)
-        {
-            return false;
-        }
-        else // We have 3 operands/args
-        {
-            GenTreeArgList* argList = gtOp.gtOp1->AsArgList();
-
-            if ((gtHWIntrinsicId == NI_AVX_InsertVector128 || gtHWIntrinsicId == NI_AVX2_InsertVector128) &&
-                (argList->Rest()->Current()->TypeGet() == TYP_I_IMPL)) // Is the type of the second arg TYP_I_IMPL?
-            {
-                // This is Avx/Avx2.InsertVector128
-                return true;
-            }
-            else if ((gtHWIntrinsicId == NI_AVX_ExtractVector128 || gtHWIntrinsicId == NI_AVX2_ExtractVector128))
-            {
-                // This is Avx/Avx2.ExtractVector128
-                return true;
-            }
-        }
-    }
+    return OperIsMemoryLoad() || OperIsMemoryStore();
 #endif // _TARGET_XARCH_
     return false;
 }
index 006812b..d30d51e 100644 (file)
@@ -479,8 +479,8 @@ public:
     // happening.
     void CopyCosts(const GenTree* const tree)
     {
-        INDEBUG(gtCostsInitialized =
-                    tree->gtCostsInitialized;) // If the 'tree' costs aren't initialized, we'll hit an assert below.
+        // If the 'tree' costs aren't initialized, we'll hit an assert below.
+        INDEBUG(gtCostsInitialized = tree->gtCostsInitialized;)
         _gtCostEx = tree->gtCostEx;
         _gtCostSz = tree->gtCostSz;
     }
@@ -797,7 +797,6 @@ public:
 
 #define GTF_NOP_DEATH               0x40000000 // GT_NOP -- operand dies here
 
-#define GTF_FLD_NULLCHECK           0x80000000 // GT_FIELD -- need to nullcheck the "this" pointer
 #define GTF_FLD_VOLATILE            0x40000000 // GT_FIELD/GT_CLS_VAR -- same as GTF_IND_VOLATILE
 #define GTF_FLD_INITCLASS           0x20000000 // GT_FIELD/GT_CLS_VAR -- field access requires preceding class/static init helper
 
@@ -805,8 +804,6 @@ public:
 #define GTF_INX_REFARR_LAYOUT       0x20000000 // GT_INDEX
 #define GTF_INX_STRING_LAYOUT       0x40000000 // GT_INDEX -- this uses the special string array layout
 
-#define GTF_IND_ARR_LEN             0x80000000 // GT_IND   -- the indirection represents an array length (of the REF
-                                               //             contribution to its argument).
 #define GTF_IND_VOLATILE            0x40000000 // GT_IND   -- the load or store must use volatile sematics (this is a nop on X86)
 #define GTF_IND_NONFAULTING         0x20000000 // Operations for which OperIsIndir() is true  -- An indir that cannot fault.
                                                // Same as GTF_ARRLEN_NONFAULTING.
@@ -1901,8 +1898,12 @@ public:
         Compiler* comp, struct ArrayInfo* arrayInfo, GenTree** pArr, ValueNum* pInxVN, FieldSeqNode** pFldSeq);
 
     // Helper method for the above.
-    void ParseArrayAddressWork(
-        Compiler* comp, ssize_t inputMul, GenTree** pArr, ValueNum* pInxVN, ssize_t* pOffset, FieldSeqNode** pFldSeq);
+    void ParseArrayAddressWork(Compiler*       comp,
+                               target_ssize_t  inputMul,
+                               GenTree**       pArr,
+                               ValueNum*       pInxVN,
+                               target_ssize_t* pOffset,
+                               FieldSeqNode**  pFldSeq);
 
     // Requires "this" to be a GT_IND.  Requires the outermost caller to set "*pFldSeq" to nullptr.
     // Returns true if it is an array index expression, or access to a (sequence of) struct field(s)
@@ -4115,6 +4116,7 @@ struct GenTreeSIMD : public GenTreeJitIntrinsic
 struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic
 {
     NamedIntrinsic gtHWIntrinsicId;
+    var_types      gtIndexBaseType; // for AVX2 Gather* intrinsics
 
     GenTreeHWIntrinsic(var_types type, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size)
         : GenTreeJitIntrinsic(GT_HWIntrinsic, type, nullptr, nullptr, baseType, size), gtHWIntrinsicId(hwIntrinsicID)
index 0a9dfb3..f3dec92 100644 (file)
@@ -1184,6 +1184,9 @@ void CodeGen::genHWIntrinsicJumpTableFallback(NamedIntrinsic            intrinsi
                                               HWIntrinsicSwitchCaseBody emitSwCase)
 {
     assert(nonConstImmReg != REG_NA);
+    // AVX2 Gather intrinsics use managed non-const fallback since they have discrete imm8 value range
+    // that does work with the current compiler generated jump-table fallback
+    assert(!HWIntrinsicInfo::isAVX2GatherIntrinsic(intrinsic));
     emitter* emit = getEmitter();
 
     const unsigned maxByte = (unsigned)HWIntrinsicInfo::lookupImmUpperBound(intrinsic) + 1;
@@ -2008,6 +2011,117 @@ void CodeGen::genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node)
             break;
         }
 
+        case NI_AVX2_GatherVector128:
+        case NI_AVX2_GatherVector256:
+        case NI_AVX2_GatherMaskVector128:
+        case NI_AVX2_GatherMaskVector256:
+        {
+            GenTreeArgList* list = op1->AsArgList();
+            op1                  = list->Current();
+            op1Reg               = op1->gtRegNum;
+            genConsumeRegs(op1);
+
+            list   = list->Rest();
+            op2    = list->Current();
+            op2Reg = op2->gtRegNum;
+            genConsumeRegs(op2);
+
+            list         = list->Rest();
+            GenTree* op3 = list->Current();
+            genConsumeRegs(op3);
+
+            list             = list->Rest();
+            GenTree* op4     = nullptr;
+            GenTree* lastOp  = nullptr;
+            GenTree* indexOp = nullptr;
+
+            regNumber op3Reg       = REG_NA;
+            regNumber op4Reg       = REG_NA;
+            regNumber addrBaseReg  = REG_NA;
+            regNumber addrIndexReg = REG_NA;
+            regNumber maskReg      = node->ExtractTempReg(RBM_ALLFLOAT);
+
+            if (numArgs == 5)
+            {
+                assert(intrinsicId == NI_AVX2_GatherMaskVector128 || intrinsicId == NI_AVX2_GatherMaskVector256);
+                op4    = list->Current();
+                list   = list->Rest();
+                lastOp = list->Current();
+                op3Reg = op3->gtRegNum;
+                op4Reg = op4->gtRegNum;
+                genConsumeRegs(op4);
+                addrBaseReg  = op2Reg;
+                addrIndexReg = op3Reg;
+                indexOp      = op3;
+
+                // copy op4Reg into the tmp mask register,
+                // the mask register will be cleared by gather instructions
+                emit->emitIns_R_R(INS_movaps, attr, maskReg, op4Reg);
+
+                if (targetReg != op1Reg)
+                {
+                    // copy source vector to the target register for masking merge
+                    emit->emitIns_R_R(INS_movaps, attr, targetReg, op1Reg);
+                }
+            }
+            else
+            {
+                assert(intrinsicId == NI_AVX2_GatherVector128 || intrinsicId == NI_AVX2_GatherVector256);
+                addrBaseReg  = op1Reg;
+                addrIndexReg = op2Reg;
+                indexOp      = op2;
+                lastOp       = op3;
+
+                // generate all-one mask vector
+                emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, maskReg, maskReg, maskReg);
+            }
+
+            bool isVector128GatherWithVector256Index = (targetType == TYP_SIMD16) && (indexOp->TypeGet() == TYP_SIMD32);
+
+            // hwintrinsiclistxarch.h uses Dword index instructions in default
+            if (varTypeIsLong(node->gtIndexBaseType))
+            {
+                switch (ins)
+                {
+                    case INS_vpgatherdd:
+                        ins = INS_vpgatherqd;
+                        if (isVector128GatherWithVector256Index)
+                        {
+                            // YMM index in address mode
+                            attr = emitTypeSize(TYP_SIMD32);
+                        }
+                        break;
+                    case INS_vpgatherdq:
+                        ins = INS_vpgatherqq;
+                        break;
+                    case INS_vgatherdps:
+                        ins = INS_vgatherqps;
+                        if (isVector128GatherWithVector256Index)
+                        {
+                            // YMM index in address mode
+                            attr = emitTypeSize(TYP_SIMD32);
+                        }
+                        break;
+                    case INS_vgatherdpd:
+                        ins = INS_vgatherqpd;
+                        break;
+                    default:
+                        unreached();
+                }
+            }
+
+            assert(lastOp->IsCnsIntOrI());
+            ssize_t ival = lastOp->AsIntCon()->IconValue();
+            assert((ival >= 0) && (ival <= 255));
+
+            assert(targetReg != maskReg);
+            assert(targetReg != addrIndexReg);
+            assert(maskReg != addrIndexReg);
+            emit->emitIns_R_AR_R(ins, attr, targetReg, maskReg, addrBaseReg, addrIndexReg, (int8_t)ival, 0);
+
+            break;
+        }
+
         case NI_AVX_GetLowerHalf:
         {
             assert(op2 == nullptr);
index ac59fc8..41ee9ef 100644 (file)
@@ -430,6 +430,10 @@ HARDWARE_INTRINSIC(AVX2_ConvertToVector256Int32,                    "ConvertToVe
 HARDWARE_INTRINSIC(AVX2_ConvertToVector256UInt32,                   "ConvertToVector256UInt32",                     AVX2,         -1,              32,           1,     {INS_invalid,           INS_pmovzxbd,       INS_invalid,        INS_pmovzxwd,       INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_BaseTypeFromFirstArg)
 HARDWARE_INTRINSIC(AVX2_ConvertToVector256Int64,                    "ConvertToVector256Int64",                      AVX2,         -1,              32,           1,     {INS_pmovsxbq,          INS_invalid,        INS_pmovsxwq,       INS_invalid,        INS_pmovsxdq,       INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_BaseTypeFromFirstArg)
 HARDWARE_INTRINSIC(AVX2_ConvertToVector256UInt64,                   "ConvertToVector256UInt64",                     AVX2,         -1,              32,           1,     {INS_invalid,           INS_pmovzxbq,       INS_invalid,        INS_pmovzxwq,       INS_invalid,        INS_pmovzxdq,       INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_BaseTypeFromFirstArg)
+HARDWARE_INTRINSIC(AVX2_GatherVector128,                            "GatherVector128",                              AVX2,         -1,              16,            3,     {INS_invalid,           INS_invalid,        INS_invalid,       INS_invalid,        INS_vpgatherdd,     INS_vpgatherdd,     INS_vpgatherdq,     INS_vpgatherdq,     INS_vgatherdps,     INS_vgatherdpd},        HW_Category_IMM,                    HW_Flag_SpecialCodeGen|HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(AVX2_GatherVector256,                            "GatherVector256",                              AVX2,         -1,              32,            3,     {INS_invalid,           INS_invalid,        INS_invalid,       INS_invalid,        INS_vpgatherdd,     INS_vpgatherdd,     INS_vpgatherdq,     INS_vpgatherdq,     INS_vgatherdps,     INS_vgatherdpd},        HW_Category_IMM,                    HW_Flag_SpecialCodeGen|HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(AVX2_GatherMaskVector128,                        "GatherMaskVector128",                          AVX2,         -1,              16,            5,     {INS_invalid,           INS_invalid,        INS_invalid,       INS_invalid,        INS_vpgatherdd,     INS_vpgatherdd,     INS_vpgatherdq,     INS_vpgatherdq,     INS_vgatherdps,     INS_vgatherdpd},        HW_Category_IMM,                    HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(AVX2_GatherMaskVector256,                        "GatherMaskVector256",                          AVX2,         -1,              32,            5,     {INS_invalid,           INS_invalid,        INS_invalid,       INS_invalid,        INS_vpgatherdd,     INS_vpgatherdd,     INS_vpgatherdq,     INS_vpgatherdq,     INS_vgatherdps,     INS_vgatherdpd},        HW_Category_IMM,                    HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_NoContainment)
 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)
index 33363b5..8f53c3a 100644 (file)
@@ -232,7 +232,6 @@ int HWIntrinsicInfo::lookupNumArgs(const GenTreeHWIntrinsic* node)
 
     if (op1->OperIsList())
     {
-#if DEBUG
         GenTreeArgList* list = op1->AsArgList();
         numArgs              = 0;
 
@@ -242,10 +241,7 @@ int HWIntrinsicInfo::lookupNumArgs(const GenTreeHWIntrinsic* node)
             list = list->Rest();
         } while (list != nullptr);
 
-        assert(numArgs == 3);
-#endif
-
-        return 3;
+        return numArgs;
     }
 
     GenTree* op2 = node->gtGetOp2();
@@ -303,6 +299,17 @@ GenTree* HWIntrinsicInfo::lookupLastOp(const GenTreeHWIntrinsic* node)
             return node->gtGetOp1()->AsArgList()->Rest()->Rest()->Current();
         }
 
+        case 5:
+        {
+            assert(node->gtGetOp1() != nullptr);
+            assert(node->gtGetOp1()->OperIsList());
+            assert(node->gtGetOp2() == nullptr);
+            assert(node->gtGetOp1()->AsArgList()->Rest()->Rest()->Rest()->Rest()->Current() != nullptr);
+            assert(node->gtGetOp1()->AsArgList()->Rest()->Rest()->Rest()->Rest()->Rest() == nullptr);
+
+            return node->gtGetOp1()->AsArgList()->Rest()->Rest()->Rest()->Rest()->Current();
+        }
+
         default:
         {
             unreached();
@@ -362,6 +369,12 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic id)
             return 31; // enum FloatComparisonMode has 32 values
         }
 
+        case NI_AVX2_GatherVector128:
+        case NI_AVX2_GatherVector256:
+        case NI_AVX2_GatherMaskVector128:
+        case NI_AVX2_GatherMaskVector256:
+            return 8;
+
         default:
         {
             assert(HWIntrinsicInfo::HasFullRangeImm(id));
@@ -371,6 +384,53 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic id)
 }
 
 //------------------------------------------------------------------------
+// isInImmRange: Check if ival is valid for the intrinsic
+//
+// Arguments:
+//    id   -- The NamedIntrinsic associated with the HWIntrinsic to lookup
+//    ival -- the imm value to be checked
+//
+// Return Value:
+//     true if ival is valid for the intrinsic
+//
+bool HWIntrinsicInfo::isInImmRange(NamedIntrinsic id, int ival)
+{
+    assert(HWIntrinsicInfo::lookupCategory(id) == HW_Category_IMM);
+
+    if (isAVX2GatherIntrinsic(id))
+    {
+        return ival == 1 || ival == 2 || ival == 4 || ival == 8;
+    }
+    else
+    {
+        return ival <= lookupImmUpperBound(id) && ival >= 0;
+    }
+}
+
+//------------------------------------------------------------------------
+// isAVX2GatherIntrinsic: Check if the intrinsic is AVX Gather*
+//
+// Arguments:
+//    id   -- The NamedIntrinsic associated with the HWIntrinsic to lookup
+//
+// Return Value:
+//     true if id is AVX Gather* intrinsic
+//
+bool HWIntrinsicInfo::isAVX2GatherIntrinsic(NamedIntrinsic id)
+{
+    switch (id)
+    {
+        case NI_AVX2_GatherVector128:
+        case NI_AVX2_GatherVector256:
+        case NI_AVX2_GatherMaskVector128:
+        case NI_AVX2_GatherMaskVector256:
+            return true;
+        default:
+            return false;
+    }
+}
+
+//------------------------------------------------------------------------
 // isFullyImplementedIsa: Gets a value that indicates whether the InstructionSet is fully implemented
 //
 // Arguments:
@@ -532,7 +592,10 @@ GenTree* Compiler::addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* last
     assert(lastOp != nullptr);
     // Full-range imm-intrinsics do not need the range-check
     // because the imm-parameter of the intrinsic method is a byte.
-    if (mustExpand && !HWIntrinsicInfo::HasFullRangeImm(intrinsic) && HWIntrinsicInfo::isImmOp(intrinsic, lastOp))
+    // AVX2 Gather intrinsics no not need the range-check
+    // because their imm-parameter have discrete valid values that are handle by managed code
+    if (mustExpand && !HWIntrinsicInfo::HasFullRangeImm(intrinsic) && HWIntrinsicInfo::isImmOp(intrinsic, lastOp) &&
+        !HWIntrinsicInfo::isAVX2GatherIntrinsic(intrinsic))
     {
         assert(!lastOp->IsCnsIntOrI());
         GenTree* upperBoundNode =
@@ -683,7 +746,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
         if (!HWIntrinsicInfo::HasFullRangeImm(intrinsic))
         {
             if (!mustExpand && lastOp->IsCnsIntOrI() &&
-                lastOp->AsIntCon()->IconValue() > HWIntrinsicInfo::lookupImmUpperBound(intrinsic))
+                !HWIntrinsicInfo::isInImmRange(intrinsic, (int)lastOp->AsIntCon()->IconValue()))
             {
                 return nullptr;
             }
@@ -808,13 +871,26 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
 
                 argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
                 op2     = getArgForHWIntrinsic(argType, argClass);
+                var_types op2Type;
+                if (intrinsic == NI_AVX2_GatherVector128 || intrinsic == NI_AVX2_GatherVector256)
+                {
+                    assert(varTypeIsSIMD(op2->TypeGet()));
+                    op2Type = getBaseTypeOfSIMDType(argClass);
+                }
 
                 argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
                 op1     = getArgForHWIntrinsic(argType, argClass);
 
                 retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, baseType, simdSize);
+
+                if (intrinsic == NI_AVX2_GatherVector128 || intrinsic == NI_AVX2_GatherVector256)
+                {
+                    assert(varTypeIsSIMD(op2->TypeGet()));
+                    retNode->AsHWIntrinsic()->gtIndexBaseType = op2Type;
+                }
                 break;
             }
+
             default:
                 unreached();
         }
@@ -1276,6 +1352,50 @@ GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic        intrinsic,
             }
             break;
         }
+
+        case NI_AVX2_GatherMaskVector128:
+        case NI_AVX2_GatherMaskVector256:
+        {
+            CORINFO_ARG_LIST_HANDLE argList = sig->args;
+            CORINFO_CLASS_HANDLE    argClass;
+            var_types               argType = TYP_UNKNOWN;
+            unsigned int            sizeBytes;
+            baseType          = getBaseTypeAndSizeOfSIMDType(sig->retTypeSigClass, &sizeBytes);
+            var_types retType = getSIMDTypeForSize(sizeBytes);
+
+            assert(sig->numArgs == 5);
+            CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList);
+            CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
+            CORINFO_ARG_LIST_HANDLE arg4 = info.compCompHnd->getArgNext(arg3);
+            CORINFO_ARG_LIST_HANDLE arg5 = info.compCompHnd->getArgNext(arg4);
+
+            argType      = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg5, &argClass)));
+            GenTree* op5 = getArgForHWIntrinsic(argType, argClass);
+            SetOpLclRelatedToSIMDIntrinsic(op5);
+
+            argType      = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg4, &argClass)));
+            GenTree* op4 = getArgForHWIntrinsic(argType, argClass);
+            SetOpLclRelatedToSIMDIntrinsic(op4);
+
+            argType                 = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass)));
+            var_types indexbaseType = getBaseTypeOfSIMDType(argClass);
+            GenTree*  op3           = getArgForHWIntrinsic(argType, argClass);
+            SetOpLclRelatedToSIMDIntrinsic(op3);
+
+            argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
+            op2     = getArgForHWIntrinsic(argType, argClass);
+            SetOpLclRelatedToSIMDIntrinsic(op2);
+
+            argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
+            op1     = getArgForHWIntrinsic(argType, argClass);
+            SetOpLclRelatedToSIMDIntrinsic(op1);
+
+            GenTree* opList = new (this, GT_LIST) GenTreeArgList(op1, gtNewArgList(op2, op3, op4, op5));
+            retNode = new (this, GT_HWIntrinsic) GenTreeHWIntrinsic(retType, opList, intrinsic, baseType, simdSize);
+            retNode->AsHWIntrinsic()->gtIndexBaseType = indexbaseType;
+            break;
+        }
+
         default:
             JITDUMP("Not implemented hardware intrinsic");
             break;
index 61a09a0..d74709a 100644 (file)
@@ -149,6 +149,8 @@ struct HWIntrinsicInfo
     static bool isImmOp(NamedIntrinsic id, const GenTree* op);
 
     static int lookupImmUpperBound(NamedIntrinsic id);
+    static bool isInImmRange(NamedIntrinsic id, int ival);
+    static bool isAVX2GatherIntrinsic(NamedIntrinsic id);
 
     static bool isFullyImplementedIsa(InstructionSet isa);
     static bool isScalarIsa(InstructionSet isa);
index 7636410..5a86ff9 100644 (file)
@@ -3710,7 +3710,7 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
             op1                                    = impPopStack().val;
             GenTree*             thisptr           = newobjThis;
             CORINFO_FIELD_HANDLE fldHnd            = info.compCompHnd->getFieldInClass(clsHnd, 0);
-            GenTree*             field             = gtNewFieldRef(TYP_BYREF, fldHnd, thisptr, 0, false);
+            GenTree*             field             = gtNewFieldRef(TYP_BYREF, fldHnd, thisptr, 0);
             GenTree*             assign            = gtNewAssignNode(field, op1);
             GenTree*             byReferenceStruct = gtCloneExpr(thisptr->gtGetOp1());
             assert(byReferenceStruct != nullptr);
@@ -3723,7 +3723,7 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
         {
             op1                         = impPopStack().val;
             CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(clsHnd, 0);
-            GenTree*             field  = gtNewFieldRef(TYP_BYREF, fldHnd, op1, 0, false);
+            GenTree*             field  = gtNewFieldRef(TYP_BYREF, fldHnd, op1, 0);
             retNode                     = field;
             break;
         }
@@ -3775,7 +3775,7 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
             // Bounds check
             CORINFO_FIELD_HANDLE lengthHnd    = info.compCompHnd->getFieldInClass(clsHnd, 1);
             const unsigned       lengthOffset = info.compCompHnd->getFieldOffset(lengthHnd);
-            GenTree*             length       = gtNewFieldRef(TYP_INT, lengthHnd, ptrToSpan, lengthOffset, false);
+            GenTree*             length       = gtNewFieldRef(TYP_INT, lengthHnd, ptrToSpan, lengthOffset);
             GenTree*             boundsCheck  = new (this, GT_ARR_BOUNDS_CHECK)
                 GenTreeBoundsChk(GT_ARR_BOUNDS_CHECK, TYP_VOID, index, length, SCK_RNGCHK_FAIL);
 
@@ -3785,7 +3785,7 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
             GenTree*             mulNode     = gtNewOperNode(GT_MUL, TYP_I_IMPL, indexIntPtr, sizeofNode);
             CORINFO_FIELD_HANDLE ptrHnd      = info.compCompHnd->getFieldInClass(clsHnd, 0);
             const unsigned       ptrOffset   = info.compCompHnd->getFieldOffset(ptrHnd);
-            GenTree*             data        = gtNewFieldRef(TYP_BYREF, ptrHnd, ptrToSpanClone, ptrOffset, false);
+            GenTree*             data        = gtNewFieldRef(TYP_BYREF, ptrHnd, ptrToSpanClone, ptrOffset);
             GenTree*             result      = gtNewOperNode(GT_ADD, TYP_BYREF, data, mulNode);
 
             // Prepare result
@@ -13698,15 +13698,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
                     case CORINFO_FIELD_INSTANCE_WITH_BASE:
 #endif
                     {
-                        bool nullcheckNeeded = false;
-
                         obj = impCheckForNullPointer(obj);
 
-                        if (isLoadAddress && (obj->gtType == TYP_BYREF) && fgAddrCouldBeNull(obj))
-                        {
-                            nullcheckNeeded = true;
-                        }
-
                         // If the object is a struct, what we really want is
                         // for the field to operate on the address of the struct.
                         if (!varTypeGCtype(obj->TypeGet()) && impIsValueType(tiObj))
@@ -13717,7 +13710,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
                         }
 
                         /* Create the data member node */
-                        op1 = gtNewFieldRef(lclTyp, resolvedToken.hField, obj, fieldInfo.offset, nullcheckNeeded);
+                        op1 = gtNewFieldRef(lclTyp, resolvedToken.hField, obj, fieldInfo.offset);
 
 #ifdef FEATURE_READYTORUN_COMPILER
                         if (fieldInfo.fieldAccessor == CORINFO_FIELD_INSTANCE_WITH_BASE)
@@ -15525,7 +15518,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
                     op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1,
                                         gtNewIconNode(OFFSETOF__CORINFO_Array__length, TYP_I_IMPL));
                     op1 = gtNewIndir(TYP_INT, op1);
-                    op1->gtFlags |= GTF_IND_ARR_LEN;
                 }
 
                 /* Push the result back on the stack */
index f64edad..f205ed8 100644 (file)
@@ -503,6 +503,14 @@ INST3(vmaskmovps,       "maskmovps",        IUM_WR, SSE38(0x2E),  BAD_CODE,
 INST3(vmaskmovpd,       "maskmovpd",        IUM_WR, SSE38(0x2F),  BAD_CODE,     SSE38(0x2D),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Conditional SIMD Packed Double-Precision Floating-Point Loads and Stores
 INST3(vpmaskmovd,       "pmaskmovd",        IUM_WR, SSE38(0x8E),  BAD_CODE,     SSE38(0x8C),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Conditional SIMD Integer Packed Dword Loads and Stores
 INST3(vpmaskmovq,       "pmaskmovq",        IUM_WR, SSE38(0x8E),  BAD_CODE,     SSE38(0x8C),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Conditional SIMD Integer Packed Qword Loads and Stores
+INST3(vpgatherdd,       "pgatherdd",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x90),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed Dword Values Using Signed Dword
+INST3(vpgatherqd,       "pgatherqd",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x91),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed Dword Values Using Signed Qword
+INST3(vpgatherdq,       "pgatherdq",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x90),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed Dword with Signed Dword Indices
+INST3(vpgatherqq,       "pgatherqq",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x91),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed Qword with Signed Dword Indices
+INST3(vgatherdps,       "gatherdps",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x92),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed SP FP values Using Signed Dword Indices
+INST3(vgatherqps,       "gatherqps",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x93),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed SP FP values Using Signed Qword Indices
+INST3(vgatherdpd,       "gatherdpd",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x92),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed DP FP Values Using Signed Dword Indices
+INST3(vgatherqpd,       "gatherqpd",        IUM_WR, BAD_CODE,     BAD_CODE,     SSE38(0x93),                             INS_Flags_IsDstDstSrcAVXInstruction)    // Gather Packed DP FP Values Using Signed Qword Indices
 
 INST3(FIRST_FMA_INSTRUCTION, "FIRST_FMA_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_FLAGS_None)
 //    id                nm                  um      mr            mi            rm                                       flags
index 49b8c7a..8b931e7 100644 (file)
@@ -151,6 +151,7 @@ CONFIG_METHODSET(JitEHDump, W("JitEHDump"))                  // Dump the EH tabl
 CONFIG_METHODSET(JitExclude, W("JitExclude"))
 CONFIG_METHODSET(JitForceProcedureSplitting, W("JitForceProcedureSplitting"))
 CONFIG_METHODSET(JitGCDump, W("JitGCDump"))
+CONFIG_METHODSET(JitDebugDump, W("JitDebugDump"))
 CONFIG_METHODSET(JitHalt, W("JitHalt")) // Emits break instruction into jitted code
 CONFIG_METHODSET(JitImportBreak, W("JitImportBreak"))
 CONFIG_METHODSET(JitInclude, W("JitInclude"))
@@ -171,6 +172,7 @@ CONFIG_METHODSET(NgenDump, W("NgenDump"))     // Same as JitDump, but for ngen
 CONFIG_METHODSET(NgenDumpIR, W("NgenDumpIR")) // Same as JitDumpIR, but for ngen
 CONFIG_METHODSET(NgenEHDump, W("NgenEHDump")) // Dump the EH table for the method, as reported to the VM
 CONFIG_METHODSET(NgenGCDump, W("NgenGCDump"))
+CONFIG_METHODSET(NgenDebugDump, W("NgenDebugDump"))
 CONFIG_METHODSET(NgenUnwindDump, W("NgenUnwindDump")) // Dump the unwind codes for the method
 ///
 /// JIT
index 0d0f480..fb5fab2 100644 (file)
@@ -5519,121 +5519,6 @@ bool Lowering::NodesAreEquivalentLeaves(GenTree* tree1, GenTree* tree2)
     }
 }
 
-/**
- * Get common information required to handle a cast instruction
- */
-void Lowering::getCastDescription(GenTree* treeNode, CastInfo* castInfo)
-{
-    // Intialize castInfo
-    memset(castInfo, 0, sizeof(*castInfo));
-
-    GenTree* castOp = treeNode->gtCast.CastOp();
-
-    var_types dstType = treeNode->CastToType();
-    var_types srcType = genActualType(castOp->TypeGet());
-
-    castInfo->unsignedDest   = varTypeIsUnsigned(dstType);
-    castInfo->unsignedSource = varTypeIsUnsigned(srcType);
-
-    // If necessary, force the srcType to unsigned when the GT_UNSIGNED flag is set.
-    if (!castInfo->unsignedSource && (treeNode->gtFlags & GTF_UNSIGNED) != 0)
-    {
-        srcType                  = genUnsignedType(srcType);
-        castInfo->unsignedSource = true;
-    }
-
-    if (treeNode->gtOverflow() &&
-        (genTypeSize(srcType) >= genTypeSize(dstType) || (srcType == TYP_INT && dstType == TYP_ULONG)))
-    {
-        castInfo->requiresOverflowCheck = true;
-    }
-
-    if (castInfo->requiresOverflowCheck)
-    {
-        ssize_t typeMin       = 0;
-        ssize_t typeMax       = 0;
-        ssize_t typeMask      = 0;
-        bool    signCheckOnly = false;
-
-        // Do we need to compare the value, or just check masks
-        switch (dstType)
-        {
-            default:
-                assert(!"unreachable: getCastDescription");
-                break;
-
-            case TYP_BYTE:
-                typeMask = ssize_t((int)0xFFFFFF80);
-                typeMin  = SCHAR_MIN;
-                typeMax  = SCHAR_MAX;
-                break;
-
-            case TYP_UBYTE:
-                typeMask = ssize_t((int)0xFFFFFF00L);
-                break;
-
-            case TYP_SHORT:
-                typeMask = ssize_t((int)0xFFFF8000);
-                typeMin  = SHRT_MIN;
-                typeMax  = SHRT_MAX;
-                break;
-
-            case TYP_USHORT:
-                typeMask = ssize_t((int)0xFFFF0000L);
-                break;
-
-            case TYP_INT:
-                if (srcType == TYP_UINT)
-                {
-                    signCheckOnly = true;
-                }
-                else
-                {
-#ifdef _TARGET_64BIT_
-                    typeMask = 0xFFFFFFFF80000000LL;
-#else
-                    typeMask = 0x80000000;
-#endif
-                    typeMin = INT_MIN;
-                    typeMax = INT_MAX;
-                }
-                break;
-
-            case TYP_UINT:
-                if (srcType == TYP_INT)
-                {
-                    signCheckOnly = true;
-                }
-                else
-                {
-#ifdef _TARGET_64BIT_
-                    typeMask = 0xFFFFFFFF00000000LL;
-#else
-                    typeMask = 0x00000000;
-#endif
-                }
-                break;
-
-            case TYP_LONG:
-                signCheckOnly = true;
-                break;
-
-            case TYP_ULONG:
-                signCheckOnly = true;
-                break;
-        }
-
-        if (signCheckOnly)
-        {
-            castInfo->signCheckOnly = true;
-        }
-
-        castInfo->typeMax  = typeMax;
-        castInfo->typeMin  = typeMin;
-        castInfo->typeMask = typeMask;
-    }
-}
-
 //------------------------------------------------------------------------
 // Containment Analysis
 //------------------------------------------------------------------------
index 656e177..c78e26b 100644 (file)
@@ -30,23 +30,6 @@ public:
     }
     virtual void DoPhase() override;
 
-    // If requiresOverflowCheck is false, all other values will be unset
-    struct CastInfo
-    {
-        bool requiresOverflowCheck; // Will the cast require an overflow check
-        bool unsignedSource;        // Is the source unsigned
-        bool unsignedDest;          // is the dest unsigned
-
-        // All other fields are only meaningful if requiresOverflowCheck is set.
-
-        ssize_t typeMin;       // Lowest storable value of the dest type
-        ssize_t typeMax;       // Highest storable value of the dest type
-        ssize_t typeMask;      // For converting from/to unsigned
-        bool    signCheckOnly; // For converting between unsigned/signed int
-    };
-
-    static void getCastDescription(GenTree* treeNode, CastInfo* castInfo);
-
     // This variant of LowerRange is called from outside of the main Lowering pass,
     // so it creates its own instance of Lowering to do so.
     void LowerRange(BasicBlock* block, LIR::ReadOnlyRange& range)
index c72d0a2..c748da0 100644 (file)
@@ -2580,6 +2580,13 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
 
     if (!HWIntrinsicInfo::SupportsContainment(intrinsicId))
     {
+        // AVX2 gather are not contaibable and always have constant IMM argument
+        if (HWIntrinsicInfo::isAVX2GatherIntrinsic(intrinsicId))
+        {
+            GenTree* lastOp = HWIntrinsicInfo::lookupLastOp(node);
+            assert(lastOp != nullptr);
+            MakeSrcContained(node, lastOp);
+        }
         // Exit early if containment isn't supported
         return;
     }
index eddeee9..ca772bd 100644 (file)
@@ -1578,7 +1578,7 @@ private:
     int BuildStoreLoc(GenTreeLclVarCommon* tree);
     int BuildIndir(GenTreeIndir* indirTree);
     int BuildGCWriteBarrier(GenTree* tree);
-    int BuildCast(GenTree* tree);
+    int BuildCast(GenTreeCast* cast);
 
 #if defined(_TARGET_XARCH_)
     // returns true if the tree can use the read-modify-write memory instruction form
index 0049668..980b2a3 100644 (file)
@@ -287,77 +287,9 @@ int LinearScan::BuildNode(GenTree* tree)
         break;
 
         case GT_CAST:
-        {
             assert(dstCount == 1);
-
-            // Non-overflow casts to/from float/double are done using SSE2 instructions
-            // and that allow the source operand to be either a reg or memop. Given the
-            // fact that casts from small int to float/double are done as two-level casts,
-            // the source operand is always guaranteed to be of size 4 or 8 bytes.
-            var_types castToType = tree->CastToType();
-            GenTree*  castOp     = tree->gtCast.CastOp();
-            var_types castOpType = castOp->TypeGet();
-            if (tree->gtFlags & GTF_UNSIGNED)
-            {
-                castOpType = genUnsignedType(castOpType);
-            }
-
-            if (varTypeIsLong(castOpType))
-            {
-                assert((castOp->OperGet() == GT_LONG) && castOp->isContained());
-            }
-
-            // FloatToIntCast needs a temporary register
-            if (varTypeIsFloating(castOpType) && varTypeIsIntOrI(tree))
-            {
-                buildInternalFloatRegisterDefForNode(tree, RBM_ALLFLOAT);
-                setInternalRegsDelayFree = true;
-            }
-
-            Lowering::CastInfo castInfo;
-
-            // Get information about the cast.
-            Lowering::getCastDescription(tree, &castInfo);
-
-            if (castInfo.requiresOverflowCheck)
-            {
-                var_types srcType = castOp->TypeGet();
-                emitAttr  cmpSize = EA_ATTR(genTypeSize(srcType));
-
-                // If we cannot store data in an immediate for instructions,
-                // then we will need to reserve a temporary register.
-
-                if (!castInfo.signCheckOnly) // In case of only sign check, temp regs are not needeed.
-                {
-                    if (castInfo.unsignedSource || castInfo.unsignedDest)
-                    {
-                        // check typeMask
-                        bool canStoreTypeMask = emitter::emitIns_valid_imm_for_alu(castInfo.typeMask);
-                        if (!canStoreTypeMask)
-                        {
-                            buildInternalIntRegisterDefForNode(tree);
-                        }
-                    }
-                    else
-                    {
-                        // For comparing against the max or min value
-                        bool canStoreMaxValue =
-                            emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, INS_FLAGS_DONT_CARE);
-                        bool canStoreMinValue =
-                            emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, INS_FLAGS_DONT_CARE);
-
-                        if (!canStoreMaxValue || !canStoreMinValue)
-                        {
-                            buildInternalIntRegisterDefForNode(tree);
-                        }
-                    }
-                }
-            }
-            srcCount = BuildOperandUses(castOp);
-            buildInternalRegisterUses();
-            BuildDef(tree);
-        }
-        break;
+            srcCount = BuildCast(tree->AsCast());
+            break;
 
         case GT_JTRUE:
             srcCount = 0;
index 13b45a9..76b56b3 100644 (file)
@@ -335,53 +335,9 @@ int LinearScan::BuildNode(GenTree* tree)
 #endif // FEATURE_HW_INTRINSICS
 
         case GT_CAST:
-        {
-            // TODO-ARM64-CQ: Int-To-Int conversions - castOp cannot be a memory op and must have an assigned
-            //                register.
-            //         see CodeGen::genIntToIntCast()
-
-            // Non-overflow casts to/from float/double are done using SSE2 instructions
-            // and that allow the source operand to be either a reg or memop. Given the
-            // fact that casts from small int to float/double are done as two-level casts,
-            // the source operand is always guaranteed to be of size 4 or 8 bytes.
-            var_types castToType = tree->CastToType();
-            GenTree*  castOp     = tree->gtCast.CastOp();
-            var_types castOpType = castOp->TypeGet();
-            if (tree->gtFlags & GTF_UNSIGNED)
-            {
-                castOpType = genUnsignedType(castOpType);
-            }
-
-            // Some overflow checks need a temp reg
-
-            Lowering::CastInfo castInfo;
-            // Get information about the cast.
-            Lowering::getCastDescription(tree, &castInfo);
-
-            if (castInfo.requiresOverflowCheck)
-            {
-                var_types srcType = castOp->TypeGet();
-                emitAttr  cmpSize = EA_ATTR(genTypeSize(srcType));
-
-                // If we cannot store the comparisons in an immediate for either
-                // comparing against the max or min value, then we will need to
-                // reserve a temporary register.
-
-                bool canStoreMaxValue = emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, cmpSize);
-                bool canStoreMinValue = emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, cmpSize);
-
-                if (!canStoreMaxValue || !canStoreMinValue)
-                {
-                    buildInternalIntRegisterDefForNode(tree);
-                }
-            }
-            BuildUse(tree->gtGetOp1());
-            srcCount = 1;
-            buildInternalRegisterUses();
             assert(dstCount == 1);
-            BuildDef(tree);
-        }
-        break;
+            srcCount = BuildCast(tree->AsCast());
+            break;
 
         case GT_NEG:
         case GT_NOT:
index 87c0991..aee5698 100644 (file)
@@ -716,4 +716,44 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
     return srcCount;
 }
 
+//------------------------------------------------------------------------
+// BuildCast: Set the NodeInfo for a GT_CAST.
+//
+// Arguments:
+//    cast - The GT_CAST node
+//
+// Return Value:
+//    The number of sources consumed by this node.
+//
+int LinearScan::BuildCast(GenTreeCast* cast)
+{
+    GenTree* src = cast->gtGetOp1();
+
+    const var_types srcType  = genActualType(src->TypeGet());
+    const var_types castType = cast->gtCastType;
+
+#ifdef _TARGET_ARM_
+    assert(!varTypeIsLong(srcType) || (src->OperIs(GT_LONG) && src->isContained()));
+
+    // Floating point to integer casts requires a temporary register.
+    if (varTypeIsFloating(srcType) && !varTypeIsFloating(castType))
+    {
+        buildInternalFloatRegisterDefForNode(cast, RBM_ALLFLOAT);
+        setInternalRegsDelayFree = true;
+    }
+#else
+    // Overflow checking cast from TYP_LONG to TYP_INT requires a temporary register to
+    // store the min and max immediate values that cannot be encoded in the CMP instruction.
+    if (cast->gtOverflow() && varTypeIsLong(srcType) && !cast->IsUnsigned() && (castType == TYP_INT))
+    {
+        buildInternalIntRegisterDefForNode(cast);
+    }
+#endif
+
+    int srcCount = BuildOperandUses(src);
+    buildInternalRegisterUses();
+    BuildDef(cast);
+    return srcCount;
+}
+
 #endif // _TARGET_ARMARCH_
index 8f012c0..b131123 100644 (file)
@@ -354,7 +354,8 @@ int LinearScan::BuildNode(GenTree* tree)
 #endif // FEATURE_HW_INTRINSICS
 
         case GT_CAST:
-            srcCount = BuildCast(tree);
+            assert(dstCount == 1);
+            srcCount = BuildCast(tree->AsCast());
             break;
 
         case GT_BITCAST:
@@ -533,6 +534,7 @@ int LinearScan::BuildNode(GenTree* tree)
 #ifdef FEATURE_HW_INTRINSICS
         case GT_HW_INTRINSIC_CHK:
 #endif // FEATURE_HW_INTRINSICS
+
             // Consumes arrLen & index - has no result
             srcCount = 2;
             assert(dstCount == 0);
@@ -2311,7 +2313,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
         if (op1->OperIsList())
         {
             assert(op2 == nullptr);
-            assert(numArgs == 3);
+            assert(numArgs >= 3);
 
             GenTreeArgList* argList = op1->AsArgList();
 
@@ -2321,10 +2323,16 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
             op2     = argList->Current();
             argList = argList->Rest();
 
-            op3     = argList->Current();
+            op3 = argList->Current();
+
+            while (argList->Rest() != nullptr)
+            {
+                argList = argList->Rest();
+            }
+
+            lastOp  = argList->Current();
             argList = argList->Rest();
 
-            lastOp = op3;
             assert(argList == nullptr);
         }
         else if (op2 != nullptr)
@@ -2590,6 +2598,45 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
             {
                 assert(numArgs == 1);
                 srcCount += BuildDelayFreeUses(op1);
+
+                buildUses = false;
+                break;
+            }
+
+            case NI_AVX2_GatherVector128:
+            case NI_AVX2_GatherVector256:
+            {
+                assert(numArgs == 3);
+                // Any pair of the index, mask, or destination registers should be different
+                srcCount += BuildOperandUses(op1);
+                srcCount += BuildDelayFreeUses(op2);
+
+                // get a tmp register for mask that will be cleared by gather instructions
+                buildInternalFloatRegisterDefForNode(intrinsicTree, allSIMDRegs());
+                setInternalRegsDelayFree = true;
+
+                buildUses = false;
+                break;
+            }
+
+            case NI_AVX2_GatherMaskVector128:
+            case NI_AVX2_GatherMaskVector256:
+            {
+                assert(numArgs == 5);
+                // Any pair of the index, mask, or destination registers should be different
+                srcCount += BuildOperandUses(op1);
+                srcCount += BuildOperandUses(op2);
+                srcCount += BuildDelayFreeUses(op3);
+
+                assert(intrinsicTree->gtGetOp1()->OperIsList());
+                GenTreeArgList* argList = intrinsicTree->gtGetOp1()->AsArgList();
+                GenTree*        op4     = argList->Rest()->Rest()->Rest()->Current();
+                srcCount += BuildDelayFreeUses(op4);
+
+                // get a tmp register for mask that will be cleared by gather instructions
+                buildInternalFloatRegisterDefForNode(intrinsicTree, allSIMDRegs());
+                setInternalRegsDelayFree = true;
+
                 buildUses = false;
                 break;
             }
@@ -2638,52 +2685,40 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
 // BuildCast: Set the NodeInfo for a GT_CAST.
 //
 // Arguments:
-//    tree      - The node of interest
+//    cast - The GT_CAST node
 //
 // Return Value:
 //    The number of sources consumed by this node.
 //
-int LinearScan::BuildCast(GenTree* tree)
+int LinearScan::BuildCast(GenTreeCast* cast)
 {
-    // TODO-XArch-CQ: Int-To-Int conversions - castOp cannot be a memory op and must have an assigned register.
-    //         see CodeGen::genIntToIntCast()
-
-    // Non-overflow casts to/from float/double are done using SSE2 instructions
-    // and that allow the source operand to be either a reg or memop. Given the
-    // fact that casts from small int to float/double are done as two-level casts,
-    // the source operand is always guaranteed to be of size 4 or 8 bytes.
-    var_types castToType = tree->CastToType();
-    GenTree*  castOp     = tree->gtCast.CastOp();
-    var_types castOpType = castOp->TypeGet();
-    regMaskTP candidates = RBM_NONE;
+    GenTree* src = cast->gtGetOp1();
 
-    if (tree->gtFlags & GTF_UNSIGNED)
-    {
-        castOpType = genUnsignedType(castOpType);
-    }
+    const var_types srcType  = genActualType(src->TypeGet());
+    const var_types castType = cast->gtCastType;
 
+    regMaskTP candidates = RBM_NONE;
 #ifdef _TARGET_X86_
-    if (varTypeIsByte(castToType))
+    if (varTypeIsByte(castType))
     {
         candidates = allByteRegs();
     }
-#endif // _TARGET_X86_
 
-    // some overflow checks need a temp reg:
-    //  - GT_CAST from INT64/UINT64 to UINT32
-    RefPosition* internalDef = nullptr;
-    if (tree->gtOverflow() && (castToType == TYP_UINT))
+    assert(!varTypeIsLong(srcType) || (src->OperIs(GT_LONG) && src->isContained()));
+#else
+    // Overflow checking cast from TYP_(U)LONG to TYP_UINT requires a temporary
+    // register to extract the upper 32 bits of the 64 bit source register.
+    if (cast->gtOverflow() && varTypeIsLong(srcType) && (castType == TYP_UINT))
     {
-        if (genTypeSize(castOpType) == 8)
-        {
-            // Here we don't need internal register to be different from targetReg,
-            // rather require it to be different from operand's reg.
-            buildInternalIntRegisterDefForNode(tree);
-        }
+        // Here we don't need internal register to be different from targetReg,
+        // rather require it to be different from operand's reg.
+        buildInternalIntRegisterDefForNode(cast);
     }
-    int srcCount = BuildOperandUses(castOp, candidates);
+#endif
+
+    int srcCount = BuildOperandUses(src, candidates);
     buildInternalRegisterUses();
-    BuildDef(tree, candidates);
+    BuildDef(cast, candidates);
     return srcCount;
 }
 
index 2868c36..7935a82 100644 (file)
@@ -6689,11 +6689,6 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac)
                     }
 
                     tree->SetOper(GT_IND);
-                    // The GTF_FLD_NULLCHECK is the same bit as GTF_IND_ARR_LEN.
-                    // We must clear it when we transform the node.
-                    // TODO-Cleanup: It appears that the GTF_FLD_NULLCHECK flag is never checked, and note
-                    // that the logic above does its own checking to determine whether a nullcheck is needed.
-                    tree->gtFlags &= ~GTF_IND_ARR_LEN;
                     tree->gtOp.gtOp1 = addr;
 
                     return fgMorphSmpOp(tree);
@@ -6741,11 +6736,6 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac)
         }
     }
     noway_assert(tree->gtOper == GT_IND);
-    // The GTF_FLD_NULLCHECK is the same bit as GTF_IND_ARR_LEN.
-    // We must clear it when we transform the node.
-    // TODO-Cleanup: It appears that the GTF_FLD_NULLCHECK flag is never checked, and note
-    // that the logic above does its own checking to determine whether a nullcheck is needed.
-    tree->gtFlags &= ~GTF_IND_ARR_LEN;
 
     GenTree* res = fgMorphSmpOp(tree);
 
index 314579c..187ef3f 100644 (file)
@@ -7,7 +7,7 @@
 
 // Named jit intrinsics
 
-enum NamedIntrinsic : unsigned int
+enum NamedIntrinsic : unsigned short
 {
     NI_Illegal                                                 = 0,
     NI_System_Enum_HasFlag                                     = 1,
index ca09b6e..06b6ebc 100644 (file)
@@ -7051,40 +7051,6 @@ void Compiler::fgValueNumberTree(GenTree* tree)
                     fgValueNumberArrIndexVal(tree, elemTypeEq, arrVN, inxVN, addrXvnp.GetLiberal(), fldSeq);
                 }
             }
-            else if (tree->gtFlags & GTF_IND_ARR_LEN)
-            {
-                // It's an array length.  The argument is the sum of an array ref with some integer values...
-                ValueNum arrRefLib  = vnStore->VNForRefInAddr(tree->gtOp.gtOp1->gtVNPair.GetLiberal());
-                ValueNum arrRefCons = vnStore->VNForRefInAddr(tree->gtOp.gtOp1->gtVNPair.GetConservative());
-
-                assert(vnStore->TypeOfVN(arrRefLib) == TYP_REF || vnStore->TypeOfVN(arrRefLib) == TYP_BYREF);
-                if (vnStore->IsVNConstant(arrRefLib))
-                {
-                    // (or in weird cases, a REF or BYREF constant, in which case the result is an exception).
-                    tree->gtVNPair.SetLiberal(
-                        vnStore->VNWithExc(ValueNumStore::VNForVoid(),
-                                           vnStore->VNExcSetSingleton(
-                                               vnStore->VNForFunc(TYP_REF, VNF_NullPtrExc, arrRefLib))));
-                }
-                else
-                {
-                    tree->gtVNPair.SetLiberal(vnStore->VNForFunc(TYP_INT, VNFunc(GT_ARR_LENGTH), arrRefLib));
-                }
-                assert(vnStore->TypeOfVN(arrRefCons) == TYP_REF || vnStore->TypeOfVN(arrRefCons) == TYP_BYREF);
-                if (vnStore->IsVNConstant(arrRefCons))
-                {
-                    // (or in weird cases, a REF or BYREF constant, in which case the result is an exception).
-                    tree->gtVNPair.SetConservative(
-                        vnStore->VNWithExc(ValueNumStore::VNForVoid(),
-                                           vnStore->VNExcSetSingleton(
-                                               vnStore->VNForFunc(TYP_REF, VNF_NullPtrExc, arrRefCons))));
-                }
-                else
-                {
-                    tree->gtVNPair.SetConservative(vnStore->VNForFunc(TYP_INT, VNFunc(GT_ARR_LENGTH), arrRefCons));
-                }
-            }
-
             // In general we skip GT_IND nodes on that are the LHS of an assignment.  (We labeled these earlier.)
             // We will "evaluate" this as part of the assignment.
             else if ((tree->gtFlags & GTF_IND_ASG_LHS) == 0)
@@ -7769,7 +7735,8 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN
 #ifdef FEATURE_READYTORUN_COMPILER
         if (useEntryPointAddrAsArg0)
         {
-            ValueNum callAddrVN = vnStore->VNForPtrSizeIntCon((ssize_t)call->gtCall.gtEntryPoint.addr);
+            ssize_t  addrValue  = (ssize_t)call->gtEntryPoint.addr;
+            ValueNum callAddrVN = vnStore->VNForHandle(addrValue, GTF_ICON_FTN_ADDR);
             vnp0                = ValueNumPair(callAddrVN, callAddrVN);
         }
         else
index e7ec886..2d0c471 100644 (file)
@@ -4459,6 +4459,7 @@ PALIMPORT LONG __cdecl labs(LONG);
 // clang complains if this is declared with __int64
 PALIMPORT long long __cdecl llabs(long long);
 
+PALIMPORT int __cdecl _signbit(double);
 PALIMPORT int __cdecl _finite(double);
 PALIMPORT int __cdecl _isnan(double);
 PALIMPORT double __cdecl _copysign(double, double);
@@ -4487,6 +4488,7 @@ PALIMPORT double __cdecl sqrt(double);
 PALIMPORT double __cdecl tan(double);
 PALIMPORT double __cdecl tanh(double);
 
+PALIMPORT int __cdecl _signbitf(float);
 PALIMPORT int __cdecl _finitef(float);
 PALIMPORT int __cdecl _isnanf(float);
 PALIMPORT float __cdecl _copysignf(float, float);
index b435366..f99efbe 100644 (file)
@@ -161,7 +161,7 @@ C_FUNC(\Name\()_End):
         .endif
 
         __PWTB_StackAlloc = __PWTB_TransitionBlock
-        __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
+        __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 104
         __PWTB_ArgumentRegister_FirstArg = __PWTB_ArgumentRegisters + 8
 
         PROLOG_SAVE_REG_PAIR_INDEXED   fp, lr, -176
@@ -192,11 +192,11 @@ C_FUNC(\Name\()_End):
 // Reserve 64 bytes of memory before calling  SAVE_ARGUMENT_REGISTERS
 .macro SAVE_ARGUMENT_REGISTERS reg, ofs
 
-        stp                    x0, x1, [\reg, #(\ofs)]
-        stp                    x2, x3, [\reg, #(\ofs + 16)]
-        stp                    x4, x5, [\reg, #(\ofs + 32)]
-        stp                    x6, x7, [\reg, #(\ofs + 48)]
-        str                    x8, [\reg, #(\ofs + 64)]
+        str                    x8, [\reg, #(\ofs)]
+        stp                    x0, x1, [\reg, #(\ofs + 8)]
+        stp                    x2, x3, [\reg, #(\ofs + 24)]
+        stp                    x4, x5, [\reg, #(\ofs + 40)]
+        stp                    x6, x7, [\reg, #(\ofs + 56)]
 
 .endm
 
@@ -212,11 +212,11 @@ C_FUNC(\Name\()_End):
 
 .macro RESTORE_ARGUMENT_REGISTERS reg, ofs
 
-        ldp                    x0, x1, [\reg, #(\ofs)]
-        ldp                    x2, x3, [\reg, #(\ofs + 16)]
-        ldp                    x4, x5, [\reg, #(\ofs + 32)]
-        ldp                    x6, x7, [\reg, #(\ofs + 48)]
-        ldr                    x8, [\reg, #(\ofs + 64)]
+        ldr                    x8, [\reg, #(\ofs)]
+        ldp                    x0, x1, [\reg, #(\ofs + 8)]
+        ldp                    x2, x3, [\reg, #(\ofs + 24)]
+        ldp                    x4, x5, [\reg, #(\ofs + 40)]
+        ldp                    x6, x7, [\reg, #(\ofs + 56)]
 
 .endm
 
index 7c0cd69..290b9b7 100644 (file)
@@ -91,6 +91,10 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface4,0x74B9D34C,0xA612,0x4B07,0x93,0xDD,0
 
 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface5,0x127d6abe,0x6c86,0x4e48,0x8e,0x7b,0x22,0x07,0x81,0xc5,0x81,0x01);
 
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface6,0x11206399,0x4b66,0x4edb,0x98,0xea,0x85,0x65,0x4e,0x59,0xad,0x45);
+
+
 #undef MIDL_DEFINE_GUID
 
 #ifdef __cplusplus
index 06adddc..2e18c12 100644 (file)
@@ -438,50 +438,50 @@ typedef struct _COR_PRF_METHOD
     mdMethodDef methodId;
     }   COR_PRF_METHOD;
 
-typedef void __stdcall __stdcall FunctionEnter( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter(
     FunctionID funcID);
 
-typedef void __stdcall __stdcall FunctionLeave( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave(
     FunctionID funcID);
 
-typedef void __stdcall __stdcall FunctionTailcall( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall(
     FunctionID funcID);
 
-typedef void __stdcall __stdcall FunctionEnter2( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter2(
     FunctionID funcId,
     UINT_PTR clientData,
     COR_PRF_FRAME_INFO func,
     COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo);
 
-typedef void __stdcall __stdcall FunctionLeave2( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave2(
     FunctionID funcId,
     UINT_PTR clientData,
     COR_PRF_FRAME_INFO func,
     COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange);
 
-typedef void __stdcall __stdcall FunctionTailcall2( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall2(
     FunctionID funcId,
     UINT_PTR clientData,
     COR_PRF_FRAME_INFO func);
 
-typedef void __stdcall __stdcall FunctionEnter3( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter3(
     FunctionIDOrClientID functionIDOrClientID);
 
-typedef void __stdcall __stdcall FunctionLeave3( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave3(
     FunctionIDOrClientID functionIDOrClientID);
 
-typedef void __stdcall __stdcall FunctionTailcall3( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall3(
     FunctionIDOrClientID functionIDOrClientID);
 
-typedef void __stdcall __stdcall FunctionEnter3WithInfo( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter3WithInfo(
     FunctionIDOrClientID functionIDOrClientID,
     COR_PRF_ELT_INFO eltInfo);
 
-typedef void __stdcall __stdcall FunctionLeave3WithInfo( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave3WithInfo(
     FunctionIDOrClientID functionIDOrClientID,
     COR_PRF_ELT_INFO eltInfo);
 
-typedef void __stdcall __stdcall FunctionTailcall3WithInfo( 
+typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall3WithInfo(
     FunctionIDOrClientID functionIDOrClientID,
     COR_PRF_ELT_INFO eltInfo);
 
index 3b810cc..8896720 100644 (file)
@@ -2272,6 +2272,86 @@ EXTERN_C const IID IID_ISOSDacInterface5;
 
 #endif         /* __ISOSDacInterface5_INTERFACE_DEFINED__ */
 
+
+#ifndef __ISOSDacInterface6_INTERFACE_DEFINED__
+#define __ISOSDacInterface6_INTERFACE_DEFINED__
+
+    /* interface ISOSDacInterface6 */
+    /* [uuid][local][object] */
+
+
+    EXTERN_C const IID IID_ISOSDacInterface6;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+    MIDL_INTERFACE("11206399-4B66-4EDB-98EA-85654E59AD45")
+    ISOSDacInterface6 : public IUnknown
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE GetMethodTableCollectibleData(
+            CLRDATA_ADDRESS mt, 
+            struct DacpMethodTableCollectibleData *data) = 0;
+    };
+
+
+#else  /* C style interface */
+
+    typedef struct ISOSDacInterface6Vtbl
+    {
+        BEGIN_INTERFACE
+
+        HRESULT(STDMETHODCALLTYPE *QueryInterface)(
+            ISOSDacInterface5 * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */
+            _COM_Outptr_  void **ppvObject);
+
+        ULONG(STDMETHODCALLTYPE *AddRef)(
+            ISOSDacInterface5 * This);
+
+        ULONG(STDMETHODCALLTYPE *Release)(
+            ISOSDacInterface5 * This);
+
+        HRESULT(STDMETHODCALLTYPE *GetMethodTableCollectibleData)(
+            CLRDATA_ADDRESS mt, 
+            struct DacpMethodTableCollectibleData *data);
+
+        END_INTERFACE
+    } ISOSDacInterface6Vtbl;
+
+    interface ISOSDacInterface6
+    {
+        CONST_VTBL struct ISOSDacInterface6Vtbl *lpVtbl;
+    };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISOSDacInterface6_QueryInterface(This,riid,ppvObject)  \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ISOSDacInterface6_AddRef(This) \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ISOSDacInterface6_Release(This)        \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ISOSDacInterface6_GetMethodTableCollectibleData(This,mt,data)  \
+    ( (This)->lpVtbl -> GetMethodTableCollectibleData(This,mt,data) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ISOSDacInterface6_INTERFACE_DEFINED__ */
+
 /* Additional Prototypes for ALL interfaces */
 
 /* end of Additional Prototypes */
index a3cc603..baa4a44 100644 (file)
@@ -396,4 +396,4 @@ if(FEATURE_EVENT_TRACE)
 endif(FEATURE_EVENT_TRACE)
 
 # Install the static PAL library for VS
-install (TARGETS coreclrpal DESTINATION lib)
+_install (TARGETS coreclrpal DESTINATION lib)
index a36ac9a..af2f994 100644 (file)
@@ -45,6 +45,34 @@ SET_DEFAULT_DEBUG_CHANNEL(CRT);
 
 /*++
 Function:
+  _signbit
+
+Determines whether given double-precision floating point value has a negative sign.
+
+Return Value
+
+_signbit returns a nonzero value (TRUE) if the sign of its argument x is negative.
+
+Parameter
+
+x  Double-precision floating-point value
+
+--*/
+int __cdecl _signbit(double x)
+{
+    int ret;
+    PERF_ENTRY(_signbit);
+    ENTRY("_signbit (x=%f)\n", x);
+
+    ret = signbit(x);
+
+    LOGEXIT("_signbit returns int %d\n", ret);
+    PERF_EXIT(_signbit);
+    return ret;
+}
+
+/*++
+Function:
   _finite
 
 Determines whether given double-precision floating point value is finite.
@@ -455,6 +483,34 @@ PALIMPORT double __cdecl PAL_pow(double x, double y)
 
 /*++
 Function:
+  _signbitf
+
+Determines whether given single-precision floating point value has a negative sign.
+
+Return Value
+
+_signbitf returns a nonzero value (TRUE) if the sign of its argument x is negative.
+
+Parameter
+
+x  Single-precision floating-point value
+
+--*/
+int __cdecl _signbitf(float x)
+{
+    int ret;
+    PERF_ENTRY(_signbitf);
+    ENTRY("_signbitf (x=%f)\n", x);
+
+    ret = signbit(x);
+
+    LOGEXIT("_signbitf returns int %d\n", ret);
+    PERF_EXIT(_signbitf);
+    return ret;
+}
+
+/*++
+Function:
   _finitef
 
 Determines whether given single-precision floating point value is finite.
index a8d8918..59f5d71 100644 (file)
@@ -249,12 +249,8 @@ def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory, extern):
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 include_directories(${CLR_DIR}/src/vm)
 
+add_library_clr(eventpipe STATIC
 """)
-        if extern: cmake_file.write("add_library")
-        else: cmake_file.write("add_library_clr")
-        cmake_file.write("""(eventpipe
-    STATIC\n""")
-
         for providerNode in tree.getElementsByTagName('provider'):
             providerName = providerNode.getAttribute('name')
             providerName = providerName.replace("Windows-", '')
@@ -268,7 +264,7 @@ include_directories(${CLR_DIR}/src/vm)
         if extern: cmake_file.write("""
 
 # Install the static eventpipe library
-install(TARGETS eventpipe DESTINATION lib)
+_install(TARGETS eventpipe DESTINATION lib)
 """)
 
 def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern):
index 296042b..dfbd68d 100644 (file)
@@ -521,7 +521,7 @@ def generateLttngFiles(etwmanifest,eventprovider_directory):
         add_subdirectory(tracepointprovider)
 
         # Install the static eventprovider library
-        install(TARGETS eventprovider DESTINATION lib)
+        _install(TARGETS eventprovider DESTINATION lib)
         """)
 
 #TracepointProvider  Cmake
index a35512e..e5b4d06 100644 (file)
@@ -359,7 +359,6 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386)
     set(VM_SOURCES_WKS_ARCH_ASM
         ${ARCH_SOURCES_DIR}/RedirectedHandledJITCase.asm
         ${ARCH_SOURCES_DIR}/asmhelpers.asm
-        ${ARCH_SOURCES_DIR}/fptext.asm
         ${ARCH_SOURCES_DIR}/gmsasm.asm
         ${ARCH_SOURCES_DIR}/jithelp.asm
     )
index 37f4142..6f955b0 100644 (file)
@@ -228,8 +228,10 @@ LEAF_END JIT_PatchedCodeLast, _TEXT
 //   RSI - address of the data  (source)
 //
 //   Note: RyuJIT assumes that all volatile registers can be trashed by
-//   the CORINFO_HELP_ASSIGN_BYREF helper (i.e. JIT_ByRefWriteBarrier).
-//   The precise set is defined by RBM_CALLEE_TRASH.
+//   the CORINFO_HELP_ASSIGN_BYREF helper (i.e. JIT_ByRefWriteBarrier)
+//   except RDI and RSI. This helper uses and defines RDI and RSI, so 
+//   they remain as live GC refs or byrefs, and are not killed.
+//
 //
 //   RCX is trashed
 //   RAX is trashed
index 83764e0..e592193 100644 (file)
@@ -53,8 +53,8 @@ extern "C"
         // check OS has enabled both XMM and YMM state support
         return ((eax & 0x06) == 0x06) ? 1 : 0;
     }
-    
-    void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
+
+    void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
     {
     }
 };
index 745626b..6289117 100644 (file)
@@ -102,7 +102,11 @@ EXTERN_C void setFPReturn(int fpSize, INT64 retVal);
 // as large as the largest FieldMarshaler subclass. This requirement
 // is guarded by an assert.
 //=======================================================================
+#ifdef _WIN64
+#define MAXFIELDMARSHALERSIZE               40
+#else
 #define MAXFIELDMARSHALERSIZE               24
+#endif
 
 //**********************************************************************
 // Parameter size
@@ -985,6 +989,11 @@ inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype)
     return (sizeofvaluetype > 4);
 }
 
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4359) // Prevent "warning C4359: 'UMEntryThunkCode': Alignment specifier is less than actual alignment (8), and will be ignored." in crossbitness scenario
+#endif // _MSC_VER
+
 struct DECLSPEC_ALIGN(4) UMEntryThunkCode
 {
     WORD        m_code[4];
@@ -1010,6 +1019,10 @@ struct DECLSPEC_ALIGN(4) UMEntryThunkCode
     }
 };
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
 struct HijackArgs
 {
     union
@@ -1082,7 +1095,7 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
 
 EXTERN_C VOID STDCALL PrecodeFixupThunk();
 
-#define PRECODE_ALIGNMENT           CODE_SIZE_ALIGN
+#define PRECODE_ALIGNMENT           sizeof(void*)
 #define SIZEOF_PRECODE_BASE         CODE_SIZE_ALIGN
 #define OFFSETOF_PRECODE_TYPE       0
 
index bd3ad51..d2ee3b7 100644 (file)
@@ -1678,6 +1678,8 @@ VOID StubLinkerCPU::EmitShuffleThunk(ShuffleEntry *pShuffleEntryArray)
     ThumbEmitEpilog();
 }
 
+#ifndef CROSSGEN_COMPILE
+
 void StubLinkerCPU::ThumbEmitCallManagedMethod(MethodDesc *pMD, bool fTailcall)
 {
     bool isRelative = MethodTable::VTableIndir2_t::isRelative
@@ -1747,7 +1749,6 @@ void StubLinkerCPU::ThumbEmitCallManagedMethod(MethodDesc *pMD, bool fTailcall)
     }
 }
 
-#ifndef CROSSGEN_COMPILE
 // Common code used to generate either an instantiating method stub or an unboxing stub (in the case where the
 // unboxing stub also needs to provide a generic instantiation parameter). The stub needs to add the
 // instantiation parameter provided in pHiddenArg and re-arrange the rest of the incoming arguments as a
@@ -2368,7 +2369,6 @@ void TailCallFrame::InitFromContext(T_CONTEXT * pContext)
 }
 
 #endif // !DACCESS_COMPILE
-#endif // !CROSSGEN_COMPILE
 
 void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD) 
 { 
@@ -2527,7 +2527,8 @@ void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
 
      SyncRegDisplayToCurrentContext(pRD);
 }
-#endif
+#endif // FEATURE_HIJACK
+#endif // !CROSSGEN_COMPILE
 
 class UMEntryThunk * UMEntryThunk::Decode(void *pCallback)
 {
index 38779b7..248a103 100644 (file)
@@ -1071,7 +1071,7 @@ void emitCOMStubCall (ComCallMethodDesc *pCOMMethod, PCODE target)
 #endif // FEATURE_COMINTEROP
 
 
-void JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
+void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
 {
     _ASSERTE(!"ARM64:NYI");
 }
index a653d85..c219d70 100644 (file)
@@ -1209,7 +1209,7 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
 
         // Doubles or HFAs containing doubles need the stack aligned appropriately.
         if (fRequiresAlign64Bit)
-            m_idxStack = ALIGN_UP(m_idxStack, 2);
+            m_idxStack = (int)ALIGN_UP(m_idxStack, 2);
 
         // Indicate the stack location of the argument to the caller.
         int argOfs = TransitionBlock::GetOffsetOfArgs() + m_idxStack * 4;
@@ -1231,7 +1231,7 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
         {
             // The argument requires 64-bit alignment. Align either the next general argument register if
             // we have any left.  See step C.3 in the algorithm in the ABI spec.       
-            m_idxGenReg = ALIGN_UP(m_idxGenReg, 2);
+            m_idxGenReg = (int)ALIGN_UP(m_idxGenReg, 2);
         }
 
         int argOfs = TransitionBlock::GetOffsetOfArgumentRegisters() + m_idxGenReg * 4;
@@ -1262,7 +1262,7 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
     {
         // The argument requires 64-bit alignment. If it is going to be passed on the stack, align
         // the next stack slot.  See step C.6 in the algorithm in the ABI spec.  
-        m_idxStack = ALIGN_UP(m_idxStack, 2);
+        m_idxStack = (int)ALIGN_UP(m_idxStack, 2);
     }
 
     int argOfs = TransitionBlock::GetOffsetOfArgs() + m_idxStack * 4;
index cd9e485..19c5167 100644 (file)
@@ -6390,8 +6390,7 @@ MethodDesc *Module::FindMethod(mdToken pMethod)
         CONTRACT_VIOLATION(ThrowsViolation);
         char szMethodName [MAX_CLASSNAME_LENGTH];
         CEEInfo::findNameOfToken(this, pMethod, szMethodName, COUNTOF (szMethodName));
-        // This used to be LF_IJW, but changed to LW_INTEROP to reclaim a bit in our log facilities
-        // IJW itself is not supported in coreclr so this code should never be run.
+        // This used to be IJW, but changed to LW_INTEROP to reclaim a bit in our log facilities
         LOG((LF_INTEROP, LL_INFO10, "Failed to find Method: %s for Vtable Fixup\n", szMethodName));
 #endif // _DEBUG
     }
@@ -6837,7 +6836,379 @@ void Module::NotifyDebuggerUnload(AppDomain *pDomain)
     g_pDebugInterface->UnloadModule(this, pDomain);
 }
 
+#if !defined(CROSSGEN_COMPILE)
+//=================================================================================
+mdToken GetTokenForVTableEntry(HINSTANCE hInst, BYTE **ppVTEntry)
+{
+    CONTRACTL{
+        NOTHROW;
+    } CONTRACTL_END;
+
+    mdToken tok =(mdToken)(UINT_PTR)*ppVTEntry;
+    _ASSERTE(TypeFromToken(tok) == mdtMethodDef || TypeFromToken(tok) == mdtMemberRef);
+    return tok;
+}
+
+//=================================================================================
+void SetTargetForVTableEntry(HINSTANCE hInst, BYTE **ppVTEntry, BYTE *pTarget)
+{
+    CONTRACTL{
+        THROWS;
+    } CONTRACTL_END;
+
+    DWORD oldProtect;
+    if (!ClrVirtualProtect(ppVTEntry, sizeof(BYTE*), PAGE_READWRITE, &oldProtect))
+    {
+        
+        // This is very bad.  We are not going to be able to update header.
+        _ASSERTE(!"SetTargetForVTableEntry(): VirtualProtect() changing IJW thunk vtable to R/W failed.\n");
+        ThrowLastError();
+    }
+
+    *ppVTEntry = pTarget;
 
+    DWORD ignore;
+    if (!ClrVirtualProtect(ppVTEntry, sizeof(BYTE*), oldProtect, &ignore))
+    {
+        // This is not so bad, we're already done the update, we just didn't return the thunk table to read only
+        _ASSERTE(!"SetTargetForVTableEntry(): VirtualProtect() changing IJW thunk vtable back to RO failed.\n");
+    }
+}
+
+//=================================================================================
+BYTE * GetTargetForVTableEntry(HINSTANCE hInst, BYTE **ppVTEntry)
+{
+    CONTRACTL{
+        NOTHROW;
+    } CONTRACTL_END;
+
+    return *ppVTEntry;
+}
+
+//======================================================================================
+// Fixup vtables stored in the header to contain pointers to method desc
+// prestubs rather than metadata method tokens.
+void Module::FixupVTables()
+{
+    CONTRACTL{
+        INSTANCE_CHECK;
+        STANDARD_VM_CHECK;
+    } CONTRACTL_END;
+
+
+    // If we've already fixed up, or this is not an IJW module, just return.
+    // NOTE: This relies on ILOnly files not having fixups. If this changes,
+    //       we need to change this conditional.
+    if (IsIJWFixedUp() || m_file->IsILOnly()) {
+        return;
+    }
+
+    HINSTANCE hInstThis = GetFile()->GetIJWBase();
+
+    // <REVISIT_TODO>@todo: workaround!</REVISIT_TODO>
+    // If we are compiling in-process, we don't want to fixup the vtables - as it
+    // will have side effects on the other copy of the module!
+    if (SystemDomain::GetCurrentDomain()->IsPassiveDomain()) {
+        return;
+    }
+
+#ifdef FEATURE_PREJIT
+    // We delayed filling in this value until the LoadLibrary occurred
+    if (HasTls() && HasNativeImage()) {
+        CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable();
+        pEEInfo->rvaStaticTlsIndex = GetTlsIndex();
+    }
+#endif
+    // Get vtable fixup data
+    COUNT_T cFixupRecords;
+    IMAGE_COR_VTABLEFIXUP *pFixupTable = m_file->GetVTableFixups(&cFixupRecords);
+
+    // No records then return
+    if (cFixupRecords == 0) {
+        return;
+    }
+
+    // Now, we need to take a lock to serialize fixup.
+    PEImage::IJWFixupData *pData = PEImage::GetIJWData(m_file->GetIJWBase());
+
+    // If it's already been fixed (in some other appdomain), record the fact and return
+    if (pData->IsFixedUp()) {
+        SetIsIJWFixedUp();
+        return;
+    }
+
+    //////////////////////////////////////////////////////
+    //
+    // This is done in three stages:
+    //  1. We enumerate the types we'll need to load
+    //  2. We load the types
+    //  3. We create and install the thunks
+    //
+
+    COUNT_T cVtableThunks = 0;
+    struct MethodLoadData
+    {
+        mdToken     token;
+        MethodDesc *pMD;
+    };
+    MethodLoadData *rgMethodsToLoad = NULL;
+    COUNT_T cMethodsToLoad = 0;
+
+    //
+    // Stage 1
+    //
+
+    // Each fixup entry describes a vtable, so iterate the vtables and sum their counts
+    {
+        DWORD iFixup;
+        for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
+            cVtableThunks += pFixupTable[iFixup].Count;
+    }
+
+    Thread *pThread = GetThread();
+    StackingAllocator *pAlloc = &pThread->m_MarshalAlloc;
+    CheckPointHolder cph(pAlloc->GetCheckpoint());
+
+    // Allocate the working array of tokens.
+    cMethodsToLoad = cVtableThunks;
+
+    rgMethodsToLoad = new (pAlloc) MethodLoadData[cMethodsToLoad];
+    memset(rgMethodsToLoad, 0, cMethodsToLoad * sizeof(MethodLoadData));
+
+    // Now take the IJW module lock and get all the tokens
+    {
+        // Take the lock
+        CrstHolder lockHolder(pData->GetLock());
+
+        // If someone has beaten us, just return
+        if (pData->IsFixedUp())
+        {
+            SetIsIJWFixedUp();
+            return;
+        }
+
+        COUNT_T iCurMethod = 0;
+
+        if (cFixupRecords != 0)
+        {
+            for (COUNT_T iFixup = 0; iFixup < cFixupRecords; iFixup++)
+            {
+                // Vtables can be 32 or 64 bit.
+                if ((pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED)) ||
+                    (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED | COR_VTABLE_FROM_UNMANAGED)) ||
+                    (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN)))
+                {
+                    const BYTE** pPointers = (const BYTE **)m_file->GetVTable(pFixupTable[iFixup].RVA);
+                    for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
+                    {
+                        if (pData->IsMethodFixedUp(iFixup, iMethod))
+                            continue;
+                        mdToken mdTok = GetTokenForVTableEntry(hInstThis, (BYTE **)(pPointers + iMethod));
+                        CONSISTENCY_CHECK(mdTok != mdTokenNil);
+                        rgMethodsToLoad[iCurMethod++].token = mdTok;
+                    }
+                }
+            }
+        }
+
+    }
+
+    //
+    // Stage 2 - Load the types
+    //
+
+    {
+        for (COUNT_T iCurMethod = 0; iCurMethod < cMethodsToLoad; iCurMethod++)
+        {
+            mdToken curTok = rgMethodsToLoad[iCurMethod].token;
+            if (!GetMDImport()->IsValidToken(curTok))
+            {
+                _ASSERTE(!"Invalid token in v-table fix-up table");
+                ThrowHR(COR_E_BADIMAGEFORMAT);
+            }
+
+
+            // Find the method desc
+            MethodDesc *pMD;
+
+            {
+                CONTRACT_VIOLATION(LoadsTypeViolation);
+                pMD = FindMethodThrowing(curTok);
+            }
+
+            CONSISTENCY_CHECK(CheckPointer(pMD));
+
+            rgMethodsToLoad[iCurMethod].pMD = pMD;
+        }
+    }
+
+    //
+    // Stage 3 - Create the thunk data
+    //
+    {
+        // Take the lock
+        CrstHolder lockHolder(pData->GetLock());
+
+        // If someone has beaten us, just return
+        if (pData->IsFixedUp())
+        {
+            SetIsIJWFixedUp();
+            return;
+        }
+
+        // This phase assumes there is only one AppDomain and that thunks
+        // can all safely point directly to the method in the current AppDomain
+
+        AppDomain *pAppDomain = GetAppDomain();
+
+        // Used to index into rgMethodsToLoad
+        COUNT_T iCurMethod = 0;
+
+
+        // Each fixup entry describes a vtable (each slot contains a metadata token
+        // at this stage).
+        DWORD iFixup;
+        for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
+            cVtableThunks += pFixupTable[iFixup].Count;
+
+        DWORD dwIndex = 0;
+        DWORD dwThunkIndex = 0;
+
+        // Now to fill in the thunk table.
+        for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
+        {
+            // Tables may contain zero fixups, in which case the RVA is null, which triggers an assert
+            if (pFixupTable[iFixup].Count == 0)
+                continue;
+
+            const BYTE** pPointers = (const BYTE **)
+                m_file->GetVTable(pFixupTable[iFixup].RVA);
+
+            // Vtables can be 32 or 64 bit.
+            if (pFixupTable[iFixup].Type == COR_VTABLE_PTRSIZED)
+            {
+                for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
+                {
+                    if (pData->IsMethodFixedUp(iFixup, iMethod))
+                        continue;
+
+                    mdToken mdTok = rgMethodsToLoad[iCurMethod].token;
+                    MethodDesc *pMD = rgMethodsToLoad[iCurMethod].pMD;
+                    iCurMethod++;
+
+#ifdef _DEBUG 
+                    if (pMD->IsNDirect())
+                    {
+                        LOG((LF_INTEROP, LL_INFO10, "[0x%lx] <-- PINV thunk for \"%s\" (target = 0x%lx)\n",
+                            (size_t)&(pPointers[iMethod]), pMD->m_pszDebugMethodName,
+                            (size_t)(((NDirectMethodDesc*)pMD)->GetNDirectTarget())));
+                    }
+#endif // _DEBUG
+
+                    CONSISTENCY_CHECK(dwThunkIndex < cVtableThunks);
+
+                    // Point the local vtable slot to the thunk we created
+                    SetTargetForVTableEntry(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pMD->GetMultiCallableAddrOfCode());
+
+                    pData->MarkMethodFixedUp(iFixup, iMethod);
+
+                    dwThunkIndex++;
+                }
+
+            }
+            else if (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED | COR_VTABLE_FROM_UNMANAGED) || 
+                    (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN)))
+            {
+                for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
+                {
+                    if (pData->IsMethodFixedUp(iFixup, iMethod))
+                        continue;
+
+                    mdToken mdTok = rgMethodsToLoad[iCurMethod].token;
+                    MethodDesc *pMD = rgMethodsToLoad[iCurMethod].pMD;
+                    iCurMethod++;
+                    LOG((LF_INTEROP, LL_INFO10, "[0x%p] <-- VTable  thunk for \"%s\" (pMD = 0x%p)\n",
+                        (UINT_PTR)&(pPointers[iMethod]), pMD->m_pszDebugMethodName, pMD));
+
+                    UMEntryThunk *pUMEntryThunk = (UMEntryThunk*)(void*)(GetDllThunkHeap()->AllocAlignedMem(sizeof(UMEntryThunk), CODE_SIZE_ALIGN)); // UMEntryThunk contains code
+                    FillMemory(pUMEntryThunk, sizeof(*pUMEntryThunk), 0);
+
+                    UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)(GetThunkHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN));
+                    FillMemory(pUMThunkMarshInfo, sizeof(*pUMThunkMarshInfo), 0);
+
+                    pUMThunkMarshInfo->LoadTimeInit(pMD);
+                    pUMEntryThunk->LoadTimeInit(NULL, NULL, pUMThunkMarshInfo, pMD, pAppDomain->GetId());
+                    SetTargetForVTableEntry(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pUMEntryThunk->GetCode());
+
+                    pData->MarkMethodFixedUp(iFixup, iMethod);
+                }
+            }
+            else if ((pFixupTable[iFixup].Type & COR_VTABLE_NOT_PTRSIZED) == COR_VTABLE_NOT_PTRSIZED)
+            {
+                // fixup type doesn't match the platform
+                THROW_BAD_FORMAT(BFA_FIXUP_WRONG_PLATFORM, this);
+            }
+            else
+            {
+                _ASSERTE(!"Unknown vtable fixup type");
+            }
+        }
+
+        // Indicate that this module has been fixed before releasing the lock
+        pData->SetIsFixedUp();  // On the data
+        SetIsIJWFixedUp();      // On the module
+    } // End of Stage 3
+}
+
+// Self-initializing accessor for m_pThunkHeap
+LoaderHeap *Module::GetDllThunkHeap()
+{
+    CONTRACTL
+    {
+        THROWS;
+        GC_TRIGGERS;
+        MODE_ANY;
+    }
+    CONTRACTL_END;
+    return PEImage::GetDllThunkHeap(GetFile()->GetIJWBase());
+
+}
+
+LoaderHeap *Module::GetThunkHeap()
+{
+    CONTRACT(LoaderHeap *)
+    {
+        INSTANCE_CHECK;
+        THROWS;
+        GC_NOTRIGGER;
+        MODE_ANY;
+        INJECT_FAULT(COMPlusThrowOM());
+        POSTCONDITION(CheckPointer(RETVAL));
+    }
+    CONTRACT_END
+
+        if (!m_pThunkHeap)
+        {
+            size_t * pPrivatePCLBytes = NULL;
+            size_t * pGlobalPCLBytes = NULL;
+
+            COUNTER_ONLY(pPrivatePCLBytes = &(GetPerfCounters().m_Loading.cbLoaderHeapSize));
+
+            LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize
+                0,                                 // DWORD dwCommitBlockSize
+                pPrivatePCLBytes,
+                ThunkHeapStubManager::g_pManager->GetRangeList(),
+                TRUE);                             // BOOL fMakeExecutable
+
+            if (FastInterlockCompareExchangePointer(&m_pThunkHeap, pNewHeap, 0) != 0)
+            {
+                delete pNewHeap;
+            }
+        }
+
+    RETURN m_pThunkHeap;
+}
+#endif // !CROSSGEN_COMPILE
 
 #ifdef FEATURE_NATIVE_IMAGE_GENERATION
 
@@ -12492,7 +12863,11 @@ void Module::DeleteProfilingData()
 }
 #endif //FEATURE_PREJIT
 
-
+void Module::SetIsIJWFixedUp()
+{
+    LIMITED_METHOD_CONTRACT;
+    FastInterlockOr(&m_dwTransientFlags, IS_IJW_FIXED_UP);
+}
 
 #ifdef FEATURE_PREJIT
 /* static */
@@ -14220,8 +14595,10 @@ void Module::ExpandAll()
 #include "clrvarargs.h" /* for VARARG C_ASSERTs in asmconstants.h */
 class CheckAsmOffsets
 {
+#ifndef CROSSBITNESS_COMPILE
 #define ASMCONSTANTS_C_ASSERT(cond) static_assert(cond, #cond);
 #include "asmconstants.h"
+#endif // CROSSBITNESS_COMPILE
 };
 
 //-------------------------------------------------------------------------------
index 73f1a8f..d8a278e 100644 (file)
@@ -1740,6 +1740,7 @@ protected:
 
     void ApplyMetaData();
 
+    void FixupVTables();
 
     void FreeClassTables();
 
@@ -3156,6 +3157,14 @@ public:
     }
 #endif // FEATURE_PREJIT
 
+    // LoaderHeap for storing IJW thunks
+    PTR_LoaderHeap           m_pThunkHeap;
+
+    // Self-initializing accessor for IJW thunk heap
+    LoaderHeap              *GetThunkHeap();
+    // Self-initializing accessor for domain-independent IJW thunk heap
+    LoaderHeap              *GetDllThunkHeap();
+
     void            EnumRegularStaticGCRefs        (AppDomain* pAppDomain, promote_func* fn, ScanContext* sc);
 
 protected:    
index 6b30ee7..12d3f3c 100644 (file)
@@ -1075,6 +1075,10 @@ void DomainFile::VtableFixups()
 {
     WRAPPER_NO_CONTRACT;
 
+#if !defined(CROSSGEN_COMPILE)
+    if (!GetCurrentModule()->IsResource())
+        GetCurrentModule()->FixupVTables();
+#endif // !CROSSGEN_COMPILE
 }
 
 void DomainFile::FinishLoad()
index a9975c3..1f22386 100644 (file)
@@ -2071,9 +2071,9 @@ HRESULT EEToProfInterfaceImpl::EnsureProfilerDetachable()
 }
 
 // Declarations for asm wrappers of profiler callbacks
-EXTERN_C void __stdcall ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID);
-EXTERN_C void __stdcall ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID);
-EXTERN_C void __stdcall ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID);
+EXTERN_C void STDMETHODCALLTYPE ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID);
+EXTERN_C void STDMETHODCALLTYPE ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID);
+EXTERN_C void STDMETHODCALLTYPE ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID);
 #define PROFILECALLBACK(name) name##Naked
 
 //---------------------------------------------------------------------------------------
index 480eb2d..2052088 100644 (file)
@@ -1225,3 +1225,19 @@ NESTED_ENTRY BackPatchWorkerAsmStub, _TEXT, NoHandler
     EPILOG_END
     ret
 NESTED_END BackPatchWorkerAsmStub, _TEXT
+
+NESTED_ENTRY ProfileEnterNaked, _TEXT, NoHandler
+    ret
+NESTED_END ProfileEnterNaked, _TEXT
+
+NESTED_ENTRY ProfileLeaveNaked, _TEXT, NoHandler
+    ret
+NESTED_END ProfileLeaveNaked, _TEXT
+
+NESTED_ENTRY ProfileTailcallNaked, _TEXT, NoHandler
+    ret
+NESTED_END ProfileTailcallNaked, _TEXT
+
+NESTED_ENTRY JIT_ProfilerEnterLeaveTailcallStub, _TEXT, NoHandler
+    ret
+NESTED_END JIT_ProfilerEnterLeaveTailcallStub, _TEXT
diff --git a/src/vm/i386/fptext.asm b/src/vm/i386/fptext.asm
deleted file mode 100644 (file)
index 2190d18..0000000
+++ /dev/null
@@ -1,277 +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.
-
-; ==++==
-; 
-
-; 
-; ==--==
-       .386
-       .model  flat
-
-       option  casemap:none
-       public  _DoubleToNumber,_NumberToDouble
-
-; NUMBER structure
-
-nPrecision     equ     (dword ptr 0)
-nScale         equ     (dword ptr 4)
-nSign          equ     (dword ptr 8)
-nDigits                equ     (word ptr 12)
-
-       .code
-
-; Powers of 10 from 1.0E1 to 1.0E15 increasing by 1
-
-Pow10By1       label   tbyte
-
-       dt      1.0E1
-       dt      1.0E2
-       dt      1.0E3
-       dt      1.0E4
-       dt      1.0E5
-       dt      1.0E6
-       dt      1.0E7
-       dt      1.0E8
-       dt      1.0E9
-       dt      1.0E10
-       dt      1.0E11
-       dt      1.0E12
-       dt      1.0E13
-       dt      1.0E14
-       dt      1.0E15
-
-; Powers of 10 from 1.0E16 to 1.0E336 increasing by 16
-
-Pow10By16      label   tbyte
-
-       dt      1.0E16
-       dt      1.0E32
-       dt      1.0E48
-       dt      1.0E64
-       dt      1.0E80
-       dt      1.0E96
-       dt      1.0E112
-       dt      1.0E128
-       dt      1.0E144
-       dt      1.0E160
-       dt      1.0E176
-       dt      1.0E192
-       dt      1.0E208
-       dt      1.0E224
-       dt      1.0E240
-       dt      1.0E256
-       dt      1.0E272
-       dt      1.0E288
-       dt      1.0E304
-       dt      1.0E320
-       dt      1.0E336
-
-; Single precision constants
-
-Single10       dd      10.0
-SingleINF      dd      7F800000H
-
-g_CwStd                dw      137fH           ;Mask all errors, 64-bit, round near
-
-; void _cdecl DoubleToNumber(double value, int precision, NUMBER* number)
-
-_DoubleToNumber                proc
-
-value          equ     (qword ptr [ebp+8])
-precision      equ     (dword ptr [ebp+16])
-number         equ     (dword ptr [ebp+20])
-paramSize      =       16
-
-cwsave         equ (word ptr [ebp-24])
-digits         equ     (tbyte ptr [ebp-20])
-temp           equ     (tbyte ptr [ebp-10])
-localSize      =       24
-
-       push    ebp
-       mov     ebp,esp
-       sub     esp,localSize
-       push    edi
-       push    ebx
-       fnstcw  cwsave
-       fldcw g_CwStd
-       fld     value
-       fstp    temp
-       mov     edi,number
-       mov     eax,precision
-       mov     nPrecision[edi],eax
-       movzx   eax,word ptr temp[8]
-       mov     edx,eax
-       shr     edx,15
-       mov     nSign[edi],edx
-       and     eax,7FFFH
-       je      DN1
-       cmp     eax,7FFFH
-       jne     DN10
-       mov     eax,80000000H
-       cmp     dword ptr temp[4],eax
-       jne     DN1
-       cmp     dword ptr temp[0],0
-       jne     DN1
-       dec     eax
-DN1:   mov     nScale[edi],eax
-       mov     nDigits[edi],0
-       jmp     DN30
-DN10:  fld     value
-       sub     eax,16382+58            ;Remove bias and 58 bits
-       imul    eax,19728               ;log10(2) * 2^16 = .30103 * 65536
-       add     eax,0FFFFH              ;Round up
-       sar     eax,16                  ;Only use high half
-       lea     edx,[eax+18]
-       mov     nScale[edi],edx
-       neg     eax
-       call    ScaleByPow10
-       fbstp   digits
-       xor     eax,eax
-       xor     ebx,ebx
-       mov     ecx,precision
-       inc     ecx
-       mov     edx,8
-       mov     al,byte ptr digits[8]
-       test    al,0F0H
-       jne     DN11
-       dec     nScale[edi]
-       jmp     DN12
-DN11:  shr     al,4
-       dec     ecx
-       je      DN20
-       add     al,'0'
-       mov     nDigits[edi+ebx*2],ax
-       inc     ebx
-       mov     al,byte ptr digits[edx]
-DN12:  and     al,0FH
-       dec     ecx
-       je      DN20
-       add     al,'0'
-       mov     nDigits[edi+ebx*2],ax
-       inc     ebx
-       dec     edx
-       jl  DN22                                        ; We've run out of digits & don't have a rounding digit, so we'll skip the rounding step.
-       mov     al,byte ptr digits[edx]
-       jmp     DN11
-DN20:  cmp     al,5
-       jb      DN22
-DN21:  dec     ebx
-       inc     nDigits[edi+ebx*2]
-       cmp     nDigits[edi+ebx*2],'9'
-       jbe     DN23
-       or      ebx,ebx
-       jne     DN21
-       mov     nDigits[edi+ebx*2],'1'
-       inc     nScale[edi]
-       jmp     DN23
-DN22:  dec     ebx
-       cmp     nDigits[edi+ebx*2],'0'
-       je      DN22
-DN23:  mov     nDigits[edi+ebx*2+2],0
-DN30:
-       fldcw   cwsave                  ;;Restore original CW
-       pop     ebx
-       pop     edi
-       mov     esp,ebp
-       pop     ebp
-       ret     ;made _cdecl for WinCE paramSize
-
-_DoubleToNumber                endp
-
-; void _cdecl NumberToDouble(NUMBER* number, double* value)
-_NumberToDouble                proc
-
-number         equ     (dword ptr [ebp+8])
-value          equ     (dword ptr [ebp+12])
-paramSize      =       8
-
-cwsave         equ (word  ptr [ebp-8])
-temp           equ     (dword ptr [ebp-4])
-localSize      =       8
-
-       push    ebp     
-       mov     ebp,esp                                 ; Save the stack ptr
-       sub     esp,localSize                   ;
-       fnstcw  cwsave
-       fldcw g_CwStd           
-       fldz                                            ; zero the register
-       mov     ecx,number                              ; move precision into ecx
-       xor     edx,edx                                 ; clear edx
-       cmp     dx,nDigits[ecx]                 ; if the first digit is 0 goto SignResult
-       je      SignResult
-       mov     eax,nScale[ecx]                 ; store the scale in eax
-       cmp     eax,-330                                ; if the scale is less than or equal to -330 goto Cleanup
-       jle     Cleanup
-       cmp     eax,310                                 ; if the scale is less than 310, goto ParseDigits
-       jl      ParseDigits
-       fstp    st(0)                           ; store value on the top of the floating point stack
-       fld     SingleINF                               ; Load infinity
-       jmp     SignResult                              ; Goto SignResult
-ParseDigits:   
-       movzx   eax,nDigits[ecx+edx*2]; load the character at nDigits[edx];
-       sub     eax,'0'                                 ; subtract '0'
-       jc      ScaleResult                             ; jump to ScaleResult if this produces a negative value
-       mov     temp,eax                                ; store the first digit in temp
-       fmul    Single10                        ; Multiply by 10
-       fiadd   temp                            ; Add the digit which we just found
-       inc     edx                                             ; increment the counter
-       cmp     edx,18                                  ; if (eax<18) goto ParseDigits
-       jb      ParseDigits
-ScaleResult:   
-       mov     eax,nScale[ecx]                 ; eax = scale
-       sub     eax,edx                                 ; scale -= (number of digits)
-       call    ScaleByPow10            ; multiply the result by 10^scale
-SignResult:    
-       cmp     nSign[ecx],0                    ; If the sign is 0 already go to Cleanup, otherwise change the sign.
-       je      Cleanup
-       fchs
-Cleanup:       
-       mov     edx,value                               ; store value in edx
-       fstp    qword ptr [edx]         ; copy from value to the fp stack
-       fldcw   cwsave                          ; Restore original CW           
-       mov     esp,ebp                                 ; restore the stack frame & exit.
-       pop     ebp
-       ret     ;Made _cdecl for WinCE  paramSize
-
-_NumberToDouble                endp
-
-; Scale st(0) by 10^eax
-               
-ScaleByPow10   proc
-       test    eax,eax
-       je      SP2
-       jl      SP3
-       mov     edx,eax
-       and     edx,0FH
-       je      SP1
-       lea     edx,[edx+edx*4]
-       fld     Pow10By1[edx*2-10]
-       fmul
-SP1:   mov     edx,eax
-       shr     edx,4
-        test    edx, edx                ; remove partial flag stall caused by shr
-       je      SP2
-       lea     edx,[edx+edx*4]
-       fld     Pow10By16[edx*2-10]
-       fmul
-SP2:   ret
-SP3:   neg     eax
-       mov     edx,eax
-       and     edx,0FH
-       je      SP4
-       lea     edx,[edx+edx*4]
-       fld     Pow10By1[edx*2-10]
-       fdiv
-SP4:   mov     edx,eax
-       shr     edx,4
-        test    edx, edx                ; remove partial flag stall caused by shr
-       je      SP5
-       lea     edx,[edx+edx*4]
-       fld     Pow10By16[edx*2-10]
-       fdiv
-SP5:   ret
-ScaleByPow10   endp
-               
-       end
index 2a7b3af..8167476 100644 (file)
@@ -4,28 +4,6 @@
 
 #include "common.h"
 
-extern "C"
-{
-    void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID)    
-    {
-        PORTABILITY_ASSERT("Implement for PAL");
-    }
-
-    void ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID)
-    {
-        PORTABILITY_ASSERT("Implement for PAL");
-    }
-
-    void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID)
-    {
-        PORTABILITY_ASSERT("Implement for PAL");
-    }
-
-    void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
-    {
-    }
-};
-
 EXTERN_C VOID JIT_TailCall()
 {
   PORTABILITY_ASSERT("JIT_TailCall");
index ebe64ed..b4cfa20 100644 (file)
@@ -423,7 +423,7 @@ extern "C"
     void STDCALL JIT_MemSet(void *dest, int c, SIZE_T count);
     void STDCALL JIT_MemCpy(void *dest, const void *src, SIZE_T count);
 
-    void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
+    void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
 };
 
 
index cb3012f..5739831 100644 (file)
@@ -6794,8 +6794,10 @@ VOID MethodTableBuilder::AllocAndInitMethodDescs()
             }
         }
 
+#ifndef CROSSGEN_COMPILE
         if (tokenRange != currentTokenRange ||
             sizeOfMethodDescs + size > MethodDescChunk::MaxSizeOfMethodDescs)
+#endif // CROSSGEN_COMPILE
         {
             if (sizeOfMethodDescs != 0)
             {
index 821dc3a..6b066ff 100644 (file)
@@ -28,6 +28,8 @@
 
 CrstStatic  PEImage::s_hashLock;
 PtrHashMap *PEImage::s_Images = NULL;
+CrstStatic  PEImage::s_ijwHashLock;
+PtrHashMap *PEImage::s_ijwFixupDataHash;
 
 extern LocaleID g_lcid; // fusion path comparison lcid
 
@@ -54,6 +56,12 @@ void PEImage::Startup()
     LockOwner lock = { &s_hashLock, IsOwnerOfCrst };
     s_Images         = ::new PtrHashMap;
     s_Images->Init(CompareImage, FALSE, &lock);
+
+    s_ijwHashLock.Init(CrstIJWHash, CRST_REENTRANCY);
+    LockOwner ijwLock = { &s_ijwHashLock, IsOwnerOfCrst };
+    s_ijwFixupDataHash = ::new PtrHashMap;
+    s_ijwFixupDataHash->Init(CompareIJWDataBase, FALSE, &ijwLock);
+
     PEImageLayout::Startup();
 #ifdef FEATURE_USE_LCID
     g_lcid = MAKELCID(LOCALE_INVARIANT, SORT_DEFAULT);
@@ -196,6 +204,20 @@ PEImage::~PEImage()
 
 }
 
+/* static */
+BOOL PEImage::CompareIJWDataBase(UPTR base, UPTR mapping)
+{
+    CONTRACTL{
+        PRECONDITION(CheckStartup());
+        PRECONDITION(CheckPointer((BYTE *)(base << 1)));
+        PRECONDITION(CheckPointer((IJWFixupData *)mapping));
+        NOTHROW;
+        GC_NOTRIGGER;
+        MODE_ANY;
+    } CONTRACTL_END;
+
+    return ((BYTE *)(base << 1) == ((IJWFixupData*)mapping)->GetBase());
+}
 
     // Thread stress
 #if 0
@@ -686,7 +708,145 @@ void DECLSPEC_NORETURN PEImage::ThrowFormat(HRESULT hrError)
     EEFileLoadException::Throw(m_path, hrError);
 }
 
+#if !defined(CROSSGEN_COMPILE)
+
+//may outlive PEImage
+PEImage::IJWFixupData::IJWFixupData(void *pBase)
+    : m_lock(CrstIJWFixupData),
+    m_base(pBase), m_flags(0), m_DllThunkHeap(NULL), m_iNextFixup(0), m_iNextMethod(0)
+{
+    WRAPPER_NO_CONTRACT;
+}
+
+PEImage::IJWFixupData::~IJWFixupData()
+{
+    WRAPPER_NO_CONTRACT;
+    if (m_DllThunkHeap)
+        delete m_DllThunkHeap;
+}
+
+
+// Self-initializing accessor for m_DllThunkHeap
+LoaderHeap *PEImage::IJWFixupData::GetThunkHeap()
+{
+    CONTRACT(LoaderHeap *)
+    {
+        INSTANCE_CHECK;
+        THROWS;
+        GC_NOTRIGGER;
+        MODE_ANY;
+        INJECT_FAULT(COMPlusThrowOM());
+        POSTCONDITION(CheckPointer(RETVAL));
+    }
+    CONTRACT_END
+
+        if (!m_DllThunkHeap)
+        {
+            size_t * pPrivatePCLBytes = NULL;
+            size_t * pGlobalPCLBytes = NULL;
+
+            COUNTER_ONLY(pPrivatePCLBytes = &(GetPerfCounters().m_Loading.cbLoaderHeapSize));
+
+            LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize
+                0,                                 // DWORD dwCommitBlockSize
+                pPrivatePCLBytes,
+                ThunkHeapStubManager::g_pManager->GetRangeList(),
+                TRUE);                             // BOOL fMakeExecutable
+
+            if (FastInterlockCompareExchangePointer((PVOID*)&m_DllThunkHeap, (VOID*)pNewHeap, (VOID*)0) != 0)
+            {
+                delete pNewHeap;
+            }
+        }
+
+    RETURN m_DllThunkHeap;
+}
+
+void PEImage::IJWFixupData::MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod)
+{
+    LIMITED_METHOD_CONTRACT;
+    // supports only sequential fixup/method
+    _ASSERTE((iFixup == m_iNextFixup + 1 && iMethod == 0) ||                 //first method of the next fixup or
+        (iFixup == m_iNextFixup && iMethod == m_iNextMethod));     //the method that was next to fixup
+
+    m_iNextFixup = iFixup;
+    m_iNextMethod = iMethod + 1;
+}
+
+BOOL PEImage::IJWFixupData::IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod)
+{
+    LIMITED_METHOD_CONTRACT;
+    if (iFixup < m_iNextFixup)
+        return TRUE;
+    if (iFixup > m_iNextFixup)
+        return FALSE;
+    if (iMethod < m_iNextMethod)
+        return TRUE;
+
+    return FALSE;
+}
+
+/*static */
+PTR_LoaderHeap PEImage::GetDllThunkHeap(void *pBase)
+{
+    CONTRACTL
+    {
+        THROWS;
+        GC_TRIGGERS;
+        MODE_ANY;
+    }
+    CONTRACTL_END;
+    return GetIJWData(pBase)->GetThunkHeap();
+}
+
+/* static */
+PEImage::IJWFixupData *PEImage::GetIJWData(void *pBase)
+{
+    CONTRACTL{
+        THROWS;
+        GC_TRIGGERS;
+        MODE_ANY;
+        INJECT_FAULT(COMPlusThrowOM(););
+    } CONTRACTL_END
+
+    // Take the IJW hash lock
+    CrstHolder hashLockHolder(&s_ijwHashLock);
+
+    // Try to find the data
+    IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->LookupValue((UPTR)pBase, pBase);
+
+    // No data, must create
+    if ((UPTR)pData == (UPTR)INVALIDENTRY)
+    {
+        pData = new IJWFixupData(pBase);
+        s_ijwFixupDataHash->InsertValue((UPTR)pBase, pData);
+    }
+
+    // Return the new data
+    return (pData);
+}
+
+/* static */
+void PEImage::UnloadIJWModule(void *pBase)
+{
+    CONTRACTL{
+        NOTHROW;
+        GC_TRIGGERS;
+        MODE_ANY;
+    } CONTRACTL_END
+
+    // Take the IJW hash lock
+    CrstHolder hashLockHolder(&s_ijwHashLock);
+
+    // Try to delete the hash entry
+    IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->DeleteValue((UPTR)pBase, pBase);
+
+    // Now delete the data
+    if ((UPTR)pData != (UPTR)INVALIDENTRY)
+        delete pData;
+}
 
+#endif // !CROSSGEN_COMPILE
 
 
 
index 22aed04..f4e2924 100644 (file)
@@ -271,6 +271,7 @@ private:
     };
 
     static BOOL CompareImage(UPTR image1, UPTR image2);
+    static BOOL CompareIJWDataBase(UPTR base, UPTR mapping);
 
     void DECLSPEC_NORETURN ThrowFormat(HRESULT hr);
 
@@ -341,6 +342,49 @@ private:
     BOOL        m_bSignatureInfoCached;
     HRESULT   m_hrSignatureInfoStatus;
     DWORD        m_dwSignatureInfo;    
+
+    //@TODO:workaround: Remove this when we have one PEImage per mapped image,
+    //@TODO:workaround: and move the lock there
+    // This is for IJW thunk initialization, as it is no longer guaranteed
+    // that the initialization will occur under the loader lock.
+    static CrstStatic   s_ijwHashLock;
+    static PtrHashMap   *s_ijwFixupDataHash;
+
+public:
+        class IJWFixupData
+        {
+        private:
+            Crst            m_lock;
+            void           *m_base;
+            DWORD           m_flags;
+            PTR_LoaderHeap  m_DllThunkHeap;
+
+            // the fixup for the next iteration in FixupVTables
+            // we use it to make sure that we do not try to fix up the same entry twice
+            // if there was a pass that was aborted in the middle
+            COUNT_T         m_iNextFixup;
+            COUNT_T         m_iNextMethod;
+
+            enum {
+                e_FIXED_UP = 0x1
+            };
+
+        public:
+            IJWFixupData(void *pBase);
+            ~IJWFixupData();
+            void *GetBase() { LIMITED_METHOD_CONTRACT; return m_base; }
+            Crst *GetLock() { LIMITED_METHOD_CONTRACT; return &m_lock; }
+            BOOL IsFixedUp() { LIMITED_METHOD_CONTRACT; return m_flags & e_FIXED_UP; }
+            void SetIsFixedUp() { LIMITED_METHOD_CONTRACT; m_flags |= e_FIXED_UP; }
+            PTR_LoaderHeap  GetThunkHeap();
+            void MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
+            BOOL IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
+        };
+
+        static IJWFixupData *GetIJWData(void *pBase);
+        static PTR_LoaderHeap GetDllThunkHeap(void *pBase);
+        static void UnloadIJWModule(void *pBase);
+
 private:
     DWORD m_dwPEKind;
     DWORD m_dwMachine;
index 03d4332..a7c64e7 100644 (file)
@@ -460,9 +460,9 @@ void ProfilingAPIUtility::LogProfInfo(int iStringResourceID, ...)
 // InitializeProfiling() below solely for the debug-only, test-only code to allow
 // enter/leave/tailcall to be turned on at startup without a profiler. See
 // code:ProfControlBlock#TestOnlyELT
-EXTERN_C void __stdcall ProfileEnterNaked(UINT_PTR clientData);
-EXTERN_C void __stdcall ProfileLeaveNaked(UINT_PTR clientData);
-EXTERN_C void __stdcall ProfileTailcallNaked(UINT_PTR clientData);
+EXTERN_C void STDMETHODCALLTYPE ProfileEnterNaked(UINT_PTR clientData);
+EXTERN_C void STDMETHODCALLTYPE ProfileLeaveNaked(UINT_PTR clientData);
+EXTERN_C void STDMETHODCALLTYPE ProfileTailcallNaked(UINT_PTR clientData);
 #endif //PROF_TEST_ONLY_FORCE_ELT
 
 // ----------------------------------------------------------------------------
index d9715b7..98e5b13 100644 (file)
@@ -1624,7 +1624,7 @@ bool StubLinker::EmitUnwindInfo(Stub* pStub, int globalsize, LoaderHeap* pHeap)
         *pUnwindCodes++ = (BYTE)0xFF; // end
     }
 
-    int epilogUnwindCodeIndex = 0;
+    ptrdiff_t epilogUnwindCodeIndex = 0;
 
     //epilog differs from prolog
     if(m_cbStackFrame >= 4096)
@@ -1659,7 +1659,7 @@ bool StubLinker::EmitUnwindInfo(Stub* pStub, int globalsize, LoaderHeap* pHeap)
     }
 
     // Number of 32-bit unwind codes
-    int codeWordsCount = (ALIGN_UP((size_t)pUnwindCodes, sizeof(void*)) - (size_t)pUnwindInfo - sizeof(DWORD))/4;
+    size_t codeWordsCount = (ALIGN_UP((size_t)pUnwindCodes, sizeof(void*)) - (size_t)pUnwindInfo - sizeof(DWORD))/4;
 
     _ASSERTE(epilogUnwindCodeIndex < 32);
 
@@ -1669,8 +1669,8 @@ bool StubLinker::EmitUnwindInfo(Stub* pStub, int globalsize, LoaderHeap* pHeap)
     *(DWORD *)pUnwindInfo = 
         ((functionLength) / 2) |
         (1 << 21) |
-        (epilogUnwindCodeIndex << 23)|
-        (codeWordsCount << 28);  
+        ((int)epilogUnwindCodeIndex << 23)|
+        ((int)codeWordsCount << 28);
 
 #elif defined(_TARGET_ARM64_)
     if (!m_fProlog)
index 71fa2cf..54b4a49 100644 (file)
                }
             ]
         }
+    },
+    {
+        "name": "System.Memory.Tests",
+        "enabled": true,
+        "exclusions": {
+            "namespaces": null,
+            "classes": null,
+            "methods": [
+               { 
+                "name": "System.Buffers.Text.Tests.FormatterTests.TestFormatterDecimal",
+                "reason": "https://github.com/dotnet/coreclr/pull/19775"
+               }
+            ]
+        }
+    },
+    {
+        "name": "System.Runtime.Extensions.Tests",
+        "enabled": true,
+        "exclusions": {
+            "namespaces": null,
+            "classes": null,
+            "methods": [
+               { 
+                "name": "System.Tests.ConvertToStringTests.FromBoxedObject",
+                "reason": "https://github.com/dotnet/coreclr/pull/19775"
+               }
+            ]
+        }
     }
 ]
index 1456113..7ad4854 100644 (file)
@@ -90596,14 +90596,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanUnorderedScalar_r.cmd_11409]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_r\CompareLessThanUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreFence_ro.cmd_11410]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\StoreFence_ro\StoreFence_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\StoreFence_ro
@@ -90724,14 +90716,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualOrderedScalar_r.cmd_11426]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_r\CompareLessThanOrEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreAlignedNonTemporal_r.cmd_11427]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\StoreAlignedNonTemporal_r\StoreAlignedNonTemporal_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\StoreAlignedNonTemporal_r
@@ -90796,14 +90780,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualScalar_r.cmd_11435]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_r\CompareNotEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [tests.cmd_11436]
 RelativePath=JIT\opt\Casts\tests\tests.cmd
 WorkingDir=JIT\opt\Casts\tests
@@ -90852,14 +90828,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualScalar_ro.cmd_11442]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_ro\CompareNotEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [shared.cmd_11443]
 RelativePath=JIT\opt\Enum\shared\shared.cmd
 WorkingDir=JIT\opt\Enum\shared
@@ -90884,14 +90852,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareOrderedScalar_r.cmd_11446]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_r\CompareOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Blend_r.cmd_11447]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse41\Blend_r\Blend_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse41\Blend_r
@@ -90964,22 +90924,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareEqualUnorderedScalar_r.cmd_11456]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_r\CompareEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareGreaterThanOrderedScalar_r.cmd_11457]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_r\CompareGreaterThanOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ShiftRightLogicalVariable_r.cmd_11458]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx2\ShiftRightLogicalVariable_r\ShiftRightLogicalVariable_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx2\ShiftRightLogicalVariable_r
@@ -90996,14 +90940,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanScalar_r.cmd_11460]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_r\CompareGreaterThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [IsSupported_r.cmd_11461]
 RelativePath=JIT\HardwareIntrinsics\X86\General\IsSupported_r\IsSupported_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\General\IsSupported_r
@@ -91052,14 +90988,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrderedScalar_ro.cmd_11467]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_ro\CompareGreaterThanOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Base.cmd_11468]
 RelativePath=JIT\HardwareIntrinsics\Arm64\Base\Base.cmd
 WorkingDir=JIT\HardwareIntrinsics\Arm64\Base
@@ -91172,14 +91100,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotGreaterThanOrEqualScalar_r.cmd_11482]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_r\CompareNotGreaterThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MoveMask_r.cmd_11483]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\MoveMask_r\MoveMask_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\MoveMask_r
@@ -91212,14 +91132,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanScalar_r.cmd_11487]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_r\CompareLessThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MultiplyHigh_r.cmd_11488]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\MultiplyHigh_r\MultiplyHigh_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\MultiplyHigh_r
@@ -91404,14 +91316,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanScalar_ro.cmd_11511]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_ro\CompareGreaterThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MoveLowToHigh_r.cmd_11512]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\MoveLowToHigh_r\MoveLowToHigh_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\MoveLowToHigh_r
@@ -91540,30 +91444,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanOrEqualUnorderedScalar_r.cmd_11528]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_r\CompareGreaterThanOrEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotLessThanOrEqualScalar_r.cmd_11529]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_r\CompareNotLessThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareEqualOrderedScalar_r.cmd_11530]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_r\CompareEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [UnpackLow_ro.cmd_11532]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro\UnpackLow_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro
@@ -91820,14 +91700,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualOrderedScalar_ro.cmd_11564]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_ro\CompareLessThanOrEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [valuetypes.cmd_11565]
 RelativePath=Loader\classloader\DefaultInterfaceMethods\valuetypes\valuetypes\valuetypes.cmd
 WorkingDir=Loader\classloader\DefaultInterfaceMethods\valuetypes\valuetypes
@@ -91964,14 +91836,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotLessThanScalar_r.cmd_11582]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_r\CompareNotLessThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadLow_r.cmd_11583]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\LoadLow_r\LoadLow_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\LoadLow_r
@@ -91980,30 +91844,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanOrEqualOrderedScalar_ro.cmd_11584]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_ro\CompareGreaterThanOrEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotGreaterThanScalar_ro.cmd_11585]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_ro\CompareNotGreaterThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareGreaterThanOrEqualOrderedScalar_r.cmd_11586]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_r\CompareGreaterThanOrEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadAlignedVector128NonTemporal_r.cmd_11587]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse41\LoadAlignedVector128NonTemporal_r\LoadAlignedVector128NonTemporal_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse41\LoadAlignedVector128NonTemporal_r
@@ -92132,22 +91972,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareScalar_r.cmd_11603]
-RelativePath=JIT\HardwareIntrinsics\X86\Avx\CompareScalar_r\CompareScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Avx\CompareScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotLessThanScalar_ro.cmd_11604]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_ro\CompareNotLessThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_13910.cmd_11605]
 RelativePath=JIT\Regression\JitBlue\GitHub_13910\GitHub_13910\GitHub_13910.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_13910\GitHub_13910
@@ -92260,14 +92084,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrderedScalar_r.cmd_11619]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_r\CompareLessThanOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Sqrt_ro.cmd_11620]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\Sqrt_ro\Sqrt_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\Sqrt_ro
@@ -92300,14 +92116,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrEqualScalar_r.cmd_11624]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_r\CompareGreaterThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_13568.cmd_11625]
 RelativePath=JIT\Regression\JitBlue\GitHub_13568\GitHub_13568\GitHub_13568.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_13568\GitHub_13568
@@ -92396,22 +92204,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualUnorderedScalar_r.cmd_11636]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_r\CompareLessThanOrEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareLessThanOrEqualScalar_r.cmd_11637]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_r\CompareLessThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [tracelogging.cmd_11638]
 RelativePath=tracing\tracevalidation\tracelogging\tracelogging\tracelogging.cmd
 WorkingDir=tracing\tracevalidation\tracelogging\tracelogging
@@ -92532,22 +92324,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareOrderedScalar_ro.cmd_11653]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_ro\CompareOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[Compare_ro.cmd_11654]
-RelativePath=JIT\HardwareIntrinsics\X86\Avx\Compare_ro\Compare_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Avx\Compare_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [AlignRight_r.cmd_11655]
 RelativePath=JIT\HardwareIntrinsics\X86\Ssse3\AlignRight_r\AlignRight_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Ssse3\AlignRight_r
@@ -92612,14 +92388,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrEqualScalar_ro.cmd_11663]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_ro\CompareGreaterThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ReciprocalScalar_r.cmd_11664]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\ReciprocalScalar_r\ReciprocalScalar_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\ReciprocalScalar_r
@@ -92716,14 +92484,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualOrderedScalar_r.cmd_11676]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_r\CompareNotEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [SetZeroVector128_ro.cmd_11677]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\SetZeroVector128_ro\SetZeroVector128_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\SetZeroVector128_ro
@@ -92788,14 +92548,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualUnorderedScalar_ro.cmd_11685]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_ro\CompareLessThanOrEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_14321.cmd_11686]
 RelativePath=JIT\Regression\JitBlue\GitHub_14321\GitHub_14321\GitHub_14321.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_14321\GitHub_14321
@@ -92836,14 +92588,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareEqualUnorderedScalar_ro.cmd_11691]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_ro\CompareEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Sse_ro.cmd_11692]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\Sse_ro\Sse_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\Sse_ro
@@ -92884,14 +92628,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareEqualOrderedScalar_ro.cmd_11697]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_ro\CompareEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadVector128_ro.cmd_11698]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\LoadVector128_ro\LoadVector128_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\LoadVector128_ro
@@ -92932,14 +92668,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareLessThanOrderedScalar_ro.cmd_11703]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_ro\CompareLessThanOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreAligned_r.cmd_11704]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx\StoreAligned_r\StoreAligned_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx\StoreAligned_r
@@ -93244,22 +92972,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareNotLessThanOrEqualScalar_ro.cmd_11742]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_ro\CompareNotLessThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareUnorderedScalar_r.cmd_11743]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_r\CompareUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ConvertToVector256_r.cmd_11744]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx2\ConvertToVector256_r\ConvertToVector256_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx2\ConvertToVector256_r
@@ -93292,14 +93004,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareEqualScalar_ro.cmd_11748]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_ro\CompareEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [DynamicMethodGCStress.cmd_11749]
 RelativePath=readytorun\DynamicMethodGCStress\DynamicMethodGCStress\DynamicMethodGCStress.cmd
 WorkingDir=readytorun\DynamicMethodGCStress\DynamicMethodGCStress
@@ -93308,14 +93012,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareUnorderedScalar_ro.cmd_11750]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_ro\CompareUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [InvokeConsumer.cmd_11751]
 RelativePath=reflection\DefaultInterfaceMethods\InvokeConsumer\InvokeConsumer.cmd
 WorkingDir=reflection\DefaultInterfaceMethods\InvokeConsumer
@@ -93324,14 +93020,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareLessThanUnorderedScalar_ro.cmd_11752]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_ro\CompareLessThanUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_16210_1.cmd_11753]
 RelativePath=JIT\Regression\JitBlue\GitHub_16210\GitHub_16210_1\GitHub_16210_1.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_16210\GitHub_16210_1
@@ -93412,14 +93100,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareLessThanScalar_ro.cmd_11763]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_ro\CompareLessThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MathCeilingDouble_r.cmd_11764]
 RelativePath=JIT\Intrinsics\MathCeilingDouble_r\MathCeilingDouble_r.cmd
 WorkingDir=JIT\Intrinsics\MathCeilingDouble_r
@@ -93508,14 +93188,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotGreaterThanOrEqualScalar_ro.cmd_11775]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_ro\CompareNotGreaterThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MathCeilingSingle_r.cmd_11776]
 RelativePath=JIT\Intrinsics\MathCeilingSingle_r\MathCeilingSingle_r.cmd
 WorkingDir=JIT\Intrinsics\MathCeilingSingle_r
@@ -93564,14 +93236,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanUnorderedScalar_ro.cmd_11782]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_ro\CompareGreaterThanUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [DevDiv_487702.cmd_11783]
 RelativePath=JIT\Regression\JitBlue\DevDiv_487702\DevDiv_487702\DevDiv_487702.cmd
 WorkingDir=JIT\Regression\JitBlue\DevDiv_487702\DevDiv_487702
@@ -93604,14 +93268,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanUnorderedScalar_r.cmd_11787]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_r\CompareGreaterThanUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadDquVector256_r.cmd_11788]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx\LoadDquVector256_r\LoadDquVector256_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx\LoadDquVector256_r
@@ -93724,22 +93380,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareEqualScalar_r.cmd_11802]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_r\CompareEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotGreaterThanScalar_r.cmd_11803]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_r\CompareNotGreaterThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [PackSignedSaturate_ro.cmd_11804]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro\PackSignedSaturate_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro
@@ -93964,14 +93604,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualOrderedScalar_ro.cmd_11832]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_ro\CompareNotEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadScalarVector128_r.cmd_11833]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\LoadScalarVector128_r\LoadScalarVector128_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\LoadScalarVector128_r
@@ -94004,14 +93636,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrEqualUnorderedScalar_ro.cmd_11837]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_ro\CompareGreaterThanOrEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [UnpackLow_r.cmd_11838]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r\UnpackLow_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r
@@ -94188,14 +93812,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareNotEqualUnorderedScalar_r.cmd_11861]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_r\CompareNotEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreAligned_r.cmd_11862]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\StoreAligned_r\StoreAligned_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\StoreAligned_r
@@ -94260,14 +93876,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareNotEqualUnorderedScalar_ro.cmd_11870]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_ro\CompareNotEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Store_r.cmd_11871]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx\Store_r\Store_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx\Store_r
@@ -94332,14 +93940,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;Pri1;NEW
 HostStyle=0
 
-[CompareLessThanOrEqualScalar_ro.cmd_11879]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_ro\CompareLessThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [UnpackLow_ro.cmd_11880]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\UnpackLow_ro\UnpackLow_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\UnpackLow_ro
index 35043a1..baabfb4 100644 (file)
@@ -90604,14 +90604,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanUnorderedScalar_r.cmd_11728]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_r\CompareLessThanUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreFence_ro.cmd_11729]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\StoreFence_ro\StoreFence_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\StoreFence_ro
@@ -90732,14 +90724,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualOrderedScalar_r.cmd_11745]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_r\CompareLessThanOrEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreAlignedNonTemporal_r.cmd_11746]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\StoreAlignedNonTemporal_r\StoreAlignedNonTemporal_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\StoreAlignedNonTemporal_r
@@ -90804,14 +90788,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualScalar_r.cmd_11754]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_r\CompareNotEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [tests.cmd_11755]
 RelativePath=JIT\opt\Casts\tests\tests.cmd
 WorkingDir=JIT\opt\Casts\tests
@@ -90868,14 +90844,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualScalar_ro.cmd_11762]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_ro\CompareNotEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [shared.cmd_11763]
 RelativePath=JIT\opt\Enum\shared\shared.cmd
 WorkingDir=JIT\opt\Enum\shared
@@ -90900,14 +90868,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareOrderedScalar_r.cmd_11766]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_r\CompareOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Blend_r.cmd_11767]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse41\Blend_r\Blend_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse41\Blend_r
@@ -90980,22 +90940,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareEqualUnorderedScalar_r.cmd_11776]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_r\CompareEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareGreaterThanOrderedScalar_r.cmd_11777]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_r\CompareGreaterThanOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ShiftRightLogicalVariable_r.cmd_11778]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx2\ShiftRightLogicalVariable_r\ShiftRightLogicalVariable_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx2\ShiftRightLogicalVariable_r
@@ -91012,14 +90956,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanScalar_r.cmd_11780]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_r\CompareGreaterThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [IsSupported_r.cmd_11781]
 RelativePath=JIT\HardwareIntrinsics\X86\General\IsSupported_r\IsSupported_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\General\IsSupported_r
@@ -91068,14 +91004,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_FAIL;9565;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanOrderedScalar_ro.cmd_11787]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_ro\CompareGreaterThanOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Base.cmd_11788]
 RelativePath=JIT\HardwareIntrinsics\Arm64\Base\Base.cmd
 WorkingDir=JIT\HardwareIntrinsics\Arm64\Base
@@ -91188,14 +91116,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotGreaterThanOrEqualScalar_r.cmd_11802]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_r\CompareNotGreaterThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MoveMask_r.cmd_11803]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\MoveMask_r\MoveMask_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\MoveMask_r
@@ -91228,14 +91148,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanScalar_r.cmd_11807]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_r\CompareLessThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MultiplyHigh_r.cmd_11808]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\MultiplyHigh_r\MultiplyHigh_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\MultiplyHigh_r
@@ -91420,14 +91332,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanScalar_ro.cmd_11831]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_ro\CompareGreaterThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MoveLowToHigh_r.cmd_11832]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\MoveLowToHigh_r\MoveLowToHigh_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\MoveLowToHigh_r
@@ -91540,22 +91444,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanOrEqualUnorderedScalar_r.cmd_11846]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_r\CompareGreaterThanOrEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotLessThanOrEqualScalar_r.cmd_11847]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_r\CompareNotLessThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [UnpackLow_ro.cmd_11849]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro\UnpackLow_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro
@@ -91820,14 +91708,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualOrderedScalar_ro.cmd_11882]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_ro\CompareLessThanOrEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [valuetypes.cmd_11883]
 RelativePath=Loader\classloader\DefaultInterfaceMethods\valuetypes\valuetypes\valuetypes.cmd
 WorkingDir=Loader\classloader\DefaultInterfaceMethods\valuetypes\valuetypes
@@ -91972,14 +91852,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotLessThanScalar_r.cmd_11901]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_r\CompareNotLessThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadLow_r.cmd_11902]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\LoadLow_r\LoadLow_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\LoadLow_r
@@ -91988,30 +91860,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanOrEqualOrderedScalar_ro.cmd_11903]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_ro\CompareGreaterThanOrEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotGreaterThanScalar_ro.cmd_11904]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_ro\CompareNotGreaterThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareGreaterThanOrEqualOrderedScalar_r.cmd_11905]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_r\CompareGreaterThanOrEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadAlignedVector128NonTemporal_r.cmd_11906]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse41\LoadAlignedVector128NonTemporal_r\LoadAlignedVector128NonTemporal_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse41\LoadAlignedVector128NonTemporal_r
@@ -92124,22 +91972,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareScalar_r.cmd_11920]
-RelativePath=JIT\HardwareIntrinsics\X86\Avx\CompareScalar_r\CompareScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Avx\CompareScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotLessThanScalar_ro.cmd_11921]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_ro\CompareNotLessThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_13910.cmd_11922]
 RelativePath=JIT\Regression\JitBlue\GitHub_13910\GitHub_13910\GitHub_13910.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_13910\GitHub_13910
@@ -92276,14 +92108,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrderedScalar_r.cmd_11939]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_r\CompareLessThanOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Sqrt_ro.cmd_11940]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\Sqrt_ro\Sqrt_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\Sqrt_ro
@@ -92316,14 +92140,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrEqualScalar_r.cmd_11944]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_r\CompareGreaterThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_13568.cmd_11945]
 RelativePath=JIT\Regression\JitBlue\GitHub_13568\GitHub_13568\GitHub_13568.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_13568\GitHub_13568
@@ -92404,22 +92220,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualUnorderedScalar_r.cmd_11955]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_r\CompareLessThanOrEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareLessThanOrEqualScalar_r.cmd_11956]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_r\CompareLessThanOrEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [tracelogging.cmd_11957]
 RelativePath=tracing\tracevalidation\tracelogging\tracelogging\tracelogging.cmd
 WorkingDir=tracing\tracevalidation\tracelogging\tracelogging
@@ -92532,14 +92332,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareOrderedScalar_ro.cmd_11971]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_ro\CompareOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [RefStructWithSpan.cmd_11972]
 RelativePath=CoreMangLib\system\span\RefStructWithSpan\RefStructWithSpan.cmd
 WorkingDir=CoreMangLib\system\span\RefStructWithSpan
@@ -92548,14 +92340,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;Pri1;NEW
 HostStyle=0
 
-[Compare_ro.cmd_11973]
-RelativePath=JIT\HardwareIntrinsics\X86\Avx\Compare_ro\Compare_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Avx\Compare_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [AlignRight_r.cmd_11974]
 RelativePath=JIT\HardwareIntrinsics\X86\Ssse3\AlignRight_r\AlignRight_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Ssse3\AlignRight_r
@@ -92620,14 +92404,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrEqualScalar_ro.cmd_11982]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_ro\CompareGreaterThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ReciprocalScalar_r.cmd_11983]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\ReciprocalScalar_r\ReciprocalScalar_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\ReciprocalScalar_r
@@ -92724,14 +92500,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualOrderedScalar_r.cmd_11995]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_r\CompareNotEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [b124443.cmd_11996]
 RelativePath=JIT\Regression\CLR-x86-JIT\V1-M15-SP2\b124443\b124443\b124443.cmd
 WorkingDir=JIT\Regression\CLR-x86-JIT\V1-M15-SP2\b124443\b124443
@@ -92780,14 +92548,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrEqualUnorderedScalar_ro.cmd_12002]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_ro\CompareLessThanOrEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_14321.cmd_12003]
 RelativePath=JIT\Regression\JitBlue\GitHub_14321\GitHub_14321\GitHub_14321.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_14321\GitHub_14321
@@ -92828,14 +92588,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareEqualUnorderedScalar_ro.cmd_12008]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_ro\CompareEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Sse_ro.cmd_12009]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\Sse_ro\Sse_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\Sse_ro
@@ -92876,14 +92628,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareEqualOrderedScalar_ro.cmd_12014]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_ro\CompareEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadVector128_ro.cmd_12015]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\LoadVector128_ro\LoadVector128_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\LoadVector128_ro
@@ -92916,14 +92660,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_FAIL;9565;EXCLUDED
 HostStyle=0
 
-[CompareLessThanOrderedScalar_ro.cmd_12019]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_ro\CompareLessThanOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [SetZeroVector128_ro.cmd_12020]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\SetZeroVector128_ro\SetZeroVector128_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\SetZeroVector128_ro
@@ -93236,22 +92972,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_FAIL;9565;EXCLUDED
 HostStyle=0
 
-[CompareNotLessThanOrEqualScalar_ro.cmd_12059]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_ro\CompareNotLessThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotLessThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareUnorderedScalar_r.cmd_12060]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_r\CompareUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ConvertToVector256_r.cmd_12061]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx2\ConvertToVector256_r\ConvertToVector256_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx2\ConvertToVector256_r
@@ -93284,14 +93004,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareEqualScalar_ro.cmd_12065]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_ro\CompareEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [DynamicMethodGCStress.cmd_12066]
 RelativePath=readytorun\DynamicMethodGCStress\DynamicMethodGCStress\DynamicMethodGCStress.cmd
 WorkingDir=readytorun\DynamicMethodGCStress\DynamicMethodGCStress
@@ -93300,14 +93012,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareUnorderedScalar_ro.cmd_12067]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_ro\CompareUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [InvokeConsumer.cmd_12068]
 RelativePath=reflection\DefaultInterfaceMethods\InvokeConsumer\InvokeConsumer.cmd
 WorkingDir=reflection\DefaultInterfaceMethods\InvokeConsumer
@@ -93316,14 +93020,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_FAIL;9565;EXCLUDED
 HostStyle=0
 
-[CompareLessThanUnorderedScalar_ro.cmd_12069]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_ro\CompareLessThanUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [GitHub_16210_1.cmd_12070]
 RelativePath=JIT\Regression\JitBlue\GitHub_16210\GitHub_16210_1\GitHub_16210_1.cmd
 WorkingDir=JIT\Regression\JitBlue\GitHub_16210\GitHub_16210_1
@@ -93396,14 +93092,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareLessThanScalar_ro.cmd_12079]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_ro\CompareLessThanScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MathCeilingDouble_r.cmd_12080]
 RelativePath=JIT\Intrinsics\MathCeilingDouble_r\MathCeilingDouble_r.cmd
 WorkingDir=JIT\Intrinsics\MathCeilingDouble_r
@@ -93500,14 +93188,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotGreaterThanOrEqualScalar_ro.cmd_12092]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_ro\CompareNotGreaterThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [MathCeilingSingle_r.cmd_12093]
 RelativePath=JIT\Intrinsics\MathCeilingSingle_r\MathCeilingSingle_r.cmd
 WorkingDir=JIT\Intrinsics\MathCeilingSingle_r
@@ -93564,14 +93244,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareGreaterThanUnorderedScalar_ro.cmd_12100]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_ro\CompareGreaterThanUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [DevDiv_487702.cmd_12101]
 RelativePath=JIT\Regression\JitBlue\DevDiv_487702\DevDiv_487702\DevDiv_487702.cmd
 WorkingDir=JIT\Regression\JitBlue\DevDiv_487702\DevDiv_487702
@@ -93604,14 +93276,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanUnorderedScalar_r.cmd_12105]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_r\CompareGreaterThanUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadDquVector256_r.cmd_12106]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx\LoadDquVector256_r\LoadDquVector256_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx\LoadDquVector256_r
@@ -93732,22 +93396,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareEqualScalar_r.cmd_12121]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_r\CompareEqualScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[CompareNotGreaterThanScalar_r.cmd_12122]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_r\CompareNotGreaterThanScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotGreaterThanScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [PackSignedSaturate_ro.cmd_12123]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro\PackSignedSaturate_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro
@@ -93948,14 +93596,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[CompareNotEqualOrderedScalar_ro.cmd_12148]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_ro\CompareNotEqualOrderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualOrderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadScalarVector128_r.cmd_12149]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\LoadScalarVector128_r\LoadScalarVector128_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\LoadScalarVector128_r
@@ -93980,14 +93620,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareGreaterThanOrEqualUnorderedScalar_ro.cmd_12152]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_ro\CompareGreaterThanOrEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareGreaterThanOrEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [UnpackLow_r.cmd_12153]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r\UnpackLow_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r
@@ -94100,14 +93732,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareEqualOrderedScalar_r.cmd_12167]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_r\CompareEqualOrderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareEqualOrderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ConvertToInt32_ro.cmd_12168]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\ConvertToInt32_ro\ConvertToInt32_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\ConvertToInt32_ro
@@ -94164,14 +93788,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;Pri1;NEW
 HostStyle=0
 
-[CompareNotEqualUnorderedScalar_r.cmd_12176]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_r\CompareNotEqualUnorderedScalar_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [StoreAligned_r.cmd_12177]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\StoreAligned_r\StoreAligned_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\StoreAligned_r
@@ -94244,14 +93860,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[CompareNotEqualUnorderedScalar_ro.cmd_12186]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_ro\CompareNotEqualUnorderedScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareNotEqualUnorderedScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Store_r.cmd_12187]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx\Store_r\Store_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx\Store_r
@@ -94316,14 +93924,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;Pri1;NEW
 HostStyle=0
 
-[CompareLessThanOrEqualScalar_ro.cmd_12195]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_ro\CompareLessThanOrEqualScalar_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\CompareLessThanOrEqualScalar_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [UnpackLow_ro.cmd_12196]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\UnpackLow_ro\UnpackLow_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\UnpackLow_ro
index 2ab7329..2a34642 100644 (file)
@@ -60,6 +60,9 @@
         <ExcludeList Include="$(XunitTestBinBase)/Interop/StructMarshalling/PInvoke/MarshalStructAsLayoutExp/*">
             <Issue>Issue building native components for the test.</Issue>
         </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/arglist/vararg/*">
+            <Issue>Native varargs not supported on unix</Issue>
+        </ExcludeList>
     </ItemGroup>
 
     <!-- Arm32 All OS -->
         <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/DevDiv_590771/DevDiv_590771/*">
             <Issue>needs triage</Issue>
         </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)\readytorun\r2rdump\R2RDumpTest\R2RDumpTest.cmd">
+        <ExcludeList Include="$(XunitTestBinBase)/readytorun/r2rdump/R2RDumpTest/*">
             <Issue>19441</Issue>
         </ExcludeList>
     </ItemGroup>
         <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport/*">
             <Issue>Varargs supported on this platform</Issue>
         </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport_r/*">
-            <Issue>Varargs supported on this platform</Issue>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/arglist/vararg/*">
+            <Issue>19705</Issue>
         </ExcludeList>
     </ItemGroup>
 
         <ExcludeList Include="$(XunitTestBinBase)/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-6/reverse-complement-6*">
             <Issue>9314</Issue>
         </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport_r/*">
+            <Issue>Varargs supported on this platform</Issue>
+        </ExcludeList>
 
         <!-- Disable COM tests since they don't properly run on Windows.Nano and at present there is no way to special case that OS flavor. -->
         <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/Primitives/NETClientPrimitives/*">
         <ExcludeList Include="$(XunitTestBinBase)/GC/Stress/Framework/ReliabilityFramework/*">
             <Issue>needs triage</Issue>
         </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)\Interop\MarshalAPI\IUnknown\IUnknownTest\IUnknownTest.cmd">
+        <ExcludeList Include="$(XunitTestBinBase)/Interop/MarshalAPI/IUnknown/IUnknownTest/*">
             <Issue>needs triage</Issue>
         </ExcludeList>
         <ExcludeList Include="$(XunitTestBinBase)/Interop/SizeConst/SizeConstTest/*">
         <ExcludeList Include="$(XunitTestBinBase)/tracing/eventsource/eventpipeandetw/eventpipeandetw/*">
             <Issue>by design Windows only</Issue>
         </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/arglist/vararg/*">
+            <Issue>not supported on unix</Issue>
+        </ExcludeList>
     </ItemGroup>
 
     <!-- Failures while testing via ILLINK -->
index f2a480e..0107958 100644 (file)
@@ -38,5 +38,6 @@ if(WIN32)
     # IJW isn't supported on ARM64
     if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
         add_subdirectory(IJW/ManagedCallingNative/IjwNativeDll)
+        add_subdirectory(IJW/NativeCallingManaged/IjwNativeCallingManagedDll)
     endif()
 endif(WIN32)
index 415c8d5..49470d3 100644 (file)
@@ -1,3 +1,7 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
 #include <windows.h>
 
 // Entrypoint jumped to by IJW dlls when their dllmain is called
index e0b9127..612e6aa 100644 (file)
@@ -5,17 +5,13 @@ set(SOURCES IjwNativeDll.cpp)
 
 if (WIN32)
   # 4365 - signed/unsigned mismatch
-  add_compile_options(-wd4365)
+  add_compile_options(/wd4365)
 
   # IJW
-  add_compile_options(-clr)
+  add_compile_options(/clr)
   
   # IJW requires the CRT as a dll, not linked in
-  if(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
-    add_compile_options(-MDd)
-  else()
-    add_compile_options(-MD)
-  endif()
+  add_compile_options(/MD$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>)
 
   # CMake enables /RTC1 and /EHsc by default, but they're not compatible with /clr, so remove them
   if(CMAKE_CXX_FLAGS_DEBUG MATCHES "/RTC1")
index 6ac5601..cb25b44 100644 (file)
@@ -1,3 +1,7 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
 #pragma unmanaged
 int NativeFunction()
 {
diff --git a/tests/src/Interop/IJW/NativeCallingManaged/IjwNativeCallingManagedDll/CMakeLists.txt b/tests/src/Interop/IJW/NativeCallingManaged/IjwNativeCallingManagedDll/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c8b0edc
--- /dev/null
@@ -0,0 +1,42 @@
+cmake_minimum_required (VERSION 2.6)
+project (IjwNativeCallingManagedDll)
+include_directories( ${INC_PLATFORM_DIR} )
+set(SOURCES IjwNativeCallingManagedDll.cpp)
+
+if (WIN32)
+  # 4365 - signed/unsigned mismatch
+  add_compile_options(/wd4365)
+
+  # IJW
+  add_compile_options(/clr)
+  
+  # IJW requires the CRT as a dll, not linked in
+  add_compile_options(/MD$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>)
+
+  # CMake enables /RTC1 and /EHsc by default, but they're not compatible with /clr, so remove them
+  if(CMAKE_CXX_FLAGS_DEBUG MATCHES "/RTC1")
+    string(REPLACE "/RTC1" " " CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+  endif()
+  
+  if(CMAKE_CXX_FLAGS MATCHES "/EHsc")
+    string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  endif()
+
+  # IJW isn't compatible with CFG
+   if(CMAKE_CXX_FLAGS MATCHES "/guard:cf")
+    string(REPLACE "/guard:cf" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+   endif()
+
+     # IJW isn't compatible with GR-
+   if(CMAKE_CXX_FLAGS MATCHES "/GR-")
+    string(REPLACE "/GR-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+   endif()
+
+endif()
+
+# add the shared library
+add_library (IjwNativeCallingManagedDll SHARED ${SOURCES})
+target_link_libraries(IjwNativeCallingManagedDll ${LINK_LIBRARIES_ADDITIONAL})
+
+# add the install targets
+install (TARGETS IjwNativeCallingManagedDll DESTINATION bin)
diff --git a/tests/src/Interop/IJW/NativeCallingManaged/IjwNativeCallingManagedDll/IjwNativeCallingManagedDll.cpp b/tests/src/Interop/IJW/NativeCallingManaged/IjwNativeCallingManagedDll/IjwNativeCallingManagedDll.cpp
new file mode 100644 (file)
index 0000000..9ba7e3a
--- /dev/null
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma managed
+int ManagedCallee()
+{
+    return 100;
+}
+
+#pragma unmanaged
+int NativeFunction()
+{
+    return ManagedCallee();
+}
+
+#pragma managed
+public ref class TestClass
+{
+public:
+    int ManagedEntryPoint()
+    {
+        return NativeFunction();
+    }
+};
diff --git a/tests/src/Interop/IJW/NativeCallingManaged/NativeCallingManaged.cs b/tests/src/Interop/IJW/NativeCallingManaged/NativeCallingManaged.cs
new file mode 100644 (file)
index 0000000..5f035d1
--- /dev/null
@@ -0,0 +1,58 @@
+// Licensed to the .NET Foundation under one or more 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.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using TestLibrary;
+
+namespace NativeCallingManaged
+{
+    class NativeCallingManaged
+    {
+        static int Main(string[] args)
+        {
+            bool success = true;
+            // Load a fake mscoree.dll to avoid starting desktop
+            LoadLibraryEx(Path.Combine(Environment.CurrentDirectory, "mscoree.dll"), IntPtr.Zero, 0);
+
+            TestFramework.BeginScenario("Calling from managed to native IJW code");
+
+            // Building with a reference to the IJW dll is difficult, so load via reflection instead
+            TestFramework.BeginTestCase("Load IJW dll via reflection");
+            Assembly ijwNativeDll = Assembly.Load("IjwNativeCallingManagedDll");
+            TestFramework.EndTestCase();
+
+            TestFramework.BeginTestCase("Call native method returning int");
+            Type testType = ijwNativeDll.GetType("TestClass");
+            object testInstance = Activator.CreateInstance(testType);
+            MethodInfo testMethod = testType.GetMethod("ManagedEntryPoint");
+            int result = (int)testMethod.Invoke(testInstance, null);
+            if(result != 100)
+            {
+                TestFramework.LogError("IJW", "Incorrect result returned: " + result);
+                success = false;
+            }
+            TestFramework.EndTestCase();
+
+            TestFramework.BeginTestCase("Ensure .NET Framework was not loaded");
+            IntPtr clrHandle = GetModuleHandle("mscoreei.dll");
+            if (clrHandle != IntPtr.Zero)
+            {
+                TestFramework.LogError("IJW", ".NET Framework loaded by IJw module load");
+                success = false;
+            }
+            TestFramework.EndTestCase();
+
+            return success ? 100 : 99;
+        }
+
+        [DllImport("kernel32.dll")]
+        static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, int dwFlags);
+
+        [DllImport("kernel32.dll")]
+        static extern IntPtr GetModuleHandle(string lpModuleName);
+    }
+}
@@ -4,34 +4,36 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <AssemblyName>NativeCallingManaged</AssemblyName>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{03F13B5B-6FB8-453D-B947-67CAAFA084A4}</ProjectGuid>
+    <ProjectGuid>{8B76A001-5654-4F11-A80B-EF12644EAD3D}</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>
+
+    <!-- IJW is Windows-only -->
+    <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows>
+
+    <!-- IJW is not supported on ARM64 -->
+    <DisableProjectBuild Condition="'$(Platform)' == 'arm64'">true</DisableProjectBuild>
   </PropertyGroup>
   <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
   <ItemGroup>
     <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
       <Visible>False</Visible>
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
   <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+    <Compile Include="NativeCallingManaged.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareEqualScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <ProjectReference Include="IjwNativeCallingManagedDll/CMakeLists.txt" />
+    <ProjectReference Include="../FakeMscoree/CMakeLists.txt" />
+    <ProjectReference Include="../../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
   </ItemGroup>
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
-  </PropertyGroup>
-</Project>
\ No newline at end of file
+</Project>
index 9e8f7d7..ff7eeb2 100644 (file)
@@ -24,7 +24,7 @@ public class Helper
     {
         if (s1.f1 != s2.f1 || s1.f2 != s2.f2 || s1.f3 != s2.f3)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintInnerSequential(s1, s1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -61,7 +61,7 @@ public class Helper
     {
         if (inner1.f1 != inner2.f1 || inner1.f2 != inner2.f2 || inner1.f3 != inner2.f3)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintINNER2(inner1, inner1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -98,7 +98,7 @@ public class Helper
     {
         if (inner1.f1 != inner2.f1 || inner1.f2 != inner2.f2 || inner1.f3 != inner2.f3)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintInnerExplicit(inner1, inner1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -148,7 +148,7 @@ public class Helper
                 outer1.arr[i].f2 != outer2.arr[i].f2 ||
                 outer1.arr[i].f3 != outer2.arr[i].f3)
             {
-                Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+                Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
                 Console.WriteLine("\tThe Actual is...");
                 Console.WriteLine("\t{0}.arr[{1}].f1 = {2}", outer1.ToString(), i, outer1.arr[i].f1);
                 Console.WriteLine("\t{0}.arr[{1}].f2 = {2}", outer1.ToString(), i, outer1.arr[i].f2);
@@ -199,7 +199,7 @@ public class Helper
         {
             if (outer1.arr[i].f1 != InnerArrayExplicit.arr[i].f1)
             {
-                Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+                Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
                 Console.WriteLine("\tThe Actual f1 field is...");
                 Console.WriteLine("\t{0}.arr[{1}].f1 = {2}", outer1.ToString(), i, outer1.arr[i].f1);
                 Console.WriteLine("\tThe Expected f1 field is...");
@@ -209,7 +209,7 @@ public class Helper
         }
         if (outer1.f4 != InnerArrayExplicit.f4)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual f4 field is...");
             Console.WriteLine("\t{0}.f4 = {1}", outer1.ToString(), outer1.f4);
             Console.WriteLine("\tThe Expected f4 field is...");
@@ -257,7 +257,7 @@ public class Helper
                 outer1.arr[i].f2 != InnerArrayExplicit.arr[i].f2 ||
                 outer1.arr[i].f3 != InnerArrayExplicit.arr[i].f3)
             {
-                Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+                Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
                 Console.WriteLine("\tThe Actual is...");
                 Console.WriteLine("\t{0}.arr[{1}].f1 = {2}", outer1.ToString(), i, outer1.arr[i].f1);
                 Console.WriteLine("\t{0}.arr[{1}].f2 = {2}", outer1.ToString(), i, outer1.arr[i].f2);
@@ -271,7 +271,7 @@ public class Helper
         }
         if (outer1.f4 != InnerArrayExplicit.f4)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual f4 field is...");
             Console.WriteLine("\t{0}.f4 = {1}", outer1.ToString(), outer1.f4);
             Console.WriteLine("\tThe Expected f4 field is...");
@@ -303,7 +303,7 @@ public class Helper
     {
         if (str1.f1 != str2.f1 || str1.f2 != str2.f2)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintCharSetAnsiSequential(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -339,7 +339,7 @@ public class Helper
     {
         if (str1.f1 != str2.f1 || str1.f2 != str2.f2)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintCharSetUnicodeSequential(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -395,7 +395,7 @@ public class Helper
             str1.ui16 != str2.ui16 || str1.i64 != str2.i64 || str1.ui64 != str2.ui64 ||
             str1.sgl != str2.sgl || str1.d != str2.d)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintNumberSequential(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -447,7 +447,7 @@ public class Helper
         int iflag = 0;
         if (str1.flag != str2.flag || str1.str != str2.str)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual flag field is...");
             Console.WriteLine("\t{0}.flag = {1}", str1.ToString(), str1.flag);
             Console.WriteLine("\t{0}.str = {1}", str1.ToString(), str1.str);
@@ -460,7 +460,7 @@ public class Helper
         {
             if (str1.vals[i] != str2.vals[i])
             {
-                Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+                Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
                 Console.WriteLine("\tThe Actual vals field is...");
                 Console.WriteLine("\t{0}.vals[{1}] = {2}", str1.ToString(), i, str1.vals[i]);
                 Console.WriteLine("\tThe Expected vals field is...");
@@ -500,7 +500,7 @@ public class Helper
     {
         if (str1.s4.age != str2.s4.age || str1.s4.name != str2.s4.name)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual s4 field is...");
             Console.WriteLine("\t{0}.s4.age = {1}", str1.ToString(), str1.s4.age);
             Console.WriteLine("\t{0}.s4.name = {1}", str1.ToString(), str1.s4.name);
@@ -511,7 +511,7 @@ public class Helper
         }
         if (str1.ef != str2.ef)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual ef field is...");
             Console.WriteLine("\t{0}.ef = {1}", str1.ToString(), str1.ef);
             Console.WriteLine("\tThe Expected s4 field is...");
@@ -541,7 +541,7 @@ public class Helper
     {
         if (str1.first != str2.first || str1.last != str2.last)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintStringStructSequentialAnsi(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -574,7 +574,7 @@ public class Helper
     {
         if (str1.first != str2.first || str1.last != str2.last)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintStringStructSequentialUnicode(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -616,7 +616,7 @@ public class Helper
             str1.jobNum != str2.jobNum ||
             str1.i32 != str2.i32 || str1.ui32 != str2.ui32 || str1.mySByte != str2.mySByte)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintS8(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -642,7 +642,7 @@ public class Helper
     {
         if (str1.i32 != str2.i32 || str1.myDelegate1 != str2.myDelegate1)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             Console.WriteLine("\t{0}.i32 = {1}", str1.ToString(), str1.i32);
             Console.WriteLine("\t{0}.myDelegate1 = {1}", str1.ToString(), str1.myDelegate1);
@@ -673,7 +673,7 @@ public class Helper
     {
         if (str1.s.s_int.i != str2.s.s_int.i || str1.s.i != str2.s.i)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintIncludeOuterIntergerStructSequential(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -705,7 +705,7 @@ public class Helper
     {
         if (str1.i32 != str2.i32 || str1.i != str2.i)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintS11(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -758,7 +758,7 @@ public class Helper
             str1.b != str2.b || str1.sb != str2.sb || str1.l != str2.l || str1.ul != str2.ul ||
             str1.f != str2.f || str1.d != str2.d)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintU(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -788,7 +788,7 @@ public class Helper
     {
         if (str1.b1 != str2.b1 || str1.b2 != str2.b2)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintByteStructPack2Explicit(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -821,7 +821,7 @@ public class Helper
     {
         if (str1.s1 != str2.s1 || str1.s2 != str2.s2)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintShortStructPack4Explicit(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -854,7 +854,7 @@ public class Helper
     {
         if (str1.i1 != str2.i1 || str1.i2 != str2.i2)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintIntStructPack8Explicit(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -887,7 +887,7 @@ public class Helper
     {
         if (str1.l1 != str2.l1 || str1.l2 != str2.l2)
         {
-            Console.WriteLine("\tFAILED! " + methodName + "did not recieve result as expected.");
+            Console.WriteLine("\tFAILED! " + methodName + "did not receive result as expected.");
             Console.WriteLine("\tThe Actual is...");
             PrintLongStructPack16Explicit(str1, str1.ToString());
             Console.WriteLine("\tThe Expected is...");
@@ -902,4 +902,4 @@ public class Helper
     }
     #endregion
     
-}
\ No newline at end of file
+}
diff --git a/tests/src/JIT/Directed/arglist/CMakeLists.txt b/tests/src/JIT/Directed/arglist/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c627a62
--- /dev/null
@@ -0,0 +1,15 @@
+cmake_minimum_required (VERSION 2.6)
+project (varargnative)
+include_directories(${INC_PLATFORM_DIR})
+
+if(WIN32)
+    add_compile_options(/TC) # compile all files as C
+else()
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+endif()
+
+# add the executable
+add_library (varargnative SHARED varargnative.c)
+
+# add the install targets
+install (TARGETS varargnative DESTINATION bin)
\ No newline at end of file
diff --git a/tests/src/JIT/Directed/arglist/vararg.cs b/tests/src/JIT/Directed/arglist/vararg.cs
new file mode 100644 (file)
index 0000000..18f0a3a
--- /dev/null
@@ -0,0 +1,5028 @@
+// Licensed to the .NET Foundation under one or more 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.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+namespace NativeVarargTest
+{
+    class VarArg
+    {
+        ////////////////////////////////////////////////////////////////////////////
+        // Member Variables
+        ////////////////////////////////////////////////////////////////////////////
+
+        private static int m_testCount;
+        private static int m_passCount;
+        private static int m_failCount;
+
+        ////////////////////////////////////////////////////////////////////////////
+        // Extern Definitions
+        ////////////////////////////////////////////////////////////////////////////
+
+        // printf
+#if WIN32
+        [DllImport("msvcrt", CallingConvention = CallingConvention.Cdecl)]
+        extern static void printf(string str, __arglist);
+#else
+        [DllImport("libc", CallingConvention = CallingConvention.Cdecl)]
+        extern static void printf(string str, __arglist);
+#endif
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static int test_passing_ints(int count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static long test_passing_longs(int count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static float test_passing_floats(int count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static double test_passing_doubles(int count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static long test_passing_int_and_longs(int int_count, int long_count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static double test_passing_floats_and_doubles(int float_count, int double_count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static double test_passing_int_and_double(double expected_value, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static double test_passing_long_and_double(double expected_value, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static double check_passing_four_three_double_struct(ThreeDoubleStruct a, ThreeDoubleStruct b, ThreeDoubleStruct c, ThreeDoubleStruct d, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static int check_passing_struct(int count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static int check_passing_four_sixteen_byte_structs(int count, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static byte echo_byte(byte arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static char echo_char(char arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static short echo_short(short arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static int echo_int(int arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static long echo_int64(long arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static float echo_float(float arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static double echo_double(double arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static OneIntStruct echo_one_int_struct(OneIntStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static TwoIntStruct echo_two_int_struct(TwoIntStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static OneLongStruct echo_one_long_struct(OneLongStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static TwoLongStruct echo_two_long_struct(TwoLongStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static EightByteStruct echo_eight_byte_struct(EightByteStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static FourIntStruct echo_four_int_struct(FourIntStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static FourLongStruct echo_four_long_struct_with_vararg(FourLongStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static FourLongStruct echo_four_long_struct(FourLongStruct arg);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static SixteenByteStruct echo_sixteen_byte_struct(SixteenByteStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static OneFloatStruct echo_one_float_struct(OneFloatStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static TwoFloatStruct echo_two_float_struct(TwoFloatStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static OneDoubleStruct echo_one_double_struct(OneDoubleStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static TwoDoubleStruct echo_two_double_struct(TwoDoubleStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static ThreeDoubleStruct echo_three_double_struct(ThreeDoubleStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static FourFloatStruct echo_four_float_struct(FourFloatStruct arg, __arglist);
+
+        [DllImport("varargnative", CallingConvention = CallingConvention.Cdecl)]
+        extern static FourDoubleStruct echo_four_double_struct(FourDoubleStruct arg, __arglist);
+
+        ////////////////////////////////////////////////////////////////////////////
+        // Test PInvoke, native vararg calls.
+        ////////////////////////////////////////////////////////////////////////////
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingInts(int[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            int expectedSum = test_passing_ints(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            int sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingLongs(long[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            long expectedSum = test_passing_longs(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            long sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingFloats(float[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            float expectedSum = test_passing_floats(expectedValues.Length, __arglist((double)expectedValues[0], (double)expectedValues[1], (double)expectedValues[2], (double)expectedValues[3]));
+
+            float sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingDoubles(double[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            double expectedSum = test_passing_doubles(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyInts(int[] expectedValues)
+        {
+            int expectedSum = test_passing_ints(expectedValues.Length, __arglist());
+
+            int sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyLongs(long[] expectedValues)
+        {
+            long expectedSum = test_passing_longs(expectedValues.Length, __arglist());
+
+            long sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they are
+        /// equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyFloats(float[] expectedValues)
+        {
+            float expectedSum = test_passing_floats(expectedValues.Length, __arglist());
+
+            float sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyDouble(double[] expectedValues)
+        {
+            double expectedSum = test_passing_doubles(expectedValues.Length, __arglist());
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they are
+        /// equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingIntsAndLongs(int[] expectedIntValues, long[] expectedLongValues)
+        {
+            Debug.Assert(expectedIntValues.Length == 2);
+            Debug.Assert(expectedLongValues.Length == 2);
+            long expectedSum = test_passing_int_and_longs(expectedIntValues.Length, expectedLongValues.Length, __arglist(expectedIntValues[0], expectedIntValues[1], expectedLongValues[0], expectedLongValues[1]));
+
+            long sum = 0;
+            for (int i = 0; i < expectedIntValues.Length; ++i)
+            {
+                sum += expectedIntValues[i];
+            }
+
+            for (int i = 0; i < expectedLongValues.Length; ++i)
+            {
+                sum += expectedLongValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingFloatsAndDoubles(float[] expectedFloatValues, double[] expectedDoubleValues)
+        {
+            Debug.Assert(expectedFloatValues.Length == 2);
+            Debug.Assert(expectedDoubleValues.Length == 2);
+            double expectedSum = test_passing_floats_and_doubles(expectedFloatValues.Length, expectedDoubleValues.Length, __arglist((double)expectedFloatValues[0], (double)expectedFloatValues[1], expectedDoubleValues[0], expectedDoubleValues[1]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedFloatValues.Length; ++i)
+            {
+                sum += expectedFloatValues[i];
+            }
+
+            for (int i = 0; i < expectedDoubleValues.Length; ++i)
+            {
+                sum += expectedDoubleValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they are
+        /// equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingIntsAndFloats()
+        {
+            int a = 10;
+            int b = 20;
+            int c = 30;
+
+            double f1 = 1.0;
+            double f2 = 2.0;
+            double f3 = 3.0;
+
+            double expectedSum = 0.0f;
+
+            expectedSum = a + b + c + f1 + f2 + f3;
+
+            double calculatedSum = test_passing_int_and_double(
+                expectedSum,
+                __arglist(
+                    a,
+                    f1,
+                    b,
+                    f2,
+                    c,
+                    f3
+                )
+            );
+
+            return expectedSum == calculatedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingLongsAndDoubles()
+        {
+            long[] expectedIntValues = new long[] { 10, 20, 30 };
+            double[] expectedFloatValues = new double[] { 1.0, 2.0, 3.0 };
+
+            double expectedSum = 0.0f;
+
+            for (int i = 0; i < expectedIntValues.Length; ++i) expectedSum += expectedIntValues[i];
+            for (int i = 0; i < expectedFloatValues.Length; ++i) expectedSum += expectedFloatValues[i];
+
+
+            double calculatedSum = test_passing_long_and_double(
+                expectedSum,
+                __arglist(
+                    expectedIntValues[0],
+                    expectedFloatValues[0],
+                    expectedIntValues[1],
+                    expectedFloatValues[1],
+                    expectedIntValues[2],
+                    expectedFloatValues[2]
+                )
+            );
+
+            return expectedSum == calculatedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyInts(int[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            int expectedSum = test_passing_ints(expectedValues.Length, __arglist(expectedValues[0], 
+                                                                                expectedValues[1], 
+                                                                                expectedValues[2], 
+                                                                                expectedValues[3],
+                                                                                expectedValues[4],
+                                                                                expectedValues[5],
+                                                                                expectedValues[6],
+                                                                                expectedValues[7],
+                                                                                expectedValues[8],
+                                                                                expectedValues[9],
+                                                                                expectedValues[10],
+                                                                                expectedValues[11],
+                                                                                expectedValues[12],
+                                                                                expectedValues[13],
+                                                                                expectedValues[14],
+                                                                                expectedValues[15],
+                                                                                expectedValues[16],
+                                                                                expectedValues[17],
+                                                                                expectedValues[18],
+                                                                                expectedValues[19],
+                                                                                expectedValues[20],
+                                                                                expectedValues[21],
+                                                                                expectedValues[22],
+                                                                                expectedValues[23],
+                                                                                expectedValues[24],
+                                                                                expectedValues[25],
+                                                                                expectedValues[26],
+                                                                                expectedValues[27],
+                                                                                expectedValues[28],
+                                                                                expectedValues[29],
+                                                                                expectedValues[30],
+                                                                                expectedValues[31],
+                                                                                expectedValues[32],
+                                                                                expectedValues[33],
+                                                                                expectedValues[34],
+                                                                                expectedValues[35],
+                                                                                expectedValues[36],
+                                                                                expectedValues[37],
+                                                                                expectedValues[38],
+                                                                                expectedValues[39],
+                                                                                expectedValues[40]));
+
+            int sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyLongs(long[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            long expectedSum = test_passing_longs(expectedValues.Length, __arglist(expectedValues[0],
+                                                                                expectedValues[1],
+                                                                                expectedValues[2],
+                                                                                expectedValues[3],
+                                                                                expectedValues[4],
+                                                                                expectedValues[5],
+                                                                                expectedValues[6],
+                                                                                expectedValues[7],
+                                                                                expectedValues[8],
+                                                                                expectedValues[9],
+                                                                                expectedValues[10],
+                                                                                expectedValues[11],
+                                                                                expectedValues[12],
+                                                                                expectedValues[13],
+                                                                                expectedValues[14],
+                                                                                expectedValues[15],
+                                                                                expectedValues[16],
+                                                                                expectedValues[17],
+                                                                                expectedValues[18],
+                                                                                expectedValues[19],
+                                                                                expectedValues[20],
+                                                                                expectedValues[21],
+                                                                                expectedValues[22],
+                                                                                expectedValues[23],
+                                                                                expectedValues[24],
+                                                                                expectedValues[25],
+                                                                                expectedValues[26],
+                                                                                expectedValues[27],
+                                                                                expectedValues[28],
+                                                                                expectedValues[29],
+                                                                                expectedValues[30],
+                                                                                expectedValues[31],
+                                                                                expectedValues[32],
+                                                                                expectedValues[33],
+                                                                                expectedValues[34],
+                                                                                expectedValues[35],
+                                                                                expectedValues[36],
+                                                                                expectedValues[37],
+                                                                                expectedValues[38],
+                                                                                expectedValues[39],
+                                                                                expectedValues[40]));
+
+            long sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyFloats(double[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            float expectedSum = test_passing_floats(expectedValues.Length, __arglist(expectedValues[0],
+                                                                                     expectedValues[1],
+                                                                                     expectedValues[2],
+                                                                                     expectedValues[3],
+                                                                                     expectedValues[4],
+                                                                                     expectedValues[5],
+                                                                                     expectedValues[6],
+                                                                                     expectedValues[7],
+                                                                                     expectedValues[8],
+                                                                                     expectedValues[9],
+                                                                                     expectedValues[10],
+                                                                                     expectedValues[11],
+                                                                                     expectedValues[12],
+                                                                                     expectedValues[13],
+                                                                                     expectedValues[14],
+                                                                                     expectedValues[15],
+                                                                                     expectedValues[16],
+                                                                                     expectedValues[17],
+                                                                                     expectedValues[18],
+                                                                                     expectedValues[19],
+                                                                                     expectedValues[20],
+                                                                                     expectedValues[21],
+                                                                                     expectedValues[22],
+                                                                                     expectedValues[23],
+                                                                                     expectedValues[24],
+                                                                                     expectedValues[25],
+                                                                                     expectedValues[26],
+                                                                                     expectedValues[27],
+                                                                                     expectedValues[28],
+                                                                                     expectedValues[29],
+                                                                                     expectedValues[30],
+                                                                                     expectedValues[31],
+                                                                                     expectedValues[32],
+                                                                                     expectedValues[33],
+                                                                                     expectedValues[34],
+                                                                                     expectedValues[35],
+                                                                                     expectedValues[36],
+                                                                                     expectedValues[37],
+                                                                                     expectedValues[38],
+                                                                                     expectedValues[39],
+                                                                                     expectedValues[40]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they are
+        /// equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyDoubles(double[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            double expectedSum = test_passing_doubles(expectedValues.Length, __arglist(expectedValues[0],
+                                                                                    expectedValues[1],
+                                                                                    expectedValues[2],
+                                                                                    expectedValues[3],
+                                                                                    expectedValues[4],
+                                                                                    expectedValues[5],
+                                                                                    expectedValues[6],
+                                                                                    expectedValues[7],
+                                                                                    expectedValues[8],
+                                                                                    expectedValues[9],
+                                                                                    expectedValues[10],
+                                                                                    expectedValues[11],
+                                                                                    expectedValues[12],
+                                                                                    expectedValues[13],
+                                                                                    expectedValues[14],
+                                                                                    expectedValues[15],
+                                                                                    expectedValues[16],
+                                                                                    expectedValues[17],
+                                                                                    expectedValues[18],
+                                                                                    expectedValues[19],
+                                                                                    expectedValues[20],
+                                                                                    expectedValues[21],
+                                                                                    expectedValues[22],
+                                                                                    expectedValues[23],
+                                                                                    expectedValues[24],
+                                                                                    expectedValues[25],
+                                                                                    expectedValues[26],
+                                                                                    expectedValues[27],
+                                                                                    expectedValues[28],
+                                                                                    expectedValues[29],
+                                                                                    expectedValues[30],
+                                                                                    expectedValues[31],
+                                                                                    expectedValues[32],
+                                                                                    expectedValues[33],
+                                                                                    expectedValues[34],
+                                                                                    expectedValues[35],
+                                                                                    expectedValues[36],
+                                                                                    expectedValues[37],
+                                                                                    expectedValues[38],
+                                                                                    expectedValues[39],
+                                                                                    expectedValues[40]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// This function will test passing struct through varargs.
+        /// 
+        /// </summary>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingStructs()
+        {
+            int success = 100;
+
+            success = ReportFailure(TestPassingEightByteStructs(), "TestPassingEightByteStructs()", success, TestPassingEightByteStructs());
+            success = ReportFailure(TestPassingSixteenByteStructs(), "TestPassingSixteenByteStructs()", success, TestPassingSixteenByteStructs());
+            success = ReportFailure(TestPassingThirtyTwoByteStructs(), "TestPassingThirtyTwoByteStructs()", success, TestPassingThirtyTwoByteStructs());
+            success = ReportFailure(TestFour16ByteStructs(), "TestFour16ByteStructs()", success, TestFour16ByteStructs());
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingEightByteStructs()
+        {
+            int success = 100;
+
+            TwoIntStruct first = new TwoIntStruct();
+            OneLongStruct second = new OneLongStruct();
+            TwoFloatStruct third = new TwoFloatStruct();
+            OneDoubleStruct fourth = new OneDoubleStruct();
+
+            first.a = 20;
+            first.b = -8;
+
+            second.a = 4020120;
+
+            third.a = 10.223f;
+            third.b = 10331.1f;
+
+            fourth.a = 120.1321321;
+
+            int firstExpectedValue = first.a + first.b;
+            long secondExpectedValue = second.a;
+            double thirdExpectedValue = third.a + third.b;
+            double fourthExpectedValue = fourth.a;
+
+            success = ReportFailure(check_passing_struct(6, __arglist(0, 0, 0, 8, 1, firstExpectedValue, first)) == 0, "check_passing_struct(6, __arglist(0, 0, 0, 8, 1, firstExpectedValue, first)) == 0", success, 16);
+            success = ReportFailure(check_passing_struct(6, __arglist(1, 0, 0, 8, 1, secondExpectedValue, second)) == 0, "check_passing_struct(6, __arglist(1, 0, 0, 8, 1, secondExpectedValue, second)) == 0", success, 17);
+            success = ReportFailure(check_passing_struct(6, __arglist(0, 1, 0, 8, 1, thirdExpectedValue, third)) == 0, "check_passing_struct(6, __arglist(0, 1, 0, 8, 1, thirdExpectedValue, third)) == 0", success, 18);
+            success = ReportFailure(check_passing_struct(6, __arglist(1, 1, 0, 8, 1, fourthExpectedValue, fourth)) == 0, "check_passing_struct(6, __arglist(1, 1, 0, 8, 1, fourthExpectedValue, fourth)) == 0", success, 19);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingSixteenByteStructs()
+        {
+            int success = 100;
+
+            TwoLongStruct first = new TwoLongStruct();
+            FourIntStruct second = new FourIntStruct();
+            TwoDoubleStruct third = new TwoDoubleStruct();
+            FourFloatStruct fourth = new FourFloatStruct();
+
+            first.a = 30;
+            first.b = -20;
+
+            second.a = 10;
+            second.b = 50;
+            second.c = 80;
+            second.b = 12000;
+
+            third.a = 10.223;
+            third.b = 10331.1;
+
+            fourth.a = 1.0f;
+            fourth.b = 2.0f;
+            fourth.c = 3.0f;
+            fourth.d = 4.0f;
+
+            long firstExpectedValue = first.a + first.b;
+            long secondExpectedValue = second.a + second.b + second.c + second.d;
+            double thirdExpectedValue = third.a + third.b;
+            double fourthExpectedValue = fourth.a + fourth.b + fourth.c + fourth.d;
+
+            success = ReportFailure(check_passing_struct(6, __arglist(0, 0, 0, 16, 1, firstExpectedValue, first)) == 0, "check_passing_struct(6, __arglist(0, 0, 0, 16, 1, firstExpectedValue, first)) == 0", success, 20);
+            success = ReportFailure(check_passing_struct(6, __arglist(1, 0, 0, 16, 1, secondExpectedValue, second)) == 0, "check_passing_struct(6, __arglist(1, 0, 0, 16, 1, secondExpectedValue, second)) == 0", success, 21);
+            success = ReportFailure(check_passing_struct(6, __arglist(0, 1, 0, 16, 1, thirdExpectedValue, third)) == 0, "check_passing_struct(6, __arglist(0, 1, 0, 16, 1, thirdExpectedValue, third)) == 0", success, 22);
+            success = ReportFailure(check_passing_struct(6, __arglist(1, 1, 0, 16, 1, fourthExpectedValue, fourth)) == 0, "check_passing_struct(6, __arglist(1, 1, 0, 16, 1, fourthExpectedValue, fourth)) == 0", success, 23);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingTwentyFourByteStructs()
+        {
+            int success = 100;
+
+            ThreeDoubleStruct first = new ThreeDoubleStruct();
+            ThreeDoubleStruct second = new ThreeDoubleStruct();
+            ThreeDoubleStruct third = new ThreeDoubleStruct();
+            ThreeDoubleStruct fourth = new ThreeDoubleStruct();
+            
+            first.a = 1.0;
+            first.b = 2.0;
+            first.c = 3.0;
+
+            second.a = 4.0;
+            second.b = 5.0;
+            second.c = 6.0;
+
+            third.a = 7.0;
+            third.b = 8.0;
+            third.c = 9.0;
+
+            fourth.a = 10.0;
+            fourth.b = 11.0;
+            fourth.c = 12.0;
+
+            double expectedSum = first.a + first.b + first.c;
+            expectedSum += second.a + second.b + second.c;
+            expectedSum += third.a + third.b + third.c;
+            expectedSum += fourth.a + fourth.b + fourth.c;
+
+            success = ReportFailure(expectedSum == check_passing_four_three_double_struct(first, second, third, fourth, __arglist()), "check_passing_four_three_double_struct(first, second, third, fourth)", success, 84);
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingThirtyTwoByteStructs()
+        {
+            int success = 100;
+
+            FourLongStruct first = new FourLongStruct();
+            FourDoubleStruct second = new FourDoubleStruct();
+
+            first.a = 20241231;
+            first.b = -8213123;
+            first.c = 1202;
+            first.c = 1231;
+
+            second.a = 10.102;
+            second.b = 50.55;
+            second.c = 80.341;
+            second.b = 12000.00000000001;
+
+            long firstExpectedValue = first.a + first.b + first.c + first.d;
+            double secondExpectedValue = second.a + second.b + second.c + second.d;
+
+            success = ReportFailure(check_passing_struct(6, __arglist(0, 0, 0, 32, 1, firstExpectedValue, first)) == 0, "check_passing_struct(6, __arglist(0, 0, 0, 32, 1, firstExpectedValue, first)) == 0", success, 24);
+            success = ReportFailure(check_passing_struct(6, __arglist(0, 1, 0, 32, 1, secondExpectedValue, second)) == 0, "check_passing_struct(6, __arglist(0, 1, 0, 32, 1, secondExpectedValue, second)) == 0", success, 25);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestMany16ByteStructs()
+        {
+            int success = 100;
+
+            TwoIntStruct s = new TwoIntStruct();
+
+            s.a = 30;
+            s.b = -20;
+
+            long expectedValue = (s.a + s.b) * 5;
+
+            success = ReportFailure(check_passing_struct(11, __arglist(0, 0, 0, 16, 5, expectedValue, s, s, s, s, s)) == 0, "check_passing_struct(11, __arglist(0, 0, 0, 16, 5, expectedValue, s, s, s, s, s)) == 0", success, 26);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestFour16ByteStructs()
+        {
+            int success = 100;
+
+            TwoLongStruct s = new TwoLongStruct();
+            TwoLongStruct s2 = new TwoLongStruct();
+            TwoLongStruct s3 = new TwoLongStruct();
+            TwoLongStruct s4 = new TwoLongStruct();
+
+            s.a = 1;
+            s.b = 2;
+
+            s2.a = 3;
+            s2.b = 4;
+
+            s3.a = 5;
+            s3.b = 6;
+
+            s4.a = 7;
+            s4.b = 8;
+
+            long expectedValue = s.a + s.b + s2.a + s2.b + s3.a + s3.b + s4.a + s4.b;
+            success = ReportFailure(check_passing_four_sixteen_byte_structs(5, __arglist(expectedValue, s, s2, s3, s4)) == 0, "check_passing_four_sixteen_byte_structs(5, __arglist(expectedValue, s, s2, s3, s4)) == 0", success, 27);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestMany32ByteStructs()
+        {
+            int success = 100;
+
+            FourLongStruct s = new FourLongStruct();
+
+            s.a = 30;
+            s.b = -20;
+            s.c = 100;
+            s.d = 200;
+
+            long expectedValue = (s.a + s.b + s.c + s.d) * 5;
+            success = ReportFailure(check_passing_struct(11, __arglist(0, 0, 0, 32, 5, expectedValue, s, s, s, s, s)) == 0, "check_passing_struct(11, __arglist(0, 0, 0, 32, 5, expectedValue, s, s, s, s, s)) == 0", success, 28);
+
+            return success;
+        }
+
+        ////////////////////////////////////////////////////////////////////////////
+        // Test ArgIterator, managed to managed native vararg calls.
+        ////////////////////////////////////////////////////////////////////////////
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingIntsManaged(int[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            int expectedSum = ManagedNativeVarargTests.TestPassingInts(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            int sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingLongsManaged(long[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            long expectedSum = ManagedNativeVarargTests.TestPassingLongs(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            long sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingFloatsManaged(float[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            float expectedSum = ManagedNativeVarargTests.TestPassingFloats(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            float sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingDoublesManaged(double[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 4);
+            double expectedSum = ManagedNativeVarargTests.TestPassingDoubles(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyIntsManaged(int[] expectedValues)
+        {
+            int expectedSum = ManagedNativeVarargTests.TestPassingInts(expectedValues.Length, __arglist());
+
+            int sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyLongsManaged(long[] expectedValues)
+        {
+            long expectedSum = ManagedNativeVarargTests.TestPassingLongs(expectedValues.Length, __arglist());
+
+            long sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyFloatsManaged(float[] expectedValues)
+        {
+            float expectedSum = ManagedNativeVarargTests.TestPassingFloats(expectedValues.Length, __arglist());
+
+            float sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they are
+        /// equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingEmptyDoubleManaged(double[] expectedValues)
+        {
+            double expectedSum = ManagedNativeVarargTests.TestPassingDoubles(expectedValues.Length, __arglist());
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingIntsAndLongsManaged(int[] expectedIntValues, long[] expectedLongValues)
+        {
+            Debug.Assert(expectedIntValues.Length == 2);
+            Debug.Assert(expectedLongValues.Length == 2);
+            long expectedSum = ManagedNativeVarargTests.TestPassingIntsAndLongs(expectedIntValues.Length, expectedLongValues.Length, __arglist(expectedIntValues[0], expectedIntValues[1], expectedLongValues[0], expectedLongValues[1]));
+
+            long sum = 0;
+            for (int i = 0; i < expectedIntValues.Length; ++i)
+            {
+                sum += expectedIntValues[i];
+            }
+
+            for (int i = 0; i < expectedLongValues.Length; ++i)
+            {
+                sum += expectedLongValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingFloatsAndDoublesManaged(float[] expectedFloatValues, double[] expectedDoubleValues)
+        {
+            Debug.Assert(expectedFloatValues.Length == 2);
+            Debug.Assert(expectedDoubleValues.Length == 2);
+            double expectedSum = ManagedNativeVarargTests.TestPassingFloatsAndDoubles(expectedFloatValues.Length, expectedDoubleValues.Length, __arglist(expectedFloatValues[0], expectedFloatValues[1], expectedDoubleValues[0], expectedDoubleValues[1]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedFloatValues.Length; ++i)
+            {
+                sum += expectedFloatValues[i];
+            }
+
+            for (int i = 0; i < expectedDoubleValues.Length; ++i)
+            {
+                sum += expectedDoubleValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingIntsAndFloatsManaged()
+        {
+            int a = 10;
+            int b = 20;
+            int c = 30;
+
+            float f1 = 1.0f;
+            float f2 = 2.0f;
+            float f3 = 3.0f;
+
+            float expectedSum = 0.0f;
+
+            expectedSum = a + b + c + f1 + f2 + f3;
+
+            float calculatedSum = ManagedNativeVarargTests.TestPassingIntsAndFloats(
+                expectedSum,
+                __arglist(
+                    a,
+                    f1,
+                    b,
+                    f2,
+                    c,
+                    f3
+                )
+            );
+
+            return expectedSum == calculatedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingLongsAndDoublesManaged()
+        {
+            long[] expectedIntValues = new long[] { 10, 20, 30 };
+            double[] expectedFloatValues = new double[] { 1.0, 2.0, 3.0 };
+
+            double expectedSum = 0.0f;
+
+            for (int i = 0; i < expectedIntValues.Length; ++i) expectedSum += expectedIntValues[i];
+            for (int i = 0; i < expectedFloatValues.Length; ++i) expectedSum += expectedFloatValues[i];
+
+
+            double calculatedSum = ManagedNativeVarargTests.TestPassingLongsAndDoubles(
+                expectedSum,
+                __arglist(
+                    expectedIntValues[0],
+                    expectedFloatValues[0],
+                    expectedIntValues[1],
+                    expectedFloatValues[1],
+                    expectedIntValues[2],
+                    expectedFloatValues[2]
+                )
+            );
+
+            return expectedSum == calculatedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyIntsManaged(int[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            int expectedSum = ManagedNativeVarargTests.TestPassingInts(expectedValues.Length, __arglist(expectedValues[0], 
+                                                                                                        expectedValues[1], 
+                                                                                                        expectedValues[2], 
+                                                                                                        expectedValues[3],
+                                                                                                        expectedValues[4],
+                                                                                                        expectedValues[5],
+                                                                                                        expectedValues[6],
+                                                                                                        expectedValues[7],
+                                                                                                        expectedValues[8],
+                                                                                                        expectedValues[9],
+                                                                                                        expectedValues[10],
+                                                                                                        expectedValues[11],
+                                                                                                        expectedValues[12],
+                                                                                                        expectedValues[13],
+                                                                                                        expectedValues[14],
+                                                                                                        expectedValues[15],
+                                                                                                        expectedValues[16],
+                                                                                                        expectedValues[17],
+                                                                                                        expectedValues[18],
+                                                                                                        expectedValues[19],
+                                                                                                        expectedValues[20],
+                                                                                                        expectedValues[21],
+                                                                                                        expectedValues[22],
+                                                                                                        expectedValues[23],
+                                                                                                        expectedValues[24],
+                                                                                                        expectedValues[25],
+                                                                                                        expectedValues[26],
+                                                                                                        expectedValues[27],
+                                                                                                        expectedValues[28],
+                                                                                                        expectedValues[29],
+                                                                                                        expectedValues[30],
+                                                                                                        expectedValues[31],
+                                                                                                        expectedValues[32],
+                                                                                                        expectedValues[33],
+                                                                                                        expectedValues[34],
+                                                                                                        expectedValues[35],
+                                                                                                        expectedValues[36],
+                                                                                                        expectedValues[37],
+                                                                                                        expectedValues[38],
+                                                                                                        expectedValues[39],
+                                                                                                        expectedValues[40]));
+
+            int sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyLongsManaged(long[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            long expectedSum = ManagedNativeVarargTests.TestPassingLongs(expectedValues.Length, __arglist(expectedValues[0],
+                                                                                                          expectedValues[1],
+                                                                                                          expectedValues[2],
+                                                                                                          expectedValues[3],
+                                                                                                          expectedValues[4],
+                                                                                                          expectedValues[5],
+                                                                                                          expectedValues[6],
+                                                                                                          expectedValues[7],
+                                                                                                          expectedValues[8],
+                                                                                                          expectedValues[9],
+                                                                                                          expectedValues[10],
+                                                                                                          expectedValues[11],
+                                                                                                          expectedValues[12],
+                                                                                                          expectedValues[13],
+                                                                                                          expectedValues[14],
+                                                                                                          expectedValues[15],
+                                                                                                          expectedValues[16],
+                                                                                                          expectedValues[17],
+                                                                                                          expectedValues[18],
+                                                                                                          expectedValues[19],
+                                                                                                          expectedValues[20],
+                                                                                                          expectedValues[21],
+                                                                                                          expectedValues[22],
+                                                                                                          expectedValues[23],
+                                                                                                          expectedValues[24],
+                                                                                                          expectedValues[25],
+                                                                                                          expectedValues[26],
+                                                                                                          expectedValues[27],
+                                                                                                          expectedValues[28],
+                                                                                                          expectedValues[29],
+                                                                                                          expectedValues[30],
+                                                                                                          expectedValues[31],
+                                                                                                          expectedValues[32],
+                                                                                                          expectedValues[33],
+                                                                                                          expectedValues[34],
+                                                                                                          expectedValues[35],
+                                                                                                          expectedValues[36],
+                                                                                                          expectedValues[37],
+                                                                                                          expectedValues[38],
+                                                                                                          expectedValues[39],
+                                                                                                          expectedValues[40]));
+
+            long sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyFloatsManaged(float[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            float expectedSum = ManagedNativeVarargTests.TestPassingFloats(expectedValues.Length, __arglist(expectedValues[0],
+                                                                                                            expectedValues[1],
+                                                                                                            expectedValues[2],
+                                                                                                            expectedValues[3],
+                                                                                                            expectedValues[4],
+                                                                                                            expectedValues[5],
+                                                                                                            expectedValues[6],
+                                                                                                            expectedValues[7],
+                                                                                                            expectedValues[8],
+                                                                                                            expectedValues[9],
+                                                                                                            expectedValues[10],
+                                                                                                            expectedValues[11],
+                                                                                                            expectedValues[12],
+                                                                                                            expectedValues[13],
+                                                                                                            expectedValues[14],
+                                                                                                            expectedValues[15],
+                                                                                                            expectedValues[16],
+                                                                                                            expectedValues[17],
+                                                                                                            expectedValues[18],
+                                                                                                            expectedValues[19],
+                                                                                                            expectedValues[20],
+                                                                                                            expectedValues[21],
+                                                                                                            expectedValues[22],
+                                                                                                            expectedValues[23],
+                                                                                                            expectedValues[24],
+                                                                                                            expectedValues[25],
+                                                                                                            expectedValues[26],
+                                                                                                            expectedValues[27],
+                                                                                                            expectedValues[28],
+                                                                                                            expectedValues[29],
+                                                                                                            expectedValues[30],
+                                                                                                            expectedValues[31],
+                                                                                                            expectedValues[32],
+                                                                                                            expectedValues[33],
+                                                                                                            expectedValues[34],
+                                                                                                            expectedValues[35],
+                                                                                                            expectedValues[36],
+                                                                                                            expectedValues[37],
+                                                                                                            expectedValues[38],
+                                                                                                            expectedValues[39],
+                                                                                                            expectedValues[40]));
+
+            float sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// The callee will simply loop over the arguments, compute the sum
+        /// then return the value.
+        /// 
+        /// Do a quick check on the value returned, and return whether they 
+        /// are equal.
+        /// 
+        /// Notes:
+        /// 
+        /// This is a particularily interesting test case because on every platform it
+        /// will force spilling locals to the stack instead of just passing in registers.
+        /// 
+        /// </summary>
+        /// <param name="expectedValues"></param>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestPassingManyDoublesManaged(double[] expectedValues)
+        {
+            Debug.Assert(expectedValues.Length == 41);
+            double expectedSum = ManagedNativeVarargTests.TestPassingDoubles(expectedValues.Length, __arglist(expectedValues[0],
+                                                                                                              expectedValues[1],
+                                                                                                              expectedValues[2],
+                                                                                                              expectedValues[3],
+                                                                                                              expectedValues[4],
+                                                                                                              expectedValues[5],
+                                                                                                              expectedValues[6],
+                                                                                                              expectedValues[7],
+                                                                                                              expectedValues[8],
+                                                                                                              expectedValues[9],
+                                                                                                              expectedValues[10],
+                                                                                                              expectedValues[11],
+                                                                                                              expectedValues[12],
+                                                                                                              expectedValues[13],
+                                                                                                              expectedValues[14],
+                                                                                                              expectedValues[15],
+                                                                                                              expectedValues[16],
+                                                                                                              expectedValues[17],
+                                                                                                              expectedValues[18],
+                                                                                                              expectedValues[19],
+                                                                                                              expectedValues[20],
+                                                                                                              expectedValues[21],
+                                                                                                              expectedValues[22],
+                                                                                                              expectedValues[23],
+                                                                                                              expectedValues[24],
+                                                                                                              expectedValues[25],
+                                                                                                              expectedValues[26],
+                                                                                                              expectedValues[27],
+                                                                                                              expectedValues[28],
+                                                                                                              expectedValues[29],
+                                                                                                              expectedValues[30],
+                                                                                                              expectedValues[31],
+                                                                                                              expectedValues[32],
+                                                                                                              expectedValues[33],
+                                                                                                              expectedValues[34],
+                                                                                                              expectedValues[35],
+                                                                                                              expectedValues[36],
+                                                                                                              expectedValues[37],
+                                                                                                              expectedValues[38],
+                                                                                                              expectedValues[39],
+                                                                                                              expectedValues[40]));
+
+            double sum = 0;
+            for (int i = 0; i < expectedValues.Length; ++i)
+            {
+                sum += expectedValues[i];
+            }
+
+            return sum == expectedSum;
+        }
+
+        /// <summary>
+        /// Given an input set create an arglist to pass to a vararg callee.
+        /// 
+        /// This function will test passing struct through varargs.
+        /// 
+        /// </summary>
+        /// <returns>bool</returns>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingStructsManaged()
+        {
+            int success = 100;
+
+            success = ReportFailure(TestPassingEightByteStructsManaged(), "TestPassingEightByteStructsManaged()", success, TestPassingEightByteStructsManaged());
+            success = ReportFailure(TestPassingSixteenByteStructsManaged(), "TestPassingSixteenByteStructsManaged()", success, TestPassingSixteenByteStructsManaged());
+            success = ReportFailure(TestPassingThirtyTwoByteStructsManaged(), "TestPassingThirtyTwoByteStructsManaged()", success, TestPassingThirtyTwoByteStructsManaged());
+            success = ReportFailure(TestFour16ByteStructsManaged(), "TestFour16ByteStructsManaged()", success, TestFour16ByteStructsManaged());
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructsManaged
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingEightByteStructsManaged()
+        {
+            int success = 100;
+
+            TwoIntStruct first = new TwoIntStruct();
+            OneLongStruct second = new OneLongStruct();
+            TwoFloatStruct third = new TwoFloatStruct();
+            OneDoubleStruct fourth = new OneDoubleStruct();
+
+            first.a = 20;
+            first.b = -8;
+
+            second.a = 4020120;
+
+            third.a = 1.0f;
+            third.b = 2.0f;
+
+            fourth.a = 1.0;
+
+            int firstExpectedValue = first.a + first.b;
+            long secondExpectedValue = second.a;
+            float thirdExpectedValue = third.a + third.b;
+            double fourthExpectedValue = fourth.a;
+
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 0, 0, 8, 1, firstExpectedValue, first)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 0, 0, 8, 1, firstExpectedValue, first)) == 0", success, 46);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 0, 0, 8, 1, secondExpectedValue, second)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 0, 0, 8, 1, secondExpectedValue, second)) == 0", success, 47);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 1, 0, 8, 1, thirdExpectedValue, third)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 1, 0, 8, 1, thirdExpectedValue, third)) == 0", success, 48);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 1, 0, 8, 1, fourthExpectedValue, fourth)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 1, 0, 8, 1, fourthExpectedValue, fourth)) == 0", success, 49);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructsManaged
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingSixteenByteStructsManaged()
+        {
+            int success = 100;
+
+            TwoLongStruct first = new TwoLongStruct();
+            FourIntStruct second = new FourIntStruct();
+            TwoDoubleStruct third = new TwoDoubleStruct();
+            FourFloatStruct fourth = new FourFloatStruct();
+
+            first.a = 30;
+            first.b = -20;
+
+            second.a = 10;
+            second.b = 50;
+            second.c = 80;
+            second.b = 12000;
+
+            third.a = 10.223;
+            third.b = 10331.1;
+
+            fourth.a = 1.0f;
+            fourth.b = 2.0f;
+            fourth.c = 3.0f;
+            fourth.d = 4.0f;
+
+            long firstExpectedValue = first.a + first.b;
+            int secondExpectedValue = second.a + second.b + second.c + second.d;
+            double thirdExpectedValue = third.a + third.b;
+            float fourthExpectedValue = fourth.a + fourth.b + fourth.c + fourth.d;
+
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 0, 0, 16, 1, firstExpectedValue, first)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 0, 0, 16, 1, firstExpectedValue, first)) == 0", success, 50);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 0, 0, 16, 1, secondExpectedValue, second)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 0, 0, 16, 1, secondExpectedValue, second)) == 0", success, 51);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 1, 0, 16, 1, thirdExpectedValue, third)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 1, 0, 16, 1, thirdExpectedValue, third)) == 0", success, 52);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 1, 0, 16, 1, fourthExpectedValue, fourth)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(1, 1, 0, 16, 1, fourthExpectedValue, fourth)) == 0", success, 53);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructsManaged
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestPassingThirtyTwoByteStructsManaged()
+        {
+            int success = 100;
+
+            FourLongStruct first = new FourLongStruct();
+            FourDoubleStruct second = new FourDoubleStruct();
+
+            first.a = 20241231;
+            first.b = -8213123;
+            first.c = 1202;
+            first.c = 1231;
+
+            second.a = 10.102;
+            second.b = 50.55;
+            second.c = 80.341;
+            second.b = 12000.00000000001;
+
+            long firstExpectedValue = first.a + first.b + first.c + first.d;
+            double secondExpectedValue = second.a + second.b + second.c + second.d;
+
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 0, 0, 32, 1, firstExpectedValue, first)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 0, 0, 32, 1, firstExpectedValue, first)) == 0", success, 54);
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 1, 0, 32, 1, secondExpectedValue, second)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(6, __arglist(0, 1, 0, 32, 1, secondExpectedValue, second)) == 0", success, 55);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructsManaged
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestMany16ByteStructsManaged()
+        {
+            int success = 100;
+
+            TwoLongStruct s = new TwoLongStruct();
+
+            s.a = 30;
+            s.b = -20;
+
+            long expectedValue = (s.a + s.b) * 5;
+
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(11, __arglist(0, 0, 0, 16, 5, expectedValue, s, s, s, s, s)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(11, __arglist(0, 0, 0, 16, 5, expectedValue, s, s, s, s, s)) == 0", success, 56);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructsManaged
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestFour16ByteStructsManaged()
+        {
+            int success = 100;
+
+            TwoLongStruct s = new TwoLongStruct();
+            TwoLongStruct s2 = new TwoLongStruct();
+            TwoLongStruct s3 = new TwoLongStruct();
+            TwoLongStruct s4 = new TwoLongStruct();
+
+            s.a = 1;
+            s.b = 2;
+
+            s2.a = 3;
+            s2.b = 4;
+
+            s3.a = 5;
+            s3.b = 6;
+
+            s4.a = 7;
+            s4.b = 8;
+
+            long expectedValue = s.a + s.b + s2.a + s2.b + s3.a + s3.b + s4.a + s4.b;
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingFourSixteenByteStructs(5, __arglist(expectedValue, s, s2, s3, s4)) == 0, "ManagedNativeVarargTests.CheckPassingFourSixteenByteStructs(5, __arglist(expectedValue, s, s2, s3, s4)) == 0", success, 57);
+
+            return success;
+        }
+
+        /// <summary>
+        /// This is a helper for TestPassingStructsManaged
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int TestMany32ByteStructsManaged()
+        {
+            int success = 100;
+
+            FourLongStruct s = new FourLongStruct();
+
+            s.a = 30;
+            s.b = -20;
+            s.c = 100;
+            s.d = 200;
+
+            long expectedValue = (s.a + s.b + s.c + s.d) * 5;
+
+            success = ReportFailure(ManagedNativeVarargTests.CheckPassingStruct(11, __arglist(0, 0, 0, 32, 5, expectedValue, s, s, s, s, s)) == 0, "ManagedNativeVarargTests.CheckPassingStruct(11, __arglist(0, 0, 0, 32, 5, expectedValue, s, s, s, s, s)) == 0", success, 58);
+
+            return success;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingIntsNoVarargsManaged()
+        {
+            int sum = ManagedNativeVarargTests.TestPassingIntsNoVarargs(1,
+                                                                        2,
+                                                                        3,
+                                                                        4,
+                                                                        5,
+                                                                        6,
+                                                                        7,
+                                                                        8,
+                                                                        9,
+                                                                        __arglist());
+
+            return sum == 45;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingLongsNoVarargsManaged()
+        {
+            long sum = ManagedNativeVarargTests.TestPassingLongsNoVarargs(1,
+                                                                          2,
+                                                                          3,
+                                                                          4,
+                                                                          5,
+                                                                          6,
+                                                                          7,
+                                                                          8,
+                                                                          9,
+                                                                          __arglist());
+
+            return sum == 45;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFloatsNoVarargsManaged()
+        {
+            float sum = ManagedNativeVarargTests.TestPassingFloatsNoVarargs(1.0f,
+                                                                            2.0f,
+                                                                            3.0f,
+                                                                            4.0f,
+                                                                            5.0f,
+                                                                            6.0f,
+                                                                            7.0f,
+                                                                            8.0f,
+                                                                            9.0f,
+                                                                            __arglist());
+
+            return sum == 45.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingDoublesNoVarargsManaged()
+        {
+            double sum = ManagedNativeVarargTests.TestPassingDoublesNoVarargs(1.0,
+                                                                              2.0,
+                                                                              3.0,
+                                                                              4.0,
+                                                                              5.0,
+                                                                              6.0,
+                                                                              7.0,
+                                                                              8.0,
+                                                                              9.0,
+                                                                              __arglist());
+            
+            return sum == 45.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingIntAndFloatsNoVarargsManaged()
+        {
+            float sum = ManagedNativeVarargTests.TestPassingIntAndFloatsNoVarargs(1,
+                                                                                  2,
+                                                                                  3,
+                                                                                  4,
+                                                                                  5,
+                                                                                  6,
+                                                                                  7,
+                                                                                  8,
+                                                                                  9,
+                                                                                  10.0f,
+                                                                                  11.0f,
+                                                                                  12.0f,
+                                                                                  13.0f,
+                                                                                  14.0f,
+                                                                                  15.0f,
+                                                                                  16.0f,
+                                                                                  17.0f,
+                                                                                  18.0f,
+                                                                                  __arglist());
+
+            return sum == 171.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFloatsAndIntNoVarargsManaged()
+        {
+            float sum = ManagedNativeVarargTests.TestPassingFloatsAndIntNoVarargs(1.0f,
+                                                                                  2.0f,
+                                                                                  3.0f,
+                                                                                  4.0f,
+                                                                                  5.0f,
+                                                                                  6.0f,
+                                                                                  7.0f,
+                                                                                  8.0f,
+                                                                                  9.0f,
+                                                                                  10,
+                                                                                  11,
+                                                                                  12,
+                                                                                  13,
+                                                                                  14,
+                                                                                  15,
+                                                                                  16,
+                                                                                  17,
+                                                                                  18,
+                                                                                  __arglist());
+
+            return sum == 171.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingIntAndDoublesNoVarargsManaged()
+        {
+            double sum = ManagedNativeVarargTests.TestPassingIntAndDoublesNoVarargs(1,
+                                                                                    2,
+                                                                                    3,
+                                                                                    4,
+                                                                                    5,
+                                                                                    6,
+                                                                                    7,
+                                                                                    8,
+                                                                                    9,
+                                                                                    10.0,
+                                                                                    11.0,
+                                                                                    12.0,
+                                                                                    13.0,
+                                                                                    14.0,
+                                                                                    15.0,
+                                                                                    16.0,
+                                                                                    17.0,
+                                                                                    18.0,
+                                                                                    __arglist());
+
+            return sum == 171.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingDoublesAndIntNoVarargsManaged()
+        {
+            double sum = ManagedNativeVarargTests.TestPassingDoublesAndIntNoVarargs(1.0,
+                                                                                    2.0,
+                                                                                    3.0,
+                                                                                    4.0,
+                                                                                    5.0,
+                                                                                    6.0,
+                                                                                    7.0,
+                                                                                    8.0,
+                                                                                    9.0,
+                                                                                    10,
+                                                                                    11,
+                                                                                    12,
+                                                                                    13,
+                                                                                    14,
+                                                                                    15,
+                                                                                    16,
+                                                                                    17,
+                                                                                    18,
+                                                                                    __arglist());
+
+            return sum == 171.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingLongAndFloatsNoVarargsManaged()
+        {
+            float sum = ManagedNativeVarargTests.TestPassingLongAndFloatsNoVarargs(1,
+                                                                                   2,
+                                                                                   3,
+                                                                                   4,
+                                                                                   5,
+                                                                                   6,
+                                                                                   7,
+                                                                                   8,
+                                                                                   9,
+                                                                                   10.0f,
+                                                                                   11.0f,
+                                                                                   12.0f,
+                                                                                   13.0f,
+                                                                                   14.0f,
+                                                                                   15.0f,
+                                                                                   16.0f,
+                                                                                   17.0f,
+                                                                                   18.0f,
+                                                                                   __arglist());
+
+            return sum == 171.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFloatsAndlongNoVarargsManaged()
+        {
+            float sum = ManagedNativeVarargTests.TestPassingFloatsAndlongNoVarargs(1.0f,
+                                                                                   2.0f,
+                                                                                   3.0f,
+                                                                                   4.0f,
+                                                                                   5.0f,
+                                                                                   6.0f,
+                                                                                   7.0f,
+                                                                                   8.0f,
+                                                                                   9.0f,
+                                                                                   10,
+                                                                                   11,
+                                                                                   12,
+                                                                                   13,
+                                                                                   14,
+                                                                                   15,
+                                                                                   16,
+                                                                                   17,
+                                                                                   18,
+                                                                                   __arglist());
+
+
+            return sum == 171.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassinglongAndDoublesNoVarargsManaged()
+        {
+            double sum = ManagedNativeVarargTests.TestPassinglongAndDoublesNoVarargs(1,
+                                                                                     2,
+                                                                                     3,
+                                                                                     4,
+                                                                                     5,
+                                                                                     6,
+                                                                                     7,
+                                                                                     8,
+                                                                                     9,
+                                                                                     10.0,
+                                                                                     11.0,
+                                                                                     12.0,
+                                                                                     13.0,
+                                                                                     14.0,
+                                                                                     15.0,
+                                                                                     16.0,
+                                                                                     17.0,
+                                                                                     18.0,
+                                                                                     __arglist());
+
+            return sum == 171.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingDoublesAndlongNoVarargsManaged()
+        {
+            double sum = ManagedNativeVarargTests.TestPassingDoublesAndlongNoVarargs(1.0,
+                                                                                     2.0,
+                                                                                     3.0,
+                                                                                     4.0,
+                                                                                     5.0,
+                                                                                     6.0,
+                                                                                     7.0,
+                                                                                     8.0,
+                                                                                     9.0,
+                                                                                     10,
+                                                                                     11,
+                                                                                     12,
+                                                                                     13,
+                                                                                     14,
+                                                                                     15,
+                                                                                     16,
+                                                                                     17,
+                                                                                     18,
+                                                                                     __arglist());
+
+            return sum == 171.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoIntStructsNoVarargsManaged()
+        {
+            TwoIntStruct one = new TwoIntStruct();
+            TwoIntStruct two = new TwoIntStruct();
+            TwoIntStruct three = new TwoIntStruct();
+            TwoIntStruct four = new TwoIntStruct();
+            TwoIntStruct five = new TwoIntStruct();
+            TwoIntStruct six = new TwoIntStruct();
+            TwoIntStruct seven = new TwoIntStruct();
+            TwoIntStruct eight = new TwoIntStruct();
+            TwoIntStruct nine = new TwoIntStruct();
+            TwoIntStruct ten = new TwoIntStruct();
+
+            one.a = 1;
+            one.b = 2;
+
+            two.a = 3;
+            two.b = 4;
+
+            
+            three.a = 5;
+            three.b = 6;
+
+            four.a = 7;
+            four.b = 8;
+
+            five.a = 9;
+            five.b = 10;
+
+            six.a = 11;
+            six.b = 12;
+
+            seven.a = 13;
+            seven.b = 14;
+
+            eight.a = 15;
+            eight.b = 16;
+
+            nine.a = 17;
+            nine.b = 18;
+
+            ten.a = 19;
+            ten.b = 20;
+
+            long sum = ManagedNativeVarargTests.TestPassingTwoIntStructsNoVarargs(one,
+                                                                                  two,
+                                                                                  three,
+                                                                                  four,
+                                                                                  five,
+                                                                                  six,
+                                                                                  seven,
+                                                                                  eight,
+                                                                                  nine,
+                                                                                  ten,
+                                                                                  __arglist());
+
+            return sum == 210;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFourIntStructsNoVarargsManaged()
+        {
+            FourIntStruct one = new FourIntStruct();
+            FourIntStruct two = new FourIntStruct();
+            FourIntStruct three = new FourIntStruct();
+            FourIntStruct four = new FourIntStruct();
+            FourIntStruct five = new FourIntStruct();
+            FourIntStruct six = new FourIntStruct();
+            FourIntStruct seven = new FourIntStruct();
+            FourIntStruct eight = new FourIntStruct();
+            FourIntStruct nine = new FourIntStruct();
+            FourIntStruct ten = new FourIntStruct();
+
+            one.a = 1;
+            one.b = 2;
+            one.c = 3;
+            one.d = 4;
+
+            two.a = 5;
+            two.b = 6;
+            two.c = 7;
+            two.d = 8;
+
+            
+            three.a = 9;
+            three.b = 10;
+            three.c = 11;
+            three.d = 12;
+
+            four.a = 13;
+            four.b = 14;
+            four.c = 15;
+            four.d = 16;
+
+            five.a = 17;
+            five.b = 18;
+            five.c = 19;
+            five.d = 20;
+
+            six.a = 21;
+            six.b = 22;
+            six.c = 23;
+            six.d = 24;
+
+            seven.a = 25;
+            seven.b = 26;
+            seven.c = 27;
+            seven.d = 28;
+
+            eight.a = 29;
+            eight.b = 30;
+            eight.c = 31;
+            eight.d = 32;
+
+            nine.a = 33;
+            nine.b = 34;
+            nine.c = 35;
+            nine.d = 36;
+
+            ten.a = 37;
+            ten.b = 38;
+            ten.c = 39;
+            ten.d = 40;
+
+            int sum = ManagedNativeVarargTests.TestPassingFourIntStructsNoVarargs(one,
+                                                                                  two,
+                                                                                  three,
+                                                                                  four,
+                                                                                  five,
+                                                                                  six,
+                                                                                  seven,
+                                                                                  eight,
+                                                                                  nine,
+                                                                                  ten,
+                                                                                  __arglist());
+
+            return sum == 820;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoLongStructsNoVarargsManaged()
+        {
+            TwoLongStruct one = new TwoLongStruct();
+            TwoLongStruct two = new TwoLongStruct();
+            TwoLongStruct three = new TwoLongStruct();
+            TwoLongStruct four = new TwoLongStruct();
+            TwoLongStruct five = new TwoLongStruct();
+            TwoLongStruct six = new TwoLongStruct();
+            TwoLongStruct seven = new TwoLongStruct();
+            TwoLongStruct eight = new TwoLongStruct();
+            TwoLongStruct nine = new TwoLongStruct();
+            TwoLongStruct ten = new TwoLongStruct();
+
+            one.a = 1;
+            one.b = 2;
+
+            two.a = 3;
+            two.b = 4;
+
+            three.a = 5;
+            three.b = 6;
+
+            four.a = 7;
+            four.b = 8;
+
+            five.a = 9;
+            five.b = 10;
+
+            six.a = 11;
+            six.b = 12;
+
+            seven.a = 13;
+            seven.b = 14;
+
+            eight.a = 15;
+            eight.b = 16;
+
+            nine.a = 17;
+            nine.b = 18;
+
+            ten.a = 19;
+            ten.b = 20;
+
+            long sum = ManagedNativeVarargTests.TestPassingTwoLongStructsNoVarargs(one,
+                                                                                   two,
+                                                                                   three,
+                                                                                   four,
+                                                                                   five,
+                                                                                   six,
+                                                                                   seven,
+                                                                                   eight,
+                                                                                   nine,
+                                                                                   ten,
+                                                                                   __arglist());
+
+            return sum == 210;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoLongStructsWithIntAndLongNoVarargsManaged()
+        {
+            TwoLongStruct one = new TwoLongStruct();
+            TwoLongStruct two = new TwoLongStruct();
+            TwoLongStruct three = new TwoLongStruct();
+            TwoLongStruct four = new TwoLongStruct();
+            TwoLongStruct five = new TwoLongStruct();
+            TwoLongStruct six = new TwoLongStruct();
+            TwoLongStruct seven = new TwoLongStruct();
+            TwoLongStruct eight = new TwoLongStruct();
+            TwoLongStruct nine = new TwoLongStruct();
+            TwoLongStruct ten = new TwoLongStruct();
+
+            one.a = 1;
+            one.b = 2;
+
+            two.a = 3;
+            two.b = 4;
+
+            three.a = 5;
+            three.b = 6;
+
+            four.a = 7;
+            four.b = 8;
+
+            five.a = 9;
+            five.b = 10;
+
+            six.a = 11;
+            six.b = 12;
+
+            seven.a = 13;
+            seven.b = 14;
+
+            eight.a = 15;
+            eight.b = 16;
+
+            nine.a = 17;
+            nine.b = 18;
+
+            ten.a = 19;
+            ten.b = 20;
+
+            bool passed = ManagedNativeVarargTests.TestPassingTwoLongStructsNoVarargs(5,
+                                                                                      210,
+                                                                                      one,
+                                                                                      two,
+                                                                                      three,
+                                                                                      four,
+                                                                                      five,
+                                                                                      six,
+                                                                                      seven,
+                                                                                      eight,
+                                                                                      nine,
+                                                                                      ten,
+                                                                                      __arglist());
+
+            return passed;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoLongStructsAndIntNoVarargsManaged()
+        {
+            TwoLongStruct one = new TwoLongStruct();
+            TwoLongStruct two = new TwoLongStruct();
+            TwoLongStruct three = new TwoLongStruct();
+            TwoLongStruct four = new TwoLongStruct();
+            TwoLongStruct five = new TwoLongStruct();
+            TwoLongStruct six = new TwoLongStruct();
+            TwoLongStruct seven = new TwoLongStruct();
+            TwoLongStruct eight = new TwoLongStruct();
+            TwoLongStruct nine = new TwoLongStruct();
+            TwoLongStruct ten = new TwoLongStruct();
+
+            one.a = 1;
+            one.b = 2;
+
+            two.a = 3;
+            two.b = 4;
+
+            
+            three.a = 5;
+            three.b = 6;
+
+            four.a = 7;
+            four.b = 8;
+
+            five.a = 9;
+            five.b = 10;
+
+            six.a = 11;
+            six.b = 12;
+
+            seven.a = 13;
+            seven.b = 14;
+
+            eight.a = 15;
+            eight.b = 16;
+
+            nine.a = 17;
+            nine.b = 18;
+
+            ten.a = 19;
+            ten.b = 20;
+
+            long sum = ManagedNativeVarargTests.TestPassingTwoLongStructsAndIntNoVarargs(21,
+                                                                                         one,
+                                                                                         two,
+                                                                                         three,
+                                                                                         four,
+                                                                                         five,
+                                                                                         six,
+                                                                                         seven,
+                                                                                         eight,
+                                                                                         nine,
+                                                                                         ten,
+                                                                                         __arglist());
+
+            return sum == 231;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFourLongStructsNoVarargsManaged()
+        {
+            FourLongStruct one = new FourLongStruct();
+            FourLongStruct two = new FourLongStruct();
+            FourLongStruct three = new FourLongStruct();
+            FourLongStruct four = new FourLongStruct();
+            FourLongStruct five = new FourLongStruct();
+            FourLongStruct six = new FourLongStruct();
+            FourLongStruct seven = new FourLongStruct();
+            FourLongStruct eight = new FourLongStruct();
+            FourLongStruct nine = new FourLongStruct();
+            FourLongStruct ten = new FourLongStruct();
+
+            one.a = 1;
+            one.b = 2;
+            one.c = 3;
+            one.d = 4;
+
+            two.a = 5;
+            two.b = 6;
+            two.c = 7;
+            two.d = 8;
+
+            
+            three.a = 9;
+            three.b = 10;
+            three.c = 11;
+            three.d = 12;
+
+            four.a = 13;
+            four.b = 14;
+            four.c = 15;
+            four.d = 16;
+
+            five.a = 17;
+            five.b = 18;
+            five.c = 19;
+            five.d = 20;
+
+            six.a = 21;
+            six.b = 22;
+            six.c = 23;
+            six.d = 24;
+
+            seven.a = 25;
+            seven.b = 26;
+            seven.c = 27;
+            seven.d = 28;
+
+            eight.a = 29;
+            eight.b = 30;
+            eight.c = 31;
+            eight.d = 32;
+
+            nine.a = 33;
+            nine.b = 34;
+            nine.c = 35;
+            nine.d = 36;
+
+            ten.a = 37;
+            ten.b = 38;
+            ten.c = 39;
+            ten.d = 40;
+
+            long sum = ManagedNativeVarargTests.TestPassingFourLongStructsNoVarargs(one,
+                                                                                    two,
+                                                                                    three,
+                                                                                    four,
+                                                                                    five,
+                                                                                    six,
+                                                                                    seven,
+                                                                                    eight,
+                                                                                    nine,
+                                                                                    ten,
+                                                                                    __arglist());
+
+            return sum == 820;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoFloatStructsNoVarargsManaged()
+        {
+            TwoFloatStruct one = new TwoFloatStruct();
+            TwoFloatStruct two = new TwoFloatStruct();
+            TwoFloatStruct three = new TwoFloatStruct();
+            TwoFloatStruct four = new TwoFloatStruct();
+            TwoFloatStruct five = new TwoFloatStruct();
+            TwoFloatStruct six = new TwoFloatStruct();
+            TwoFloatStruct seven = new TwoFloatStruct();
+            TwoFloatStruct eight = new TwoFloatStruct();
+            TwoFloatStruct nine = new TwoFloatStruct();
+            TwoFloatStruct ten = new TwoFloatStruct();
+
+            one.a = 1.0f;
+            one.b = 2.0f;
+
+            two.a = 3.0f;
+            two.b = 4.0f;
+
+            
+            three.a = 5.0f;
+            three.b = 6.0f;
+
+            four.a = 7.0f;
+            four.b = 8.0f;
+
+            five.a = 9.0f;
+            five.b = 10.0f;
+
+            six.a = 11.0f;
+            six.b = 12.0f;
+
+            seven.a = 13.0f;
+            seven.b = 14.0f;
+
+            eight.a = 15.0f;
+            eight.b = 16.0f;
+
+            nine.a = 17.0f;
+            nine.b = 18.0f;
+
+            ten.a = 19.0f;
+            ten.b = 20.0f;
+
+            float sum = ManagedNativeVarargTests.TestPassingTwoFloatStructsNoVarargs(one,
+                                                                                     two,
+                                                                                     three,
+                                                                                     four,
+                                                                                     five,
+                                                                                     six,
+                                                                                     seven,
+                                                                                     eight,
+                                                                                     nine,
+                                                                                     ten,
+                                                                                     __arglist());
+
+            return sum == 210.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFourFloatStructsNoVarargsManaged()
+        {
+            FourFloatStruct one = new FourFloatStruct();
+            FourFloatStruct two = new FourFloatStruct();
+            FourFloatStruct three = new FourFloatStruct();
+            FourFloatStruct four = new FourFloatStruct();
+            FourFloatStruct five = new FourFloatStruct();
+            FourFloatStruct six = new FourFloatStruct();
+            FourFloatStruct seven = new FourFloatStruct();
+            FourFloatStruct eight = new FourFloatStruct();
+            FourFloatStruct nine = new FourFloatStruct();
+            FourFloatStruct ten = new FourFloatStruct();
+
+            one.a = 1.0f;
+            one.b = 2.0f;
+            one.c = 3.0f;
+            one.d = 4.0f;
+
+            two.a = 5.0f;
+            two.b = 6.0f;
+            two.c = 7.0f;
+            two.d = 8.0f;
+
+            
+            three.a = 9.0f;
+            three.b = 10.0f;
+            three.c = 11.0f;
+            three.d = 12.0f;
+
+            four.a = 13.0f;
+            four.b = 14.0f;
+            four.c = 15.0f;
+            four.d = 16.0f;
+
+            five.a = 17.0f;
+            five.b = 18.0f;
+            five.c = 19.0f;
+            five.d = 20.0f;
+
+            six.a = 21.0f;
+            six.b = 22.0f;
+            six.c = 23.0f;
+            six.d = 24.0f;
+
+            seven.a = 25.0f;
+            seven.b = 26.0f;
+            seven.c = 27.0f;
+            seven.d = 28.0f;
+
+            eight.a = 29.0f;
+            eight.b = 30.0f;
+            eight.c = 31.0f;
+            eight.d = 32.0f;
+
+            nine.a = 33.0f;
+            nine.b = 34.0f;
+            nine.c = 35.0f;
+            nine.d = 36.0f;
+
+            ten.a = 37.0f;
+            ten.b = 38.0f;
+            ten.c = 39.0f;
+            ten.d = 40.0f;
+
+            float sum = ManagedNativeVarargTests.TestPassingFourFloatStructsNoVarargs(one,
+                                                                                     two,
+                                                                                     three,
+                                                                                     four,
+                                                                                     five,
+                                                                                     six,
+                                                                                     seven,
+                                                                                     eight,
+                                                                                     nine,
+                                                                                     ten,
+                                                                                     __arglist());
+
+            return sum == 820.0f;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoDoubleStructsNoVarargsManaged()
+        {
+            TwoDoubleStruct one = new TwoDoubleStruct();
+            TwoDoubleStruct two = new TwoDoubleStruct();
+            TwoDoubleStruct three = new TwoDoubleStruct();
+            TwoDoubleStruct four = new TwoDoubleStruct();
+            TwoDoubleStruct five = new TwoDoubleStruct();
+            TwoDoubleStruct six = new TwoDoubleStruct();
+            TwoDoubleStruct seven = new TwoDoubleStruct();
+            TwoDoubleStruct eight = new TwoDoubleStruct();
+            TwoDoubleStruct nine = new TwoDoubleStruct();
+            TwoDoubleStruct ten = new TwoDoubleStruct();
+
+            one.a = 1.0;
+            one.b = 2.0;
+
+            two.a = 3.0;
+            two.b = 4.0;
+
+            
+            three.a = 5.0;
+            three.b = 6.0;
+
+            four.a = 7.0;
+            four.b = 8.0;
+
+            five.a = 9.0;
+            five.b = 10.0;
+
+            six.a = 11.0;
+            six.b = 12.0;
+
+            seven.a = 13.0;
+            seven.b = 14.0;
+
+            eight.a = 15.0;
+            eight.b = 16.0;
+
+            nine.a = 17.0;
+            nine.b = 18.0;
+
+            ten.a = 19.0;
+            ten.b = 20.0;
+
+            double sum = ManagedNativeVarargTests.TestPassingTwoDoubleStructsNoVarargs(one,
+                                                                                       two,
+                                                                                       three,
+                                                                                       four,
+                                                                                       five,
+                                                                                       six,
+                                                                                       seven,
+                                                                                       eight,
+                                                                                       nine,
+                                                                                       ten,
+                                                                                       __arglist());
+
+            return sum == 210.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoLongStructsAndFloatNoVarargsManaged()
+        {
+            TwoDoubleStruct one = new TwoDoubleStruct();
+            TwoDoubleStruct two = new TwoDoubleStruct();
+            TwoDoubleStruct three = new TwoDoubleStruct();
+            TwoDoubleStruct four = new TwoDoubleStruct();
+            TwoDoubleStruct five = new TwoDoubleStruct();
+            TwoDoubleStruct six = new TwoDoubleStruct();
+            TwoDoubleStruct seven = new TwoDoubleStruct();
+            TwoDoubleStruct eight = new TwoDoubleStruct();
+            TwoDoubleStruct nine = new TwoDoubleStruct();
+            TwoDoubleStruct ten = new TwoDoubleStruct();
+
+            one.a = 1.0;
+            one.b = 2.0;
+
+            two.a = 3.0;
+            two.b = 4.0;
+
+            
+            three.a = 5.0;
+            three.b = 6.0;
+
+            four.a = 7.0;
+            four.b = 8.0;
+
+            five.a = 9.0;
+            five.b = 10.0;
+
+            six.a = 11.0;
+            six.b = 12.0;
+
+            seven.a = 13.0;
+            seven.b = 14.0;
+
+            eight.a = 15.0;
+            eight.b = 16.0;
+
+            nine.a = 17.0;
+            nine.b = 18.0;
+
+            ten.a = 19.0;
+            ten.b = 20.0;
+
+            double sum = ManagedNativeVarargTests.TestPassingTwoDoubleStructsAndFloatNoVarargs(21,
+                                                                                              one,
+                                                                                              two,
+                                                                                              three,
+                                                                                              four,
+                                                                                              five,
+                                                                                              six,
+                                                                                              seven,
+                                                                                              eight,
+                                                                                              nine,
+                                                                                              ten,
+                                                                                              __arglist());
+
+            return sum == 231.0;
+        }
+
+        /// <summary>
+        /// Test passing using the vararg calling convention; however, not passing
+        /// and varargs. This is to assure that the non-variadic arguments
+        /// are passing correctly.
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingFourDoubleStructsNoVarargsManaged()
+        {
+            FourDoubleStruct one = new FourDoubleStruct();
+            FourDoubleStruct two = new FourDoubleStruct();
+            FourDoubleStruct three = new FourDoubleStruct();
+            FourDoubleStruct four = new FourDoubleStruct();
+            FourDoubleStruct five = new FourDoubleStruct();
+            FourDoubleStruct six = new FourDoubleStruct();
+            FourDoubleStruct seven = new FourDoubleStruct();
+            FourDoubleStruct eight = new FourDoubleStruct();
+            FourDoubleStruct nine = new FourDoubleStruct();
+            FourDoubleStruct ten = new FourDoubleStruct();
+
+            one.a = 1.0;
+            one.b = 2.0;
+            one.c = 3.0;
+            one.d = 4.0;
+
+            two.a = 5.0;
+            two.b = 6.0;
+            two.c = 7.0;
+            two.d = 8.0;
+
+            
+            three.a = 9.0;
+            three.b = 10.0;
+            three.c = 11.0;
+            three.d = 12.0;
+
+            four.a = 13.0;
+            four.b = 14.0;
+            four.c = 15.0;
+            four.d = 16.0;
+
+            five.a = 17.0;
+            five.b = 18.0;
+            five.c = 19.0;
+            five.d = 20.0;
+
+            six.a = 21.0;
+            six.b = 22.0;
+            six.c = 23.0;
+            six.d = 24.0;
+
+            seven.a = 25.0;
+            seven.b = 26.0;
+            seven.c = 27.0;
+            seven.d = 28.0;
+
+            eight.a = 29.0;
+            eight.b = 30.0;
+            eight.c = 31.0;
+            eight.d = 32.0;
+
+            nine.a = 33.0;
+            nine.b = 34.0;
+            nine.c = 35.0;
+            nine.d = 36.0;
+
+            ten.a = 37.0;
+            ten.b = 38.0;
+            ten.c = 39.0;
+            ten.d = 40.0;
+
+            double sum = ManagedNativeVarargTests.TestPassingFourDoubleStructsNoVarargs(one,
+                                                                                        two,
+                                                                                        three,
+                                                                                        four,
+                                                                                        five,
+                                                                                        six,
+                                                                                        seven,
+                                                                                        eight,
+                                                                                        nine,
+                                                                                        ten,
+                                                                                        __arglist());
+
+            return sum == 820.0;
+        }
+        
+        /// <summary>
+        /// Test passing using the regular calling convention ten eight byte
+        /// structs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTenEightBytes() 
+        {
+            EightByteStruct one = new EightByteStruct();
+            EightByteStruct two = new EightByteStruct();
+            EightByteStruct three = new EightByteStruct();
+            EightByteStruct four = new EightByteStruct();
+            EightByteStruct five = new EightByteStruct();
+            EightByteStruct six = new EightByteStruct();
+            EightByteStruct seven = new EightByteStruct();
+            EightByteStruct eight = new EightByteStruct();
+            EightByteStruct nine = new EightByteStruct();
+            EightByteStruct ten = new EightByteStruct();
+
+            long cookie = 1010;
+
+            one.one = 1;
+            one.two = 2;
+            one.three = 3;
+            one.four = 4;
+            one.five = 5;
+            one.six = 6;
+            one.seven = 7;
+            one.eight = 8;
+
+            two.one = 9;
+            two.two = 10;
+            two.three = 11;
+            two.four = 12;
+            two.five = 13;
+            two.six = 14;
+            two.seven = 15;
+            two.eight = 16;
+
+            three.one = 17;
+            three.two = 18;
+            three.three = 19;
+            three.four = 20;
+            three.five = 21;
+            three.six = 22;
+            three.seven = 23;
+            three.eight = 24;
+
+            four.one = 25;
+            four.two = 26;
+            four.three = 27;
+            four.four = 28;
+            four.five = 29;
+            four.six = 30;
+            four.seven = 31;
+            four.eight = 32;
+
+            five.one = 33;
+            five.two = 34;
+            five.three = 35;
+            five.four = 36;
+            five.five = 37;
+            five.six = 38;
+            five.seven = 39;
+            five.eight = 40;
+
+            six.one = 41;
+            six.two = 42;
+            six.three = 43;
+            six.four = 44;
+            six.five = 45;
+            six.six = 46;
+            six.seven = 47;
+            six.eight = 48;
+
+            seven.one = 49;
+            seven.two = 50;
+            seven.three = 51;
+            seven.four = 52;
+            seven.five = 53;
+            seven.six = 54;
+            seven.seven = 55;
+            seven.eight = 56;
+
+            eight.one = 57;
+            eight.two = 58;
+            eight.three = 59;
+            eight.four = 60;
+            eight.five = 61;
+            eight.six = 62;
+            eight.seven = 63;
+            eight.eight = 64;
+
+            nine.one = 65;
+            nine.two = 66;
+            nine.three = 67;
+            nine.four = 68;
+            nine.five = 69;
+            nine.six = 70;
+            nine.seven = 71;
+            nine.eight = 72;
+
+            ten.one = 73;
+            ten.two = 74;
+            ten.three = 75;
+            ten.four = 76;
+            ten.five = 77;
+            ten.six = 78;
+            ten.seven = 79;
+            ten.eight = 80;
+
+            int sum = TestPassingTenEightBytesHelper(cookie, one, two, three, four, five, six, seven, eight, nine, ten);
+
+            return sum == 3240;
+        }
+
+        /// <summary>
+        /// Test passing using the regular calling convention ten sixteen byte
+        /// structs
+        /// 
+        /// </summary>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTenSixteenBytes() 
+        {
+            SixteenByteStruct one = new SixteenByteStruct();
+            SixteenByteStruct two = new SixteenByteStruct();
+            SixteenByteStruct three = new SixteenByteStruct();
+            SixteenByteStruct four = new SixteenByteStruct();
+            SixteenByteStruct five = new SixteenByteStruct();
+            SixteenByteStruct six = new SixteenByteStruct();
+            SixteenByteStruct seven = new SixteenByteStruct();
+            SixteenByteStruct eight = new SixteenByteStruct();
+            SixteenByteStruct nine = new SixteenByteStruct();
+            SixteenByteStruct ten = new SixteenByteStruct();
+
+            long cookie = 1010;
+
+            one.one = 1;
+            one.two = 2;
+            one.three = 3;
+            one.four = 4;
+            one.five = 5;
+            one.six = 6;
+            one.seven = 7;
+            one.eight = 8;
+            one.nine = 9;
+            one.ten = 10;
+            one.eleven = 11;
+            one.twelve = 12;
+            one.thirteen = 13;
+            one.fourteen = 14;
+            one.fifteen = 15;
+            one.sixteen = 16;
+
+            two.one = 17;
+            two.two = 18;
+            two.three = 19;
+            two.four = 20;
+            two.five = 21;
+            two.six = 22;
+            two.seven = 23;
+            two.eight = 24;
+            two.nine = 25;
+            two.ten = 26;
+            two.eleven = 27;
+            two.twelve = 28;
+            two.thirteen = 29;
+            two.fourteen = 30;
+            two.fifteen = 31;
+            two.sixteen = 32;
+
+            three.one = 33;
+            three.two = 34;
+            three.three = 35;
+            three.four = 36;
+            three.five = 37;
+            three.six = 38;
+            three.seven = 39;
+            three.eight = 40;
+            three.nine = 41;
+            three.ten = 42;
+            three.eleven = 43;
+            three.twelve = 44;
+            three.thirteen = 45;
+            three.fourteen = 46;
+            three.fifteen = 47;
+            three.sixteen = 48;
+
+            four.one = 49;
+            four.two = 50;
+            four.three = 51;
+            four.four = 52;
+            four.five = 53;
+            four.six = 54;
+            four.seven = 55;
+            four.eight = 56;
+            four.nine = 57;
+            four.ten = 58;
+            four.eleven = 59;
+            four.twelve = 60;
+            four.thirteen = 61;
+            four.fourteen = 62;
+            four.fifteen = 63;
+            four.sixteen = 64;
+
+            five.one = 65;
+            five.two = 66;
+            five.three = 67;
+            five.four = 68;
+            five.five = 69;
+            five.six = 70;
+            five.seven = 71;
+            five.eight = 72;
+            five.nine = 73;
+            five.ten = 74;
+            five.eleven = 75;
+            five.twelve = 76;
+            five.thirteen = 77;
+            five.fourteen = 78;
+            five.fifteen = 79;
+            five.sixteen = 80;
+
+            six.one = 81;
+            six.two = 82;
+            six.three = 83;
+            six.four = 84;
+            six.five = 85;
+            six.six = 86;
+            six.seven = 87;
+            six.eight = 88;
+            six.nine = 89;
+            six.ten = 90;
+            six.eleven = 91;
+            six.twelve = 92;
+            six.thirteen = 93;
+            six.fourteen = 94;
+            six.fifteen = 95;
+            six.sixteen = 96;
+
+            seven.one = 97;
+            seven.two = 98;
+            seven.three = 99;
+            seven.four = 100;
+            seven.five = 101;
+            seven.six = 102;
+            seven.seven = 103;
+            seven.eight = 104;
+            seven.nine = 105;
+            seven.ten = 106;
+            seven.eleven = 107;
+            seven.twelve = 108;
+            seven.thirteen = 109;
+            seven.fourteen = 110;
+            seven.fifteen = 111;
+            seven.sixteen = 112;
+
+            eight.one = 113;
+            eight.two = 114;
+            eight.three = 115;
+            eight.four = 116;
+            eight.five = 117;
+            eight.six = 118;
+            eight.seven = 119;
+            eight.eight = 120;
+            eight.nine = 121;
+            eight.ten = 122;
+            eight.eleven = 123;
+            eight.twelve = 124;
+            eight.thirteen = 125;
+            eight.fourteen = 126;
+            eight.fifteen = 127;
+            eight.sixteen = 128;
+
+            nine.one = 129;
+            nine.two = 130;
+            nine.three = 131;
+            nine.four = 132;
+            nine.five = 133;
+            nine.six = 134;
+            nine.seven = 135;
+            nine.eight = 136;
+            nine.nine = 137;
+            nine.ten = 138;
+            nine.eleven = 139;
+            nine.twelve = 140;
+            nine.thirteen = 141;
+            nine.fourteen = 142;
+            nine.fifteen = 143;
+            nine.sixteen = 144;
+
+            ten.one = 145;
+            ten.two = 146;
+            ten.three = 147;
+            ten.four = 148;
+            ten.five = 149;
+            ten.six = 150;
+            ten.seven = 151;
+            ten.eight = 152;
+            ten.nine = 153;
+            ten.ten = 154;
+            ten.eleven = 155;
+            ten.twelve = 156;
+            ten.thirteen = 157;
+            ten.fourteen = 158;
+            ten.fifteen = 159;
+            ten.sixteen = 160;
+
+            int sum = TestPassingTenSixteenBytesHelper(cookie, one, two, three, four, five, six, seven, eight, nine, ten);
+
+            return sum == 12880;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestPassingTenEightBytesHelper(long cookie,
+                                                         EightByteStruct one,
+                                                         EightByteStruct two,
+                                                         EightByteStruct three,
+                                                         EightByteStruct four,
+                                                         EightByteStruct five,
+                                                         EightByteStruct six,
+                                                         EightByteStruct seven,
+                                                         EightByteStruct eight,
+                                                         EightByteStruct nine,
+                                                         EightByteStruct ten)
+        {
+            int sum = 0;
+
+            sum += one.one + one.two + one.three + one.four + one.five + one.six + one.seven + one.eight;
+            sum += two.one + two.two + two.three + two.four + two.five + two.six + two.seven + two.eight;
+            sum += three.one + three.two + three.three + three.four + three.five + three.six + three.seven + three.eight;
+            sum += four.one + four.two + four.three + four.four + four.five + four.six + four.seven + four.eight;
+            sum += five.one + five.two + five.three + five.four + five.five + five.six + five.seven + five.eight;
+            sum += six.one + six.two + six.three + six.four + six.five + six.six + six.seven + six.eight;
+            sum += seven.one + seven.two + seven.three + seven.four + seven.five + seven.six + seven.seven + seven.eight;
+            sum += eight.one + eight.two + eight.three + eight.four + eight.five + eight.six + eight.seven + eight.eight;
+            sum += nine.one + nine.two + nine.three + nine.four + nine.five + nine.six + nine.seven + nine.eight;
+            sum += ten.one + ten.two + ten.three + ten.four + ten.five + ten.six + ten.seven + ten.eight;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestPassingTenSixteenBytesHelper(long cookie,
+                                                           SixteenByteStruct one,
+                                                           SixteenByteStruct two,
+                                                           SixteenByteStruct three,
+                                                           SixteenByteStruct four,
+                                                           SixteenByteStruct five,
+                                                           SixteenByteStruct six,
+                                                           SixteenByteStruct seven,
+                                                           SixteenByteStruct eight,
+                                                           SixteenByteStruct nine,
+                                                           SixteenByteStruct ten)
+        {
+            int sum = 0;
+
+            sum += one.one + one.two + one.three + one.four + one.five + one.six + one.seven + one.eight + one.nine + one.ten + one.eleven + one.twelve + one.thirteen + one.fourteen + one.fifteen + one.sixteen;
+            sum += two.one + two.two + two.three + two.four + two.five + two.six + two.seven + two.eight + two.nine + two.ten + two.eleven + two.twelve + two.thirteen + two.fourteen + two.fifteen + two.sixteen;
+            sum += three.one + three.two + three.three + three.four + three.five + three.six + three.seven + three.eight + three.nine + three.ten + three.eleven + three.twelve + three.thirteen + three.fourteen + three.fifteen + three.sixteen;
+            sum += four.one + four.two + four.three + four.four + four.five + four.six + four.seven + four.eight + four.nine + four.ten + four.eleven + four.twelve + four.thirteen + four.fourteen + four.fifteen + four.sixteen;
+            sum += five.one + five.two + five.three + five.four + five.five + five.six + five.seven + five.eight + five.nine + five.ten + five.eleven + five.twelve + five.thirteen + five.fourteen + five.fifteen + five.sixteen;
+            sum += six.one + six.two + six.three + six.four + six.five + six.six + six.seven + six.eight + six.nine + six.ten + six.eleven + six.twelve + six.thirteen + six.fourteen + six.fifteen + six.sixteen;
+            sum += seven.one + seven.two + seven.three + seven.four + seven.five + seven.six + seven.seven + seven.eight + seven.nine + seven.ten + seven.eleven + seven.twelve + seven.thirteen + seven.fourteen + seven.fifteen + seven.sixteen;
+            sum += eight.one + eight.two + eight.three + eight.four + eight.five + eight.six + eight.seven + eight.eight + eight.nine + eight.ten + eight.eleven + eight.twelve + eight.thirteen + eight.fourteen + eight.fifteen + eight.sixteen;
+            sum += nine.one + nine.two + nine.three + nine.four + nine.five + nine.six + nine.seven + nine.eight + nine.nine + nine.ten + nine.eleven + nine.twelve + nine.thirteen + nine.fourteen + nine.fifteen + nine.sixteen;
+            sum += ten.one + ten.two + ten.three + ten.four + ten.five + ten.six + ten.seven + ten.eight + ten.nine + ten.ten + ten.eleven + ten.twelve + ten.thirteen + ten.fourteen + ten.fifteen + ten.sixteen;
+
+            return sum;
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Echo Tests
+        //
+        // Notes:
+        //
+        //  Simple tests which confirm that what is passed to the method/function 
+        //  is the same when it is returned.
+        //
+        ////////////////////////////////////////////////////////////////////////
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoByteNoVararg(byte arg)
+        {
+            byte returnValue = echo_byte(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoCharNoVararg(char arg)
+        {
+            char returnValue = echo_char(arg, __arglist());
+
+            return returnValue == arg;
+        }
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoShortNoVararg(short arg)
+        {
+            short returnValue = echo_short(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoIntNoVararg(int arg)
+        {
+            int returnValue = echo_int(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoLongNoVararg(long arg)
+        {
+            long returnValue = echo_int64(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFloatNoVararg(float arg)
+        {
+            float returnValue = echo_float(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoDoubleNoVararg(double arg)
+        {
+            double returnValue = echo_double(arg, __arglist());
+
+            return returnValue == arg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneIntStructNoVararg()
+        {
+            OneIntStruct arg = new OneIntStruct();
+            arg.a = 1;
+
+            OneIntStruct returnValue = echo_one_int_struct(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoIntStructNoVararg()
+        {
+            TwoIntStruct arg = new TwoIntStruct();
+            arg.a = 1;
+            arg.b = 2;
+
+            TwoIntStruct returnValue = echo_two_int_struct(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneLongStructNoVararg()
+        {
+            OneLongStruct arg = new OneLongStruct();
+            arg.a = 1;
+
+            OneLongStruct returnValue = echo_one_long_struct(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoLongStructNoVararg()
+        {
+            TwoLongStruct arg = new TwoLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+
+            TwoLongStruct returnValue = echo_two_long_struct(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoEightByteStructStructNoVararg()
+        {
+            EightByteStruct arg = new EightByteStruct();
+            arg.one = 1;
+            arg.two = 2;
+            arg.three = 3;
+            arg.four = 4;
+            arg.five = 5;
+            arg.six = 6;
+            arg.seven = 7;
+            arg.eight = 8;
+
+            EightByteStruct returnValue = echo_eight_byte_struct(arg, __arglist());
+
+            bool equal = arg.one == returnValue.one && 
+                         arg.two == returnValue.two &&
+                         arg.three == returnValue.three &&
+                         arg.four == returnValue.four &&
+                         arg.five == returnValue.five &&
+                         arg.six == returnValue.six &&
+                         arg.seven == returnValue.seven &&
+                         arg.eight == returnValue.eight;
+
+            return equal;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourIntStructNoVararg()
+        {
+            FourIntStruct arg = new FourIntStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourIntStruct returnValue = echo_four_int_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoSixteenByteStructNoVararg()
+        {
+            SixteenByteStruct arg = new SixteenByteStruct();
+            arg.one = 1;
+            arg.two = 2;
+            arg.three = 3;
+            arg.four = 4;
+            arg.five = 5;
+            arg.six = 6;
+            arg.seven = 7;
+            arg.eight = 8;
+            arg.nine = 9;
+            arg.ten = 10;
+            arg.eleven = 11;
+            arg.twelve = 12;
+            arg.thirteen = 13;
+            arg.fourteen = 14;
+            arg.fifteen = 15;
+            arg.sixteen = 16;
+
+            SixteenByteStruct returnValue = echo_sixteen_byte_struct(arg, __arglist());
+
+            bool equal = arg.one == returnValue.one && 
+                         arg.two == returnValue.two &&
+                         arg.three == returnValue.three &&
+                         arg.four == returnValue.four &&
+                         arg.five == returnValue.five &&
+                         arg.six == returnValue.six &&
+                         arg.seven == returnValue.seven &&
+                         arg.eight == returnValue.eight &&
+                         arg.nine == returnValue.nine &&
+                         arg.ten == returnValue.ten &&
+                         arg.eleven == returnValue.eleven &&
+                         arg.twelve == returnValue.twelve &&
+                         arg.thirteen == returnValue.thirteen &&
+                         arg.fourteen == returnValue.fourteen &&
+                         arg.fifteen == returnValue.fifteen &&
+                         arg.sixteen == returnValue.sixteen;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourLongStruct()
+        {
+            FourLongStruct arg = new FourLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourLongStruct returnValue = echo_four_long_struct(arg);
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourLongStructNoVararg()
+        {
+            FourLongStruct arg = new FourLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourLongStruct returnValue = echo_four_long_struct_with_vararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneFloatStructNoVararg() 
+        {
+            OneFloatStruct arg = new OneFloatStruct();
+            arg.a = 1.0f;
+
+            OneFloatStruct returnValue = echo_one_float_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoFloatStructNoVararg()
+        {
+            TwoFloatStruct arg = new TwoFloatStruct();
+            arg.a = 1.0f;
+            arg.b = 2.0f;
+
+            TwoFloatStruct returnValue = echo_two_float_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneDoubleStructNoVararg()
+        {
+            OneDoubleStruct arg = new OneDoubleStruct();
+            arg.a = 1.0;
+
+            OneDoubleStruct returnValue = echo_one_double_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoDoubleStructNoVararg()
+        {
+            TwoDoubleStruct arg = new TwoDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+
+            TwoDoubleStruct returnValue = echo_two_double_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoThreeDoubleStructNoVararg()
+        {
+            ThreeDoubleStruct arg = new ThreeDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+            arg.c = 3.0;
+
+            ThreeDoubleStruct returnValue = echo_three_double_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b && arg.c == returnValue.c;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourFloatStructNoVararg()
+        {
+            FourFloatStruct arg = new FourFloatStruct();
+            arg.a = 1.0f;
+            arg.b = 2.0f;
+            arg.c = 3.0f;
+            arg.d = 4.0f;
+
+            FourFloatStruct returnValue = echo_four_float_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourDoubleStructNoVararg()
+        {
+            FourDoubleStruct arg = new FourDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+            arg.c = 3.0;
+            arg.d = 4.0;
+
+            FourDoubleStruct returnValue = echo_four_double_struct(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Echo Tests
+        //
+        // Notes:
+        //
+        //  Simple tests which confirm that what is passed to the method/function 
+        //  is the same when it is returned.
+        //
+        //  These tests, are the managed to managed calls.
+        //
+        ////////////////////////////////////////////////////////////////////////
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoByteManagedNoVararg(byte arg)
+        {
+            byte returnValue = ManagedNativeVarargTests.TestEchoByteManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoCharManagedNoVararg(char arg)
+        {
+            char returnValue = ManagedNativeVarargTests.TestEchoCharManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoShortManagedNoVararg(short arg)
+        {
+            short returnValue = ManagedNativeVarargTests.TestEchoShortManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoIntManagedNoVararg(int arg)
+        {
+            int returnValue = ManagedNativeVarargTests.TestEchoIntManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoLongManagedNoVararg(long arg)
+        {
+            long returnValue = ManagedNativeVarargTests.TestEchoLongManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFloatManagedNoVararg(float arg)
+        {
+            float returnValue = ManagedNativeVarargTests.TestEchoFloatManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoDoubleManagedNoVararg(double arg)
+        {
+            double returnValue = ManagedNativeVarargTests.TestEchoDoubleManagedNoVararg(arg, __arglist());
+
+            return returnValue == arg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneIntStructManagedNoVararg()
+        {
+            OneIntStruct arg = new OneIntStruct();
+            arg.a = 1;
+
+            OneIntStruct returnValue = ManagedNativeVarargTests.TestEchoOneIntStructManagedNoVararg(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoIntStructManagedNoVararg()
+        {
+            TwoIntStruct arg = new TwoIntStruct();
+            arg.a = 1;
+            arg.b = 2;
+
+            TwoIntStruct returnValue = ManagedNativeVarargTests.TestEchoTwoIntStructManagedNoVararg(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneLongStructManagedNoVararg()
+        {
+            OneLongStruct arg = new OneLongStruct();
+            arg.a = 1;
+
+            OneLongStruct returnValue = ManagedNativeVarargTests.TestEchoOneLongStructManagedNoVararg(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoLongStructManagedNoVararg()
+        {
+            TwoLongStruct arg = new TwoLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+
+            TwoLongStruct returnValue = ManagedNativeVarargTests.TestEchoTwoLongStructManagedNoVararg(arg, __arglist());
+
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoEightByteStructStructManagedNoVararg()
+        {
+            EightByteStruct arg = new EightByteStruct();
+            arg.one = 1;
+            arg.two = 2;
+            arg.three = 3;
+            arg.four = 4;
+            arg.five = 5;
+            arg.six = 6;
+            arg.seven = 7;
+            arg.eight = 8;
+
+            EightByteStruct returnValue = ManagedNativeVarargTests.TestEchoEightByteStructStructManagedNoVararg(arg, __arglist());
+
+            bool equal = arg.one == returnValue.one && 
+                         arg.two == returnValue.two &&
+                         arg.three == returnValue.three &&
+                         arg.four == returnValue.four &&
+                         arg.five == returnValue.five &&
+                         arg.six == returnValue.six &&
+                         arg.seven == returnValue.seven &&
+                         arg.eight == returnValue.eight;
+
+            return equal;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourIntStructManagedNoVararg()
+        {
+            FourIntStruct arg = new FourIntStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourIntStruct returnValue = ManagedNativeVarargTests.TestEchoFourIntStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoSixteenByteStructManagedNoVararg()
+        {
+            SixteenByteStruct arg = new SixteenByteStruct();
+            arg.one = 1;
+            arg.two = 2;
+            arg.three = 3;
+            arg.four = 4;
+            arg.five = 5;
+            arg.six = 6;
+            arg.seven = 7;
+            arg.eight = 8;
+            arg.nine = 9;
+            arg.ten = 10;
+            arg.eleven = 11;
+            arg.twelve = 12;
+            arg.thirteen = 13;
+            arg.fourteen = 14;
+            arg.fifteen = 15;
+            arg.sixteen = 16;
+
+            SixteenByteStruct returnValue = ManagedNativeVarargTests.TestEchoSixteenByteStructManagedNoVararg(arg, __arglist());
+
+            bool equal = arg.one == returnValue.one && 
+                         arg.two == returnValue.two &&
+                         arg.three == returnValue.three &&
+                         arg.four == returnValue.four &&
+                         arg.five == returnValue.five &&
+                         arg.six == returnValue.six &&
+                         arg.seven == returnValue.seven &&
+                         arg.eight == returnValue.eight &&
+                         arg.nine == returnValue.nine &&
+                         arg.ten == returnValue.ten &&
+                         arg.eleven == returnValue.eleven &&
+                         arg.twelve == returnValue.twelve &&
+                         arg.thirteen == returnValue.thirteen &&
+                         arg.fourteen == returnValue.fourteen &&
+                         arg.fifteen == returnValue.fifteen &&
+                         arg.sixteen == returnValue.sixteen;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourLongStructManagedNoVararg()
+        {
+            FourLongStruct arg = new FourLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourLongStruct returnValue = ManagedNativeVarargTests.TestEchoFourLongStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneFloatStructManagedNoVararg() 
+        {
+            OneFloatStruct arg = new OneFloatStruct();
+            arg.a = 1.0f;
+
+            OneFloatStruct returnValue = ManagedNativeVarargTests.TestEchoOneFloatStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoFloatStructManagedNoVararg()
+        {
+            TwoFloatStruct arg = new TwoFloatStruct();
+            arg.a = 1.0f;
+            arg.b = 2.0f;
+
+            TwoFloatStruct returnValue = ManagedNativeVarargTests.TestEchoTwoFloatStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneDoubleStructManagedNoVararg()
+        {
+            OneDoubleStruct arg = new OneDoubleStruct();
+            arg.a = 1.0;
+
+            OneDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoOneDoubleStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoDoubleStructManagedNoVararg()
+        {
+            TwoDoubleStruct arg = new TwoDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+
+            TwoDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoTwoDoubleStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoThreeDoubleStructManagedNoVararg()
+        {
+            ThreeDoubleStruct arg = new ThreeDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+            arg.c = 3.0;
+
+            ThreeDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoThreeDoubleStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b && arg.c == returnValue.c;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourFloatStructManagedNoVararg()
+        {
+            FourFloatStruct arg = new FourFloatStruct();
+            arg.a = 1.0f;
+            arg.b = 2.0f;
+            arg.c = 3.0f;
+            arg.d = 4.0f;
+
+            FourFloatStruct returnValue = ManagedNativeVarargTests.TestEchoFourFloatStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourDoubleStructManagedNoVararg()
+        {
+            FourDoubleStruct arg = new FourDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+            arg.c = 3.0;
+            arg.d = 4.0;
+
+            FourDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoFourDoubleStructManagedNoVararg(arg, __arglist());
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoByteManaged(byte arg)
+        {
+            byte returnValue = ManagedNativeVarargTests.TestEchoByteManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoCharManaged(char arg)
+        {
+            char returnValue = ManagedNativeVarargTests.TestEchoCharManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoShortManaged(short arg)
+        {
+            short returnValue = ManagedNativeVarargTests.TestEchoShortManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoIntManaged(int arg)
+        {
+            int returnValue = ManagedNativeVarargTests.TestEchoIntManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoLongManaged(long arg)
+        {
+            long returnValue = ManagedNativeVarargTests.TestEchoLongManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFloatManaged(float arg)
+        {
+            float returnValue = ManagedNativeVarargTests.TestEchoFloatManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoDoubleManaged(double arg)
+        {
+            double returnValue = ManagedNativeVarargTests.TestEchoDoubleManaged(arg, __arglist(arg));
+
+            return returnValue == arg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneIntStructManaged()
+        {
+            OneIntStruct arg = new OneIntStruct();
+            arg.a = 1;
+
+            OneIntStruct returnValue = ManagedNativeVarargTests.TestEchoOneIntStructManaged(arg, __arglist(arg));
+
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoIntStructManaged()
+        {
+            TwoIntStruct arg = new TwoIntStruct();
+            arg.a = 1;
+            arg.b = 2;
+
+            TwoIntStruct returnValue = ManagedNativeVarargTests.TestEchoTwoIntStructManaged(arg, __arglist(arg));
+
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneLongStructManaged()
+        {
+            OneLongStruct arg = new OneLongStruct();
+            arg.a = 1;
+
+            OneLongStruct returnValue = ManagedNativeVarargTests.TestEchoOneLongStructManaged(arg, __arglist(arg));
+
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoLongStructManaged()
+        {
+            TwoLongStruct arg = new TwoLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+
+            TwoLongStruct returnValue = ManagedNativeVarargTests.TestEchoTwoLongStructManaged(arg, __arglist(arg));
+
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoEightByteStructStructManaged()
+        {
+            EightByteStruct arg = new EightByteStruct();
+            arg.one = 1;
+            arg.two = 2;
+            arg.three = 3;
+            arg.four = 4;
+            arg.five = 5;
+            arg.six = 6;
+            arg.seven = 7;
+            arg.eight = 8;
+
+            EightByteStruct returnValue = ManagedNativeVarargTests.TestEchoEightByteStructStructManaged(arg, __arglist(arg));
+
+            bool equal = arg.one == returnValue.one && 
+                         arg.two == returnValue.two &&
+                         arg.three == returnValue.three &&
+                         arg.four == returnValue.four &&
+                         arg.five == returnValue.five &&
+                         arg.six == returnValue.six &&
+                         arg.seven == returnValue.seven &&
+                         arg.eight == returnValue.eight;
+
+            return equal;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourIntStructManaged()
+        {
+            FourIntStruct arg = new FourIntStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourIntStruct returnValue = ManagedNativeVarargTests.TestEchoFourIntStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoSixteenByteStructManaged()
+        {
+            SixteenByteStruct arg = new SixteenByteStruct();
+            arg.one = 1;
+            arg.two = 2;
+            arg.three = 3;
+            arg.four = 4;
+            arg.five = 5;
+            arg.six = 6;
+            arg.seven = 7;
+            arg.eight = 8;
+            arg.nine = 9;
+            arg.ten = 10;
+            arg.eleven = 11;
+            arg.twelve = 12;
+            arg.thirteen = 13;
+            arg.fourteen = 14;
+            arg.fifteen = 15;
+            arg.sixteen = 16;
+
+            SixteenByteStruct returnValue = ManagedNativeVarargTests.TestEchoSixteenByteStructManaged(arg, __arglist(arg));
+
+            bool equal = arg.one == returnValue.one && 
+                         arg.two == returnValue.two &&
+                         arg.three == returnValue.three &&
+                         arg.four == returnValue.four &&
+                         arg.five == returnValue.five &&
+                         arg.six == returnValue.six &&
+                         arg.seven == returnValue.seven &&
+                         arg.eight == returnValue.eight &&
+                         arg.nine == returnValue.nine &&
+                         arg.ten == returnValue.ten &&
+                         arg.eleven == returnValue.eleven &&
+                         arg.twelve == returnValue.twelve &&
+                         arg.thirteen == returnValue.thirteen &&
+                         arg.fourteen == returnValue.fourteen &&
+                         arg.fifteen == returnValue.fifteen &&
+                         arg.sixteen == returnValue.sixteen;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourLongStructManaged()
+        {
+            FourLongStruct arg = new FourLongStruct();
+            arg.a = 1;
+            arg.b = 2;
+            arg.c = 3;
+            arg.d = 4;
+
+            FourLongStruct returnValue = ManagedNativeVarargTests.TestEchoFourLongStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneFloatStructManaged() 
+        {
+            OneFloatStruct arg = new OneFloatStruct();
+            arg.a = 1.0f;
+
+            OneFloatStruct returnValue = ManagedNativeVarargTests.TestEchoOneFloatStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoFloatStructManaged()
+        {
+            TwoFloatStruct arg = new TwoFloatStruct();
+            arg.a = 1.0f;
+            arg.b = 2.0f;
+
+            TwoFloatStruct returnValue = ManagedNativeVarargTests.TestEchoTwoFloatStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoOneDoubleStructManaged()
+        {
+            OneDoubleStruct arg = new OneDoubleStruct();
+            arg.a = 1.0;
+
+            OneDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoOneDoubleStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoTwoDoubleStructManaged()
+        {
+            TwoDoubleStruct arg = new TwoDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+
+            TwoDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoTwoDoubleStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoThreeDoubleStructManaged()
+        {
+            ThreeDoubleStruct arg = new ThreeDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+            arg.c = 3.0;
+
+            ThreeDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoThreeDoubleStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a && arg.b == returnValue.b && arg.c == returnValue.c;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourFloatStructManaged()
+        {
+            FourFloatStruct arg = new FourFloatStruct();
+            arg.a = 1.0f;
+            arg.b = 2.0f;
+            arg.c = 3.0f;
+            arg.d = 4.0f;
+
+            FourFloatStruct returnValue = ManagedNativeVarargTests.TestEchoFourFloatStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool TestEchoFourDoubleStructManaged()
+        {
+            FourDoubleStruct arg = new FourDoubleStruct();
+            arg.a = 1.0;
+            arg.b = 2.0;
+            arg.c = 3.0;
+            arg.d = 4.0;
+
+            FourDoubleStruct returnValue = ManagedNativeVarargTests.TestEchoFourDoubleStructManaged(arg, __arglist(arg));
+            bool equal = arg.a == returnValue.a &&
+                         arg.b == returnValue.b &&
+                         arg.c == returnValue.c &&
+                         arg.d == returnValue.d;
+
+            return equal;
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Report Failure
+        ////////////////////////////////////////////////////////////////////////
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int ReportFailure(bool success, string name, int old_val, int new_val) 
+        {
+            ++m_testCount;
+            if (!success)
+            {
+                printf("Failure: %s\n", __arglist(name));
+
+                ++m_failCount;
+                return new_val;
+            }
+            else
+            {
+                printf("Passed: %s\n", __arglist(name));
+                ++m_passCount;
+            }
+
+            return old_val;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool ReportFailure(bool success, string name, bool old_val, bool new_val) 
+        {
+            ++m_testCount;
+            if (!success)
+            {
+                printf("Failure: %s\n", __arglist(name));
+
+                ++m_failCount;
+                return new_val;
+            }
+            else
+            {
+                printf("Passed: %s\n", __arglist(name));
+                ++m_passCount;
+            }
+
+            return old_val;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static bool ReportFailure(int success, string name, bool old_val, bool new_val) 
+        {
+            ++m_testCount;
+            if (success != 100)
+            {
+                printf("Failure: %s\n", __arglist(name));
+
+                ++m_failCount;
+                return new_val;
+            }
+            else
+            {
+                printf("Passed: %s\n", __arglist(name));
+                ++m_passCount;
+            }
+
+            return old_val;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int ReportFailure(int success, string name, int old_val, int new_val) 
+        {
+            ++m_testCount;
+            if (success != 100)
+            {
+                printf("Failure: %s\n", __arglist(name));
+
+                ++m_failCount;
+                return new_val;
+            }
+            else
+            {
+                printf("Passed: %s\n", __arglist(name));
+                ++m_passCount;
+            }
+
+            return old_val;
+        }
+
+        ////////////////////////////////////////////////////////////////////////////
+        // Main test driver
+        ////////////////////////////////////////////////////////////////////////////
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        static int Main(string[] args)
+        {
+            int success = 100;
+            m_testCount = 0;
+
+            success = ReportFailure(TestPassingIntsManaged(new int[] { 100, 299, -100, 50 }), "TestPassingIntsManaged(new int[] { 100, 299, -100, 50 })", success, 30);
+
+            TestFour16ByteStructs();
+
+            // !Varargs
+            success = ReportFailure(TestPassingTenEightBytes(), "TestPassingTenEightBytes", success, 81);
+            success = ReportFailure(TestPassingTenSixteenBytes(), "TestPassingTenSixteenBytes", success, 82);
+            
+            success = ReportFailure(TestPassingIntsNoVarargsManaged(), "TestPassingIntsNoVarargsManaged", success, 59);
+            success = ReportFailure(TestPassingLongsNoVarargsManaged(), "TestPassingLongsNoVarargsManaged", success, 60);
+            
+            success = ReportFailure(TestPassingFloatsNoVarargsManaged(), "TestPassingFloatsNoVarargsManaged", success, 61);
+            success = ReportFailure(TestPassingDoublesNoVarargsManaged(), "TestPassingDoublesNoVarargsManaged", success, 62);
+            
+            success = ReportFailure(TestPassingIntAndFloatsNoVarargsManaged(), "TestPassingIntAndFloatsNoVarargsManaged", success, 63);
+            success = ReportFailure(TestPassingFloatsAndIntNoVarargsManaged(), "TestPassingFloatsAndIntNoVarargsManaged", success, 64);
+            
+            success = ReportFailure(TestPassingIntAndDoublesNoVarargsManaged(), "TestPassingIntAndDoublesNoVarargsManaged", success, 65);
+            success = ReportFailure(TestPassingDoublesAndIntNoVarargsManaged(), "TestPassingDoublesAndIntNoVarargsManaged", success, 66);
+            
+            success = ReportFailure(TestPassingLongAndFloatsNoVarargsManaged(), "TestPassingLongAndFloatsNoVarargsManaged()", success, 67);
+            success = ReportFailure(TestPassingFloatsAndlongNoVarargsManaged(), "TestPassingFloatsAndlongNoVarargsManaged()", success, 68);
+            
+            success = ReportFailure(TestPassinglongAndDoublesNoVarargsManaged(), "TestPassinglongAndDoublesNoVarargsManaged()", success, 69);
+            success = ReportFailure(TestPassingDoublesAndlongNoVarargsManaged(), "TestPassingDoublesAndlongNoVarargsManaged()", success, 70);
+            
+            success = ReportFailure(TestPassingTwoIntStructsNoVarargsManaged(), "TestPassingTwoIntStructsNoVarargsManaged()", success, 71);
+            success = ReportFailure(TestPassingFourIntStructsNoVarargsManaged(), "TestPassingFourIntStructsNoVaragsManaged()", success, 72);
+            
+            success = ReportFailure(TestPassingTwoLongStructsNoVarargsManaged(), "TestPassingTwoLongStructsNoVarargsManaged()", success, 73);
+            success = ReportFailure(TestPassingTwoLongStructsWithIntAndLongNoVarargsManaged(), "TestPassingTwoLongStructsWithIntAndLongNoVarargsManaged()", success, 83);
+            success = ReportFailure(TestPassingTwoLongStructsAndIntNoVarargsManaged(), "TestPassingTwoLongStructsAndIntNoVarargsManaged()", success, 74);
+            
+            success = ReportFailure(TestPassingFourLongStructsNoVarargsManaged(), "TestPassingFourLongStructsNoVarargsManaged()", success, 75);
+            success = ReportFailure(TestPassingTwoFloatStructsNoVarargsManaged(), "TestPassingTwoFloatStructsNoVarargsManaged()", success, 76);
+            
+            success = ReportFailure(TestPassingFourFloatStructsNoVarargsManaged(), "TestPassingFourFloatStructsNoVarargsManaged()", success, 77);
+            success = ReportFailure(TestPassingTwoDoubleStructsNoVarargsManaged() , "TestPassingTwoDoubleStructsNoVarargsManaged() ", success, 78);
+            
+            success = ReportFailure(TestPassingTwoLongStructsAndFloatNoVarargsManaged(), "TestPassingTwoLongStructsAndFloatNoVarargsManaged()", success, 79);
+            success = ReportFailure(TestPassingFourDoubleStructsNoVarargsManaged(), "TestPassingFourDoubleStructsNoVarargsManaged()", success, 80);
+            
+            success = ReportFailure(TestPassingIntsManaged(new int[] { 100, 299, -100, 50 }), "TestPassingIntsManaged(new int[] { 100, 299, -100, 50 })", success, 30);
+            success = ReportFailure(TestPassingLongsManaged(new long[] { 100L, 299L, -100L, 50L }), "TestPassingLongsManaged(new long[] { 100L, 299L, -100L, 50L })", success, 31);
+            success = ReportFailure(TestPassingFloatsManaged(new float[] { 100.0f, 299.0f, -100.0f, 50.0f }), "TestPassingFloatsManaged(new float[] { 100.0f, 299.0f, -100.0f, 50.0f })", success, 32);
+            success = ReportFailure(TestPassingDoublesManaged(new double[] { 100.0d, 299.0d, -100.0d, 50.0d }), "TestPassingDoublesManaged(new double[] { 100.0d, 299.0d, -100.0d, 50.0d })", success, 33);
+
+            success = ReportFailure(TestPassingManyIntsManaged(new int[]
+            {
+                1002,
+                40,
+                39,
+                12,
+                14,
+                -502,
+                -13,
+                11,
+                98,
+                45,
+                3,
+                80,
+                7,
+                -1,
+                48,
+                66,
+                23,
+                62,
+                1092,
+                -890,
+                -20,
+                -41,
+                88,
+                98,
+                1,
+                2,
+                3,
+                4012,
+                16,
+                673,
+                873,
+                45,
+                85,
+                -3041,
+                22,
+                62,
+                401,
+                901,
+                501,
+                1001,
+                1002
+            }), "TestPassingManyIntsManaged", success, 34);
+
+            success = ReportFailure(TestPassingManyLongsManaged(new long[]
+            {
+                1002L,
+                40L,
+                39L,
+                12L,
+                14L,
+                -502L,
+                -13L,
+                11L,
+                98L,
+                45L,
+                3L,
+                80L,
+                7L,
+                -1L,
+                48L,
+                66L,
+                23L,
+                62L,
+                1092L,
+                -890L,
+                -20L,
+                -41L,
+                88L,
+                98L,
+                1L,
+                2L,
+                3L,
+                4012L,
+                16L,
+                673L,
+                873L,
+                45L,
+                85L,
+                -3041L,
+                22L,
+                62L,
+                401L,
+                901L,
+                501L,
+                1001L,
+                1002L
+            }), "TestPassingManyLongsManaged", success, 35);
+
+            success = ReportFailure(TestPassingManyFloatsManaged(new float[]
+            {
+                1002,
+                40,
+                39,
+                12,
+                14,
+                -502,
+                -13,
+                11,
+                98,
+                45,
+                3,
+                80,
+                7,
+                -1,
+                48,
+                66,
+                23,
+                62,
+                1092,
+                -890,
+                -20,
+                -41,
+                88,
+                98,
+                1,
+                2,
+                3,
+                4012,
+                16,
+                673,
+                873,
+                45,
+                85,
+                -3041,
+                22,
+                62,
+                401,
+                901,
+                501,
+                1001,
+                1002
+            }), "TestPassingManyFloatsManaged", success, 36);
+
+            success = ReportFailure(TestPassingManyDoublesManaged(new double[]
+            {
+                1002,
+                40,
+                39,
+                12,
+                14,
+                -502,
+                -13,
+                11,
+                98,
+                45,
+                3,
+                80,
+                7,
+                -1,
+                48,
+                66,
+                23,
+                62,
+                1092,
+                -890,
+                -20,
+                -41,
+                88,
+                98,
+                1,
+                2,
+                3,
+                4012,
+                16,
+                673,
+                873,
+                45,
+                85,
+                -3041,
+                22,
+                62,
+                401,
+                901,
+                501,
+                1001,
+                1002
+            }), "TestPassingManyDoublesManaged", success, 37);
+            
+            success = ReportFailure(TestPassingIntsAndLongsManaged(new int[] { 100, 200 }, new long[] { 102312131L, 91239191L }), "TestPassingIntsAndLongsManaged(new int[] { 100, 200 }, new long[] { 102312131L, 91239191L })", success, 38);
+            success = ReportFailure(TestPassingFloatsAndDoublesManaged(new float[] { 100.0F, 200.0F }, new double[] { 12.1231321, 441.2332132335342321 }), "TestPassingFloatsAndDoublesManaged(new float[] { 100.0F, 200.0F }, new double[] { 12.1231321, 441.2332132335342321 })", success, 39);
+
+            success = ReportFailure(TestPassingIntsAndFloatsManaged(), "TestPassingIntsAndFloatsManaged()", success, 40);
+            success = ReportFailure(TestPassingLongsAndDoublesManaged(), "TestPassingLongsAndDoublesManaged()", success, 41);
+
+            // Try passing empty varargs.
+            success = ReportFailure(TestPassingEmptyIntsManaged(new int[] { }), "TestPassingEmptyIntsManaged(new int[] { })", success, 42);
+            success = ReportFailure(TestPassingEmptyLongsManaged(new long[] { }), "TestPassingEmptyLongsManaged(new long[] { })", success, 43);
+            success = ReportFailure(TestPassingEmptyFloatsManaged(new float[] { }), "TestPassingEmptyFloatsManaged(new float[] { })", success, 44);
+            success = ReportFailure(TestPassingEmptyDoubleManaged(new double[] { }), "TestPassingEmptyDoubleManaged(new double[] { })", success, 45);
+
+            success = ReportFailure(TestPassingStructsManaged(), "TestPassingStructsManaged()", success, TestPassingStructsManaged());
+
+            ////////////////////////////////////////////////////////////////////
+            // PInvoke Tests
+            ////////////////////////////////////////////////////////////////////
+            
+            success = ReportFailure(TestPassingInts(new int[] { 100, 299, -100, 50 }), "TestPassingInts(new int[] { 100, 299, -100, 50 })", success, 1);
+            success = ReportFailure(TestPassingLongs(new long[] { 100L, 299L, -100L, 50L }), "TestPassingLongs(new long[] { 100L, 299L, -100L, 50L })", success, 2);
+            success = ReportFailure(TestPassingFloats(new float[] { 100.0f, 299.0f, -100.0f, 50.0f }), "TestPassingFloats(new float[] { 100.0f, 299.0f, -100.0f, 50.0f })", success, 3);
+            success = ReportFailure(TestPassingDoubles(new double[] { 100.0d, 299.0d, -100.0d, 50.0d }), "TestPassingDoubles(new double[] { 100.0d, 299.0d, -100.0d, 50.0d })", success, 4);
+
+            success = ReportFailure(TestPassingManyInts(new int[]
+            {
+                1002,
+                40,
+                39,
+                12,
+                14,
+                -502,
+                -13,
+                11,
+                98,
+                45,
+                3,
+                80,
+                7,
+                -1,
+                48,
+                66,
+                23,
+                62,
+                1092,
+                -890,
+                -20,
+                -41,
+                88,
+                98,
+                1,
+                2,
+                3,
+                4012,
+                16,
+                673,
+                873,
+                45,
+                85,
+                -3041,
+                22,
+                62,
+                401,
+                901,
+                501,
+                1001,
+                1002
+            }), "TestPassingManyInts", success, 5);
+
+            success = ReportFailure(TestPassingManyLongs(new long[]
+            {
+                1002L,
+                40L,
+                39L,
+                12L,
+                14L,
+                -502L,
+                -13L,
+                11L,
+                98L,
+                45L,
+                3L,
+                80L,
+                7L,
+                -1L,
+                48L,
+                66L,
+                23L,
+                62L,
+                1092L,
+                -890L,
+                -20L,
+                -41L,
+                88L,
+                98L,
+                1L,
+                2L,
+                3L,
+                4012L,
+                16L,
+                673L,
+                873L,
+                45L,
+                85L,
+                -3041L,
+                22L,
+                62L,
+                401L,
+                901L,
+                501L,
+                1001L,
+                1002L
+            }), "TestPassingManyLongs", success, 6);
+
+            // Passing doubles to native method.
+            success = ReportFailure(TestPassingManyFloats(new double[]
+            {
+                1002,
+                40,
+                39,
+                12,
+                14,
+                -502,
+                -13,
+                11,
+                98,
+                45,
+                3,
+                80,
+                7,
+                -1,
+                48,
+                66,
+                23,
+                62,
+                1092,
+                -890,
+                -20,
+                -41,
+                88,
+                98,
+                1,
+                2,
+                3,
+                4012,
+                16,
+                673,
+                873,
+                45,
+                85,
+                -3041,
+                22,
+                62,
+                401,
+                901,
+                501,
+                1001,
+                1002
+            }), "TestPassingManyFloats", success, 7);
+
+            success = ReportFailure(TestPassingManyDoubles(new double[]
+            {
+                1002,
+                40,
+                39,
+                12,
+                14,
+                -502,
+                -13,
+                11,
+                98,
+                45,
+                3,
+                80,
+                7,
+                -1,
+                48,
+                66,
+                23,
+                62,
+                1092,
+                -890,
+                -20,
+                -41,
+                88,
+                98,
+                1,
+                2,
+                3,
+                4012,
+                16,
+                673,
+                873,
+                45,
+                85,
+                -3041,
+                22,
+                62,
+                401,
+                901,
+                501,
+                1001,
+                1002
+            }), "TestPassingManyDoubles", success, 8);
+            
+            success = ReportFailure(TestPassingIntsAndLongs(new int[] { 100, 200 }, new long[] { 102312131L, 91239191L }), "TestPassingIntsAndLongs(new int[] { 100, 200 }, new long[] { 102312131L, 91239191L })", success, 9);
+            success = ReportFailure(TestPassingFloatsAndDoubles(new float[] { 100.0F, 200.0F }, new double[] { 12.1231321, 441.2332132335342321 }), "TestPassingFloatsAndDoubles(new float[] { 100.0F, 200.0F }, new double[] { 12.1231321, 441.2332132335342321 })", success, 10);
+
+            success = ReportFailure(TestPassingIntsAndFloats(), "TestPassingIntsAndFloats()", success, 28);
+            success = ReportFailure(TestPassingLongsAndDoubles(), "TestPassingLongsAndDoubles()", success, 29);
+
+            // Try passing empty varargs.
+            success = ReportFailure(TestPassingEmptyInts(new int[] { }), "TestPassingEmptyInts(new int[] { })", success, 11);
+            success = ReportFailure(TestPassingEmptyLongs(new long[] { }), "TestPassingEmptyLongs(new long[] { })", success, 12);
+            success = ReportFailure(TestPassingEmptyFloats(new float[] { }), "TestPassingEmptyFloats(new float[] { })", success, 13);
+            success = ReportFailure(TestPassingEmptyDouble(new double[] { }), "TestPassingEmptyDouble(new double[] { })", success, 14);
+
+            success = ReportFailure(TestPassingStructs(), "TestPassingStructs()", success, TestPassingStructs());
+
+            success = ReportFailure(TestPassingTwentyFourByteStructs(), "TestPassingTwentyFourByteStructs()", success, 108);
+
+            // Managed to managed Echo types.
+            // return passed fixed arg
+            success = ReportFailure(TestEchoByteManagedNoVararg(1), "TestEchoByteManagedNoVararg(1)", success, 109);
+            success = ReportFailure(TestEchoCharManagedNoVararg('c'), "TestEchoCharManagedNoVararg(1)", success, 110);
+            success = ReportFailure(TestEchoShortManagedNoVararg(2), "TestEchoShortManagedNoVararg(2)", success, 111);
+            success = ReportFailure(TestEchoIntManagedNoVararg(3), "TestEchoIntManagedNoVararg(3)", success, 112);
+            success = ReportFailure(TestEchoLongManagedNoVararg(4), "TestEchoLongManagedNoVararg(4)", success, 113);
+            success = ReportFailure(TestEchoFloatManagedNoVararg(5.0f), "TestEchoFloatManagedNoVararg(5.0f)", success, 114);
+            success = ReportFailure(TestEchoDoubleManagedNoVararg(6.0), "TestEchoDoubleManagedNoVararg(6.0)", success, 115);
+            success = ReportFailure(TestEchoOneIntStructManagedNoVararg(), "TestEchoOneIntStructManagedNoVararg()", success, 116);
+            success = ReportFailure(TestEchoTwoIntStructManagedNoVararg(), "TestEchoTwoIntStructManagedNoVararg()", success, 117);
+            success = ReportFailure(TestEchoOneLongStructManagedNoVararg(), "TestEchoOneLongStructManagedNoVararg()", success, 118);
+            success = ReportFailure(TestEchoTwoLongStructManagedNoVararg(), "TestEchoTwoLongStructManagedNoVararg()", success, 119);
+            success = ReportFailure(TestEchoEightByteStructStructManagedNoVararg(), "TestEchoEightByteStructStructManagedNoVararg()", success, 120);
+            success = ReportFailure(TestEchoFourIntStructManagedNoVararg(), "TestEchoFourIntStructManagedNoVararg()", success, 121);
+            success = ReportFailure(TestEchoSixteenByteStructManagedNoVararg(), "TestEchoSixteenByteStructManagedNoVararg()", success, 122);
+            success = ReportFailure(TestEchoFourLongStruct(), "TestEchoFourLongStruct()", success, 123);
+            success = ReportFailure(TestEchoFourLongStructManagedNoVararg(), "TestEchoFourLongStructManagedNoVararg()", success, 124);
+            success = ReportFailure(TestEchoOneFloatStructManagedNoVararg(), "TestEchoOneFloatStructManagedNoVararg()", success, 125);
+            success = ReportFailure(TestEchoTwoFloatStructManagedNoVararg(), "TestEchoTwoFloatStructManagedNoVararg()", success, 126);
+            success = ReportFailure(TestEchoOneDoubleStructManagedNoVararg(), "TestEchoOneDoubleStructManagedNoVararg()", success, 127);
+            success = ReportFailure(TestEchoTwoDoubleStructManagedNoVararg(), "TestEchoTwoDoubleStructManagedNoVararg()", success, 128);
+            success = ReportFailure(TestEchoThreeDoubleStructManagedNoVararg(), "TestEchoThreeDoubleStructManagedNoVararg()", success, 129);
+            success = ReportFailure(TestEchoFourFloatStructManagedNoVararg(), "TestEchoFourFloatStructManagedNoVararg()", success, 130);
+            success = ReportFailure(TestEchoFourDoubleStructManagedNoVararg(), "TestEchoFourDoubleStructManagedNoVararg()", success, 131);
+
+            // Managed to managed Echo types.
+            // return passed vararg
+            success = ReportFailure(TestEchoByteManaged(1), "TestEchoByteManaged(1)", success, 132);
+            success = ReportFailure(TestEchoCharManaged('c'), "TestEchoCharManaged(1)", success, 133);
+            success = ReportFailure(TestEchoShortManaged(2), "TestEchoShortManaged(2)", success, 134);
+            success = ReportFailure(TestEchoIntManaged(3), "TestEchoIntManaged(3)", success, 135);
+            success = ReportFailure(TestEchoLongManaged(4), "TestEchoLongManaged(4)", success, 136);
+            success = ReportFailure(TestEchoFloatManaged(5.0f), "TestEchoFloatManaged(5.0f)", success, 137);
+            success = ReportFailure(TestEchoDoubleManaged(6.0), "TestEchoDoubleManaged(6.0)", success, 138);
+            success = ReportFailure(TestEchoOneIntStructManaged(), "TestEchoOneIntStructManaged()", success, 139);
+            success = ReportFailure(TestEchoTwoIntStructManaged(), "TestEchoTwoIntStructManaged()", success, 140);
+            success = ReportFailure(TestEchoOneLongStructManaged(), "TestEchoOneLongStructManaged()", success, 141);
+            success = ReportFailure(TestEchoTwoLongStructManaged(), "TestEchoTwoLongStructManaged()", success, 142);
+            success = ReportFailure(TestEchoEightByteStructStructManaged(), "TestEchoEightByteStructStructManaged()", success, 143);
+            success = ReportFailure(TestEchoFourIntStructManaged(), "TestEchoFourIntStructManaged()", success, 144);
+            success = ReportFailure(TestEchoSixteenByteStructManaged(), "TestEchoSixteenByteStructManaged()", success, 145);
+            success = ReportFailure(TestEchoFourLongStruct(), "TestEchoFourLongStruct()", success, 146);
+            success = ReportFailure(TestEchoFourLongStructManaged(), "TestEchoFourLongStructManaged()", success, 147);
+            success = ReportFailure(TestEchoOneFloatStructManaged(), "TestEchoOneFloatStructManaged()", success, 148);
+            success = ReportFailure(TestEchoTwoFloatStructManaged(), "TestEchoTwoFloatStructManaged()", success, 149);
+            success = ReportFailure(TestEchoOneDoubleStructManaged(), "TestEchoOneDoubleStructManaged()", success, 150);
+            success = ReportFailure(TestEchoTwoDoubleStructManaged(), "TestEchoTwoDoubleStructManaged()", success, 151);
+            success = ReportFailure(TestEchoThreeDoubleStructManaged(), "TestEchoThreeDoubleStructManaged()", success, 152);
+            success = ReportFailure(TestEchoFourFloatStructManaged(), "TestEchoFourFloatStructManaged()", success, 153);
+            success = ReportFailure(TestEchoFourDoubleStructManaged(), "TestEchoFourDoubleStructManaged()", success, 154);
+
+            // Echo types.
+            success = ReportFailure(TestEchoByteNoVararg(1), "TestEchoByteNoVararg(1)", success, 85);
+            success = ReportFailure(TestEchoCharNoVararg('c'), "TestEchoCharNoVararg(1)", success, 86);
+            // Issue: https://github.com/dotnet/coreclr/issues/19705
+            // success = ReportFailure(TestEchoShortNoVararg(2), "TestEchoShortNoVararg(2)", success, 87);
+            success = ReportFailure(TestEchoIntNoVararg(3), "TestEchoIntNoVararg(3)", success, 88);
+            success = ReportFailure(TestEchoLongNoVararg(4), "TestEchoLongNoVararg(4)", success, 89);
+            success = ReportFailure(TestEchoFloatNoVararg(5.0f), "TestEchoFloatNoVararg(5.0f)", success, 90);
+            success = ReportFailure(TestEchoDoubleNoVararg(6.0), "TestEchoDoubleNoVararg(6.0)", success, 91);
+            success = ReportFailure(TestEchoOneIntStructNoVararg(), "TestEchoOneIntStructNoVararg()", success, 92);
+            success = ReportFailure(TestEchoTwoIntStructNoVararg(), "TestEchoTwoIntStructNoVararg()", success, 93);
+            success = ReportFailure(TestEchoOneLongStructNoVararg(), "TestEchoOneLongStructNoVararg()", success, 94);
+            success = ReportFailure(TestEchoTwoLongStructNoVararg(), "TestEchoTwoLongStructNoVararg()", success, 95);
+            success = ReportFailure(TestEchoEightByteStructStructNoVararg(), "TestEchoEightByteStructStructNoVararg()", success, 96);
+            success = ReportFailure(TestEchoFourIntStructNoVararg(), "TestEchoFourIntStructNoVararg()", success, 97);
+            success = ReportFailure(TestEchoSixteenByteStructNoVararg(), "TestEchoSixteenByteStructNoVararg()", success, 98);
+            success = ReportFailure(TestEchoFourLongStruct(), "TestEchoFourLongStruct()", success, 108);
+            success = ReportFailure(TestEchoFourLongStructNoVararg(), "TestEchoFourLongStructNoVararg()", success, 99);
+            success = ReportFailure(TestEchoOneFloatStructNoVararg(), "TestEchoOneFloatStructNoVararg()", success, 101);
+            success = ReportFailure(TestEchoTwoFloatStructNoVararg(), "TestEchoTwoFloatStructNoVararg()", success, 102);
+            success = ReportFailure(TestEchoOneDoubleStructNoVararg(), "TestEchoOneDoubleStructNoVararg()", success, 103);
+            success = ReportFailure(TestEchoTwoDoubleStructNoVararg(), "TestEchoTwoDoubleStructNoVararg()", success, 104);
+            success = ReportFailure(TestEchoThreeDoubleStructNoVararg(), "TestEchoThreeDoubleStructNoVararg()", success, 105);
+            success = ReportFailure(TestEchoFourFloatStructNoVararg(), "TestEchoFourFloatStructNoVararg()", success, 106);
+            success = ReportFailure(TestEchoFourDoubleStructNoVararg(), "TestEchoFourDoubleStructNoVararg()", success, 107);
+
+            printf("\n", __arglist());
+            printf("%d Tests run. %d Passed, %d Failed.\n", __arglist(m_testCount, m_passCount, m_failCount));
+
+            return success;
+        }
+    }
+}
diff --git a/tests/src/JIT/Directed/arglist/vararg.csproj b/tests/src/JIT/Directed/arglist/vararg.csproj
new file mode 100644 (file)
index 0000000..69a08a4
--- /dev/null
@@ -0,0 +1,43 @@
+<?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>
+    <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{21D66817-79E2-4E66-8839-EBC4B4BAD6C1}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DefineConstants Condition=" '$(OSGroup)' == 'Windows_NT' ">$(DefineConstants);WIN32</DefineConstants>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <PropertyGroup>
+    <DebugType>PdbOnly</DebugType>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="vararg.cs" />
+    <Compile Include="varargmanaged.cs"/>
+    <Compile Include="varargtypes.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="CMakeLists.txt" />
+  </ItemGroup>
+</Project>
diff --git a/tests/src/JIT/Directed/arglist/varargmanaged.cs b/tests/src/JIT/Directed/arglist/varargmanaged.cs
new file mode 100644 (file)
index 0000000..d8b8ca5
--- /dev/null
@@ -0,0 +1,1319 @@
+// Licensed to the .NET Foundation under one or more 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.Diagnostics;
+using System.Runtime.CompilerServices;
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NativeVarargTest
+{
+    public class ManagedNativeVarargTests
+    {
+        ////////////////////////////////////////////////////////////////////////
+        // Test passing fixed args to functions marked varargs
+        //
+        // Does not use ArgIterator, only tests fixed args not varargs.
+        //
+        // Note that all methods will take an empty arglist, which will mark
+        // the method as vararg.
+        ////////////////////////////////////////////////////////////////////////
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestPassingIntsNoVarargs(int one, 
+                                                   int two, 
+                                                   int three, 
+                                                   int four,
+                                                   int five, 
+                                                   int six, 
+                                                   int seven, 
+                                                   int eight,
+                                                   int nine,
+                                                   __arglist)
+        {
+            return one + two + three + four + five + six + seven + eight + nine;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestPassingLongsNoVarargs(long one, 
+                                                     long two, 
+                                                     long three, 
+                                                     long four,
+                                                     long five, 
+                                                     long six, 
+                                                     long seven, 
+                                                     long eight,
+                                                     long nine,
+                                                     __arglist)
+        {
+            return one + two + three + four + five + six + seven + eight + nine;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingFloatsNoVarargs(float one, 
+                                                     float two, 
+                                                     float three, 
+                                                     float four,
+                                                     float five, 
+                                                     float six, 
+                                                     float seven, 
+                                                     float eight,
+                                                     float nine,
+                                                     __arglist)
+        {
+            return one + two + three + four + five + six + seven + eight + nine;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingDoublesNoVarargs(double one, 
+                                                         double two, 
+                                                         double three, 
+                                                         double four,
+                                                         double five, 
+                                                         double six, 
+                                                         double seven, 
+                                                         double eight,
+                                                         double nine,
+                                                         __arglist)
+        {
+            return one + two + three + four + five + six + seven + eight + nine;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingIntAndFloatsNoVarargs(int one, 
+                                                             int two, 
+                                                             int three, 
+                                                             int four,
+                                                             int five, 
+                                                             int six, 
+                                                             int seven, 
+                                                             int eight,
+                                                             int nine,
+                                                             float ten, 
+                                                             float eleven, 
+                                                             float twelve, 
+                                                             float thirteen,
+                                                             float fourteen, 
+                                                             float fifteen, 
+                                                             float sixteen, 
+                                                             float seventeen,
+                                                             float eighteen,
+                                                            __arglist)
+        {
+            float sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingFloatsAndIntNoVarargs(float one, 
+                                                             float two, 
+                                                             float three, 
+                                                             float four,
+                                                             float five, 
+                                                             float six, 
+                                                             float seven, 
+                                                             float eight,
+                                                             float nine,
+                                                             int ten, 
+                                                             int eleven, 
+                                                             int twelve, 
+                                                             int thirteen,
+                                                             int fourteen, 
+                                                             int fifteen, 
+                                                             int sixteen, 
+                                                             int seventeen,
+                                                             int eighteen,
+                                                            __arglist)
+        {
+            float sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingIntAndDoublesNoVarargs(int one, 
+                                                               int two, 
+                                                               int three, 
+                                                               int four,
+                                                               int five, 
+                                                               int six, 
+                                                               int seven, 
+                                                               int eight,
+                                                               int nine,
+                                                               double ten, 
+                                                               double eleven, 
+                                                               double twelve, 
+                                                               double thirteen,
+                                                               double fourteen, 
+                                                               double fifteen, 
+                                                               double sixteen, 
+                                                               double seventeen,
+                                                               double eighteen,
+                                                              __arglist)
+        {
+            double sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingDoublesAndIntNoVarargs(double one, 
+                                                               double two, 
+                                                               double three, 
+                                                               double four,
+                                                               double five, 
+                                                               double six, 
+                                                               double seven, 
+                                                               double eight,
+                                                               double nine,
+                                                               int ten, 
+                                                               int eleven, 
+                                                               int twelve, 
+                                                               int thirteen,
+                                                               int fourteen, 
+                                                               int fifteen, 
+                                                               int sixteen, 
+                                                               int seventeen,
+                                                               int eighteen,
+                                                              __arglist)
+        {
+            double sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingLongAndFloatsNoVarargs(long one, 
+                                                              long two, 
+                                                              long three, 
+                                                              long four,
+                                                              long five, 
+                                                              long six, 
+                                                              long seven, 
+                                                              long eight,
+                                                              long nine,
+                                                              float ten, 
+                                                              float eleven, 
+                                                              float twelve, 
+                                                              float thirteen,
+                                                              float fourteen, 
+                                                              float fifteen, 
+                                                              float sixteen, 
+                                                              float seventeen,
+                                                              float eighteen,
+                                                             __arglist)
+        {
+            float sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingFloatsAndlongNoVarargs(float one, 
+                                                              float two, 
+                                                              float three, 
+                                                              float four,
+                                                              float five, 
+                                                              float six, 
+                                                              float seven, 
+                                                              float eight,
+                                                              float nine,
+                                                              long ten, 
+                                                              long eleven, 
+                                                              long twelve, 
+                                                              long thirteen,
+                                                              long fourteen, 
+                                                              long fifteen, 
+                                                              long sixteen, 
+                                                              long seventeen,
+                                                              long eighteen,
+                                                             __arglist)
+        {
+            float sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassinglongAndDoublesNoVarargs(long one, 
+                                                                long two, 
+                                                                long three, 
+                                                                long four,
+                                                                long five, 
+                                                                long six, 
+                                                                long seven, 
+                                                                long eight,
+                                                                long nine,
+                                                                double ten, 
+                                                                double eleven, 
+                                                                double twelve, 
+                                                                double thirteen,
+                                                                double fourteen, 
+                                                                double fifteen, 
+                                                                double sixteen, 
+                                                                double seventeen,
+                                                                double eighteen,
+                                                               __arglist)
+        {
+            double sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingDoublesAndlongNoVarargs(double one, 
+                                                                double two, 
+                                                                double three, 
+                                                                double four,
+                                                                double five, 
+                                                                double six, 
+                                                                double seven, 
+                                                                double eight,
+                                                                double nine,
+                                                                long ten, 
+                                                                long eleven, 
+                                                                long twelve, 
+                                                                long thirteen,
+                                                                long fourteen, 
+                                                                long fifteen, 
+                                                                long sixteen, 
+                                                                long seventeen,
+                                                                long eighteen,
+                                                               __arglist)
+        {
+            double sum = one + two + three + four + five + six + seven + eight + nine;
+            sum += ten + eleven + twelve + thirteen + fourteen + fifteen + sixteen + seventeen + eighteen;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestPassingTwoIntStructsNoVarargs(TwoIntStruct one, 
+                                                            TwoIntStruct two, 
+                                                            TwoIntStruct three, 
+                                                            TwoIntStruct four,
+                                                            TwoIntStruct five, 
+                                                            TwoIntStruct six, 
+                                                            TwoIntStruct seven, 
+                                                            TwoIntStruct eight,
+                                                            TwoIntStruct nine,
+                                                            TwoIntStruct ten, 
+                                                            __arglist)
+        {
+            int sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestPassingFourIntStructsNoVarargs(FourIntStruct one, 
+                                                             FourIntStruct two, 
+                                                             FourIntStruct three, 
+                                                             FourIntStruct four,
+                                                             FourIntStruct five, 
+                                                             FourIntStruct six, 
+                                                             FourIntStruct seven, 
+                                                             FourIntStruct eight,
+                                                             FourIntStruct nine,
+                                                             FourIntStruct ten, 
+                                                             __arglist)
+        {
+            int sum = one.a + one.b + one.c + one.d;
+            sum += two.a + two.b + two.c + two.d;
+            sum += three.a + three.b + three.c + three.d;
+            sum += four.a + four.b + four.c + four.d;
+            sum += five.a + five.b + five.c + five.d;
+            sum += six.a + six.b + six.c + six.d;
+            sum += seven.a + seven.b + seven.c + seven.d;
+            sum += eight.a + eight.b + eight.c + eight.d;
+            sum += nine.a + nine.b + nine.c + nine.d;
+            sum += ten.a + ten.b + ten.c + ten.d;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static bool TestPassingTwoLongStructsNoVarargs(int count,
+                                                              long expected,
+                                                              TwoLongStruct one, 
+                                                              TwoLongStruct two, 
+                                                              TwoLongStruct three, 
+                                                              TwoLongStruct four,
+                                                              TwoLongStruct five, 
+                                                              TwoLongStruct six, 
+                                                              TwoLongStruct seven, 
+                                                              TwoLongStruct eight,
+                                                              TwoLongStruct nine,
+                                                              TwoLongStruct ten, 
+                                                              __arglist)
+        {
+            long sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            return sum == expected;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestPassingTwoLongStructsNoVarargs(TwoLongStruct one, 
+                                                              TwoLongStruct two, 
+                                                              TwoLongStruct three, 
+                                                              TwoLongStruct four,
+                                                              TwoLongStruct five, 
+                                                              TwoLongStruct six, 
+                                                              TwoLongStruct seven, 
+                                                              TwoLongStruct eight,
+                                                              TwoLongStruct nine,
+                                                              TwoLongStruct ten, 
+                                                              __arglist)
+        {
+            long sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestPassingTwoLongStructsAndIntNoVarargs(int a,
+                                                           TwoLongStruct one, 
+                                                           TwoLongStruct two, 
+                                                           TwoLongStruct three, 
+                                                           TwoLongStruct four,
+                                                           TwoLongStruct five, 
+                                                           TwoLongStruct six, 
+                                                           TwoLongStruct seven, 
+                                                           TwoLongStruct eight,
+                                                           TwoLongStruct nine,
+                                                           TwoLongStruct ten, 
+                                                           __arglist)
+        {
+            long sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            sum += a;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestPassingFourLongStructsNoVarargs(FourLongStruct one, 
+                                                               FourLongStruct two, 
+                                                               FourLongStruct three, 
+                                                               FourLongStruct four,
+                                                               FourLongStruct five, 
+                                                               FourLongStruct six, 
+                                                               FourLongStruct seven, 
+                                                               FourLongStruct eight,
+                                                               FourLongStruct nine,
+                                                               FourLongStruct ten, 
+                                                               __arglist)
+        {
+            long sum = one.a + one.b + one.c + one.d;
+            sum += two.a + two.b + two.c + two.d;
+            sum += three.a + three.b + three.c + three.d;
+            sum += four.a + four.b + four.c + four.d;
+            sum += five.a + five.b + five.c + five.d;
+            sum += six.a + six.b + six.c + six.d;
+            sum += seven.a + seven.b + seven.c + seven.d;
+            sum += eight.a + eight.b + eight.c + eight.d;
+            sum += nine.a + nine.b + nine.c + nine.d;
+            sum += ten.a + ten.b + ten.c + ten.d;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingTwoFloatStructsNoVarargs(TwoFloatStruct one, 
+                                                     TwoFloatStruct two, 
+                                                     TwoFloatStruct three, 
+                                                     TwoFloatStruct four,
+                                                     TwoFloatStruct five, 
+                                                     TwoFloatStruct six, 
+                                                     TwoFloatStruct seven, 
+                                                     TwoFloatStruct eight,
+                                                     TwoFloatStruct nine,
+                                                     TwoFloatStruct ten, 
+                                                     __arglist)
+        {
+            float sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingFourFloatStructsNoVarargs(FourFloatStruct one, 
+                                                        FourFloatStruct two, 
+                                                        FourFloatStruct three, 
+                                                        FourFloatStruct four,
+                                                        FourFloatStruct five, 
+                                                        FourFloatStruct six, 
+                                                        FourFloatStruct seven, 
+                                                        FourFloatStruct eight,
+                                                        FourFloatStruct nine,
+                                                        FourFloatStruct ten, 
+                                                        __arglist)
+        {
+            float sum = one.a + one.b + one.c + one.d;
+            sum += two.a + two.b + two.c + two.d;
+            sum += three.a + three.b + three.c + three.d;
+            sum += four.a + four.b + four.c + four.d;
+            sum += five.a + five.b + five.c + five.d;
+            sum += six.a + six.b + six.c + six.d;
+            sum += seven.a + seven.b + seven.c + seven.d;
+            sum += eight.a + eight.b + eight.c + eight.d;
+            sum += nine.a + nine.b + nine.c + nine.d;
+            sum += ten.a + ten.b + ten.c + ten.d;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingTwoDoubleStructsNoVarargs(TwoDoubleStruct one, 
+                                                         TwoDoubleStruct two, 
+                                                         TwoDoubleStruct three, 
+                                                         TwoDoubleStruct four,
+                                                         TwoDoubleStruct five, 
+                                                         TwoDoubleStruct six, 
+                                                         TwoDoubleStruct seven, 
+                                                         TwoDoubleStruct eight,
+                                                         TwoDoubleStruct nine,
+                                                         TwoDoubleStruct ten, 
+                                                         __arglist)
+        {
+            double sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingTwoDoubleStructsAndFloatNoVarargs(float a,
+                                                                    TwoDoubleStruct one, 
+                                                                    TwoDoubleStruct two, 
+                                                                    TwoDoubleStruct three, 
+                                                                    TwoDoubleStruct four,
+                                                                    TwoDoubleStruct five, 
+                                                                    TwoDoubleStruct six, 
+                                                                    TwoDoubleStruct seven, 
+                                                                    TwoDoubleStruct eight,
+                                                                    TwoDoubleStruct nine,
+                                                                    TwoDoubleStruct ten, 
+                                                             __arglist)
+        {
+            double sum = one.a + one.b;
+            sum += two.a + two.b;
+            sum += three.a + three.b;
+            sum += four.a + four.b;
+            sum += five.a + five.b;
+            sum += six.a + six.b;
+            sum += seven.a + seven.b;
+            sum += eight.a + eight.b;
+            sum += nine.a + nine.b;
+            sum += ten.a + ten.b;
+
+            sum += a;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingFourDoubleStructsNoVarargs(FourDoubleStruct one, 
+                                                                   FourDoubleStruct two, 
+                                                                   FourDoubleStruct three, 
+                                                                   FourDoubleStruct four,
+                                                                   FourDoubleStruct five, 
+                                                                   FourDoubleStruct six, 
+                                                                   FourDoubleStruct seven, 
+                                                                   FourDoubleStruct eight,
+                                                                   FourDoubleStruct nine,
+                                                                   FourDoubleStruct ten, 
+                                                                   __arglist)
+        {
+            double sum = one.a + one.b + one.c + one.d;
+            sum += two.a + two.b + two.c + two.d;
+            sum += three.a + three.b + three.c + three.d;
+            sum += four.a + four.b + four.c + four.d;
+            sum += five.a + five.b + five.c + five.d;
+            sum += six.a + six.b + six.c + six.d;
+            sum += seven.a + seven.b + seven.c + seven.d;
+            sum += eight.a + eight.b + eight.c + eight.d;
+            sum += nine.a + nine.b + nine.c + nine.d;
+            sum += ten.a + ten.b + ten.c + ten.d;
+
+            return sum;
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Test returns
+        ////////////////////////////////////////////////////////////////////////
+
+        public static byte TestEchoByteManagedNoVararg(byte arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static char TestEchoCharManagedNoVararg(char arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static short TestEchoShortManagedNoVararg(short arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestEchoIntManagedNoVararg(int arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestEchoLongManagedNoVararg(long arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestEchoFloatManagedNoVararg(float arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestEchoDoubleManagedNoVararg(double arg, __arglist)
+        {
+            return arg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneIntStruct TestEchoOneIntStructManagedNoVararg(OneIntStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoIntStruct TestEchoTwoIntStructManagedNoVararg(TwoIntStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneLongStruct TestEchoOneLongStructManagedNoVararg(OneLongStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoLongStruct TestEchoTwoLongStructManagedNoVararg(TwoLongStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static EightByteStruct TestEchoEightByteStructStructManagedNoVararg(EightByteStruct arg, __arglist)
+        {
+            return arg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourIntStruct TestEchoFourIntStructManagedNoVararg(FourIntStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static SixteenByteStruct TestEchoSixteenByteStructManagedNoVararg(SixteenByteStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourLongStruct TestEchoFourLongStructManagedNoVararg(FourLongStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneFloatStruct TestEchoOneFloatStructManagedNoVararg(OneFloatStruct arg, __arglist) 
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoFloatStruct TestEchoTwoFloatStructManagedNoVararg(TwoFloatStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneDoubleStruct TestEchoOneDoubleStructManagedNoVararg(OneDoubleStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoDoubleStruct TestEchoTwoDoubleStructManagedNoVararg(TwoDoubleStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static ThreeDoubleStruct TestEchoThreeDoubleStructManagedNoVararg(ThreeDoubleStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourFloatStruct TestEchoFourFloatStructManagedNoVararg(FourFloatStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourDoubleStruct TestEchoFourDoubleStructManagedNoVararg(FourDoubleStruct arg, __arglist)
+        {
+            return arg;
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Test passing variable amount of args
+        //
+        // Uses ArgIterator
+        ////////////////////////////////////////////////////////////////////////
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestPassingInts(int count, __arglist)
+        {
+            int calculatedCount = 0;
+            ArgIterator it = new ArgIterator(__arglist);
+
+            int sum = 0;
+            while (it.GetRemainingCount() != 0)
+            {
+                int arg = __refvalue(it.GetNextArg(), int);
+
+                sum += arg;
+
+                ++calculatedCount;
+            }
+
+            if (calculatedCount != count) return -1;
+            
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestPassingLongs(int count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            int calculatedCount = 0;
+
+            long sum = 0;
+            while (it.GetRemainingCount() != 0)
+            {
+                long arg = __refvalue(it.GetNextArg(), long);
+
+                sum += arg;
+                ++calculatedCount;
+            }
+
+            if (calculatedCount != count) return -1;
+            
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingFloats(int count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            int calculatedCount = 0;
+
+            float sum = 0;
+            while (it.GetRemainingCount() != 0)
+            {
+                float arg = __refvalue(it.GetNextArg(), float);
+
+                sum += arg;
+                ++calculatedCount;
+            }
+
+            if (calculatedCount != count) return -1;
+            
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingDoubles(int count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            int calculatedCount = 0;
+
+            double sum = 0;
+            while (it.GetRemainingCount() != 0)
+            {
+                double arg = __refvalue(it.GetNextArg(), double);
+
+                sum += arg;
+                ++calculatedCount;
+            }
+
+            if (calculatedCount != count) return -1;
+            
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestPassingIntsAndLongs(int int_count, int long_count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+
+            int count = int_count + long_count;
+            long sum = 0;
+
+            for (int index = 0; index < int_count; ++index)
+            {
+                sum += __refvalue(it.GetNextArg(), int);
+            }
+
+            for (int index = 0; index < long_count; ++index)
+            {
+                sum += __refvalue(it.GetNextArg(), long);
+            }
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingFloatsAndDoubles(int float_count, int double_count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+
+            int count = float_count + double_count;
+            double sum = 0;
+
+            for (int index = 0; index < float_count; ++index)
+            {
+                sum += __refvalue(it.GetNextArg(), float);
+            }
+
+            for (int index = 0; index < double_count; ++index)
+            {
+                sum += __refvalue(it.GetNextArg(), double);
+            }
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestPassingIntsAndFloats(float expected_value, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            float sum = 0;
+
+            for (int index = 0; index < 6; ++index)
+            {
+                if (index % 2 == 0) {
+                    sum += __refvalue(it.GetNextArg(), int);
+                }
+                else
+                {
+                    sum += __refvalue(it.GetNextArg(), float);
+                }
+            }
+
+            if (expected_value != 66.0f) return -1;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestPassingLongsAndDoubles(double expected_value, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            double sum = 0;
+
+            for (int index = 0; index < 6; ++index)
+            {
+                if (index % 2 == 0) {
+                    sum += __refvalue(it.GetNextArg(), long);
+                }
+                else
+                {
+                    sum += __refvalue(it.GetNextArg(), double);
+                }
+            }
+
+            if (expected_value != 66.0) return -1;
+
+            return sum;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int CheckPassingStruct(int count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+    
+            int passed = 0;
+
+            bool is_b = __refvalue(it.GetNextArg(), int) == 1;
+            bool is_floating = __refvalue(it.GetNextArg(), int) == 1;
+            bool is_mixed = __refvalue(it.GetNextArg(), int) == 1;
+            int byte_count = __refvalue(it.GetNextArg(), int);
+            int struct_count = __refvalue(it.GetNextArg(), int);
+
+            if (!is_floating)
+            {
+                if (byte_count == 8)
+                {
+                    // Eight byte structs.
+                    if (is_b)
+                    {
+                        OneLongStruct s = new OneLongStruct();
+
+                        long sum = 0;
+                        long expected_value = __refvalue(it.GetNextArg(), long);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), OneLongStruct);
+                            sum += s.a;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                    else
+                    {
+                        TwoIntStruct s = new TwoIntStruct();
+
+                        int sum = 0;
+                        int expected_value =  __refvalue(it.GetNextArg(), int);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), TwoIntStruct);
+                            sum += s.a + s.b;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                }
+                else if (byte_count == 16)
+                {
+                    // 16 byte structs.
+                    if (is_b)
+                    {
+                        FourIntStruct s = new FourIntStruct();
+
+                        int sum = 0;
+                        int expected_value = __refvalue(it.GetNextArg(), int);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), FourIntStruct);
+                            sum += s.a + s.b + s.c + s.d;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                    else
+                    {
+                        TwoLongStruct s = new TwoLongStruct();
+
+                        long sum = 0;
+                        long expected_value = __refvalue(it.GetNextArg(), long);
+                        sum = 0;
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), TwoLongStruct);
+                            sum += s.a + s.b;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                }
+
+                else if (byte_count == 32)
+                {
+                    FourLongStruct s = new FourLongStruct();
+                    
+                    long sum = 0;
+                    long expected_value = __refvalue(it.GetNextArg(), long);
+
+                    while (struct_count-- != 0) {
+                        s = __refvalue(it.GetNextArg(), FourLongStruct);
+                        sum += s.a + s.b + s.c + s.d;
+                    }
+
+                    if (sum != expected_value) passed = 1;
+                }
+            }
+            else
+            {
+                if (byte_count == 8)
+                {
+                    // Eight byte structs.
+                    if (is_b)
+                    {
+                        OneDoubleStruct s = new OneDoubleStruct();
+
+                        double sum = 0;
+                        double expected_value = __refvalue(it.GetNextArg(), double);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), OneDoubleStruct);
+                            sum += s.a;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                    else
+                    {
+                        TwoFloatStruct s = new TwoFloatStruct();
+
+                        float sum = 0f;
+                        float expected_value = __refvalue(it.GetNextArg(), float);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), TwoFloatStruct);
+                            sum += s.a + s.b;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                }
+                else if (byte_count == 16)
+                {
+                    // 16 byte structs.
+                    if (is_b)
+                    {
+                        FourFloatStruct s = new FourFloatStruct();
+                        
+                        float sum = 0;
+                        float expected_value = __refvalue(it.GetNextArg(), float);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), FourFloatStruct);
+                            sum += s.a + s.b + s.c + s.d;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                    else
+                    {
+                        TwoDoubleStruct s = new TwoDoubleStruct();
+                        
+                        double sum = 0;
+                        double expected_value = __refvalue(it.GetNextArg(), double);
+
+                        while (struct_count-- != 0) {
+                            s = __refvalue(it.GetNextArg(), TwoDoubleStruct);
+                            sum += s.a + s.b;
+                        }
+
+                        if (sum != expected_value) passed = 1;
+                    }
+                }
+
+                else if (byte_count == 32)
+                {
+                    FourDoubleStruct s = new FourDoubleStruct();
+                    
+                    double sum = 0;
+                    double expected_value = __refvalue(it.GetNextArg(), double);
+
+                    while (struct_count-- != 0) {
+                        s = __refvalue(it.GetNextArg(), FourDoubleStruct);
+                        sum += s.a + s.b + s.c + s.d;
+                    }
+
+                    if (sum != expected_value) passed = 1;
+                }
+            }
+
+            return passed;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int CheckPassingFourSixteenByteStructs(int count, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+
+            int passed = 0;
+            long calculated_value = 0;
+
+            long expected_value = __refvalue(it.GetNextArg(), long);
+
+            for (int index = 0; index < 4; ++index) {
+                TwoLongStruct s = __refvalue(it.GetNextArg(), TwoLongStruct);
+
+                calculated_value += s.a + s.b;
+            }
+
+            passed = expected_value == calculated_value ? 0 : 1;
+            return passed;
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Test returns, using passed vararg
+        ////////////////////////////////////////////////////////////////////////
+
+        public static byte TestEchoByteManaged(byte arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            Debug.Assert(it.GetRemainingCount() > 0);
+
+            var varArg = __refvalue(it.GetNextArg(), byte);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static char TestEchoCharManaged(char arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), char);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static short TestEchoShortManaged(short arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), short);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int TestEchoIntManaged(int arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), int);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static long TestEchoLongManaged(long arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), long);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static float TestEchoFloatManaged(float arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), float);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static double TestEchoDoubleManaged(double arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), double);
+
+            return varArg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneIntStruct TestEchoOneIntStructManaged(OneIntStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), OneIntStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoIntStruct TestEchoTwoIntStructManaged(TwoIntStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), TwoIntStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneLongStruct TestEchoOneLongStructManaged(OneLongStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), OneLongStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoLongStruct TestEchoTwoLongStructManaged(TwoLongStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), TwoLongStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static EightByteStruct TestEchoEightByteStructStructManaged(EightByteStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), EightByteStruct);
+
+            return varArg;
+        }
+        
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourIntStruct TestEchoFourIntStructManaged(FourIntStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), FourIntStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static SixteenByteStruct TestEchoSixteenByteStructManaged(SixteenByteStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), SixteenByteStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourLongStruct TestEchoFourLongStructManaged(FourLongStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), FourLongStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneFloatStruct TestEchoOneFloatStructManaged(OneFloatStruct arg, __arglist) 
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), OneFloatStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoFloatStruct TestEchoTwoFloatStructManaged(TwoFloatStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), TwoFloatStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static OneDoubleStruct TestEchoOneDoubleStructManaged(OneDoubleStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), OneDoubleStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static TwoDoubleStruct TestEchoTwoDoubleStructManaged(TwoDoubleStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), TwoDoubleStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static ThreeDoubleStruct TestEchoThreeDoubleStructManaged(ThreeDoubleStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), ThreeDoubleStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourFloatStruct TestEchoFourFloatStructManaged(FourFloatStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), FourFloatStruct);
+
+            return varArg;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static FourDoubleStruct TestEchoFourDoubleStructManaged(FourDoubleStruct arg, __arglist)
+        {
+            ArgIterator it = new ArgIterator(__arglist);
+            var varArg = __refvalue(it.GetNextArg(), FourDoubleStruct);
+
+            return varArg;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/src/JIT/Directed/arglist/varargnative.c b/tests/src/JIT/Directed/arglist/varargnative.c
new file mode 100644 (file)
index 0000000..b14b556
--- /dev/null
@@ -0,0 +1,759 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT __attribute__((visibility("default")))
+
+#if __i386__
+#define _cdecl __attribute__((cdecl))
+#else
+#define _cdecl
+#endif
+
+#endif // _MSC_VER
+
+/* Structures */
+
+/*
+ * struct one_byte_struct (4 bytes)
+*/
+typedef struct 
+{
+    int one;
+} one_int_struct;
+
+/*
+ * struct two_int_struct (8 bytes)
+*/
+typedef struct 
+{
+    int one;
+    int two;
+} two_int_struct;
+
+/*
+ * struct one_long_long_struct (8 bytes)
+*/
+typedef struct 
+{
+    __int64 one;
+} one_long_long_struct;
+
+/*
+ * struct two_long_long_struct (16 bytes)
+*/
+typedef struct 
+{
+    __int64 one;
+    __int64 two;
+} two_long_long_struct;
+
+/*
+ * struct four_int_struct (16 bytes)
+*/
+typedef struct 
+{
+    int one;
+    int two;
+    int three;
+    int four;
+} four_int_struct;
+
+/*
+ * struct four_long_long_struct (32 bytes)
+*/
+typedef struct 
+{
+    __int64 one;
+    __int64 two;
+    __int64 three;
+    __int64 four;
+} four_long_long_struct;
+
+/*
+ * struct one_float_struct (4 bytes)
+*/
+typedef struct 
+{
+    float one;
+} one_float_struct;
+
+/*
+ * struct two_float_struct (8 bytes)
+*/
+typedef struct 
+{
+    float one;
+    float two;
+} two_float_struct;
+
+/*
+ * struct one_double_struct (8 bytes)
+*/
+typedef struct 
+{
+    double one;
+} one_double_struct;
+
+/*
+ * struct two_double_struct (16 bytes)
+*/
+typedef struct 
+{
+    double one;
+    double two;
+} two_double_struct;
+
+/*
+ * struct three_double_struct (24 bytes)
+*/
+typedef struct 
+{
+    double one;
+    double two;
+    double three;
+} three_double_struct;
+
+/*
+ * struct four_float_struct (16 bytes)
+*/
+typedef struct 
+{
+    float one;
+    float two;
+    float three;
+    float four;
+} four_float_struct;
+
+/*
+ * struct four_double_struct (32 bytes)
+*/
+typedef struct 
+{
+    double one;
+    double two;
+    double three;
+    double four;
+} four_double_struct;
+
+/*
+ * struct eight_byte_struct (8 bytes)
+*/
+typedef struct
+{
+    char one;
+    char two;
+    char three;
+    char four;
+    char five;
+    char six;
+    char seven;
+    char eight;
+} eight_byte_struct;
+
+/*
+ * struct sixteen_byte_struct (8 bytes)
+*/
+typedef struct
+{
+    char one;
+    char two;
+    char three;
+    char four;
+    char five;
+    char six;
+    char seven;
+    char eight;
+    char nine;
+    char ten;
+    char eleven;
+    char twelve;
+    char thirteen;
+    char fourteen;
+    char fifteen;
+    char sixteen;
+} sixteen_byte_struct;
+
+/* Tests */
+
+DLLEXPORT int _cdecl test_passing_ints(int count, ...)
+{
+    va_list ap;
+    int index, sum;
+
+    va_start(ap, count);
+
+    sum = 0;
+    for (index = 0; index < count; ++index)
+    {
+        sum += va_arg(ap, int);
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+DLLEXPORT __int64 _cdecl test_passing_longs(int count, ...)
+{
+    va_list ap;
+    int index;
+    __int64 sum;
+
+    va_start(ap, count);
+
+    sum = 0;
+    for (index = 0; index < count; ++index)
+    {
+        sum += va_arg(ap, __int64);
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+DLLEXPORT float _cdecl test_passing_floats(int count, ...)
+{
+    va_list ap;
+    int index;
+    double sum;
+
+    va_start(ap, count);
+
+    sum = 0;
+    for (index = 0; index < count; ++index)
+    {
+        sum += va_arg(ap, double);
+    }
+
+    va_end(ap);
+    return (float)sum;
+}
+
+DLLEXPORT double _cdecl test_passing_doubles(int count, ...)
+{
+    va_list ap;
+    int index;
+    double sum;
+
+    va_start(ap, count);
+
+    sum = 0;
+    for (index = 0; index < count; ++index)
+    {
+        sum += va_arg(ap, double);
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+DLLEXPORT __int64 _cdecl test_passing_int_and_longs(int int_count, int long_count, ...)
+{
+    va_list ap;
+    int index, count;
+    __int64 sum;
+
+    count = int_count + long_count;
+    va_start(ap, long_count);
+
+    sum = 0;
+    for (index = 0; index < int_count; ++index)
+    {
+        sum += va_arg(ap, int);
+    }
+
+    for (index = 0; index < long_count; ++index)
+    {
+        sum += va_arg(ap, __int64);
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+DLLEXPORT double _cdecl test_passing_floats_and_doubles(int float_count, int double_count, ...)
+{
+    va_list ap;
+    int index, count;
+    double sum;
+
+    count = float_count + double_count;
+    va_start(ap, double_count);
+
+
+    sum = 0;
+    for (index = 0; index < float_count; ++index)
+    {
+        // Read a double, C ABI defines reading a float as undefined, or
+        // an error on unix. However, the managed side will correctly pass a
+        // float.
+        sum += va_arg(ap, double);
+    }
+
+    for (index = 0; index < double_count; ++index)
+    {
+        sum += va_arg(ap, double);
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+/*
+    Args:
+        expected_value (double) : expected sum
+        int                     : first value
+        double                  : second value
+        int                     : third value
+        double                  : fourth value
+        int                     : fifth value
+        double                  : sixth value
+*/
+DLLEXPORT double _cdecl test_passing_int_and_double(double expected_value, ...)
+{
+    va_list ap;
+    int index, count;
+    double sum;
+
+    count = 6;
+    va_start(ap, expected_value);
+
+    sum = 0;
+    for (index = 0; index < 6; ++index)
+    {
+        if (index % 2 == 0) {
+            sum += va_arg(ap, int);
+        }
+        else
+        {
+            sum += va_arg(ap, double);
+        }
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+/*
+    Args:
+        expected_value (double) : expected sum
+        __int64                 : first value
+        double                  : second value
+        __int64                 : third value
+        double                  : fourth value
+        __int64                 : fifth value
+        double                  : sixth value
+*/
+DLLEXPORT double _cdecl test_passing_long_and_double(double expected_value, ...)
+{
+    va_list ap;
+    int index, count;
+    double sum;
+
+    count = 6;
+    va_start(ap, expected_value);
+
+    sum = 0;
+    for (index = 0; index < 6; ++index)
+    {
+        if (index % 2 == 0) {
+            sum += va_arg(ap, __int64);
+        }
+        else
+        {
+            sum += va_arg(ap, double);
+        }
+    }
+
+    va_end(ap);
+    return sum;
+}
+
+/*
+    Args:
+        count (int)         : count of args
+        is_int_structs(int) : first value
+        is_float_value(int) : second value
+        is_mixed (int)      : third value
+        byte_count (int)    : fourth value
+        struct_count (int)  : fifth value
+*/
+DLLEXPORT int _cdecl check_passing_struct(int count, ...)
+{
+    va_list ap;
+    int is_b, is_floating, is_mixed, byte_count, struct_count;
+    
+    int expected_value_i;
+    __int64 expected_value_l;
+    double expected_value_f;
+    double expected_value_d;
+
+    int passed = 0;
+
+    va_start(ap, count);
+
+    is_b = va_arg(ap, int);
+    is_floating = va_arg(ap, int);
+    is_mixed = va_arg(ap, int);
+    byte_count = va_arg(ap, int);
+    struct_count = va_arg(ap, int);
+
+    if (!is_floating)
+    {
+        if (byte_count == 8)
+        {
+            // Eight byte structs.
+            if (is_b)
+            {
+                // This is one_long_long_struct
+                one_long_long_struct s;
+                __int64 sum;
+
+                expected_value_l = va_arg(ap, __int64);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, one_long_long_struct);
+                    sum += s.one;
+                }
+
+                if (sum != expected_value_l) passed = 1;
+            }
+            else
+            {
+                // This is two_int_struct
+                two_int_struct s;
+                int sum;
+
+                expected_value_i = va_arg(ap, int);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, two_int_struct);
+                    sum += s.one + s.two;
+                }
+
+                if (sum != expected_value_i) passed = 1;
+            }
+        }
+        else if (byte_count == 16)
+        {
+            // 16 byte structs.
+            if (is_b)
+            {
+                // This is four_int_struct
+                four_int_struct s;
+                int sum;
+
+                expected_value_i = va_arg(ap, int);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, four_int_struct);
+                    sum += s.one + s.two + s.three + s.four;
+                }
+
+                if (sum != expected_value_i) passed = 1;
+            }
+            else
+            {
+                // This is two_long_long_struct
+                two_long_long_struct s;
+                __int64 sum;
+
+                expected_value_l = va_arg(ap, __int64);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, two_long_long_struct);
+                    sum += s.one + s.two;
+                }
+
+                if (sum != expected_value_l) passed = 1;
+            }
+        }
+
+        else if (byte_count == 32)
+        {
+            // This is sixteen_byte_struct
+            four_long_long_struct s;
+            __int64 sum;
+
+            expected_value_l = va_arg(ap, __int64);
+            sum = 0;
+
+            while (struct_count--) {
+                s = va_arg(ap, four_long_long_struct);
+                sum += s.one + s.two + s.three + s.four;
+            }
+
+            if (sum != expected_value_l) passed = 1;
+        }
+    }
+    else
+    {
+        if (byte_count == 8)
+        {
+            // Eight byte structs.
+            if (is_b)
+            {
+                // This is one_double_struct
+                one_double_struct s;
+                double sum;
+
+                expected_value_d = va_arg(ap, double);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, one_double_struct);
+                    sum += s.one;
+                }
+
+                if (sum != expected_value_d) passed = 1;
+            }
+            else
+            {
+                // This is two_float_struct
+                two_float_struct s;
+                float sum;
+
+                expected_value_f = va_arg(ap, double);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, two_float_struct);
+                    sum += s.one + s.two;
+                }
+
+                if (sum != expected_value_f) passed = 1;
+            }
+        }
+        else if (byte_count == 16)
+        {
+            // 16 byte structs.
+            if (is_b)
+            {
+                // This is four_float_struct
+                four_float_struct s;
+                float sum;
+
+                expected_value_f = va_arg(ap, double);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, four_float_struct);
+                    sum += s.one + s.two + s.three + s.four;
+                }
+
+                if (sum != expected_value_f) passed = 1;
+            }
+            else
+            {
+                // This is two_double_struct
+                two_double_struct s;
+                double sum;
+
+                expected_value_d = va_arg(ap, double);
+                sum = 0;
+
+                while (struct_count--) {
+                    s = va_arg(ap, two_double_struct);
+                    sum += s.one + s.two;
+                }
+
+                if (sum != expected_value_d) passed = 1;
+            }
+        }
+
+        else if (byte_count == 32)
+        {
+            // This is four_double_struct
+            four_double_struct s;
+            double sum;
+
+            expected_value_d = va_arg(ap, double);
+            sum = 0;
+
+            while (struct_count--) {
+                s = va_arg(ap, four_double_struct);
+                sum += s.one + s.two + s.three + s.four;
+            }
+
+            if (sum != expected_value_d) passed = 1;
+        }
+    }
+
+    va_end(ap);
+    return passed;
+}
+
+DLLEXPORT double _cdecl check_passing_four_three_double_struct(three_double_struct one, three_double_struct two, three_double_struct three, three_double_struct four, ...)
+{
+    double sum;
+
+    sum = 0;
+
+    sum += one.one + one.two + one.three;
+    sum += two.one + two.two + two.three;
+    sum += three.one + three.two + three.three;
+    sum += four.one + four.two + four.three;
+
+    return sum;
+}
+
+/*
+    Args:
+        count (int)             : count of args
+        two_long_long_struct    : first value
+        two_long_long_struct    : second value
+        two_long_long_struct    : third value
+        two_long_long_struct    : fourth value
+*/
+DLLEXPORT int _cdecl check_passing_four_sixteen_byte_structs(int count, ...)
+{
+    va_list ap;
+    int passed, index;
+    two_long_long_struct s;
+    __int64 expected_value, calculated_value;
+
+    passed = 0;
+    calculated_value = 0;
+
+    va_start(ap, count);
+
+    expected_value = va_arg(ap, __int64);
+
+    for (index = 0; index < 4; ++index) {
+        s = va_arg(ap, two_long_long_struct);
+
+        calculated_value += s.one + s.two;
+    }
+
+    va_end(ap);
+
+    passed = expected_value == calculated_value ? 0 : 1;
+    return passed;
+}
+
+DLLEXPORT char _cdecl echo_byte(char arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT char _cdecl echo_char(char arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT __int8 _cdecl echo_short(__int8 arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT __int32 _cdecl echo_int(__int32 arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT __int64 _cdecl echo_int64(__int64 arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT float _cdecl echo_float(float arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT double _cdecl echo_double(double arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT one_int_struct _cdecl echo_one_int_struct(one_int_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT two_int_struct _cdecl echo_two_int_struct(two_int_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT one_long_long_struct _cdecl echo_one_long_struct(one_long_long_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT two_long_long_struct _cdecl echo_two_long_struct(two_long_long_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT four_long_long_struct _cdecl echo_four_long_struct(four_long_long_struct arg)
+{
+    return arg;
+}
+
+DLLEXPORT four_long_long_struct _cdecl echo_four_long_struct_with_vararg(four_long_long_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT eight_byte_struct _cdecl echo_eight_byte_struct(eight_byte_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT four_int_struct _cdecl echo_four_int_struct(four_int_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT sixteen_byte_struct _cdecl echo_sixteen_byte_struct(sixteen_byte_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT one_float_struct _cdecl echo_one_float_struct(one_float_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT two_float_struct _cdecl echo_two_float_struct(two_float_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT one_double_struct _cdecl echo_one_double_struct(one_double_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT two_double_struct _cdecl echo_two_double_struct(two_double_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT three_double_struct _cdecl echo_three_double_struct(three_double_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT four_float_struct _cdecl echo_four_float_struct(four_float_struct arg, ...)
+{
+    return arg;
+}
+
+DLLEXPORT four_double_struct _cdecl echo_four_double_struct(four_double_struct arg, ...)
+{
+    return arg;
+}
diff --git a/tests/src/JIT/Directed/arglist/varargtypes.cs b/tests/src/JIT/Directed/arglist/varargtypes.cs
new file mode 100644 (file)
index 0000000..4c055d3
--- /dev/null
@@ -0,0 +1,121 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace NativeVarargTest
+{
+    public struct OneIntStruct 
+    {
+        public int a;
+    }
+
+    public struct TwoIntStruct
+    {
+        public int a;
+        public int b;
+    }
+
+    public struct OneLongStruct
+    {
+        public long a;
+    }
+
+    public struct TwoLongStruct
+    {
+        public long a;
+        public long b;
+    }
+
+    public struct EightByteStruct
+    {
+        public byte one;
+        public byte two;
+        public byte three;
+        public byte four;
+        public byte five;
+        public byte six;
+        public byte seven;
+        public byte eight;
+    }
+
+    public struct FourIntStruct
+    {
+        public int a;
+        public int b;
+        public int c;
+        public int d;
+    }
+
+    public struct SixteenByteStruct
+    {
+        public byte one;
+        public byte two;
+        public byte three;
+        public byte four;
+        public byte five;
+        public byte six;
+        public byte seven;
+        public byte eight;
+        public byte nine;
+        public byte ten;
+        public byte eleven;
+        public byte twelve;
+        public byte thirteen;
+        public byte fourteen;
+        public byte fifteen;
+        public byte sixteen;
+    }
+
+    public struct FourLongStruct
+    {
+        public long a;
+        public long b;
+        public long c;
+        public long d;
+    }
+
+    public struct OneFloatStruct
+    {
+        public float a;
+    }
+
+    public struct TwoFloatStruct
+    {
+        public float a;
+        public float b;
+    }
+
+    public struct OneDoubleStruct
+    {
+        public double a;
+    }
+
+    public struct TwoDoubleStruct
+    {
+        public double a;
+        public double b;
+    }
+
+    public struct ThreeDoubleStruct
+    {
+        public double a;
+        public double b;
+        public double c;
+    }
+
+    public struct FourFloatStruct
+    {
+        public float a;
+        public float b;
+        public float c;
+        public float d;
+    }
+
+    public struct FourDoubleStruct
+    {
+        public double a;
+        public double b;
+        public double c;
+        public double d;
+    }
+}
\ No newline at end of file
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs
new file mode 100644 (file)
index 0000000..b1a8023
--- /dev/null
@@ -0,0 +1,1179 @@
+// Licensed to the .NET Foundation under one or more 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+using System.Collections.Generic;
+
+namespace IntelHardwareIntrinsicTest
+{
+    class Program
+    {
+        const int Pass = 100;
+        const int Fail = 0;
+
+        const int N = 64;
+
+        static byte Four;
+        static byte Eight;
+        static byte invalid;
+
+        static readonly float[] floatSourceTable = new float[N];
+        static readonly double[] doubleSourceTable = new double[N];
+        static readonly int[] intSourceTable = new int[N];
+        static readonly long[] longSourceTable = new long[N];
+
+        static readonly int[] intIndexTable = new int[4] {8, 16, 32, 63};
+        static readonly long[] longIndexTable = new long[2] {16, 32};
+        static readonly long[] vector256longIndexTable = new long[4] {8, 16, 32, 63};
+
+        static readonly int[] intMaskTable = new int[4] {-1, 0, -1, 0};
+        static readonly long[] longMaskTable = new long[2] {-1, 0};
+
+        static unsafe int Main(string[] args)
+        {
+            int testResult = Pass;
+
+            if (Avx2.IsSupported)
+            {
+                Four = 4;
+                Eight = 8;
+                invalid = 15;
+
+                for (int i = 0; i < N; i++)
+                {
+                    floatSourceTable[i] = (float)i * 10.0f;
+                    doubleSourceTable[i] = (double)i * 10.0;
+                    intSourceTable[i] = i * 10;
+                    longSourceTable[i] = i * 10;
+                }
+
+                Vector128<int> indexi;
+                Vector128<long> indexl;
+                Vector256<long> indexl256;
+
+                fixed (int* iptr = intIndexTable)
+                fixed (long* lptr = longIndexTable)
+                fixed (long* l256ptr = vector256longIndexTable)
+                {
+                    indexi = Sse2.LoadVector128(iptr);
+                    indexl = Sse2.LoadVector128(lptr);
+                    indexl256 = Avx.LoadVector256(l256ptr);
+                }
+
+                Vector128<int> maski;
+                Vector128<uint> maskui;
+                Vector128<long> maskl;
+                Vector128<ulong> maskul;
+                Vector128<float> maskf;
+                Vector128<double> maskd;
+
+                fixed (int* iptr = intMaskTable)
+                fixed (long* lptr = longMaskTable)
+                {
+                    maski = Sse2.LoadVector128(iptr);
+                    maskl = Sse2.LoadVector128(lptr);
+
+                    maskui = Sse.StaticCast<int, uint>(maski);
+                    maskul = Sse.StaticCast<long, ulong>(maskl);
+                    maskf = Sse.StaticCast<int, float>(maski);
+                    maskd = Sse.StaticCast<long, double>(maskl);
+                }
+
+                Vector128<int> sourcei = Sse2.SetZeroVector128<int>();
+                Vector128<uint> sourceui = Sse2.SetZeroVector128<uint>();
+                Vector128<long> sourcel = Sse2.SetZeroVector128<long>();
+                Vector128<ulong> sourceul = Sse2.SetZeroVector128<ulong>();
+                Vector128<float> sourcef = Sse.SetZeroVector128();
+                Vector128<double> sourced = Sse2.SetZeroVector128<double>();
+
+
+                // public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<int> index, Vector128<float> mask, byte scale)
+                using (TestTable<float, int> floatTable = new TestTable<float, int>(floatSourceTable, new float[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<float>), typeof(float*), typeof(Vector128<int>), typeof(Vector128<float>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, maskf, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with non-const scale (IMM):");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+
+                // public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<int> index, Vector128<double> mask, byte scale)
+                using (TestTable<double, int> doubletTable = new TestTable<double, int>(doubleSourceTable, new double[2]))
+                {
+                    var vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector128<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<double>), typeof(double*), typeof(Vector128<int>), typeof(Vector128<double>), typeof(byte)}).
+                            Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi, maskd, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd,  Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with non-const scale (IMM):");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd,  invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<int> index, Vector128<int> mask, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<int>), typeof(int*), typeof(Vector128<int>), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, maski, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<int> index, Vector128<uint> mask, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<uint>), typeof(uint*), typeof(Vector128<int>), typeof(Vector128<uint>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, maskui, (byte)4});
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<int> index, Vector128<long> mask, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<long>), typeof(long*), typeof(Vector128<int>), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi, maskl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<int> index, Vector128<ulong> mask, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<ulong>), typeof(ulong*), typeof(Vector128<int>), typeof(Vector128<ulong>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi, maskul, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector128<long> index, Vector128<int> mask, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<int>), typeof(int*), typeof(Vector128<long>), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl, maski, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on int with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski,  3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski,  Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski,  invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector128<long> index, Vector128<uint> mask, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<uint>), typeof(uint*), typeof(Vector128<long>), typeof(Vector128<uint>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl, maskui, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on uint with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<long> GatherMaskVector128(Vector128<long> source, long* baseAddress, Vector128<long> index, Vector128<long> mask, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<long>), typeof(long*), typeof(Vector128<long>), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, maskl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on long with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<ulong> GatherMaskVector128(Vector128<ulong> source, ulong* baseAddress, Vector128<long> index, Vector128<ulong> mask, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<ulong>), typeof(ulong*), typeof(Vector128<long>), typeof(Vector128<ulong>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, maskul, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on ulong with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid non-const scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+                
+                // public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector128<long> index, Vector128<float> mask, byte scale)
+                using (TestTable<float, long> floatTable = new TestTable<float, long>(floatSourceTable, new float[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with Vector128 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<float>), typeof(float*), typeof(Vector128<long>), typeof(Vector128<float>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl, maskf, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on float with Vector128 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid non-const scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<double> GatherMaskVector128(Vector128<double> source, double* baseAddress, Vector128<long> index, Vector128<double> mask, byte scale)
+                using (TestTable<double, long> doubletTable = new TestTable<double, long>(doubleSourceTable, new double[2]))
+                {
+                    var vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with Vector128 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector128<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<double>), typeof(double*), typeof(Vector128<long>), typeof(Vector128<double>), typeof(byte)}).
+                            Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, maskd, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on double with Vector128 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid non-const scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<int> GatherMaskVector128(Vector128<int> source, int* baseAddress, Vector256<long> index, Vector128<int> mask, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<int>), typeof(int*), typeof(Vector256<long>), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl256, maski, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on int with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<uint> GatherMaskVector128(Vector128<uint> source, uint* baseAddress, Vector256<long> index, Vector128<uint> mask, byte scale) 
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<uint>), typeof(uint*), typeof(Vector256<long>), typeof(Vector128<uint>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl256, maskui, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on uint with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<float> GatherMaskVector128(Vector128<float> source, float* baseAddress, Vector256<long> index, Vector128<float> mask, byte scale)
+                using (TestTable<float, long> floatTable = new TestTable<float, long>(floatSourceTable, new float[4]))
+                {
+                    var vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with Vector256 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128<float>), typeof(float*), typeof(Vector256<long>), typeof(Vector128<float>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl256, maskf, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on float with Vector256 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+            }
+
+            return testResult;
+        }
+
+        public unsafe struct TestTable<T, U> : IDisposable where T : struct where U : struct
+        {
+            public T[] inArray;
+            public T[] outArray;
+
+            public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
+            public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+            GCHandle inHandle;
+            GCHandle outHandle;
+            public TestTable(T[] a, T[] b)
+            {
+                this.inArray = a;
+                this.outArray = b;
+
+                inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned);
+                outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+            }
+            public bool CheckResult(Func<T, T, bool> check, U[] indexArray)
+            {
+                int length = Math.Min(indexArray.Length, outArray.Length);
+                for (int i = 0; i < length; i++)
+                {
+                    bool take = i % 2 == 0;
+                    if ((take && !check(inArray[Convert.ToInt32(indexArray[i])], outArray[i])) ||
+                        (!take && !EqualityComparer<T>.Default.Equals(outArray[i], default(T))))
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            public void Dispose()
+            {
+                inHandle.Free();
+                outHandle.Free();
+            }
+        }
+
+    }
+}
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{2099478C-8A85-4032-8F86-402DA54F8FA2}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize></Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareOrderedScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherMaskVector128.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>
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{AA7AFEBE-8C40-4A22-8A1E-5FC39EDD9A51}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize>True</Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareOrderedScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherMaskVector128.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/Avx2/GatherMaskVector256.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256.cs
new file mode 100644 (file)
index 0000000..551860c
--- /dev/null
@@ -0,0 +1,763 @@
+// Licensed to the .NET Foundation under one or more 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+using System.Collections.Generic;
+
+namespace IntelHardwareIntrinsicTest
+{
+    class Program
+    {
+        const int Pass = 100;
+        const int Fail = 0;
+
+        const int N = 128;
+
+        static byte Four;
+        static byte Eight;
+        static byte invalid;
+
+        static readonly float[] floatSourceTable = new float[N];
+        static readonly double[] doubleSourceTable = new double[N];
+        static readonly int[] intSourceTable = new int[N];
+        static readonly long[] longSourceTable = new long[N];
+
+        static readonly int[] intIndexTable = new int[8] {1, 2, 4, 8, 16, 32, 40, 63};
+        static readonly long[] longIndexTable = new long[4] {2, 8, 16, 32};
+        static readonly int[] vector128intIndexTable = new int[4] {8, 16, 32, 63};
+
+        static readonly int[] intMaskTable = new int[8] {-1, 0, -1, 0, -1, 0, -1, 0};
+        static readonly long[] longMaskTable = new long[4] {-1, 0, -1, 0};
+
+        static unsafe int Main(string[] args)
+        {
+            int testResult = Pass;
+
+            if (Avx2.IsSupported)
+            {
+                Four = 4;
+                Eight = 8;
+                invalid = 15;
+
+                for (int i = 0; i < N; i++)
+                {
+                    floatSourceTable[i] = (float)i * 10.0f;
+                    doubleSourceTable[i] = (double)i * 10.0;
+                    intSourceTable[i] = i * 10;
+                    longSourceTable[i] = i * 10;
+                }
+
+                Vector256<int> indexi;
+                Vector256<long> indexl;
+                Vector128<int> indexi128;
+
+                fixed (int* iptr = intIndexTable)
+                fixed (long* lptr = longIndexTable)
+                fixed (int* i128ptr = vector128intIndexTable)
+                {
+                    indexi = Avx.LoadVector256(iptr);
+                    indexl = Avx.LoadVector256(lptr);
+                    indexi128 = Sse2.LoadVector128(i128ptr);
+                }
+
+                Vector256<int> maski;
+                Vector256<uint> maskui;
+                Vector256<long> maskl;
+                Vector256<ulong> maskul;
+                Vector256<float> maskf;
+                Vector256<double> maskd;
+
+                fixed (int* iptr = intMaskTable)
+                fixed (long* lptr = longMaskTable)
+                {
+                    maski = Avx.LoadVector256(iptr);
+                    maskl = Avx.LoadVector256(lptr);
+
+                    maskui = Avx.StaticCast<int, uint>(maski);
+                    maskul = Avx.StaticCast<long, ulong>(maskl);
+                    maskf = Avx.StaticCast<int, float>(maski);
+                    maskd = Avx.StaticCast<long, double>(maskl);
+                }
+
+                Vector256<int> sourcei = Avx.SetZeroVector256<int>();
+                Vector256<uint> sourceui = Avx.SetZeroVector256<uint>();
+                Vector256<long> sourcel = Avx.SetZeroVector256<long>();
+                Vector256<ulong> sourceul = Avx.SetZeroVector256<ulong>();
+                Vector256<float> sourcef = Avx.SetZeroVector256<float>();
+                Vector256<double> sourced = Avx.SetZeroVector256<double>();
+
+                // public static unsafe Vector256<float> GatherMaskVector256(Vector256<float> source, float* baseAddress, Vector256<int> index, Vector256<float> mask, byte scale)
+                using (TestTable<float, int> floatTable = new TestTable<float, int>(floatSourceTable, new float[8]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<float>), typeof(float*), typeof(Vector256<int>), typeof(Vector256<float>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, maskf, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf,  3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on float with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf,  Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on float with non-const scale (IMM):");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf,  invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on float with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector128<int> index, Vector256<double> mask, byte scale)
+                using (TestTable<double, int> doubletTable = new TestTable<double, int>(doubleSourceTable, new double[4]))
+                {
+                    var vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector256<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<double>), typeof(double*), typeof(Vector128<int>), typeof(Vector256<double>), typeof(byte)}).
+                            Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi128, maskd, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd,  3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd,  Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with non-const scale (IMM):");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd,  invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<int> GatherMaskVector256(Vector256<int> source, int* baseAddress, Vector256<int> index, Vector256<int> mask, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[8]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<int>), typeof(int*), typeof(Vector256<int>), typeof(Vector256<int>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, maski, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on int with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on int with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on int with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<uint> GatherMaskVector256(Vector256<uint> source, uint* baseAddress, Vector256<int> index, Vector256<uint> mask, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[8]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<uint>), typeof(uint*), typeof(Vector256<int>), typeof(Vector256<uint>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, maskui, (byte)4 });
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on uint with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on uint with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on uint with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector128<int> index, Vector256<long> mask, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<long>), typeof(long*), typeof(Vector128<int>), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi128, maskl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector128<int> index, Vector256<ulong> mask, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<ulong>), typeof(ulong*), typeof(Vector128<int>), typeof(Vector256<ulong>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi128, maskul, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul,  3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul,  Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul,  invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<long> GatherMaskVector256(Vector256<long> source, long* baseAddress, Vector256<long> index, Vector256<long> mask, byte scale) 
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<long>), typeof(long*), typeof(Vector256<long>), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, maskl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on long with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<ulong> GatherMaskVector256(Vector256<ulong> source, ulong* baseAddress, Vector256<long> index, Vector256<ulong> mask, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<ulong>), typeof(ulong*), typeof(Vector256<long>), typeof(Vector256<ulong>), typeof(byte)}).
+                            Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, maskul, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on ulong with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul,  3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul,  Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul,  invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }                
+
+                // public static unsafe Vector256<double> GatherMaskVector256(Vector256<double> source, double* baseAddress, Vector256<long> index, Vector256<double> mask, byte scale)
+                using (TestTable<double, long> doubletTable = new TestTable<double, long>(doubleSourceTable, new double[4]))
+                {
+                    var vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with Vector256 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector256<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256<double>), typeof(double*), typeof(Vector256<long>), typeof(Vector256<double>), typeof(byte)}).
+                            Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, maskd, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on double with Vector256 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 3);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, invalid);
+                        Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+            }
+
+            
+
+            return testResult;
+        }
+
+        public unsafe struct TestTable<T, U> : IDisposable where T : struct where U : struct
+        {
+            public T[] inArray;
+            public T[] outArray;
+
+            public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
+            public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+            GCHandle inHandle;
+            GCHandle outHandle;
+            public TestTable(T[] a, T[] b)
+            {
+                this.inArray = a;
+                this.outArray = b;
+
+                inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned);
+                outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+            }
+            public bool CheckResult(Func<T, T, bool> check, U[] indexArray)
+            {
+                int length = Math.Min(indexArray.Length, outArray.Length);
+                for (int i = 0; i < length; i++)
+                {
+                    bool take = i % 2 == 0;
+                    if ((take && !check(inArray[Convert.ToInt32(indexArray[i])], outArray[i])) ||
+                        (!take && !EqualityComparer<T>.Default.Equals(outArray[i], default(T))))
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            public void Dispose()
+            {
+                inHandle.Free();
+                outHandle.Free();
+            }
+        }
+
+    }
+}
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{15931119-A410-40C5-9FCC-D7A714C68512}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize></Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareUnorderedScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherMaskVector256.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>
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{66739F14-FEA4-4993-B0E7-3E9B0D824FED}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize>True</Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareUnorderedScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherMaskVector256.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/Avx2/GatherVector128.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128.cs
new file mode 100644 (file)
index 0000000..5142495
--- /dev/null
@@ -0,0 +1,1143 @@
+// Licensed to the .NET Foundation under one or more 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+    class Program
+    {
+        const int Pass = 100;
+        const int Fail = 0;
+
+        const int N = 64;
+
+        static byte Four;
+        static byte Eight;
+        static byte invalid;
+
+        static readonly float[] floatSourceTable = new float[N];
+        static readonly double[] doubleSourceTable = new double[N];
+        static readonly int[] intSourceTable = new int[N];
+        static readonly long[] longSourceTable = new long[N];
+
+        static readonly int[] intIndexTable = new int[4] {8, 16, 32, 63};
+        static readonly long[] longIndexTable = new long[2] {16, 32};
+        static readonly long[] vector256longIndexTable = new long[4] {8, 16, 32, 63};
+
+        static unsafe int Main(string[] args)
+        {
+            int testResult = Pass;
+
+            if (Avx2.IsSupported)
+            {
+                Four = 4;
+                Eight = 8;
+                invalid = 15;
+
+                for (int i = 0; i < N; i++)
+                {
+                    floatSourceTable[i] = (float)i * 10.0f;
+                    doubleSourceTable[i] = (double)i * 10.0;
+                    intSourceTable[i] = i * 10;
+                    longSourceTable[i] = i * 10;
+                }
+
+                Vector128<int> indexi;
+                Vector128<long> indexl;
+                Vector256<long> indexl256;
+
+                fixed (int* iptr = intIndexTable)
+                fixed (long* lptr = longIndexTable)
+                fixed (long* l256ptr = vector256longIndexTable)
+                {
+                    indexi = Sse2.LoadVector128(iptr);
+                    indexl = Sse2.LoadVector128(lptr);
+                    indexl256 = Avx.LoadVector256(l256ptr);
+                }
+
+                // public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<float, int> floatTable = new TestTable<float, int>(floatSourceTable, new float[4]))
+                {
+                    var vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(float*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with non-const scale (IMM):");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<double, int> doubletTable = new TestTable<double, int>(doubleSourceTable, new double[2]))
+                {
+                    var vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector128<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(double*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with non-const scale (IMM):");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(int*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(uint*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(long*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(ulong*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector128<long> index, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(int*), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on int with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector128<long> index, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(uint*), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on uint with Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<long> GatherVector128(long* baseAddress, Vector128<long> index, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(long*), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on long with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<ulong> GatherVector128(ulong* baseAddress, Vector128<long> index, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[2]))
+                {
+                    var vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(ulong*), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on ulong with Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on ulong with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on long with invalid non-const scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+                
+                // public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector128<long> index, byte scale)
+                using (TestTable<float, long> floatTable = new TestTable<float, long>(floatSourceTable, new float[4]))
+                {
+                    var vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with Vector128 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(float*), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on float with Vector128 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with invalid non-const scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<double> GatherVector128(double* baseAddress, Vector128<long> index, byte scale)
+                using (TestTable<double, long> doubletTable = new TestTable<double, long>(doubleSourceTable, new double[2]))
+                {
+                    var vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with Vector128 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector128<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(double*), typeof(Vector128<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on double with Vector128 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with invalid scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with non-const scale (IMM) and Vector128 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on double with invalid non-const scale (IMM) and Vector128 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<int> GatherVector128(int* baseAddress, Vector256<long> index, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(int*), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl256, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on int with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<uint> GatherVector128(uint* baseAddress, Vector256<long> index, byte scale)
+                using (TestTable<int, long> intTable = new TestTable<int, long>(intSourceTable, new int[4]))
+                {
+                    var vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(uint*), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl256, (byte)4 });
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on uint with Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector128<float> GatherVector128(float* baseAddress, Vector256<long> index, byte scale)
+                using (TestTable<float, long> floatTable = new TestTable<float, long>(floatSourceTable, new float[4]))
+                {
+                    var vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with Vector256 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector128<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(float*), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl256, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed with reflection on float with Vector256 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, 3);
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, invalid);
+                        Console.WriteLine("AVX2 GatherVector128 failed on float with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+            }
+
+            return testResult;
+        }
+
+        public unsafe struct TestTable<T, U> : IDisposable where T : struct where U : struct
+        {
+            public T[] inArray;
+            public T[] outArray;
+
+            public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
+            public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+            GCHandle inHandle;
+            GCHandle outHandle;
+            public TestTable(T[] a, T[] b)
+            {
+                this.inArray = a;
+                this.outArray = b;
+
+                inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned);
+                outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+            }
+            public bool CheckResult(Func<T, T, bool> check, U[] indexArray)
+            {
+                int length = Math.Min(indexArray.Length, outArray.Length);
+                for (int i = 0; i < length; i++)
+                {
+                    if (!check(inArray[Convert.ToInt32(indexArray[i])], outArray[i]))
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            public void Dispose()
+            {
+                inHandle.Free();
+                outHandle.Free();
+            }
+        }
+
+    }
+}
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{BF772C6E-6EA2-4649-9618-D3DB0AE49F41}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize></Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareNotLessThanScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherVector128.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>
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{44063F5C-8943-4FC0-AEDF-45ED4A744CA9}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize>True</Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareNotLessThanScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherVector128.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/Avx2/GatherVector256.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256.cs
new file mode 100644 (file)
index 0000000..ab4a5ff
--- /dev/null
@@ -0,0 +1,731 @@
+// Licensed to the .NET Foundation under one or more 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+    class Program
+    {
+        const int Pass = 100;
+        const int Fail = 0;
+
+        const int N = 128;
+
+        static byte Four;
+        static byte Eight;
+        static byte invalid;
+
+        static readonly float[] floatSourceTable = new float[N];
+        static readonly double[] doubleSourceTable = new double[N];
+        static readonly int[] intSourceTable = new int[N];
+        static readonly long[] longSourceTable = new long[N];
+
+        static readonly int[] intIndexTable = new int[8] {1, 2, 4, 8, 16, 32, 40, 63};
+        static readonly long[] longIndexTable = new long[4] {2, 8, 16, 32};
+        static readonly int[] vector128intIndexTable = new int[4] {8, 16, 32, 63};
+
+        static unsafe int Main(string[] args)
+        {
+            int testResult = Pass;
+
+            if (Avx2.IsSupported)
+            {
+                Four = 4;
+                Eight = 8;
+                invalid = 15;
+
+                for (int i = 0; i < N; i++)
+                {
+                    floatSourceTable[i] = (float)i * 10.0f;
+                    doubleSourceTable[i] = (double)i * 10.0;
+                    intSourceTable[i] = i * 10;
+                    longSourceTable[i] = i * 10;
+                }
+
+                Vector256<int> indexi;
+                Vector256<long> indexl;
+                Vector128<int> indexi128;
+
+                fixed (int* iptr = intIndexTable)
+                fixed (long* lptr = longIndexTable)
+                fixed (int* i128ptr = vector128intIndexTable)
+                {
+                    indexi = Avx.LoadVector256(iptr);
+                    indexl = Avx.LoadVector256(lptr);
+                    indexi128 = Sse2.LoadVector128(i128ptr);
+                }
+
+                // public static unsafe Vector256<float> GatherVector256(float* baseAddress, Vector256<int> index, byte scale)
+                using (TestTable<float, int> floatTable = new TestTable<float, int>(floatSourceTable, new float[8]))
+                {
+                    var vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, 4);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<float>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(float*), typeof(Vector256<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, (byte)4 });
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on float:");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on float with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, Four);
+                    Unsafe.Write(floatTable.outArrayPtr, vf);
+
+                    if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on float with non-const scale (IMM):");
+                        foreach (var item in floatTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on float with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector128<int> index, byte scale) 
+                using (TestTable<double, int> doubletTable = new TestTable<double, int>(doubleSourceTable, new double[4]))
+                {
+                    var vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector256<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(double*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi128, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on double:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with non-const scale (IMM):");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<int> GatherVector256(int* baseAddress, Vector256<int> index, byte scale) 
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[8]))
+                {
+                    var vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<int>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(int*), typeof(Vector256<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on int:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on int with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on int with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on int with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<uint> GatherVector256(uint* baseAddress, Vector256<int> index, byte scale)
+                using (TestTable<int, int> intTable = new TestTable<int, int>(intSourceTable, new int[8]))
+                {
+                    var vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, 4);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<uint>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(uint*), typeof(Vector256<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, (byte)4 });
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on uint:");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on uint with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, Four);
+                    Unsafe.Write(intTable.outArrayPtr, vf);
+
+                    if (!intTable.CheckResult((x, y) => x == y, intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on uint with non-const scale (IMM):");
+                        foreach (var item in intTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on uint with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(long*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi128, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on long:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector128<int> index, byte scale)
+                using (TestTable<long, int> longTable = new TestTable<long, int>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(ulong*), typeof(Vector128<int>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi128, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on ulong:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong with invalid scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong with non-const scale (IMM):");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong with invalid non-const scale (IMM)");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<long> GatherVector256(long* baseAddress, Vector256<long> index, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<long>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(long*), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on long with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+                // public static unsafe Vector256<ulong> GatherVector256(ulong* baseAddress, Vector256<long> index, byte scale)
+                using (TestTable<long, long> longTable = new TestTable<long, long>(longSourceTable, new long[4]))
+                {
+                    var vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, 8);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vf = (Vector256<ulong>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(ulong*), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, (byte)8 });
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on ulong with Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, Eight);
+                    Unsafe.Write(longTable.outArrayPtr, vf);
+
+                    if (!longTable.CheckResult((x, y) => x == y, longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on ulong with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in longTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }                
+
+                // public static unsafe Vector256<double> GatherVector256(double* baseAddress, Vector256<long> index, byte scale)
+                using (TestTable<double, long> doubletTable = new TestTable<double, long>(doubleSourceTable, new double[4]))
+                {
+                    var vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, 8);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with Vector256 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    vd = (Vector256<double>)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(double*), typeof(Vector256<long>), typeof(byte)}).
+                            Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, (byte)8 });
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed with reflection on double with Vector256 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, 3);
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with invalid scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+
+                    vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, Eight);
+                    Unsafe.Write(doubletTable.outArrayPtr, vd);
+
+                    if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable))
+                    {
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with non-const scale (IMM) and Vector256 long index:");
+                        foreach (var item in doubletTable.outArray)
+                        {
+                            Console.Write(item + ", ");
+                        }
+                        Console.WriteLine();
+                        testResult = Fail;
+                    }
+
+                    try
+                    {
+                        vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, invalid);
+                        Console.WriteLine("AVX2 GatherVector256 failed on double with invalid non-const scale (IMM) and Vector256 long index");
+                        testResult = Fail;
+                    }
+                    catch (System.ArgumentOutOfRangeException)
+                    {
+                        // sucess
+                    }
+                }
+
+            }
+
+            return testResult;
+        }
+
+        public unsafe struct TestTable<T, U> : IDisposable where T : struct where U : struct
+        {
+            public T[] inArray;
+            public T[] outArray;
+
+            public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
+            public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+            GCHandle inHandle;
+            GCHandle outHandle;
+            public TestTable(T[] a, T[] b)
+            {
+                this.inArray = a;
+                this.outArray = b;
+
+                inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned);
+                outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+            }
+            public bool CheckResult(Func<T, T, bool> check, U[] indexArray)
+            {
+                int length = Math.Min(indexArray.Length, outArray.Length);
+                for (int i = 0; i < length; i++)
+                {
+                    if (!check(inArray[Convert.ToInt32(indexArray[i])], outArray[i]))
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            public void Dispose()
+            {
+                inHandle.Free();
+                outHandle.Free();
+            }
+        }
+
+    }
+}
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{EB82DD03-0CB7-41E2-8879-63C128833B6E}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize></Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareEqualOrderedScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherVector256.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>
@@ -5,15 +5,14 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{81E414C4-4281-4C1F-BC30-EACDCD551D1D}</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">
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
+    <DebugType>None</DebugType>
     <Optimize>True</Optimize>
   </PropertyGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareEqualOrderedScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Compile Include="GatherVector256.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>
index 2e7054c..ff1aec9 100644 (file)
@@ -77,167 +77,212 @@ 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] + 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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] + right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] + right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] + right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] + right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] + right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] + right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] + right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] + right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] + right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] + right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AddSaturate",                  ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] & right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] & right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] & right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(~BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "(~BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(~left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(byte)(~left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(~left[0] & right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(short)(~left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(~left[0] & right[0]) != result[0]",                                                                                         ["ValidateRemainingResults"] = "(ushort)(~left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(~left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(uint)(~left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(~left[0] & right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ulong)(~left[i] & right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Average",                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)((left[0] + right[0] + 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] / 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("ExtractScalarTest.template",  new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract",                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16",                                                                                      ["Imm"] = "1",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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", ["LargestVectorSize"] = "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", ["LargestVectorSize"] = "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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] * 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) | BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) | BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] | right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] | right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] | right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] | right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] | right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] | right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] | right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] | right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] | right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] | right[i]) != result[i]"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",                                                                                                         ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",                                                           ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
-    ("ImmUnOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",                                                                                       ["Imm"] = "1",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] - 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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] - right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] - right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] - right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] - right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] - right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] - right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] - right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] - right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] - right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] - right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.SubtractSaturate(left[0], right[0], result[0])",                                                                          ["ValidateRemainingResults"] = "Sse2Verify.SubtractSaturate(left[i], right[i], result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Sse2Verify.SubtractSaturate(left[0], right[0], result[0])",                                                                          ["ValidateRemainingResults"] = "Sse2Verify.SubtractSaturate(left[i], right[i], result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractScalar",               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) ^ BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) ^ BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] ^ right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] ^ right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] ^ right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] ^ right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] ^ right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] ^ right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] ^ right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] ^ right[i]) != result[i]"}),
-    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] ^ right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] ^ right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] + 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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] + right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] + right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] + right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] + right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] + right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AddSaturate",                              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] & right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] & right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] & right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(~BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "(~BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(~left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(byte)(~left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(~left[0] & right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(short)(~left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(~left[0] & right[0]) != result[0]",                                                                                         ["ValidateRemainingResults"] = "(ushort)(~left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(~left[0] & right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(uint)(~left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(~left[0] & right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ulong)(~left[i] & right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Average",                                  ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)((left[0] + right[0] + 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["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"] = "CompareEqualScalar",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)",                                                      ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqualOrderedScalar",                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] == right[0]) != result"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqualUnorderedScalar",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] == right[0]) != result"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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"] = "CompareGreaterThanScalar",                 ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)",                                                       ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanOrderedScalar",          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] > right[0]) != result"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanUnorderedScalar",        ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] > right[0]) != result"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanOrEqual",                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((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"] = "CompareGreaterThanOrEqualScalar",          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)",                                                      ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanOrEqualOrderedScalar",   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] >= right[0]) != result"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanOrEqualUnorderedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] >= right[0]) != result"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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"] = "CompareLessThanScalar",                    ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)",                                                       ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanOrderedScalar",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] < right[0]) != result"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanUnorderedScalar",           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] < right[0]) != result"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanOrEqual",                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((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"] = "CompareLessThanOrEqualScalar",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)",                                                      ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanOrEqualOrderedScalar",      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] <= right[0]) != result"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanOrEqualUnorderedScalar",    ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] <= right[0]) != result"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotEqual",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((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"] = "CompareNotEqualScalar",                    ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)",                                                      ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotEqualOrderedScalar",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] != right[0]) != result"}),
+    ("BooleanCmpOpTest.template",   new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotEqualUnorderedScalar",           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Boolean",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(left[0] != right[0]) != result"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotGreaterThan",                    ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(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"] = "CompareNotGreaterThanScalar",              ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)",                                                      ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotGreaterThanOrEqual",             ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(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"] = "CompareNotGreaterThanOrEqualScalar",       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)",                                                     ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotLessThan",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(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"] = "CompareNotLessThanScalar",                 ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)",                                                      ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotLessThanOrEqual",                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(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"] = "CompareNotLessThanOrEqualScalar",          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)",                                                     ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareOrdered",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((!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"] = "CompareOrderedScalar",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((!double.IsNaN(left[0]) && !double.IsNaN(right[0])) ? -1 : 0)",                        ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareUnordered",                         ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((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"] = "CompareUnorderedScalar",                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((double.IsNaN(left[0]) || double.IsNaN(right[0])) ? -1 : 0)",                          ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Divide",                                   ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] / 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("ExtractScalarTest.template",  new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract",                                  ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16",                                                                                      ["Imm"] = "1",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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", ["LargestVectorSize"] = "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", ["LargestVectorSize"] = "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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] * 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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) | BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) | BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] | right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] | right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] | right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] | right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] | right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] | right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] | right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] | right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] | right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] | right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "PackSignedSaturate",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["ValidateFirstResult"] = "Sse2Verify.PackSignedSaturate(result, left, right)",                                                                                 ["ValidateRemainingResults"] = "Sse2Verify.PackSignedSaturate(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "PackSignedSaturate",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.PackSignedSaturate(result, left, right)",                                                                                 ["ValidateRemainingResults"] = "Sse2Verify.PackSignedSaturate(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "PackUnsignedSaturate",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.PackUnsignedSaturate(result, left, right)",                                                                               ["ValidateRemainingResults"] = "Sse2Verify.PackUnsignedSaturate(result, left, right)"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",                                                                                                         ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",                                                           ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ScalarSimdUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double",                                                                                                       ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",                                                         ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
+    ("ImmUnOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical",                         ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",                                                                                       ["Imm"] = "1",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",   ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",                                                         ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",                                                          ["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",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",                                                         ["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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",   ["LargestVectorSize"] = "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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] - 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",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] - right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] - right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                                 ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] - right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] - right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                                 ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] - right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] - right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                                 ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] - right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] - right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract",                                 ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] - right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] - right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate",                         ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.SubtractSaturate(left[0], right[0], result[0])",                                                                          ["ValidateRemainingResults"] = "Sse2Verify.SubtractSaturate(left[i], right[i], result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate",                         ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Sse2Verify.SubtractSaturate(left[0], right[0], result[0])",                                                                          ["ValidateRemainingResults"] = "Sse2Verify.SubtractSaturate(left[i], right[i], result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractScalar",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "Sse2Verify.UnpackHigh(result, left, right)",                                                                                          ["ValidateRemainingResults"] = "Sse2Verify.UnpackHigh(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "Sse2Verify.UnpackLow(result, left, right)",                                                                                           ["ValidateRemainingResults"] = "Sse2Verify.UnpackLow(result, left, right)"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) ^ BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) ^ BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] ^ right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] ^ right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] ^ right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] ^ right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["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",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["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",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] ^ right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] ^ right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] ^ right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] ^ right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",    new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] ^ right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] ^ right[i]) != result[i]"}),
 };
 
 private static readonly (string templateFileName, Dictionary<string, string> templateData)[] Sse3Inputs = new []
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..be6a5ff
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareEqualOrderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareEqualOrderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareEqualOrderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareEqualOrderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareEqualOrderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareEqualOrderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareEqualOrderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareEqualOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareEqualOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareEqualOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareEqualOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareEqualOrderedScalarBoolean();
+            var result = Sse2.CompareEqualOrderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareEqualOrderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareEqualOrderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] == right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareEqualOrderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualOrderedScalar.cs
deleted file mode 100644 (file)
index e5a9ec3..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        const int Pass = 100;
-        const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareEqualOrderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareEqualOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] == y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x == y ? -1l : 0) == z", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-            return testResult;
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar.Double.cs
new file mode 100644 (file)
index 0000000..cf543ad
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareEqualScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareEqualScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareEqualScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareEqualScalarDouble testClass)
+            {
+                var result = Sse2.CompareEqualScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareEqualScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareEqualScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareEqualScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareEqualScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareEqualScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareEqualScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareEqualScalarDouble();
+            var result = Sse2.CompareEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareEqualScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] == right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareEqualScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar.cs
deleted file mode 100644 (file)
index a2b1a33..0000000
+++ /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.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        const int Pass = 100;
-        const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareEqualScalar);
-
-            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];
-                        var result = Sse2.CompareEqualScalar(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] ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x == y ? -1l : 0) == z", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-            return testResult;
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualScalar_ro.csproj
deleted file mode 100644 (file)
index 4a95770..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{B5152634-64C2-49B7-B049-73728855F514}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareEqualScalar.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/CompareEqualUnorderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..27cbf16
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareEqualUnorderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareEqualUnorderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareEqualUnorderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareEqualUnorderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareEqualUnorderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareEqualUnorderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareEqualUnorderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareEqualUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareEqualUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareEqualUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareEqualUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareEqualUnorderedScalarBoolean();
+            var result = Sse2.CompareEqualUnorderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareEqualUnorderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareEqualUnorderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] == right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareEqualUnorderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar.cs
deleted file mode 100644 (file)
index a1dff35..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        const int Pass = 100;
-        const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareEqualUnorderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareEqualUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] == y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareEqualUnorderedScalar", 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/CompareEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar_r.csproj
deleted file mode 100644 (file)
index 099db89..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{0C1E06B8-4DD8-471D-914E-A464EB3F5FB0}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareEqualUnorderedScalar.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/CompareEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqualUnorderedScalar_ro.csproj
deleted file mode 100644 (file)
index 0a5e1b4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{5E49EB53-2BD9-469E-8125-3878DB8DB8B1}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareEqualUnorderedScalar.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/CompareGreaterThanOrEqualOrderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..4e5534a
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareGreaterThanOrEqualOrderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarBoolean();
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] >= right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanOrEqualOrderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar.cs
deleted file mode 100644 (file)
index e913b84..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareGreaterThanOrEqualOrderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareGreaterThanOrEqualOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] >= y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareGreaterThanOrEqualOrderedScalar", 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/CompareGreaterThanOrEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar_r.csproj
deleted file mode 100644 (file)
index e571c88..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{C55BCD67-C516-4B41-B2CB-28B55192B868}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrEqualOrderedScalar.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/CompareGreaterThanOrEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualOrderedScalar_ro.csproj
deleted file mode 100644 (file)
index 5d4a6d4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{A9EBC815-0839-4047-8602-7AB7AFB9C876}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrEqualOrderedScalar.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/CompareGreaterThanOrEqualScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar.Double.cs
new file mode 100644 (file)
index 0000000..6a93fba
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareGreaterThanOrEqualScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarDouble testClass)
+            {
+                var result = Sse2.CompareGreaterThanOrEqualScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareGreaterThanOrEqualScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareGreaterThanOrEqualScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareGreaterThanOrEqualScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareGreaterThanOrEqualScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareGreaterThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarDouble();
+            var result = Sse2.CompareGreaterThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareGreaterThanOrEqualScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareGreaterThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanOrEqualScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar.cs
deleted file mode 100644 (file)
index b94ac3d..0000000
+++ /dev/null
@@ -1,57 +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.CompareGreaterThanOrEqualScalar);
-
-            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];
-                        var result = Sse2.CompareGreaterThanOrEqualScalar(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] ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareGreaterThanOrEqualScalar", 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/CompareGreaterThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualScalar_r.csproj
deleted file mode 100644 (file)
index d42e836..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{F69D5695-D22E-41D8-B030-43CFF17B95ED}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrEqualScalar.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/CompareGreaterThanOrEqualUnorderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..d7b4a90
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareGreaterThanOrEqualUnorderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarBoolean();
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] >= right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanOrEqualUnorderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar.cs
deleted file mode 100644 (file)
index 16f8df7..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareGreaterThanOrEqualUnorderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareGreaterThanOrEqualUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] >= y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareGreaterThanOrEqualUnorderedScalar", 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/CompareGreaterThanOrEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar_r.csproj
deleted file mode 100644 (file)
index 104d659..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{D865492C-FD82-4454-BE55-FDA217C69FC2}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrEqualUnorderedScalar.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/CompareGreaterThanOrEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqualUnorderedScalar_ro.csproj
deleted file mode 100644 (file)
index 3fe2f18..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{3584397A-13D4-4F6D-8E11-F01E9561338E}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrEqualUnorderedScalar.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/CompareGreaterThanOrderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..d82d431
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareGreaterThanOrderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareGreaterThanOrderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanOrderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareGreaterThanOrderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareGreaterThanOrderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareGreaterThanOrderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareGreaterThanOrderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareGreaterThanOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareGreaterThanOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareGreaterThanOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareGreaterThanOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareGreaterThanOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareGreaterThanOrderedScalarBoolean();
+            var result = Sse2.CompareGreaterThanOrderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareGreaterThanOrderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareGreaterThanOrderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] > right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanOrderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar.cs
deleted file mode 100644 (file)
index ae9f961..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareGreaterThanOrderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareGreaterThanOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] > y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareGreaterThanOrderedScalar", 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/CompareGreaterThanOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar_r.csproj
deleted file mode 100644 (file)
index e502108..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{C28A4AAF-7F4E-4FC2-B7E8-AB856A453C8F}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrderedScalar.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/CompareGreaterThanOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrderedScalar_ro.csproj
deleted file mode 100644 (file)
index bcc6080..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{083F679A-B810-4523-892B-B86CC2089A05}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanOrderedScalar.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/CompareGreaterThanScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar.Double.cs
new file mode 100644 (file)
index 0000000..e7ebc12
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareGreaterThanScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareGreaterThanScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareGreaterThanScalarDouble testClass)
+            {
+                var result = Sse2.CompareGreaterThanScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareGreaterThanScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareGreaterThanScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareGreaterThanScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareGreaterThanScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareGreaterThanScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareGreaterThanScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareGreaterThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareGreaterThanScalarDouble();
+            var result = Sse2.CompareGreaterThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareGreaterThanScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareGreaterThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] > right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar.cs
deleted file mode 100644 (file)
index 5cfbec4..0000000
+++ /dev/null
@@ -1,57 +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.CompareGreaterThanScalar);
-
-            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.CompareGreaterThanScalar(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] ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareGreaterThanScalar", 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/CompareGreaterThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar_r.csproj
deleted file mode 100644 (file)
index 84616d8..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{35415AB4-E885-4E32-A735-CBDA1AE8783E}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanScalar.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/CompareGreaterThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanScalar_ro.csproj
deleted file mode 100644 (file)
index fdadb0d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{6E3A0CC9-42E5-4CA4-8BC7-719C22CD57A7}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanScalar.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/CompareGreaterThanUnorderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..fe920b6
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareGreaterThanUnorderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareGreaterThanUnorderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareGreaterThanUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareGreaterThanUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareGreaterThanUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareGreaterThanUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareGreaterThanUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareGreaterThanUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarBoolean();
+            var result = Sse2.CompareGreaterThanUnorderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareGreaterThanUnorderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareGreaterThanUnorderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] > right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanUnorderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar.cs
deleted file mode 100644 (file)
index 913f00d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareGreaterThanUnorderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareGreaterThanUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] > y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareGreaterThanUnorderedScalar", 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/CompareGreaterThanUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar_r.csproj
deleted file mode 100644 (file)
index c5c2b33..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{0CABBFB3-3404-4E3D-B3A1-C4D4CFD40C03}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanUnorderedScalar.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/CompareGreaterThanUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanUnorderedScalar_ro.csproj
deleted file mode 100644 (file)
index 57f5b93..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{8C267FA4-FED6-493B-8FD7-DAA0E31A9934}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareGreaterThanUnorderedScalar.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/CompareLessThanOrEqualOrderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..c57feff
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareLessThanOrEqualOrderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareLessThanOrEqualOrderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarBoolean();
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareLessThanOrEqualOrderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] <= right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanOrEqualOrderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar.cs
deleted file mode 100644 (file)
index bb82ac1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareLessThanOrEqualOrderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareLessThanOrEqualOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] <= y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareLessThanOrEqualOrderedScalar", 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/CompareLessThanOrEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar_r.csproj
deleted file mode 100644 (file)
index aca2158..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{398DEA1A-16E3-4EE8-8668-54DFB80EB7AB}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrEqualOrderedScalar.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/CompareLessThanOrEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualOrderedScalar_ro.csproj
deleted file mode 100644 (file)
index 9d78789..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{3AC17539-DEBA-4FFB-BE4A-4FCB21C37294}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrEqualOrderedScalar.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/CompareLessThanOrEqualScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar.Double.cs
new file mode 100644 (file)
index 0000000..4b074fc
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareLessThanOrEqualScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareLessThanOrEqualScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareLessThanOrEqualScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareLessThanOrEqualScalarDouble testClass)
+            {
+                var result = Sse2.CompareLessThanOrEqualScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareLessThanOrEqualScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareLessThanOrEqualScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareLessThanOrEqualScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareLessThanOrEqualScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareLessThanOrEqualScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareLessThanOrEqualScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareLessThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareLessThanOrEqualScalarDouble();
+            var result = Sse2.CompareLessThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareLessThanOrEqualScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareLessThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanOrEqualScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar.cs
deleted file mode 100644 (file)
index a7dc17c..0000000
+++ /dev/null
@@ -1,57 +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.CompareLessThanOrEqualScalar);
-
-            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.CompareLessThanOrEqualScalar(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] ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareLessThanOrEqualScalar", 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/CompareLessThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar_r.csproj
deleted file mode 100644 (file)
index 2b4af4f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{81043FA3-79B2-47C2-B87B-155D02C56129}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrEqualScalar.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/CompareLessThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualScalar_ro.csproj
deleted file mode 100644 (file)
index 3c3235a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{D5F2B67E-9F8B-47E1-B817-15A62A807902}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrEqualScalar.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/CompareLessThanOrEqualUnorderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..6c6341f
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareLessThanOrEqualUnorderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareLessThanOrEqualUnorderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarBoolean();
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareLessThanOrEqualUnorderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] <= right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanOrEqualUnorderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar.cs
deleted file mode 100644 (file)
index 3e16c5e..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareLessThanOrEqualUnorderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareLessThanOrEqualUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] <= y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareLessThanOrEqualUnorderedScalar", 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/CompareLessThanOrEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar_r.csproj
deleted file mode 100644 (file)
index 1e69097..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{BFB0C199-C3B9-4194-80C9-66DAE8F32BED}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrEqualUnorderedScalar.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/CompareLessThanOrEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqualUnorderedScalar_ro.csproj
deleted file mode 100644 (file)
index 916959f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{88243AD7-6A24-41B0-9ED1-C995551F23DA}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrEqualUnorderedScalar.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/CompareLessThanOrderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..3671313
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareLessThanOrderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareLessThanOrderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareLessThanOrderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareLessThanOrderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareLessThanOrderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareLessThanOrderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareLessThanOrderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareLessThanOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareLessThanOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareLessThanOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareLessThanOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareLessThanOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareLessThanOrderedScalarBoolean();
+            var result = Sse2.CompareLessThanOrderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareLessThanOrderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareLessThanOrderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] < right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanOrderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar.cs
deleted file mode 100644 (file)
index d321540..0000000
+++ /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.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-
-        const int Pass = 100;
-        const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareLessThanOrderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareLessThanOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] < y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareLessThanOrderedScalar", 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/CompareLessThanOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar_r.csproj
deleted file mode 100644 (file)
index de22eff..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{93E4851E-5200-4A1E-AC26-FD8B18476570}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrderedScalar.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/CompareLessThanOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrderedScalar_ro.csproj
deleted file mode 100644 (file)
index 668e160..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{EFB18286-69A8-4260-8AD9-94A576984ECB}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanOrderedScalar.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/CompareLessThanScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar.Double.cs
new file mode 100644 (file)
index 0000000..3f45434
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareLessThanScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareLessThanScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareLessThanScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareLessThanScalarDouble testClass)
+            {
+                var result = Sse2.CompareLessThanScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareLessThanScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareLessThanScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareLessThanScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareLessThanScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareLessThanScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareLessThanScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareLessThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareLessThanScalarDouble();
+            var result = Sse2.CompareLessThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareLessThanScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareLessThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] < right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar.cs
deleted file mode 100644 (file)
index 30d682b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-
-        const int Pass = 100;
-        const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareLessThanScalar);
-
-            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.CompareLessThanScalar(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] ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareLessThanScalar", 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/CompareLessThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar_r.csproj
deleted file mode 100644 (file)
index 85095e8..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{4C7EE867-4785-47FC-AFBE-AF4A72651577}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanScalar.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/CompareLessThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanScalar_ro.csproj
deleted file mode 100644 (file)
index 9f1d05c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{1C1FEDB0-64E8-405A-922A-67731CE53956}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanScalar.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/CompareLessThanUnorderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..5244aa5
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareLessThanUnorderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareLessThanUnorderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareLessThanUnorderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareLessThanUnorderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareLessThanUnorderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareLessThanUnorderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareLessThanUnorderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareLessThanUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareLessThanUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareLessThanUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareLessThanUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareLessThanUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareLessThanUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareLessThanUnorderedScalarBoolean();
+            var result = Sse2.CompareLessThanUnorderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareLessThanUnorderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareLessThanUnorderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] < right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanUnorderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar.cs
deleted file mode 100644 (file)
index 9455ee1..0000000
+++ /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.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-
-        const int Pass = 100;
-        const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareLessThanUnorderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareLessThanUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = x[0] < y[0] ? true : false;
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareLessThanUnorderedScalar", 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/CompareLessThanUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar_r.csproj
deleted file mode 100644 (file)
index 9ad52c3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{8810F33B-6D6A-43A9-8FBF-0C5BE46046CD}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanUnorderedScalar.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/CompareLessThanUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanUnorderedScalar_ro.csproj
deleted file mode 100644 (file)
index 1d55cb1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{2EB27EC3-3440-443F-8CCF-2EC9B900982D}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareLessThanUnorderedScalar.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/CompareNotEqualOrderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..7b51643
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareNotEqualOrderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareNotEqualOrderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareNotEqualOrderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareNotEqualOrderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareNotEqualOrderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareNotEqualOrderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareNotEqualOrderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotEqualOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotEqualOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotEqualOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotEqualOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotEqualOrderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareNotEqualOrderedScalarBoolean();
+            var result = Sse2.CompareNotEqualOrderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotEqualOrderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotEqualOrderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] != right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotEqualOrderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar.cs
deleted file mode 100644 (file)
index 71f02af..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareNotEqualOrderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareNotEqualOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = (x[0] != y[0]);
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareNotEqualOrderedScalar", 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/CompareNotEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar_r.csproj
deleted file mode 100644 (file)
index 1f77b49..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{9E2D750B-1AD6-4CCB-8CEE-856A702714DB}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotEqualOrderedScalar.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/CompareNotEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualOrderedScalar_ro.csproj
deleted file mode 100644 (file)
index 043972d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{A51475EC-9B61-442A-B8E9-90817E8C5FF3}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotEqualOrderedScalar.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/CompareNotEqualScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar.Double.cs
new file mode 100644 (file)
index 0000000..1b10b71
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareNotEqualScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareNotEqualScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareNotEqualScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareNotEqualScalarDouble testClass)
+            {
+                var result = Sse2.CompareNotEqualScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareNotEqualScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareNotEqualScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotEqualScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotEqualScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotEqualScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotEqualScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareNotEqualScalarDouble();
+            var result = Sse2.CompareNotEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotEqualScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] != right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotEqualScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar.cs
deleted file mode 100644 (file)
index 7c889f3..0000000
+++ /dev/null
@@ -1,57 +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.CompareNotEqualScalar);
-
-            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.CompareNotEqualScalar(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] ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = x != y ? double.NaN : 0) == z", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-
-            return testResult;
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar_r.csproj
deleted file mode 100644 (file)
index 688d22f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{5E0CE7C0-B254-46AF-A81E-F2EBA971B8A3}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotEqualScalar.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/CompareNotEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualScalar_ro.csproj
deleted file mode 100644 (file)
index de5b698..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{49727A3A-3AEF-4BDC-A3BB-6FEBC8C106D5}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotEqualScalar.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/CompareNotEqualUnorderedScalar.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar.Boolean.cs
new file mode 100644 (file)
index 0000000..fc552a0
--- /dev/null
@@ -0,0 +1,368 @@
+// Licensed to the .NET Foundation under one or more 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 CompareNotEqualUnorderedScalarBoolean()
+        {
+            var test = new BooleanComparisonOpTest__CompareNotEqualUnorderedScalarBoolean();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class BooleanComparisonOpTest__CompareNotEqualUnorderedScalarBoolean
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(BooleanComparisonOpTest__CompareNotEqualUnorderedScalarBoolean testClass)
+            {
+                var result = Sse2.CompareNotEqualUnorderedScalar(_fld1, _fld2);
+                testClass.ValidateResult(_fld1, _fld2, result);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static 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 BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+
+        static BooleanComparisonOpTest__CompareNotEqualUnorderedScalarBoolean()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public BooleanComparisonOpTest__CompareNotEqualUnorderedScalarBoolean()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotEqualUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotEqualUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotEqualUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqualUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotEqualUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            ValidateResult(_clsVar1, _clsVar2, result);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotEqualUnorderedScalar(left, right);
+
+            ValidateResult(left, right, result);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new BooleanComparisonOpTest__CompareNotEqualUnorderedScalarBoolean();
+            var result = Sse2.CompareNotEqualUnorderedScalar(test._fld1, test._fld2);
+
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotEqualUnorderedScalar(_fld1, _fld2);
+
+            ValidateResult(_fld1, _fld2, result);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotEqualUnorderedScalar(test._fld1, test._fld2);
+            ValidateResult(test._fld1, test._fld2, result);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
+        {
+            if ((left[0] != right[0]) != result)
+            {
+                Succeeded = false;
+
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotEqualUnorderedScalar)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar.cs
deleted file mode 100644 (file)
index 96e0745..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
-    internal static partial class Program
-    {
-        private const int Pass = 100;
-        private const int Fail = 0;
-
-        static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.CompareNotEqualUnorderedScalar);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableScalarSse2<double, bool>.Create(testsCount, 2.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        var result = Sse2.CompareNotEqualUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEightOne<double, bool> checkDouble = (Span<double> x, Span<double> y, bool z, ref bool a) =>
-                    {
-                        a = (x[0] != y[0]);
-                        return a == z;
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, bool z, ref bool a) => CompareNotEqualUnorderedScalar", 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/CompareNotEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar_r.csproj
deleted file mode 100644 (file)
index 1aa19d4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{FC56E4E9-E46B-4E86-A022-70EAA6A3776E}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotEqualUnorderedScalar.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/CompareNotEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqualUnorderedScalar_ro.csproj
deleted file mode 100644 (file)
index 40fcae0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{3E67F586-EB9F-4209-BED1-CDDB2CA032FB}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotEqualUnorderedScalar.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/CompareNotGreaterThanOrEqualScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar.Double.cs
new file mode 100644 (file)
index 0000000..a4d56c9
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareNotGreaterThanOrEqualScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarDouble testClass)
+            {
+                var result = Sse2.CompareNotGreaterThanOrEqualScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarDouble();
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotGreaterThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotGreaterThanOrEqualScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar.cs
deleted file mode 100644 (file)
index 98a00bc..0000000
+++ /dev/null
@@ -1,57 +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.CompareNotGreaterThanOrEqualScalar);
-
-            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];
-                        var result = Sse2.CompareNotGreaterThanOrEqualScalar(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]) ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareNotGreaterThanOrEqualScalar", 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/CompareNotGreaterThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar_r.csproj
deleted file mode 100644 (file)
index 7a8d60d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{9719321A-FA33-43E6-B01E-102879E77321}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotGreaterThanOrEqualScalar.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/CompareNotGreaterThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqualScalar_ro.csproj
deleted file mode 100644 (file)
index a2145c1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{93C1DB28-D5A7-493D-8017-9E028D39E025}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotGreaterThanOrEqualScalar.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/CompareNotGreaterThanScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar.Double.cs
new file mode 100644 (file)
index 0000000..a42a3a8
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareNotGreaterThanScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareNotGreaterThanScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareNotGreaterThanScalarDouble testClass)
+            {
+                var result = Sse2.CompareNotGreaterThanScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareNotGreaterThanScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareNotGreaterThanScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotGreaterThanScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotGreaterThanScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotGreaterThanScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotGreaterThanScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotGreaterThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotGreaterThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotGreaterThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareNotGreaterThanScalarDouble();
+            var result = Sse2.CompareNotGreaterThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotGreaterThanScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotGreaterThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotGreaterThanScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar.cs
deleted file mode 100644 (file)
index 0a7778a..0000000
+++ /dev/null
@@ -1,57 +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.CompareNotGreaterThanScalar);
-
-            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.CompareNotGreaterThanScalar(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]) ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x > y) ? double.NaN : 0) == z", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-
-            return testResult;
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar_r.csproj
deleted file mode 100644 (file)
index c391a38..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{CE864D5D-9D54-4000-A5BE-EC7052673CE5}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotGreaterThanScalar.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/CompareNotGreaterThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanScalar_ro.csproj
deleted file mode 100644 (file)
index 8b32b3c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{8B32892C-136B-4809-A082-F4EEF0FD0A8F}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotGreaterThanScalar.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/CompareNotLessThanOrEqualScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar.Double.cs
new file mode 100644 (file)
index 0000000..8d7e7b5
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareNotLessThanOrEqualScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarDouble testClass)
+            {
+                var result = Sse2.CompareNotLessThanOrEqualScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotLessThanOrEqualScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotLessThanOrEqualScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotLessThanOrEqualScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanOrEqualScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotLessThanOrEqualScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotLessThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotLessThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotLessThanOrEqualScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarDouble();
+            var result = Sse2.CompareNotLessThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotLessThanOrEqualScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotLessThanOrEqualScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotLessThanOrEqualScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar.cs
deleted file mode 100644 (file)
index 560db5a..0000000
+++ /dev/null
@@ -1,57 +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.CompareNotLessThanOrEqualScalar);
-
-            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];
-                        var result = Sse2.CompareNotLessThanOrEqualScalar(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]) ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x <= y) ? double.NaN : 0) == z", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-
-            return testResult;
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar_r.csproj
deleted file mode 100644 (file)
index 60aadcd..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{608FCA63-FF4F-4A38-9503-9CF51D291BAB}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotLessThanOrEqualScalar.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/CompareNotLessThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqualScalar_ro.csproj
deleted file mode 100644 (file)
index cf1f383..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{D61F7DC7-97A3-4A5A-8A49-B80195B7EBFA}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
-  <ItemGroup>
-    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
-      <Visible>False</Visible>
-    </CodeAnalysisDependentAssemblyPaths>
-  </ItemGroup>
-  <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CompareNotLessThanOrEqualScalar.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/CompareNotLessThanScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar.Double.cs
new file mode 100644 (file)
index 0000000..1a84177
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareNotLessThanScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareNotLessThanScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareNotLessThanScalarDouble testClass)
+            {
+                var result = Sse2.CompareNotLessThanScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareNotLessThanScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareNotLessThanScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareNotLessThanScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareNotLessThanScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareNotLessThanScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareNotLessThanScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareNotLessThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotLessThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareNotLessThanScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareNotLessThanScalarDouble();
+            var result = Sse2.CompareNotLessThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareNotLessThanScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareNotLessThanScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareNotLessThanScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanScalar.cs
deleted file mode 100644 (file)
index b53619d..0000000
+++ /dev/null
@@ -1,57 +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.CompareNotLessThanScalar);
-
-            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.CompareNotLessThanScalar(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]) ? BitConverter.Int64BitsToDouble(-1) : 0;
-                        a[1] = x[1];
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x <= y) ? double.NaN : 0) == z", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-
-            return testResult;
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar.Double.cs
new file mode 100644 (file)
index 0000000..ae47b04
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareOrderedScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareOrderedScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareOrderedScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareOrderedScalarDouble testClass)
+            {
+                var result = Sse2.CompareOrderedScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareOrderedScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareOrderedScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareOrderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareOrderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareOrderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareOrderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareOrderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareOrderedScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareOrderedScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareOrderedScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareOrderedScalarDouble();
+            var result = Sse2.CompareOrderedScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareOrderedScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareOrderedScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((!double.IsNaN(left[0]) && !double.IsNaN(right[0])) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareOrderedScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrderedScalar.cs
deleted file mode 100644 (file)
index 1349bdd..0000000
+++ /dev/null
@@ -1,65 +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.CompareOrderedScalar);
-
-            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.CompareOrderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
-                    {
-                        if (!double.IsNaN(x[0]) && !double.IsNaN(y[0]))
-                        {
-                            a[0] = BitConverter.Int64BitsToDouble(-1);
-                            a[1] = x[1];
-                        }
-                        else
-                        {
-                            a[0] = 0;
-                            a[1] = x[1];
-                        }
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareOrderedScalar", 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/CompareUnorderedScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar.Double.cs
new file mode 100644 (file)
index 0000000..209ff85
--- /dev/null
@@ -0,0 +1,403 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void CompareUnorderedScalarDouble()
+        {
+            var test = new SimpleBinaryOpTest__CompareUnorderedScalarDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__CompareUnorderedScalarDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__CompareUnorderedScalarDouble testClass)
+            {
+                var result = Sse2.CompareUnorderedScalar(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__CompareUnorderedScalarDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__CompareUnorderedScalarDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.CompareUnorderedScalar(
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.CompareUnorderedScalar(
+                Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.CompareUnorderedScalar(
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareUnorderedScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.CompareUnorderedScalar(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.CompareUnorderedScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareUnorderedScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.CompareUnorderedScalar(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__CompareUnorderedScalarDouble();
+            var result = Sse2.CompareUnorderedScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.CompareUnorderedScalar(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.CompareUnorderedScalar(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
+
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != ((double.IsNaN(left[0]) || double.IsNaN(right[0])) ? -1 : 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)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareUnorderedScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnorderedScalar.cs
deleted file mode 100644 (file)
index 23a9282..0000000
+++ /dev/null
@@ -1,65 +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.CompareUnorderedScalar);
-
-            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.CompareUnorderedScalar(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result);
-                    }
-
-                    CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
-                    {
-                        if (double.IsNaN(x[0]) || double.IsNaN(y[0]))
-                        {
-                            a[0] = BitConverter.Int64BitsToDouble(-1);
-                            a[1] = x[1];
-                        }
-                        else
-                        {
-                            a[0] = 0;
-                            a[1] = x[1];
-                        }
-                        return BitConverter.DoubleToInt64Bits(a[0]) == BitConverter.DoubleToInt64Bits(z[0]) &&
-                               BitConverter.DoubleToInt64Bits(a[1]) == BitConverter.DoubleToInt64Bits(z[1]);
-                    };
-
-                    if (!doubleTable.CheckResult(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => CompareUnorderedScalar", checkDouble);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-
-            return testResult;
-        }
-    }
-}
index e2ab97d..df6ba2e 100644 (file)
@@ -53,23 +53,47 @@ namespace JIT.HardwareIntrinsics.X86
                 ["CompareEqual.SByte"] = CompareEqualSByte,
                 ["CompareEqual.UInt16"] = CompareEqualUInt16,
                 ["CompareEqual.UInt32"] = CompareEqualUInt32,
+                ["CompareEqualScalar.Double"] = CompareEqualScalarDouble,
+                ["CompareEqualOrderedScalar.Boolean"] = CompareEqualOrderedScalarBoolean,
+                ["CompareEqualUnorderedScalar.Boolean"] = CompareEqualUnorderedScalarBoolean,
                 ["CompareGreaterThan.Double"] = CompareGreaterThanDouble,
                 ["CompareGreaterThan.Int16"] = CompareGreaterThanInt16,
                 ["CompareGreaterThan.Int32"] = CompareGreaterThanInt32,
                 ["CompareGreaterThan.SByte"] = CompareGreaterThanSByte,
+                ["CompareGreaterThanScalar.Double"] = CompareGreaterThanScalarDouble,
+                ["CompareGreaterThanOrderedScalar.Boolean"] = CompareGreaterThanOrderedScalarBoolean,
+                ["CompareGreaterThanUnorderedScalar.Boolean"] = CompareGreaterThanUnorderedScalarBoolean,
                 ["CompareGreaterThanOrEqual.Double"] = CompareGreaterThanOrEqualDouble,
+                ["CompareGreaterThanOrEqualScalar.Double"] = CompareGreaterThanOrEqualScalarDouble,
+                ["CompareGreaterThanOrEqualOrderedScalar.Boolean"] = CompareGreaterThanOrEqualOrderedScalarBoolean,
+                ["CompareGreaterThanOrEqualUnorderedScalar.Boolean"] = CompareGreaterThanOrEqualUnorderedScalarBoolean,
                 ["CompareLessThan.Double"] = CompareLessThanDouble,
                 ["CompareLessThan.Int16"] = CompareLessThanInt16,
                 ["CompareLessThan.Int32"] = CompareLessThanInt32,
                 ["CompareLessThan.SByte"] = CompareLessThanSByte,
+                ["CompareLessThanScalar.Double"] = CompareLessThanScalarDouble,
+                ["CompareLessThanOrderedScalar.Boolean"] = CompareLessThanOrderedScalarBoolean,
+                ["CompareLessThanUnorderedScalar.Boolean"] = CompareLessThanUnorderedScalarBoolean,
                 ["CompareLessThanOrEqual.Double"] = CompareLessThanOrEqualDouble,
+                ["CompareLessThanOrEqualScalar.Double"] = CompareLessThanOrEqualScalarDouble,
+                ["CompareLessThanOrEqualOrderedScalar.Boolean"] = CompareLessThanOrEqualOrderedScalarBoolean,
+                ["CompareLessThanOrEqualUnorderedScalar.Boolean"] = CompareLessThanOrEqualUnorderedScalarBoolean,
                 ["CompareNotEqual.Double"] = CompareNotEqualDouble,
+                ["CompareNotEqualScalar.Double"] = CompareNotEqualScalarDouble,
+                ["CompareNotEqualOrderedScalar.Boolean"] = CompareNotEqualOrderedScalarBoolean,
+                ["CompareNotEqualUnorderedScalar.Boolean"] = CompareNotEqualUnorderedScalarBoolean,
                 ["CompareNotGreaterThan.Double"] = CompareNotGreaterThanDouble,
+                ["CompareNotGreaterThanScalar.Double"] = CompareNotGreaterThanScalarDouble,
                 ["CompareNotGreaterThanOrEqual.Double"] = CompareNotGreaterThanOrEqualDouble,
+                ["CompareNotGreaterThanOrEqualScalar.Double"] = CompareNotGreaterThanOrEqualScalarDouble,
                 ["CompareNotLessThan.Double"] = CompareNotLessThanDouble,
+                ["CompareNotLessThanScalar.Double"] = CompareNotLessThanScalarDouble,
                 ["CompareNotLessThanOrEqual.Double"] = CompareNotLessThanOrEqualDouble,
+                ["CompareNotLessThanOrEqualScalar.Double"] = CompareNotLessThanOrEqualScalarDouble,
                 ["CompareOrdered.Double"] = CompareOrderedDouble,
+                ["CompareOrderedScalar.Double"] = CompareOrderedScalarDouble,
                 ["CompareUnordered.Double"] = CompareUnorderedDouble,
+                ["CompareUnorderedScalar.Double"] = CompareUnorderedScalarDouble,
                 ["Divide.Double"] = DivideDouble,
                 ["DivideScalar.Double"] = DivideScalarDouble,
                 ["Extract.UInt16.1"] = ExtractUInt161,
index 1ec402e..3765365 100644 (file)
     <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.Double.cs" />
     <Compile Include="CompareEqual.Int16.cs" />
     <Compile Include="CompareEqual.Int32.cs" />
     <Compile Include="CompareEqual.SByte.cs" />
     <Compile Include="CompareEqual.UInt16.cs" />
     <Compile Include="CompareEqual.UInt32.cs" />
+    <Compile Include="CompareEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareEqualScalar.Double.cs" />
+    <Compile Include="CompareEqualUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareGreaterThan.Double.cs" />
     <Compile Include="CompareGreaterThan.Int16.cs" />
     <Compile Include="CompareGreaterThan.Int32.cs" />
     <Compile Include="CompareGreaterThan.SByte.cs" />
+    <Compile Include="CompareGreaterThanOrderedScalar.Boolean.cs" />
     <Compile Include="CompareGreaterThanOrEqual.Double.cs" />
+    <Compile Include="CompareGreaterThanOrEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareGreaterThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareGreaterThanOrEqualUnorderedScalar.Boolean.cs" />
+    <Compile Include="CompareGreaterThanScalar.Double.cs" />
+    <Compile Include="CompareGreaterThanUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareLessThan.Double.cs" />
     <Compile Include="CompareLessThan.Int16.cs" />
     <Compile Include="CompareLessThan.Int32.cs" />
     <Compile Include="CompareLessThan.SByte.cs" />
+    <Compile Include="CompareLessThanOrderedScalar.Boolean.cs" />
     <Compile Include="CompareLessThanOrEqual.Double.cs" />
+    <Compile Include="CompareLessThanOrEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareLessThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareLessThanOrEqualUnorderedScalar.Boolean.cs" />
+    <Compile Include="CompareLessThanScalar.Double.cs" />
+    <Compile Include="CompareLessThanUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareNotEqual.Double.cs" />
+    <Compile Include="CompareNotEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareNotEqualScalar.Double.cs" />
+    <Compile Include="CompareNotEqualUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareNotGreaterThan.Double.cs" />
     <Compile Include="CompareNotGreaterThanOrEqual.Double.cs" />
+    <Compile Include="CompareNotGreaterThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareNotGreaterThanScalar.Double.cs" />
     <Compile Include="CompareNotLessThan.Double.cs" />
     <Compile Include="CompareNotLessThanOrEqual.Double.cs" />
+    <Compile Include="CompareNotLessThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareNotLessThanScalar.Double.cs" />
     <Compile Include="CompareOrdered.Double.cs" />
+    <Compile Include="CompareOrderedScalar.Double.cs" />
     <Compile Include="CompareUnordered.Double.cs" />
+    <Compile Include="CompareUnorderedScalar.Double.cs" />
     <Compile Include="Divide.Double.cs" />
     <Compile Include="DivideScalar.Double.cs" />
     <Compile Include="Extract.UInt16.1.cs" />
     <Compile Include="Xor.UInt64.cs" />
     <Compile Include="Program.Sse2.cs" />
     <Compile Include="..\Shared\Program.cs" />
+    <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />    
     <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
     <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
     <Compile Include="..\Shared\ScalarSimdUnOpTest_DataTable.cs" />    
index 72d4292..391073b 100644 (file)
@@ -27,8 +27,8 @@
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Add.Double.cs" />
     <Compile Include="Add.Byte.cs" />
+    <Compile Include="Add.Double.cs" />
     <Compile Include="Add.Int16.cs" />
     <Compile Include="Add.Int32.cs" />
     <Compile Include="Add.Int64.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.SByte.cs"/>
     <Compile Include="AddSaturate.UInt16.cs"/>
-    <Compile Include="AddScalar.Double.cs"/>              
-    <Compile Include="And.Double.cs" />
+    <Compile Include="AddScalar.Double.cs"/> 
     <Compile Include="And.Byte.cs" />
+    <Compile Include="And.Double.cs" />
     <Compile Include="And.Int16.cs" />
     <Compile Include="And.Int32.cs" />
     <Compile Include="And.Int64.cs" />
@@ -50,8 +50,8 @@
     <Compile Include="And.UInt16.cs" />
     <Compile Include="And.UInt32.cs" />
     <Compile Include="And.UInt64.cs" />
-    <Compile Include="AndNot.Double.cs" />
     <Compile Include="AndNot.Byte.cs" />
+    <Compile Include="AndNot.Double.cs" />
     <Compile Include="AndNot.Int16.cs" />
     <Compile Include="AndNot.Int32.cs" />
     <Compile Include="AndNot.Int64.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="Average.UInt16.cs"/> 
     <Compile Include="CompareEqual.Byte.cs" />
+    <Compile Include="CompareEqual.Double.cs" />
     <Compile Include="CompareEqual.Int16.cs" />
     <Compile Include="CompareEqual.Int32.cs" />
     <Compile Include="CompareEqual.SByte.cs" />
     <Compile Include="CompareEqual.UInt16.cs" />
     <Compile Include="CompareEqual.UInt32.cs" />
+    <Compile Include="CompareEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareEqualScalar.Double.cs" />
+    <Compile Include="CompareEqualUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareGreaterThan.Double.cs" />
     <Compile Include="CompareGreaterThan.Int16.cs" />
     <Compile Include="CompareGreaterThan.Int32.cs" />
     <Compile Include="CompareGreaterThan.SByte.cs" />
+    <Compile Include="CompareGreaterThanOrderedScalar.Boolean.cs" />
     <Compile Include="CompareGreaterThanOrEqual.Double.cs" />
+    <Compile Include="CompareGreaterThanOrEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareGreaterThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareGreaterThanOrEqualUnorderedScalar.Boolean.cs" />
+    <Compile Include="CompareGreaterThanScalar.Double.cs" />
+    <Compile Include="CompareGreaterThanUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareLessThan.Double.cs" />
     <Compile Include="CompareLessThan.Int16.cs" />
     <Compile Include="CompareLessThan.Int32.cs" />
     <Compile Include="CompareLessThan.SByte.cs" />
+    <Compile Include="CompareLessThanOrderedScalar.Boolean.cs" />
     <Compile Include="CompareLessThanOrEqual.Double.cs" />
+    <Compile Include="CompareLessThanOrEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareLessThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareLessThanOrEqualUnorderedScalar.Boolean.cs" />
+    <Compile Include="CompareLessThanScalar.Double.cs" />
+    <Compile Include="CompareLessThanUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareNotEqual.Double.cs" />
+    <Compile Include="CompareNotEqualOrderedScalar.Boolean.cs" />
+    <Compile Include="CompareNotEqualScalar.Double.cs" />
+    <Compile Include="CompareNotEqualUnorderedScalar.Boolean.cs" />
     <Compile Include="CompareNotGreaterThan.Double.cs" />
     <Compile Include="CompareNotGreaterThanOrEqual.Double.cs" />
+    <Compile Include="CompareNotGreaterThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareNotGreaterThanScalar.Double.cs" />
     <Compile Include="CompareNotLessThan.Double.cs" />
     <Compile Include="CompareNotLessThanOrEqual.Double.cs" />
+    <Compile Include="CompareNotLessThanOrEqualScalar.Double.cs" />
+    <Compile Include="CompareNotLessThanScalar.Double.cs" />
     <Compile Include="CompareOrdered.Double.cs" />
+    <Compile Include="CompareOrderedScalar.Double.cs" />
     <Compile Include="CompareUnordered.Double.cs" />
+    <Compile Include="CompareUnorderedScalar.Double.cs" />
     <Compile Include="Divide.Double.cs" />
     <Compile Include="DivideScalar.Double.cs" />
     <Compile Include="Extract.UInt16.1.cs" />
     <Compile Include="Extract.UInt16.129.cs" />
     <Compile Include="Insert.Int16.1.cs" />
-    <Compile Include="Insert.UInt16.1.cs" />
     <Compile Include="Insert.Int16.129.cs" />
+    <Compile Include="Insert.UInt16.1.cs" />
     <Compile Include="Insert.UInt16.129.cs" />
-    <Compile Include="Max.Double.cs" />
     <Compile Include="Max.Byte.cs" />
+    <Compile Include="Max.Double.cs" />
     <Compile Include="Max.Int16.cs" />
     <Compile Include="MaxScalar.Double.cs" />
-    <Compile Include="Min.Double.cs" />
     <Compile Include="Min.Byte.cs" />
+    <Compile Include="Min.Double.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.Double.cs" />
     <Compile Include="Or.Int16.cs" />
     <Compile Include="Or.Int32.cs" />
     <Compile Include="Or.Int64.cs" />
     <Compile Include="Or.UInt16.cs" />
     <Compile Include="Or.UInt32.cs" />
     <Compile Include="Or.UInt64.cs" />
+    <Compile Include="Program.Sse2.cs" />
     <Compile Include="SetAllVector128.Byte.cs" />
-    <Compile Include="SetAllVector128.SByte.cs" />
+    <Compile Include="SetAllVector128.Double.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.SByte.cs" />
+    <Compile Include="SetAllVector128.UInt16.cs" />
+    <Compile Include="SetAllVector128.UInt32.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.Int16.16.cs" />
     <Compile Include="ShiftLeftLogical.Int32.1.cs" />
-    <Compile Include="ShiftLeftLogical.UInt32.1.cs" />
+    <Compile Include="ShiftLeftLogical.Int32.32.cs" />
     <Compile Include="ShiftLeftLogical.Int64.1.cs" />
-    <Compile Include="ShiftLeftLogical.UInt64.1.cs" />
-    <Compile Include="ShiftLeftLogical.Int16.16.cs" />
+    <Compile Include="ShiftLeftLogical.Int64.64.cs" />
+    <Compile Include="ShiftLeftLogical.UInt16.1.cs" />
     <Compile Include="ShiftLeftLogical.UInt16.16.cs" />
-    <Compile Include="ShiftLeftLogical.Int32.32.cs" />
+    <Compile Include="ShiftLeftLogical.UInt32.1.cs" />
     <Compile Include="ShiftLeftLogical.UInt32.32.cs" />
-    <Compile Include="ShiftLeftLogical.Int64.64.cs" />
+    <Compile Include="ShiftLeftLogical.UInt64.1.cs" />
     <Compile Include="ShiftLeftLogical.UInt64.64.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.Byte.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.Int16.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.Int32.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.Int64.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.SByte.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.UInt16.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.UInt32.1.cs" />
+    <Compile Include="ShiftLeftLogical128BitLane.UInt64.1.cs" />
+    <Compile Include="ShiftRightArithmetic.Int16.1.cs" />
+    <Compile Include="ShiftRightArithmetic.Int16.16.cs" />
+    <Compile Include="ShiftRightArithmetic.Int32.1.cs" />
+    <Compile Include="ShiftRightArithmetic.Int32.32.cs" />
     <Compile Include="ShiftRightLogical.Int16.1.cs" />
-    <Compile Include="ShiftRightLogical.UInt16.1.cs" />
+    <Compile Include="ShiftRightLogical.Int16.16.cs" />
     <Compile Include="ShiftRightLogical.Int32.1.cs" />
-    <Compile Include="ShiftRightLogical.UInt32.1.cs" />
+    <Compile Include="ShiftRightLogical.Int32.32.cs" />
     <Compile Include="ShiftRightLogical.Int64.1.cs" />
-    <Compile Include="ShiftRightLogical.UInt64.1.cs" />
-    <Compile Include="ShiftRightLogical.Int16.16.cs" />
+    <Compile Include="ShiftRightLogical.Int64.64.cs" />
+    <Compile Include="ShiftRightLogical.UInt16.1.cs" />
     <Compile Include="ShiftRightLogical.UInt16.16.cs" />
-    <Compile Include="ShiftRightLogical.Int32.32.cs" />
+    <Compile Include="ShiftRightLogical.UInt32.1.cs" />
     <Compile Include="ShiftRightLogical.UInt32.32.cs" />
-    <Compile Include="ShiftRightLogical.Int64.64.cs" />
+    <Compile Include="ShiftRightLogical.UInt64.1.cs" />
     <Compile Include="ShiftRightLogical.UInt64.64.cs" />
-    <Compile Include="ShiftRightArithmetic.Int16.1.cs" />
-    <Compile Include="ShiftRightArithmetic.Int32.1.cs" />
-    <Compile Include="ShiftRightArithmetic.Int16.16.cs" />
-    <Compile Include="ShiftRightArithmetic.Int32.32.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.SByte.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.Byte.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.Int16.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.UInt16.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.Int32.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.UInt32.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.Int64.1.cs" />
-    <Compile Include="ShiftLeftLogical128BitLane.UInt64.1.cs" />
-    <Compile Include="ShiftRightLogical128BitLane.SByte.1.cs" />
     <Compile Include="ShiftRightLogical128BitLane.Byte.1.cs" />
     <Compile Include="ShiftRightLogical128BitLane.Int16.1.cs" />
-    <Compile Include="ShiftRightLogical128BitLane.UInt16.1.cs" />
     <Compile Include="ShiftRightLogical128BitLane.Int32.1.cs" />
-    <Compile Include="ShiftRightLogical128BitLane.UInt32.1.cs" />
     <Compile Include="ShiftRightLogical128BitLane.Int64.1.cs" />
+    <Compile Include="ShiftRightLogical128BitLane.SByte.1.cs" />
+    <Compile Include="ShiftRightLogical128BitLane.UInt16.1.cs" />
+    <Compile Include="ShiftRightLogical128BitLane.UInt32.1.cs" />
     <Compile Include="ShiftRightLogical128BitLane.UInt64.1.cs" />
-    <Compile Include="Subtract.Double.cs" />
     <Compile Include="Subtract.Byte.cs" />
+    <Compile Include="Subtract.Double.cs" />
     <Compile Include="Subtract.Int16.cs" />
     <Compile Include="Subtract.Int32.cs" />
     <Compile Include="Subtract.Int64.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.SByte.cs"/>
     <Compile Include="SubtractSaturate.UInt16.cs"/>
-    <Compile Include="SubtractScalar.Double.cs" />    
-    <Compile Include="Xor.Double.cs" />
+    <Compile Include="SubtractScalar.Double.cs" /> 
     <Compile Include="Xor.Byte.cs" />
+    <Compile Include="Xor.Double.cs" />
     <Compile Include="Xor.Int16.cs" />
     <Compile Include="Xor.Int32.cs" />
     <Compile Include="Xor.Int64.cs" />
     <Compile Include="Xor.UInt16.cs" />
     <Compile Include="Xor.UInt32.cs" />
     <Compile Include="Xor.UInt64.cs" />
-    <Compile Include="Program.Sse2.cs" />
     <Compile Include="..\Shared\Program.cs" />
+    <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />
     <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
     <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
     <Compile Include="..\Shared\ScalarSimdUnOpTest_DataTable.cs" />
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs b/tests/src/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs
new file mode 100644 (file)
index 0000000..64fc0d3
--- /dev/null
@@ -0,0 +1,107 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// The test exposed a bug in CORINFO_HELP_ASSIGN_BYREF GC kill set on Unix x64.
+// that caused segfault.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+
+namespace Repro
+{
+    [Serializable]
+    public struct CompositeSource
+    {
+        public double? Modifier { get; set; }
+        public int InstrumentId { get; set; }
+        public string Section { get; set; }
+
+        public bool IsCash { get; set; }
+        public bool IsHedge { get; set; }
+
+    }
+
+    public class Test
+    {
+        private static readonly DateTime BaseDate = new DateTime(2012, 1, 1);
+
+        private readonly Random rng;
+
+        public int Count { get; }
+
+        public Test(Random rng, List<CompositeSource> sources)
+        {
+            this.rng = rng;
+            var holdingsAttribution = this.GetNumbers(sources);
+            var hedgeAttribution = this.GetNumbers(sources).Where(x => x.Date >= holdingsAttribution.Min(y => y.Date)).ToList();
+            this.Count = hedgeAttribution.Count;
+        }
+
+        private List<(DateTime Date, CompositeSource Key, decimal Attribution)> GetNumbers(List<CompositeSource> sources)
+        {
+            var items = new List<(DateTime Date, CompositeSource Key, decimal Attribution)>();
+
+            foreach (var _ in Enumerable.Range(0, rng.Next(1000, 10000)))
+            {
+                items.Add((
+                    BaseDate.AddDays(rng.Next(1, 100)),
+                    sources[rng.Next(0, sources.Count - 1)],
+                    Convert.ToDecimal(rng.NextDouble() * rng.Next(1, 10))));
+            }
+
+            return items;
+        }
+    }
+
+    class Program
+    {
+        static readonly Random Rng = new Random(38237);
+
+        public static List<CompositeSource> GetCompositeSources()
+        {
+
+            var list = new List<CompositeSource>();
+            foreach (var _ in Enumerable.Range(0, 100))
+            {
+                lock (Rng)
+                {
+                    list.Add(new CompositeSource
+                    {
+                        InstrumentId = 1,
+                        IsCash = true,
+                        IsHedge = true,
+                        Modifier = 0.5,
+                        Section = "hello"
+                    });
+                }
+
+            }
+
+            return list;
+        }
+
+        static int Main()
+        {
+            Console.WriteLine("Starting stress loop");
+            var compositeSources = GetCompositeSources();
+            var res = Parallel.For(0, 10, i =>
+            {
+                int seed;
+                lock (Rng)
+                {
+                    seed = Rng.Next();
+                }
+                Console.WriteLine(new Test(new Random(seed), compositeSources).Count);
+            });
+
+            Console.WriteLine("Result: {0}", res.IsCompleted ? "Completed Normally" :
+                $"Completed to {res.LowestBreakIteration}");
+            return res.IsCompleted ? 100 : -1;
+        }
+    }
+}
@@ -4,35 +4,32 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <AssemblyName>$(MSBuildProjectName)</AssemblyName>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{87F2B90D-85D3-4304-99D3-355F109BE961}</ProjectGuid>
+    <ProjectGuid>{ADEEA3D1-B67B-456E-8F2B-6DCCACC2D34C}</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>
+    <CLRTestPriority>1</CLRTestPriority>
   </PropertyGroup>
   <!-- Default configurations to help VS understand the configurations -->
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
   <ItemGroup>
     <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
       <Visible>False</Visible>
     </CodeAnalysisDependentAssemblyPaths>
   </ItemGroup>
   <PropertyGroup>
-    <DebugType>Embedded</DebugType>
-    <Optimize>
-    </Optimize>
+    <DebugType>None</DebugType>
+    <Optimize>False</Optimize>
   </PropertyGroup>
   <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+    <Compile Include="$(MSBuildProjectName).cs" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CompareGreaterThanOrEqualScalar.cs" />
-    <Compile Include="TestTableSse2.cs" />
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </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>
index aa56d76..2f4365f 100644 (file)
@@ -336,6 +336,7 @@ JIT/Regression/VS-ia64-JIT/V1.2-M01/b15632/b15632/b15632.sh
 JIT/Regression/VS-ia64-JIT/V1.2-M02/b12011/b12011/b12011.sh
 JIT/Regression/VS-ia64-JIT/V2.0-Beta2/b410474/b410474/b410474.sh
 JIT/Regression/VS-ia64-JIT/V2.0-RTM/b286991/b286991/b286991.sh
+JIT/Directed/arglist/vararg/vararg.sh
 managed/Compilation/Compilation/Compilation.sh
 readytorun/r2rdump/R2RDumpTest/R2RDumpTest.sh
 Regressions/coreclr/0584/Test584/Test584.sh