IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED "SIMD intrinsics may not be used by partial trust applications."
IDS_IBC_MISSING_EXTERNAL_TYPE "The generic type specified by the IBC data is not available to this assembly"
IDS_IBC_MISSING_EXTERNAL_METHOD "The generic method specified by the IBC data is not available to this assembly"
+ IDS_EE_HWINTRINSIC_NGEN_DISALLOWED "Hardware intrinsics may not be used with ngen."
IDS_INET_E_CANNOT_CONNECT "Cannot connect to URL for '%1'."
IDS_INET_E_RESOURCE_NOT_FOUND "The server or proxy was not found for '%1'."
#define IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED 0x1ac4
#define IDS_IBC_MISSING_EXTERNAL_TYPE 0x1ac5
#define IDS_IBC_MISSING_EXTERNAL_METHOD 0x1ac6
+#define IDS_EE_HWINTRINSIC_NGEN_DISALLOWED 0x1ac7
#define BFA_INVALID_FILE_TOKEN 0x2000
#define BFA_INVALID_TOKEN_TYPE 0x2001
#endif // _TARGET_X86_
-// Instruction set flags fo// Instruction set flags for Intel hardware intrinsics
+// Instruction set flags for Intel hardware intrinsics
#ifdef _TARGET_XARCH_
opts.compSupportsISA = 0;
InstructionSet lookupHWIntrinsicISA(const char* className);
NamedIntrinsic lookupHWIntrinsic(const char* methodName, InstructionSet isa);
InstructionSet isaOfHWIntrinsic(NamedIntrinsic intrinsic);
- GenTree* impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
- GenTree* impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method);
+ GenTree* impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
+ GenTree* impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
#endif
GenTreePtr impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
CORINFO_SIG_INFO* sig,
#endif
}
+ bool compSupports(InstructionSet isa)
+ {
+#ifdef _TARGET_XARCH_
+ return (opts.compSupportsISA & (1 << isa)) != 0;
+#else
+ return false;
+#endif
+ }
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#endif // _TARGET_XARCH_
#ifdef _TARGET_XARCH_
- // only for Intel hardware intrinsics
uint64_t compSupportsISA;
void setSupportedISA(InstructionSet isa)
{
compSupportsISA |= 1 << isa;
}
- bool compSupports(InstructionSet isa)
- {
- return (compSupportsISA & (1 << isa)) != 0;
- }
#endif
// optimize maximally and/or favor speed over size?
// Arguments:
// intrinsic -- id of the intrinsic function.
// method -- method handle of the intrinsic function.
+// sig -- signature of the intrinsic call
//
// Return Value:
// the expanded intrinsic.
//
-GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
InstructionSet isa = isaOfHWIntrinsic(intrinsic);
switch (isa)
{
case InstructionSet_SSE:
- return impSSEIntrinsic(intrinsic, method);
+ return impSSEIntrinsic(intrinsic, method, sig);
case InstructionSet_SSE2:
- return impSSE2Intrinsic(intrinsic, method);
+ return impSSE2Intrinsic(intrinsic, method, sig);
case InstructionSet_SSE3:
- return impSSE3Intrinsic(intrinsic, method);
+ return impSSE3Intrinsic(intrinsic, method, sig);
case InstructionSet_SSSE3:
- return impSSSE3Intrinsic(intrinsic, method);
+ return impSSSE3Intrinsic(intrinsic, method, sig);
case InstructionSet_SSE41:
- return impSSE41Intrinsic(intrinsic, method);
+ return impSSE41Intrinsic(intrinsic, method, sig);
case InstructionSet_SSE42:
- return impSSE42Intrinsic(intrinsic, method);
+ return impSSE42Intrinsic(intrinsic, method, sig);
case InstructionSet_AVX:
- return impAVXIntrinsic(intrinsic, method);
+ return impAVXIntrinsic(intrinsic, method, sig);
case InstructionSet_AVX2:
- return impAVX2Intrinsic(intrinsic, method);
+ return impAVX2Intrinsic(intrinsic, method, sig);
case InstructionSet_AES:
- return impAESIntrinsic(intrinsic, method);
+ return impAESIntrinsic(intrinsic, method, sig);
case InstructionSet_BMI1:
- return impBMI1Intrinsic(intrinsic, method);
+ return impBMI1Intrinsic(intrinsic, method, sig);
case InstructionSet_BMI2:
- return impBMI2Intrinsic(intrinsic, method);
+ return impBMI2Intrinsic(intrinsic, method, sig);
case InstructionSet_FMA:
- return impFMAIntrinsic(intrinsic, method);
+ return impFMAIntrinsic(intrinsic, method, sig);
case InstructionSet_LZCNT:
- return impLZCNTIntrinsic(intrinsic, method);
+ return impLZCNTIntrinsic(intrinsic, method, sig);
case InstructionSet_PCLMULQDQ:
- return impPCLMULQDQIntrinsic(intrinsic, method);
+ return impPCLMULQDQIntrinsic(intrinsic, method, sig);
case InstructionSet_POPCNT:
- return impPOPCNTIntrinsic(intrinsic, method);
+ return impPOPCNTIntrinsic(intrinsic, method, sig);
default:
return nullptr;
}
}
-GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_SSE_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_SSE));
+ return gtNewIconNode(compSupports(InstructionSet_SSE));
default:
return nullptr;
}
}
-GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_SSE2_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_SSE2));
+ return gtNewIconNode(compSupports(InstructionSet_SSE2));
default:
return nullptr;
}
}
-GenTree* Compiler::impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_SSE3_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_SSE3));
+ return gtNewIconNode(compSupports(InstructionSet_SSE3));
default:
return nullptr;
}
}
-GenTree* Compiler::impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_SSSE3_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_SSSE3));
+ return gtNewIconNode(compSupports(InstructionSet_SSSE3));
default:
return nullptr;
}
}
-GenTree* Compiler::impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_SSE41_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_SSE41));
+ return gtNewIconNode(compSupports(InstructionSet_SSE41));
default:
return nullptr;
}
}
-GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_SSE42_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_SSE42));
+ return gtNewIconNode(compSupports(InstructionSet_SSE42));
default:
return nullptr;
}
}
-GenTree* Compiler::impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_AVX_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_AVX));
+ return gtNewIconNode(compSupports(InstructionSet_AVX));
default:
return nullptr;
}
}
-GenTree* Compiler::impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_AVX2_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_AVX2));
+ return gtNewIconNode(compSupports(InstructionSet_AVX2));
default:
return nullptr;
}
}
-GenTree* Compiler::impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_AES_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_AES));
+ return gtNewIconNode(compSupports(InstructionSet_AES));
default:
return nullptr;
}
}
-GenTree* Compiler::impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_BMI1_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_BMI1));
+ return gtNewIconNode(compSupports(InstructionSet_BMI1));
default:
return nullptr;
}
}
-GenTree* Compiler::impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_BMI2_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_BMI2));
+ return gtNewIconNode(compSupports(InstructionSet_BMI2));
default:
return nullptr;
}
}
-GenTree* Compiler::impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_FMA_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_FMA));
+ return gtNewIconNode(compSupports(InstructionSet_FMA));
default:
return nullptr;
}
}
-GenTree* Compiler::impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_LZCNT_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_LZCNT));
+ return gtNewIconNode(compSupports(InstructionSet_LZCNT));
default:
return nullptr;
}
}
-GenTree* Compiler::impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_PCLMULQDQ_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_PCLMULQDQ));
+ return gtNewIconNode(compSupports(InstructionSet_PCLMULQDQ));
default:
return nullptr;
}
}
-GenTree* Compiler::impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method)
+GenTree* Compiler::impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
{
switch (intrinsic)
{
case NI_POPCNT_IsSupported:
- return gtNewIconNode(opts.compSupports(InstructionSet_POPCNT));
+ return gtNewIconNode(compSupports(InstructionSet_POPCNT));
default:
return nullptr;
GenTreePtr retNode = nullptr;
//
- // We disable the inlining of instrinsics for MinOpts.
- //
- if (!mustExpand && (opts.compDbgCode || opts.MinOpts()))
+ // We disable the inlining of intrinsic for MinOpts,
+ // but we should always expand hardware intrinsics whose managed method body
+ // is a directly recursive call site. This design makes hardware intrinsic
+ // be able to work with debugger and reflection.
+ if (!mustExpand && (opts.compDbgCode || opts.MinOpts()) && !gtIsRecursiveCall(method))
{
*pIntrinsicID = CORINFO_INTRINSIC_Illegal;
return retNode;
#ifdef _TARGET_XARCH_
if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END)
{
- retNode = impX86HWIntrinsic(ni, method);
+ retNode = impX86HWIntrinsic(ni, method, sig);
}
#endif
switch (ni)
#define EmitSize(x) (EA_ATTR(genTypeSize(TypeGet(x))))
-// Enum specifying the instruction set for generating floating point or SIMD code.
-// These enums are ordered such that each one is inclusive of previous instruction sets
-// and the VM ensures this as well when setting the CONFIG flags.
enum InstructionSet
{
#ifdef _TARGET_XARCH_
InstructionSet_AVX = 8,
InstructionSet_AVX2 = 9,
// Linear order end
- // Instruction sets have the linear order only in above area.
- // Values of InstructionSet not in this area cannot be compared
- // (i.e. compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4).
-
+ // TODO - Instruction sets have the linear order only in above area.
+ // We should no long compare the return value of getSIMDInstructionSet()
+ // or getFloatingPointInstructionSet() to the InstructionSet values.
+ // Should refactor SIMD code only to be aware of SIMD feature levels
+ // (SSE2, SSE3_4, AVX, and AVX2, etc.) rather than concrete ISA.
+
InstructionSet_AES = 32,
InstructionSet_BMI1 = 33,
InstructionSet_BMI2 = 34,
// See the LICENSE file in the project root for more information.
using System;
+using System.Runtime.Intrinsics;
namespace System.Runtime.Intrinsics.X86
{
// See the LICENSE file in the project root for more information.
using System;
+using System.Runtime.Intrinsics;
namespace System.Runtime.Intrinsics.X86
{
}
}
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+ // All the funtions in System.Runtime.Intrinsics.X86 are hardware intrinsics.
+ // We specially treat them here to reduce the disk footprint of mscorlib.
+ if (GetModule()->IsSystem() && !bmtGenerics->HasInstantiation())
+ {
+ LPCUTF8 x86className;
+ LPCUTF8 x86nameSpace;
+ HRESULT hr = GetMDImport()->GetNameOfTypeDef(bmtInternal->pType->GetTypeDefToken(), &x86className, &x86nameSpace);
+
+ if (hr == S_OK && strcmp(x86nameSpace, "System.Runtime.Intrinsics.X86") == 0)
+ {
+ if (IsCompilationProcess())
+ {
+ // Disable AOT compiling for managed implementation of hardware intrinsics in mscorlib.
+ COMPlusThrow(kTypeLoadException, IDS_EE_HWINTRINSIC_NGEN_DISALLOWED);
+ }
+ bmtProp->fIsHardwareIntrinsic = true;
+ }
+ }
+#endif
#ifdef FEATURE_COMINTEROP
NULL,
NULL);
- if (hr == S_OK)
- {
- pNewMD->SetIsJitIntrinsic();
- }
-
- // All the funtions in System.Runtime.Intrinsics.X86 are hardware intrinsics.
- // We specially treat them here to reduce the disk footprint of mscorlib.
- LPCUTF8 className;
- LPCUTF8 nameSpace;
-
- HRESULT hrns = GetMDImport()->GetNameOfTypeDef(bmtInternal->pType->GetTypeDefToken(), &className, &nameSpace);
-
- if (hrns == S_OK && strcmp(nameSpace, "System.Runtime.Intrinsics.X86") == 0)
+ if (hr == S_OK || bmtProp->fIsHardwareIntrinsic)
{
pNewMD->SetIsJitIntrinsic();
}
{
BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
}
-
+
if (IsValueClass())
{
//
bool fDynamicStatics; // Set to true if the statics will be allocated in the dynamic
bool fGenericsStatics; // Set to true if the there are per-instantiation statics
+ bool fIsHardwareIntrinsic; // Set to true if the class is a hardware intrinsic
+
DWORD dwNonGCRegularStaticFieldBytes;
DWORD dwNonGCThreadStaticFieldBytes;
level = CORZAP_LOGLEVEL_INFO;
}
+ if (resID == IDS_EE_HWINTRINSIC_NGEN_DISALLOWED)
+ {
+ // Supress printing of "Hardware intrinsics may not be used with ngen."
+ level = CORZAP_LOGLEVEL_INFO;
+ }
+
#ifdef CROSSGEN_COMPILE
if ((resID == IDS_IBC_MISSING_EXTERNAL_TYPE) ||
(resID == IDS_IBC_MISSING_EXTERNAL_METHOD))
<Version>$(CoreFxPackageVersion)</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Intrinsics.X86">
- <Version>4.5.0-preview1-25718-03</Version>
+ <Version>$(CoreFxPackageVersion)</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup>
// 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.Numerics;
namespace IntelHardwareIntrinsicTest
{
result = false;
}
}
- if (Aes.IsSupported && Bmi1.IsSupported && Bmi2.IsSupported && Fma.IsSupported &&
- Lzcnt.IsSupported && Popcnt.IsSupported && Pclmulqdq.IsSupported)
- {
- result = result && true;
- }
- else
- {
- result = false;
- }
+ }
+
+ if (Vector<byte>.Count == 32 && !Avx2.IsSupported)
+ {
+ result = false;
+ }
+
+ if (Vector<byte>.Count == 16 && Vector.IsHardwareAccelerated && !Sse2.IsSupported)
+ {
+ result = false;
}
// Non-X86 platforms
result = false;
}
}
+
+ // Reflection call
+ var issupported = "get_IsSupported";
+ if (Convert.ToBoolean(typeof(Sse).GetMethod(issupported).Invoke(null, null)) != Sse.IsSupported ||
+ Convert.ToBoolean(typeof(Sse2).GetMethod(issupported).Invoke(null, null)) != Sse2.IsSupported ||
+ Convert.ToBoolean(typeof(Sse3).GetMethod(issupported).Invoke(null, null)) != Sse3.IsSupported ||
+ Convert.ToBoolean(typeof(Ssse3).GetMethod(issupported).Invoke(null, null)) != Ssse3.IsSupported ||
+ Convert.ToBoolean(typeof(Sse41).GetMethod(issupported).Invoke(null, null)) != Sse41.IsSupported ||
+ Convert.ToBoolean(typeof(Sse42).GetMethod(issupported).Invoke(null, null)) != Sse42.IsSupported ||
+ Convert.ToBoolean(typeof(Aes).GetMethod(issupported).Invoke(null, null)) != Aes.IsSupported ||
+ Convert.ToBoolean(typeof(Avx).GetMethod(issupported).Invoke(null, null)) != Avx.IsSupported ||
+ Convert.ToBoolean(typeof(Avx2).GetMethod(issupported).Invoke(null, null)) != Avx2.IsSupported ||
+ Convert.ToBoolean(typeof(Fma).GetMethod(issupported).Invoke(null, null)) != Fma.IsSupported ||
+ Convert.ToBoolean(typeof(Lzcnt).GetMethod(issupported).Invoke(null, null)) != Lzcnt.IsSupported ||
+ Convert.ToBoolean(typeof(Bmi1).GetMethod(issupported).Invoke(null, null)) != Bmi1.IsSupported ||
+ Convert.ToBoolean(typeof(Bmi2).GetMethod(issupported).Invoke(null, null)) != Bmi2.IsSupported ||
+ Convert.ToBoolean(typeof(Popcnt).GetMethod(issupported).Invoke(null, null)) != Popcnt.IsSupported ||
+ Convert.ToBoolean(typeof(Pclmulqdq).GetMethod(issupported).Invoke(null, null)) != Pclmulqdq.IsSupported
+ )
+ {
+ result = false;
+ }
return result ? 100 : 0;
}
--- /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>{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>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="IsSupported.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
\ No newline at end of file