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
{
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
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
<_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 -->
<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" />
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, isDecimal:true);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, isDecimal: true);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
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)
char fmt = ParseFormatSpecifier(format, out int digits);
int precision = DoublePrecision;
NumberBuffer number = default;
+ number.kind = NumberBufferKind.Double;
switch (fmt)
{
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;
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, isDecimal: false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
char fmt = ParseFormatSpecifier(format, out int digits);
int precision = FloatPrecision;
NumberBuffer number = default;
+ number.kind = NumberBufferKind.Double;
switch (fmt)
{
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;
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
}
if (fmt != 0)
{
- NumberToString(ref sb, ref number, fmt, digits, info, false);
+ NumberToString(ref sb, ref number, fmt, digits, info);
}
else
{
int i = (int)(buffer + Int32Precision - p);
number.scale = i;
+ number.kind = NumberBufferKind.Integer;
char* dst = number.digits;
while (--i >= 0)
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)
int i = (int)(buffer + Int64Precision - p);
number.scale = i;
+ number.kind = NumberBufferKind.Integer;
char* dst = number.digits;
while (--i >= 0)
int i = (int)(buffer + UInt64Precision - p);
number.scale = i;
+ number.kind = NumberBufferKind.Integer;
char* dst = number.digits;
while (--i >= 0)
'\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':
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
}
}
- 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;
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;
}
else
{
- number.sign = false; // We need to format -0 without the sign set.
number.scale = 0; // Decimals with scale ('0.00') should be rounded.
}
if (i == 0)
{
number.scale = 0;
- number.sign = false;
+
+ if (number.kind == NumberBufferKind.Integer)
+ {
+ number.sign = false;
+ }
}
dig[i] = '\0';
}
[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
+ }
}
}
{
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;
/// <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(); }
/// <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)
/// __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(); }
}
}
/// __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);
}
}
/// <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)
{
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)
#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; } }
install_clr(sos)
if(NOT WIN32)
- install(FILES sosdocsunix.txt DESTINATION .)
+ _install(FILES sosdocsunix.txt DESTINATION .)
endif(NOT WIN32)
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;
// 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;
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)
{
// 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);
}
// 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.
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)
{
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)
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();
{
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)
{
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;
}
{
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;
}
TADDR *mBuffer;
CGCDescSeries *mCurrSeries;
+ TADDR mLoaderAllocatorObjectHandle;
+
int i, mCount;
TADDR mCurr, mStop, mObject;
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
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;
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);
TADDR *Buffer;
CGCDesc *GCDesc;
+ TADDR LoaderAllocatorObjectHandle;
bool ArrayOfVC;
bool ContainsPointers;
+ bool Collectible;
size_t BaseSize;
size_t ComponentSize;
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)
{
}
// 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;
*exponent = 0;
UNREACHABLE();
}
-}
\ No newline at end of file
+}
#include "diyfp.h"
+#ifdef _MSC_VER
+#define _signbit signbit
+#define _signbitf signbit
+#endif
+
struct PowerOfTen
{
UINT64 significand;
#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 )
{
// ========================================================================================================================================
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;
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;
// 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
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");
// 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)
{
}
// 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)
// 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)
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;
}
}
// 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;
}
// 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;
}
// 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;
}
// 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--)
{
{
for (int k = MaxSubICUVersion; k >= MinSubICUVersion; k--)
{
- if (OpenICULibraries(i, j, k, symbolName, symbolVersion))
+ if (OpenICULibraries(i, j, k, versionPrefix, symbolName, symbolVersion))
{
return true;
}
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__
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) \
dlclose(libicui18n);
libicui18n = nullptr;
}
-}
\ No newline at end of file
+}
// 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))
{
ifaceRet = static_cast<ISOSDacInterface5*>(this);
}
+ else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface6)))
+ {
+ ifaceRet = static_cast<ISOSDacInterface6*>(this);
+ }
else
{
*iface = NULL;
public ISOSDacInterface2,
public ISOSDacInterface3,
public ISOSDacInterface4,
- public ISOSDacInterface5
+ public ISOSDacInterface5,
+ public ISOSDacInterface6
{
public:
ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0);
// 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.
//
}
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)
// 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.
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."
#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
import "unknwn.idl";
#endif
+#define STDMETHODCALLTYPE
+
typedef UINT_PTR ProcessID;
typedef UINT_PTR AssemblyID;
typedef UINT_PTR AppDomainID;
* 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);
/*
* 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);
* 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);
/*
* 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);
}
};
+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;
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_
ArmVolatileContextPointer volatileCurrContextPointers;
DWORD * pPC; // processor neutral name
-
+#ifndef CROSSGEN_COMPILE
REGDISPLAY()
{
// Initialize regdisplay
// 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
{
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);
+};
#ifndef ALLOC_ALIGN_CONSTANT
-#define ALLOC_ALIGN_CONSTANT ((1<<LOG2_PTRSIZE)-1)
+#define ALLOC_ALIGN_CONSTANT (sizeof(void*)-1)
#endif
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
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);
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);
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);
}
//------------------------------------------------------------------------
-// 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);
}
//------------------------------------------------------------------------
}
//----------------------------------------------------------------------
-// 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
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;
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_)
#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);
}
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)
{
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.
#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)
{
#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
//
}
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
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
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;
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
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
#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);
}
//------------------------------------------------------------------------
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);
opts.disDiffable = false;
opts.dspCode = false;
opts.dspEHTable = false;
+ opts.dspDebugInfo = false;
opts.dspGCtbls = false;
opts.disAsm2 = false;
opts.dspUnwind = false;
{
opts.dspEHTable = true;
}
+
+ if (JitConfig.NgenDebugDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
+ {
+ opts.dspDebugInfo = true;
+ }
}
else
{
{
opts.dspEHTable = true;
}
+
+ if (JitConfig.JitDebugDump().contains(info.compMethodName, info.compClassName,
+ &info.compMethodInfo->args))
+ {
+ opts.dspDebugInfo = true;
+ }
}
}
break;
case GT_FIELD:
-
- if (tree->gtFlags & GTF_FLD_NULLCHECK)
- {
- chars += printf("[FLD_NULLCHECK]");
- }
if (tree->gtFlags & GTF_FLD_VOLATILE)
{
chars += printf("[FLD_VOLATILE]");
{
chars += printf("[IND_INVARIANT]");
}
- if (tree->gtFlags & GTF_IND_ARR_LEN)
- {
- chars += printf("[IND_ARR_INDEX]");
- }
break;
case GT_CLS_VAR:
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);
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
* 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' */
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)
assert(opts.compScopeInfo);
#ifdef DEBUG
- if (verbose)
+ if (verbose || opts.dspDebugInfo)
{
eeDispVars(info.compMethodHnd, eeVarsCount, (ICorDebugInfo::NativeVarInfo*)eeVars);
}
assert(opts.compDbgInfo);
#if defined(DEBUG)
- if (verbose)
+ if (verbose || opts.dspDebugInfo)
{
eeDispLineInfos();
}
}
}
-/*****************************************************************************
- *
- * 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;
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);
}
/*****************************************************************************
}
#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;
+ }
+}
/* 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 */
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
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 */
// 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;
}
#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)
{
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)
{
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)
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);
/*****************************************************************************
*
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 */
// 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;
}
#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)
{
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)
{
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)
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);
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
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;
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;
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)
{
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 */
}
#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;
}
#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)
{
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 */
}
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)
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);
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:
{
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:
{
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);
// 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,
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_
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);
}
// 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();
// 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);
}
}
}
-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)
{
{
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:
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
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)
// 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;
}
{
// 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) &&
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;
}
// 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;
}
#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
#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.
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)
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)
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;
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);
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)
if (op1->OperIsList())
{
-#if DEBUG
GenTreeArgList* list = op1->AsArgList();
numArgs = 0;
list = list->Rest();
} while (list != nullptr);
- assert(numArgs == 3);
-#endif
-
- return 3;
+ return numArgs;
}
GenTree* op2 = node->gtGetOp2();
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();
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));
}
//------------------------------------------------------------------------
+// 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:
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 =
if (!HWIntrinsicInfo::HasFullRangeImm(intrinsic))
{
if (!mustExpand && lastOp->IsCnsIntOrI() &&
- lastOp->AsIntCon()->IconValue() > HWIntrinsicInfo::lookupImmUpperBound(intrinsic))
+ !HWIntrinsicInfo::isInImmRange(intrinsic, (int)lastOp->AsIntCon()->IconValue()))
{
return nullptr;
}
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();
}
}
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;
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);
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);
{
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;
}
// 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);
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
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))
}
/* 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)
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 */
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
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"))
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
}
}
-/**
- * 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
//------------------------------------------------------------------------
}
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)
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;
}
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
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;
#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:
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_
#endif // FEATURE_HW_INTRINSICS
case GT_CAST:
- srcCount = BuildCast(tree);
+ assert(dstCount == 1);
+ srcCount = BuildCast(tree->AsCast());
break;
case GT_BITCAST:
#ifdef FEATURE_HW_INTRINSICS
case GT_HW_INTRINSIC_CHK:
#endif // FEATURE_HW_INTRINSICS
+
// Consumes arrLen & index - has no result
srcCount = 2;
assert(dstCount == 0);
if (op1->OperIsList())
{
assert(op2 == nullptr);
- assert(numArgs == 3);
+ assert(numArgs >= 3);
GenTreeArgList* argList = op1->AsArgList();
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)
{
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;
}
// 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;
}
}
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);
}
}
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);
// Named jit intrinsics
-enum NamedIntrinsic : unsigned int
+enum NamedIntrinsic : unsigned short
{
NI_Illegal = 0,
NI_System_Enum_HasFlag = 1,
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)
#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
// 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);
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);
.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
// 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
.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
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
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);
#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 */
endif(FEATURE_EVENT_TRACE)
# Install the static PAL library for VS
-install (TARGETS coreclrpal DESTINATION lib)
+_install (TARGETS coreclrpal DESTINATION lib)
/*++
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.
/*++
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.
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-", '')
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):
add_subdirectory(tracepointprovider)
# Install the static eventprovider library
- install(TARGETS eventprovider DESTINATION lib)
+ _install(TARGETS eventprovider DESTINATION lib)
""")
#TracepointProvider Cmake
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
)
// 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
// 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)
{
}
};
// 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
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];
}
};
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
struct HijackArgs
{
union
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
ThumbEmitEpilog();
}
+#ifndef CROSSGEN_COMPILE
+
void StubLinkerCPU::ThumbEmitCallManagedMethod(MethodDesc *pMD, bool fTailcall)
{
bool isRelative = MethodTable::VTableIndir2_t::isRelative
}
}
-#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
}
#endif // !DACCESS_COMPILE
-#endif // !CROSSGEN_COMPILE
void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
{
SyncRegDisplayToCurrentContext(pRD);
}
-#endif
+#endif // FEATURE_HIJACK
+#endif // !CROSSGEN_COMPILE
class UMEntryThunk * UMEntryThunk::Decode(void *pCallback)
{
#endif // FEATURE_COMINTEROP
-void JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
+void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
{
_ASSERTE(!"ARM64:NYI");
}
// 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;
{
// 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;
{
// 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;
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
}
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
}
#endif //FEATURE_PREJIT
-
+void Module::SetIsIJWFixedUp()
+{
+ LIMITED_METHOD_CONTRACT;
+ FastInterlockOr(&m_dwTransientFlags, IS_IJW_FIXED_UP);
+}
#ifdef FEATURE_PREJIT
/* static */
#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
};
//-------------------------------------------------------------------------------
void ApplyMetaData();
+ void FixupVTables();
void FreeClassTables();
}
#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:
{
WRAPPER_NO_CONTRACT;
+#if !defined(CROSSGEN_COMPILE)
+ if (!GetCurrentModule()->IsResource())
+ GetCurrentModule()->FixupVTables();
+#endif // !CROSSGEN_COMPILE
}
void DomainFile::FinishLoad()
}
// 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
//---------------------------------------------------------------------------------------
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
+++ /dev/null
-; Licensed to the .NET Foundation under one or more 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
#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");
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);
};
}
}
+#ifndef CROSSGEN_COMPILE
if (tokenRange != currentTokenRange ||
sizeOfMethodDescs + size > MethodDescChunk::MaxSizeOfMethodDescs)
+#endif // CROSSGEN_COMPILE
{
if (sizeOfMethodDescs != 0)
{
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
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);
}
+/* 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
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
};
static BOOL CompareImage(UPTR image1, UPTR image2);
+ static BOOL CompareIJWDataBase(UPTR base, UPTR mapping);
void DECLSPEC_NORETURN ThrowFormat(HRESULT hr);
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;
// 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
// ----------------------------------------------------------------------------
*pUnwindCodes++ = (BYTE)0xFF; // end
}
- int epilogUnwindCodeIndex = 0;
+ ptrdiff_t epilogUnwindCodeIndex = 0;
//epilog differs from prolog
if(m_cbStackFrame >= 4096)
}
// 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);
*(DWORD *)pUnwindInfo =
((functionLength) / 2) |
(1 << 21) |
- (epilogUnwindCodeIndex << 23)|
- (codeWordsCount << 28);
+ ((int)epilogUnwindCodeIndex << 23)|
+ ((int)codeWordsCount << 28);
#elif defined(_TARGET_ARM64_)
if (!m_fProlog)
}
]
}
+ },
+ {
+ "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"
+ }
+ ]
+ }
}
]
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
<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 -->
# 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)
+// Licensed to the .NET Foundation under one or more 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
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")
+// Licensed to the .NET Foundation under one or more 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()
{
--- /dev/null
+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)
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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();
+ }
+};
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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);
+ }
+}
<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>
{
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...");
{
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...");
{
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...");
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);
{
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...");
}
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...");
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);
}
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...");
{
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...");
{
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...");
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...");
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);
{
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...");
{
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);
}
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...");
{
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...");
{
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...");
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...");
{
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);
{
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...");
{
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...");
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...");
{
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...");
{
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...");
{
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...");
{
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...");
}
#endregion
-}
\ No newline at end of file
+}
--- /dev/null
+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
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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;
+ }
+ }
+}
--- /dev/null
+<?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>
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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;
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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();
+ }
+ }
+
+ }
+}
<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>
<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>
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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();
+ }
+ }
+
+ }
+}
<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>
<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>
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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();
+ }
+ }
+
+ }
+}
<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>
<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>
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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();
+ }
+ }
+
+ }
+}
<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>
<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>
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 []
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. 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);
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more 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;
- }
- }
-}
["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,
<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" />
<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" />
<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" />
--- /dev/null
+// Licensed to the .NET Foundation under one or more 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;
+ }
+ }
+}
<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>
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