NamedIntrinsic result = NI_Illegal;
- if (strcmp(namespaceName, "System") == 0)
+ if (strncmp(namespaceName, "System", 6) == 0)
{
- if ((strcmp(className, "Enum") == 0) && (strcmp(methodName, "HasFlag") == 0))
- {
- result = NI_System_Enum_HasFlag;
- }
- else if (strcmp(className, "Activator") == 0)
+ namespaceName += 6;
+
+ if (namespaceName[0] == '\0')
{
- if (strcmp(methodName, "AllocatorOf") == 0)
+ if (strcmp(className, "Activator") == 0)
{
- result = NI_System_Activator_AllocatorOf;
+ if (strcmp(methodName, "AllocatorOf") == 0)
+ {
+ result = NI_System_Activator_AllocatorOf;
+ }
+ else if (strcmp(methodName, "DefaultConstructorOf") == 0)
+ {
+ result = NI_System_Activator_DefaultConstructorOf;
+ }
}
- else if (strcmp(methodName, "DefaultConstructorOf") == 0)
+ else if (strcmp(className, "Array") == 0)
{
- result = NI_System_Activator_DefaultConstructorOf;
+ if (strcmp(methodName, "Clone") == 0)
+ {
+ result = NI_System_Array_Clone;
+ }
+ else if (strcmp(methodName, "GetLength") == 0)
+ {
+ result = NI_System_Array_GetLength;
+ }
+ else if (strcmp(methodName, "GetLowerBound") == 0)
+ {
+ result = NI_System_Array_GetLowerBound;
+ }
+ else if (strcmp(methodName, "GetUpperBound") == 0)
+ {
+ result = NI_System_Array_GetUpperBound;
+ }
}
- }
- else if (strcmp(className, "BitConverter") == 0)
- {
- if (methodName[0] == 'D')
+ else if (strcmp(className, "BitConverter") == 0)
{
if (strcmp(methodName, "DoubleToInt64Bits") == 0)
{
{
result = NI_System_BitConverter_DoubleToInt64Bits;
}
- }
- else if (methodName[0] == 'I')
- {
- if (strcmp(methodName, "Int32BitsToSingle") == 0)
+ else if (strcmp(methodName, "Int32BitsToSingle") == 0)
{
result = NI_System_BitConverter_Int32BitsToSingle;
}
{
result = NI_System_BitConverter_Int64BitsToDouble;
}
- }
- else if (methodName[0] == 'S')
- {
- if (strcmp(methodName, "SingleToInt32Bits") == 0)
+ else if (strcmp(methodName, "SingleToInt32Bits") == 0)
{
result = NI_System_BitConverter_SingleToInt32Bits;
}
{
result = NI_System_BitConverter_SingleToInt32Bits;
}
- }
- else if (methodName[0] == 'U')
- {
- if (strcmp(methodName, "UInt32BitsToSingle") == 0)
+ else if (strcmp(methodName, "UInt32BitsToSingle") == 0)
{
result = NI_System_BitConverter_Int32BitsToSingle;
}
result = NI_System_BitConverter_Int64BitsToDouble;
}
}
- }
- else if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0)
- {
- if (strcmp(methodName, "Abs") == 0)
- {
- result = NI_System_Math_Abs;
- }
- else if (strcmp(methodName, "Acos") == 0)
- {
- result = NI_System_Math_Acos;
- }
- else if (strcmp(methodName, "Acosh") == 0)
- {
- result = NI_System_Math_Acosh;
- }
- else if (strcmp(methodName, "Asin") == 0)
- {
- result = NI_System_Math_Asin;
- }
- else if (strcmp(methodName, "Asinh") == 0)
- {
- result = NI_System_Math_Asinh;
- }
- else if (strcmp(methodName, "Atan") == 0)
- {
- result = NI_System_Math_Atan;
- }
- else if (strcmp(methodName, "Atanh") == 0)
- {
- result = NI_System_Math_Atanh;
- }
- else if (strcmp(methodName, "Atan2") == 0)
- {
- result = NI_System_Math_Atan2;
- }
- else if (strcmp(methodName, "Cbrt") == 0)
- {
- result = NI_System_Math_Cbrt;
- }
- else if (strcmp(methodName, "Ceiling") == 0)
- {
- result = NI_System_Math_Ceiling;
- }
- else if (strcmp(methodName, "Cos") == 0)
- {
- result = NI_System_Math_Cos;
- }
- else if (strcmp(methodName, "Cosh") == 0)
- {
- result = NI_System_Math_Cosh;
- }
- else if (strcmp(methodName, "Exp") == 0)
- {
- result = NI_System_Math_Exp;
- }
- else if (strcmp(methodName, "Floor") == 0)
- {
- result = NI_System_Math_Floor;
- }
- else if (strcmp(methodName, "FMod") == 0)
- {
- result = NI_System_Math_FMod;
- }
- else if (strcmp(methodName, "FusedMultiplyAdd") == 0)
- {
- result = NI_System_Math_FusedMultiplyAdd;
- }
- else if (strcmp(methodName, "ILogB") == 0)
- {
- result = NI_System_Math_ILogB;
- }
- else if (strcmp(methodName, "Log") == 0)
- {
- result = NI_System_Math_Log;
- }
- else if (strcmp(methodName, "Log2") == 0)
- {
- result = NI_System_Math_Log2;
- }
- else if (strcmp(methodName, "Log10") == 0)
- {
- result = NI_System_Math_Log10;
- }
- else if (strcmp(methodName, "Max") == 0)
- {
- result = NI_System_Math_Max;
- }
- else if (strcmp(methodName, "Min") == 0)
- {
- result = NI_System_Math_Min;
- }
- else if (strcmp(methodName, "Pow") == 0)
- {
- result = NI_System_Math_Pow;
- }
- else if (strcmp(methodName, "Round") == 0)
- {
- result = NI_System_Math_Round;
- }
- else if (strcmp(methodName, "Sin") == 0)
- {
- result = NI_System_Math_Sin;
- }
- else if (strcmp(methodName, "Sinh") == 0)
- {
- result = NI_System_Math_Sinh;
- }
- else if (strcmp(methodName, "Sqrt") == 0)
- {
- result = NI_System_Math_Sqrt;
- }
- else if (strcmp(methodName, "Tan") == 0)
+ else if (strcmp(className, "Enum") == 0)
{
- result = NI_System_Math_Tan;
+ if (strcmp(methodName, "HasFlag") == 0)
+ {
+ result = NI_System_Enum_HasFlag;
+ }
}
- else if (strcmp(methodName, "Tanh") == 0)
+ else if (strcmp(className, "EETypePtr") == 0)
{
- result = NI_System_Math_Tanh;
+ if (strcmp(methodName, "EETypePtrOf") == 0)
+ {
+ result = NI_System_EETypePtr_EETypePtrOf;
+ }
}
- else if (strcmp(methodName, "Truncate") == 0)
+ else if (strcmp(className, "GC") == 0)
{
- result = NI_System_Math_Truncate;
+ if (strcmp(methodName, "KeepAlive") == 0)
+ {
+ result = NI_System_GC_KeepAlive;
+ }
}
- }
- else if (strcmp(className, "GC") == 0)
- {
- if (strcmp(methodName, "KeepAlive") == 0)
+ else if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0)
{
- result = NI_System_GC_KeepAlive;
+ if (strcmp(methodName, "Abs") == 0)
+ {
+ result = NI_System_Math_Abs;
+ }
+ else if (strcmp(methodName, "Acos") == 0)
+ {
+ result = NI_System_Math_Acos;
+ }
+ else if (strcmp(methodName, "Acosh") == 0)
+ {
+ result = NI_System_Math_Acosh;
+ }
+ else if (strcmp(methodName, "Asin") == 0)
+ {
+ result = NI_System_Math_Asin;
+ }
+ else if (strcmp(methodName, "Asinh") == 0)
+ {
+ result = NI_System_Math_Asinh;
+ }
+ else if (strcmp(methodName, "Atan") == 0)
+ {
+ result = NI_System_Math_Atan;
+ }
+ else if (strcmp(methodName, "Atanh") == 0)
+ {
+ result = NI_System_Math_Atanh;
+ }
+ else if (strcmp(methodName, "Atan2") == 0)
+ {
+ result = NI_System_Math_Atan2;
+ }
+ else if (strcmp(methodName, "Cbrt") == 0)
+ {
+ result = NI_System_Math_Cbrt;
+ }
+ else if (strcmp(methodName, "Ceiling") == 0)
+ {
+ result = NI_System_Math_Ceiling;
+ }
+ else if (strcmp(methodName, "Cos") == 0)
+ {
+ result = NI_System_Math_Cos;
+ }
+ else if (strcmp(methodName, "Cosh") == 0)
+ {
+ result = NI_System_Math_Cosh;
+ }
+ else if (strcmp(methodName, "Exp") == 0)
+ {
+ result = NI_System_Math_Exp;
+ }
+ else if (strcmp(methodName, "Floor") == 0)
+ {
+ result = NI_System_Math_Floor;
+ }
+ else if (strcmp(methodName, "FMod") == 0)
+ {
+ result = NI_System_Math_FMod;
+ }
+ else if (strcmp(methodName, "FusedMultiplyAdd") == 0)
+ {
+ result = NI_System_Math_FusedMultiplyAdd;
+ }
+ else if (strcmp(methodName, "ILogB") == 0)
+ {
+ result = NI_System_Math_ILogB;
+ }
+ else if (strcmp(methodName, "Log") == 0)
+ {
+ result = NI_System_Math_Log;
+ }
+ else if (strcmp(methodName, "Log2") == 0)
+ {
+ result = NI_System_Math_Log2;
+ }
+ else if (strcmp(methodName, "Log10") == 0)
+ {
+ result = NI_System_Math_Log10;
+ }
+ else if (strcmp(methodName, "Max") == 0)
+ {
+ result = NI_System_Math_Max;
+ }
+ else if (strcmp(methodName, "Min") == 0)
+ {
+ result = NI_System_Math_Min;
+ }
+ else if (strcmp(methodName, "Pow") == 0)
+ {
+ result = NI_System_Math_Pow;
+ }
+ else if (strcmp(methodName, "Round") == 0)
+ {
+ result = NI_System_Math_Round;
+ }
+ else if (strcmp(methodName, "Sin") == 0)
+ {
+ result = NI_System_Math_Sin;
+ }
+ else if (strcmp(methodName, "Sinh") == 0)
+ {
+ result = NI_System_Math_Sinh;
+ }
+ else if (strcmp(methodName, "Sqrt") == 0)
+ {
+ result = NI_System_Math_Sqrt;
+ }
+ else if (strcmp(methodName, "Tan") == 0)
+ {
+ result = NI_System_Math_Tan;
+ }
+ else if (strcmp(methodName, "Tanh") == 0)
+ {
+ result = NI_System_Math_Tanh;
+ }
+ else if (strcmp(methodName, "Truncate") == 0)
+ {
+ result = NI_System_Math_Truncate;
+ }
}
- }
- else if (strcmp(className, "Array") == 0)
- {
- if (strcmp(methodName, "Clone") == 0)
+ else if (strcmp(className, "MemoryExtensions") == 0)
{
- result = NI_System_Array_Clone;
+ if (strcmp(methodName, "AsSpan") == 0)
+ {
+ result = NI_System_MemoryExtensions_AsSpan;
+ }
+ else if (strcmp(methodName, "Equals") == 0)
+ {
+ result = NI_System_MemoryExtensions_Equals;
+ }
+ else if (strcmp(methodName, "SequenceEqual") == 0)
+ {
+ result = NI_System_MemoryExtensions_SequenceEqual;
+ }
+ else if (strcmp(methodName, "StartsWith") == 0)
+ {
+ result = NI_System_MemoryExtensions_StartsWith;
+ }
}
- else if (strcmp(methodName, "GetLength") == 0)
+ else if (strcmp(className, "Object") == 0)
{
- result = NI_System_Array_GetLength;
+ if (strcmp(methodName, "GetType") == 0)
+ {
+ result = NI_System_Object_GetType;
+ }
+ else if (strcmp(methodName, "MemberwiseClone") == 0)
+ {
+ result = NI_System_Object_MemberwiseClone;
+ }
}
- else if (strcmp(methodName, "GetLowerBound") == 0)
+ else if (strcmp(className, "ReadOnlySpan`1") == 0)
{
- result = NI_System_Array_GetLowerBound;
+ if (strcmp(methodName, "get_Item") == 0)
+ {
+ result = NI_System_ReadOnlySpan_get_Item;
+ }
}
- else if (strcmp(methodName, "GetUpperBound") == 0)
+ else if (strcmp(className, "RuntimeType") == 0)
{
- result = NI_System_Array_GetUpperBound;
+ if (strcmp(methodName, "get_IsActualEnum") == 0)
+ {
+ result = NI_System_Type_get_IsEnum;
+ }
}
- }
- else if (strcmp(className, "Object") == 0)
- {
- if (strcmp(methodName, "MemberwiseClone") == 0)
+ else if (strcmp(className, "RuntimeTypeHandle") == 0)
{
- result = NI_System_Object_MemberwiseClone;
+ if (strcmp(methodName, "GetValueInternal") == 0)
+ {
+ result = NI_System_RuntimeTypeHandle_GetValueInternal;
+ }
}
- else if (strcmp(methodName, "GetType") == 0)
+ else if (strcmp(className, "Span`1") == 0)
{
- result = NI_System_Object_GetType;
+ if (strcmp(methodName, "get_Item") == 0)
+ {
+ result = NI_System_Span_get_Item;
+ }
}
- }
- else if (strcmp(className, "RuntimeTypeHandle") == 0)
- {
- if (strcmp(methodName, "GetValueInternal") == 0)
+ else if (strcmp(className, "String") == 0)
{
- result = NI_System_RuntimeTypeHandle_GetValueInternal;
+ if (strcmp(methodName, "Equals") == 0)
+ {
+ result = NI_System_String_Equals;
+ }
+ else if (strcmp(methodName, "get_Chars") == 0)
+ {
+ result = NI_System_String_get_Chars;
+ }
+ else if (strcmp(methodName, "get_Length") == 0)
+ {
+ result = NI_System_String_get_Length;
+ }
+ else if (strcmp(methodName, "op_Implicit") == 0)
+ {
+ result = NI_System_String_op_Implicit;
+ }
+ else if (strcmp(methodName, "StartsWith") == 0)
+ {
+ result = NI_System_String_StartsWith;
+ }
}
- }
- else if (strcmp(className, "RuntimeType") == 0)
- {
- if (strcmp(methodName, "get_IsActualEnum") == 0)
+ else if (strcmp(className, "Type") == 0)
{
- result = NI_System_Type_get_IsEnum;
+ if (strcmp(methodName, "get_IsEnum") == 0)
+ {
+ result = NI_System_Type_get_IsEnum;
+ }
+ else if (strcmp(methodName, "get_IsValueType") == 0)
+ {
+ result = NI_System_Type_get_IsValueType;
+ }
+ else if (strcmp(methodName, "get_IsByRefLike") == 0)
+ {
+ result = NI_System_Type_get_IsByRefLike;
+ }
+ else if (strcmp(methodName, "GetEnumUnderlyingType") == 0)
+ {
+ result = NI_System_Type_GetEnumUnderlyingType;
+ }
+ else if (strcmp(methodName, "GetTypeFromHandle") == 0)
+ {
+ result = NI_System_Type_GetTypeFromHandle;
+ }
+ else if (strcmp(methodName, "IsAssignableFrom") == 0)
+ {
+ result = NI_System_Type_IsAssignableFrom;
+ }
+ else if (strcmp(methodName, "IsAssignableTo") == 0)
+ {
+ result = NI_System_Type_IsAssignableTo;
+ }
+ else if (strcmp(methodName, "op_Equality") == 0)
+ {
+ result = NI_System_Type_op_Equality;
+ }
+ else if (strcmp(methodName, "op_Inequality") == 0)
+ {
+ result = NI_System_Type_op_Inequality;
+ }
}
}
- else if (strcmp(className, "Type") == 0)
+ else if (namespaceName[0] == '.')
{
- if (strcmp(methodName, "get_IsValueType") == 0)
- {
- result = NI_System_Type_get_IsValueType;
- }
- else if (strcmp(methodName, "get_IsByRefLike") == 0)
- {
- result = NI_System_Type_get_IsByRefLike;
- }
- else if (strcmp(methodName, "IsAssignableFrom") == 0)
- {
- result = NI_System_Type_IsAssignableFrom;
- }
- else if (strcmp(methodName, "IsAssignableTo") == 0)
- {
- result = NI_System_Type_IsAssignableTo;
- }
- else if (strcmp(methodName, "op_Equality") == 0)
- {
- result = NI_System_Type_op_Equality;
- }
- else if (strcmp(methodName, "op_Inequality") == 0)
+ namespaceName += 1;
+
+#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
+ if (strcmp(namespaceName, "Buffers.Binary") == 0)
{
- result = NI_System_Type_op_Inequality;
+ if (strcmp(className, "BinaryPrimitives") == 0)
+ {
+ if (strcmp(methodName, "ReverseEndianness") == 0)
+ {
+ result = NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness;
+ }
+ }
}
- else if (strcmp(methodName, "GetTypeFromHandle") == 0)
+ else
+#endif // defined(TARGET_XARCH) || defined(TARGET_ARM64)
+ if (strcmp(namespaceName, "Collections.Generic") == 0)
{
- result = NI_System_Type_GetTypeFromHandle;
+ if (strcmp(className, "Comparer`1") == 0)
+ {
+ if (strcmp(methodName, "get_Default") == 0)
+ {
+ result = NI_System_Collections_Generic_Comparer_get_Default;
+ }
+ }
+ else if (strcmp(className, "EqualityComparer`1") == 0)
+ {
+ if (strcmp(methodName, "get_Default") == 0)
+ {
+ result = NI_System_Collections_Generic_EqualityComparer_get_Default;
+ }
+ }
}
- else if (strcmp(methodName, "get_IsEnum") == 0)
+ else if (strcmp(namespaceName, "Numerics") == 0)
{
- result = NI_System_Type_get_IsEnum;
+ if (strcmp(className, "BitOperations") == 0)
+ {
+ if (strcmp(methodName, "PopCount") == 0)
+ {
+ result = NI_System_Numerics_BitOperations_PopCount;
+ }
+ }
+ else
+ {
+#ifdef FEATURE_HW_INTRINSICS
+ CORINFO_SIG_INFO sig;
+ info.compCompHnd->getMethodSig(method, &sig);
+
+ int sizeOfVectorT = getSIMDVectorRegisterByteLength();
+
+ result = SimdAsHWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName,
+ sizeOfVectorT);
+#endif // FEATURE_HW_INTRINSICS
+
+ if (result == NI_Illegal)
+ {
+ // This allows the relevant code paths to be dropped as dead code even
+ // on platforms where FEATURE_HW_INTRINSICS is not supported.
+
+ if (strcmp(methodName, "get_IsSupported") == 0)
+ {
+ assert(strcmp(className, "Vector`1") == 0);
+ result = NI_IsSupported_Type;
+ }
+ else if (strcmp(methodName, "get_IsHardwareAccelerated") == 0)
+ {
+ result = NI_IsSupported_False;
+ }
+ else if (strcmp(methodName, "get_Count") == 0)
+ {
+ assert(strcmp(className, "Vector`1") == 0);
+ result = NI_Vector_GetCount;
+ }
+ else if (gtIsRecursiveCall(method))
+ {
+ // For the framework itself, any recursive intrinsics will either be
+ // only supported on a single platform or will be guarded by a relevant
+ // IsSupported check so the throw PNSE will be valid or dropped.
+
+ result = NI_Throw_PlatformNotSupportedException;
+ }
+ }
+ }
}
- else if (strcmp(methodName, "GetEnumUnderlyingType") == 0)
+ else if (strncmp(namespaceName, "Runtime.", 8) == 0)
{
- result = NI_System_Type_GetEnumUnderlyingType;
- }
- }
- else if (strcmp(className, "String") == 0)
- {
- if (strcmp(methodName, "Equals") == 0)
- {
- result = NI_System_String_Equals;
- }
- else if (strcmp(methodName, "get_Chars") == 0)
- {
- result = NI_System_String_get_Chars;
- }
- else if (strcmp(methodName, "get_Length") == 0)
- {
- result = NI_System_String_get_Length;
- }
- else if (strcmp(methodName, "op_Implicit") == 0)
- {
- result = NI_System_String_op_Implicit;
- }
- else if (strcmp(methodName, "StartsWith") == 0)
- {
- result = NI_System_String_StartsWith;
- }
- }
- else if (strcmp(className, "MemoryExtensions") == 0)
- {
- if (strcmp(methodName, "AsSpan") == 0)
- {
- result = NI_System_MemoryExtensions_AsSpan;
- }
- if (strcmp(methodName, "SequenceEqual") == 0)
- {
- result = NI_System_MemoryExtensions_SequenceEqual;
- }
- else if (strcmp(methodName, "Equals") == 0)
- {
- result = NI_System_MemoryExtensions_Equals;
- }
- else if (strcmp(methodName, "StartsWith") == 0)
- {
- result = NI_System_MemoryExtensions_StartsWith;
- }
- }
- else if (strcmp(className, "Span`1") == 0)
- {
- if (strcmp(methodName, "get_Item") == 0)
- {
- result = NI_System_Span_get_Item;
- }
- }
- else if (strcmp(className, "ReadOnlySpan`1") == 0)
- {
- if (strcmp(methodName, "get_Item") == 0)
- {
- result = NI_System_ReadOnlySpan_get_Item;
- }
- }
- else if (strcmp(className, "EETypePtr") == 0)
- {
- if (strcmp(methodName, "EETypePtrOf") == 0)
- {
- result = NI_System_EETypePtr_EETypePtrOf;
- }
- }
- }
- else if (strcmp(namespaceName, "Internal.Runtime") == 0)
- {
- if (strcmp(className, "MethodTable") == 0)
- {
- if (strcmp(methodName, "Of") == 0)
- {
- result = NI_Internal_Runtime_MethodTable_Of;
- }
- }
- }
- else if (strcmp(namespaceName, "System.Threading") == 0)
- {
- if (strcmp(className, "Thread") == 0)
- {
- if (strcmp(methodName, "get_CurrentThread") == 0)
- {
- result = NI_System_Threading_Thread_get_CurrentThread;
- }
- else if (strcmp(methodName, "get_ManagedThreadId") == 0)
- {
- result = NI_System_Threading_Thread_get_ManagedThreadId;
- }
- }
- else if (strcmp(className, "Interlocked") == 0)
- {
-#ifndef TARGET_ARM64
- // TODO-CQ: Implement for XArch (https://github.com/dotnet/runtime/issues/32239).
- if (strcmp(methodName, "And") == 0)
- {
- result = NI_System_Threading_Interlocked_And;
- }
- else if (strcmp(methodName, "Or") == 0)
- {
- result = NI_System_Threading_Interlocked_Or;
- }
-#endif
- if (strcmp(methodName, "CompareExchange") == 0)
- {
- result = NI_System_Threading_Interlocked_CompareExchange;
- }
- else if (strcmp(methodName, "Exchange") == 0)
- {
- result = NI_System_Threading_Interlocked_Exchange;
- }
- else if (strcmp(methodName, "ExchangeAdd") == 0)
- {
- result = NI_System_Threading_Interlocked_ExchangeAdd;
- }
- else if (strcmp(methodName, "MemoryBarrier") == 0)
- {
- result = NI_System_Threading_Interlocked_MemoryBarrier;
- }
- else if (strcmp(methodName, "ReadMemoryBarrier") == 0)
- {
- result = NI_System_Threading_Interlocked_ReadMemoryBarrier;
- }
- }
- }
-#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
- else if (strcmp(namespaceName, "System.Buffers.Binary") == 0)
- {
- if ((strcmp(className, "BinaryPrimitives") == 0) && (strcmp(methodName, "ReverseEndianness") == 0))
- {
- result = NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness;
- }
- }
-#endif // defined(TARGET_XARCH) || defined(TARGET_ARM64)
- else if (strcmp(namespaceName, "System.Collections.Generic") == 0)
- {
- if ((strcmp(className, "EqualityComparer`1") == 0) && (strcmp(methodName, "get_Default") == 0))
- {
- result = NI_System_Collections_Generic_EqualityComparer_get_Default;
- }
- else if ((strcmp(className, "Comparer`1") == 0) && (strcmp(methodName, "get_Default") == 0))
- {
- result = NI_System_Collections_Generic_Comparer_get_Default;
- }
- }
- else if ((strcmp(namespaceName, "System.Numerics") == 0) && (strcmp(className, "BitOperations") == 0))
- {
- if (strcmp(methodName, "PopCount") == 0)
- {
- result = NI_System_Numerics_BitOperations_PopCount;
- }
- }
- else if (strcmp(namespaceName, "System.Numerics") == 0)
- {
-#ifdef FEATURE_HW_INTRINSICS
- CORINFO_SIG_INFO sig;
- info.compCompHnd->getMethodSig(method, &sig);
-
- int sizeOfVectorT = getSIMDVectorRegisterByteLength();
-
- result = SimdAsHWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName, sizeOfVectorT);
-#endif // FEATURE_HW_INTRINSICS
-
- if (result == NI_Illegal)
- {
- // This allows the relevant code paths to be dropped as dead code even
- // on platforms where FEATURE_HW_INTRINSICS is not supported.
-
- if (strcmp(methodName, "get_IsSupported") == 0)
- {
- assert(strcmp(className, "Vector`1") == 0);
- result = NI_IsSupported_Type;
- }
- else if (strcmp(methodName, "get_IsHardwareAccelerated") == 0)
- {
- result = NI_IsSupported_False;
- }
- else if (strcmp(methodName, "get_Count") == 0)
- {
- assert(strcmp(className, "Vector`1") == 0);
- result = NI_Vector_GetCount;
- }
- else if (gtIsRecursiveCall(method))
- {
- // For the framework itself, any recursive intrinsics will either be
- // only supported on a single platform or will be guarded by a relevant
- // IsSupported check so the throw PNSE will be valid or dropped.
-
- result = NI_Throw_PlatformNotSupportedException;
- }
- }
- }
- else if (strcmp(namespaceName, "System.Runtime.CompilerServices") == 0)
- {
- if (strcmp(className, "Unsafe") == 0)
- {
- if (strcmp(methodName, "Add") == 0)
- {
- result = NI_SRCS_UNSAFE_Add;
- }
- else if (strcmp(methodName, "AddByteOffset") == 0)
- {
- result = NI_SRCS_UNSAFE_AddByteOffset;
- }
- else if (strcmp(methodName, "AreSame") == 0)
- {
- result = NI_SRCS_UNSAFE_AreSame;
- }
- else if (strcmp(methodName, "As") == 0)
- {
- result = NI_SRCS_UNSAFE_As;
- }
- else if (strcmp(methodName, "AsPointer") == 0)
- {
- result = NI_SRCS_UNSAFE_AsPointer;
- }
- else if (strcmp(methodName, "AsRef") == 0)
- {
- result = NI_SRCS_UNSAFE_AsRef;
- }
- else if (strcmp(methodName, "ByteOffset") == 0)
- {
- result = NI_SRCS_UNSAFE_ByteOffset;
- }
- else if (strcmp(methodName, "Copy") == 0)
- {
- result = NI_SRCS_UNSAFE_Copy;
- }
- else if (strcmp(methodName, "CopyBlock") == 0)
- {
- result = NI_SRCS_UNSAFE_CopyBlock;
- }
- else if (strcmp(methodName, "CopyBlockUnaligned") == 0)
- {
- result = NI_SRCS_UNSAFE_CopyBlockUnaligned;
- }
- else if (strcmp(methodName, "InitBlock") == 0)
- {
- result = NI_SRCS_UNSAFE_InitBlock;
- }
- else if (strcmp(methodName, "InitBlockUnaligned") == 0)
- {
- result = NI_SRCS_UNSAFE_InitBlockUnaligned;
- }
- else if (strcmp(methodName, "IsAddressGreaterThan") == 0)
- {
- result = NI_SRCS_UNSAFE_IsAddressGreaterThan;
- }
- else if (strcmp(methodName, "IsAddressLessThan") == 0)
- {
- result = NI_SRCS_UNSAFE_IsAddressLessThan;
- }
- else if (strcmp(methodName, "IsNullRef") == 0)
- {
- result = NI_SRCS_UNSAFE_IsNullRef;
- }
- else if (strcmp(methodName, "NullRef") == 0)
- {
- result = NI_SRCS_UNSAFE_NullRef;
- }
- else if (strcmp(methodName, "Read") == 0)
- {
- result = NI_SRCS_UNSAFE_Read;
- }
- else if (strcmp(methodName, "ReadUnaligned") == 0)
- {
- result = NI_SRCS_UNSAFE_ReadUnaligned;
- }
- else if (strcmp(methodName, "SizeOf") == 0)
- {
- result = NI_SRCS_UNSAFE_SizeOf;
- }
- else if (strcmp(methodName, "SkipInit") == 0)
- {
- result = NI_SRCS_UNSAFE_SkipInit;
- }
- else if (strcmp(methodName, "Subtract") == 0)
- {
- result = NI_SRCS_UNSAFE_Subtract;
- }
- else if (strcmp(methodName, "SubtractByteOffset") == 0)
- {
- result = NI_SRCS_UNSAFE_SubtractByteOffset;
- }
- else if (strcmp(methodName, "Unbox") == 0)
- {
- result = NI_SRCS_UNSAFE_Unbox;
- }
- else if (strcmp(methodName, "Write") == 0)
- {
- result = NI_SRCS_UNSAFE_Write;
- }
- else if (strcmp(methodName, "WriteUnaligned") == 0)
- {
- result = NI_SRCS_UNSAFE_WriteUnaligned;
- }
- }
- else if (strcmp(className, "RuntimeHelpers") == 0)
- {
- if (strcmp(methodName, "CreateSpan") == 0)
- {
- result = NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan;
- }
- else if (strcmp(methodName, "InitializeArray") == 0)
- {
- result = NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray;
- }
- else if (strcmp(methodName, "IsKnownConstant") == 0)
- {
- result = NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant;
- }
- }
- }
- else if (strcmp(namespaceName, "System.Runtime.InteropServices") == 0)
- {
- if (strcmp(className, "MemoryMarshal") == 0)
- {
- if (strcmp(methodName, "GetArrayDataReference") == 0)
- {
- result = NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference;
- }
- }
- }
- else if (strncmp(namespaceName, "System.Runtime.Intrinsics", 25) == 0)
- {
- // We go down this path even when FEATURE_HW_INTRINSICS isn't enabled
- // so we can specially handle IsSupported and recursive calls.
-
- // This is required to appropriately handle the intrinsics on platforms
- // which don't support them. On such a platform methods like Vector64.Create
- // will be seen as `Intrinsic` and `mustExpand` due to having a code path
- // which is recursive. When such a path is hit we expect it to be handled by
- // the importer and we fire an assert if it wasn't and in previous versions
- // of the JIT would fail fast. This was changed to throw a PNSE instead but
- // we still assert as most intrinsics should have been recognized/handled.
+ namespaceName += 8;
- // In order to avoid the assert, we specially handle the IsSupported checks
- // (to better allow dead-code optimizations) and we explicitly throw a PNSE
- // as we know that is the desired behavior for the HWIntrinsics when not
- // supported. For cases like Vector64.Create, this is fine because it will
- // be behind a relevant IsSupported check and will never be hit and the
- // software fallback will be executed instead.
-
- CLANG_FORMAT_COMMENT_ANCHOR;
+ if (strcmp(namespaceName, "CompilerServices") == 0)
+ {
+ if (strcmp(className, "RuntimeHelpers") == 0)
+ {
+ if (strcmp(methodName, "CreateSpan") == 0)
+ {
+ result = NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan;
+ }
+ else if (strcmp(methodName, "InitializeArray") == 0)
+ {
+ result = NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray;
+ }
+ else if (strcmp(methodName, "IsKnownConstant") == 0)
+ {
+ result = NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant;
+ }
+ }
+ else if (strcmp(className, "Unsafe") == 0)
+ {
+ if (strcmp(methodName, "Add") == 0)
+ {
+ result = NI_SRCS_UNSAFE_Add;
+ }
+ else if (strcmp(methodName, "AddByteOffset") == 0)
+ {
+ result = NI_SRCS_UNSAFE_AddByteOffset;
+ }
+ else if (strcmp(methodName, "AreSame") == 0)
+ {
+ result = NI_SRCS_UNSAFE_AreSame;
+ }
+ else if (strcmp(methodName, "As") == 0)
+ {
+ result = NI_SRCS_UNSAFE_As;
+ }
+ else if (strcmp(methodName, "AsPointer") == 0)
+ {
+ result = NI_SRCS_UNSAFE_AsPointer;
+ }
+ else if (strcmp(methodName, "AsRef") == 0)
+ {
+ result = NI_SRCS_UNSAFE_AsRef;
+ }
+ else if (strcmp(methodName, "ByteOffset") == 0)
+ {
+ result = NI_SRCS_UNSAFE_ByteOffset;
+ }
+ else if (strcmp(methodName, "Copy") == 0)
+ {
+ result = NI_SRCS_UNSAFE_Copy;
+ }
+ else if (strcmp(methodName, "CopyBlock") == 0)
+ {
+ result = NI_SRCS_UNSAFE_CopyBlock;
+ }
+ else if (strcmp(methodName, "CopyBlockUnaligned") == 0)
+ {
+ result = NI_SRCS_UNSAFE_CopyBlockUnaligned;
+ }
+ else if (strcmp(methodName, "InitBlock") == 0)
+ {
+ result = NI_SRCS_UNSAFE_InitBlock;
+ }
+ else if (strcmp(methodName, "InitBlockUnaligned") == 0)
+ {
+ result = NI_SRCS_UNSAFE_InitBlockUnaligned;
+ }
+ else if (strcmp(methodName, "IsAddressGreaterThan") == 0)
+ {
+ result = NI_SRCS_UNSAFE_IsAddressGreaterThan;
+ }
+ else if (strcmp(methodName, "IsAddressLessThan") == 0)
+ {
+ result = NI_SRCS_UNSAFE_IsAddressLessThan;
+ }
+ else if (strcmp(methodName, "IsNullRef") == 0)
+ {
+ result = NI_SRCS_UNSAFE_IsNullRef;
+ }
+ else if (strcmp(methodName, "NullRef") == 0)
+ {
+ result = NI_SRCS_UNSAFE_NullRef;
+ }
+ else if (strcmp(methodName, "Read") == 0)
+ {
+ result = NI_SRCS_UNSAFE_Read;
+ }
+ else if (strcmp(methodName, "ReadUnaligned") == 0)
+ {
+ result = NI_SRCS_UNSAFE_ReadUnaligned;
+ }
+ else if (strcmp(methodName, "SizeOf") == 0)
+ {
+ result = NI_SRCS_UNSAFE_SizeOf;
+ }
+ else if (strcmp(methodName, "SkipInit") == 0)
+ {
+ result = NI_SRCS_UNSAFE_SkipInit;
+ }
+ else if (strcmp(methodName, "Subtract") == 0)
+ {
+ result = NI_SRCS_UNSAFE_Subtract;
+ }
+ else if (strcmp(methodName, "SubtractByteOffset") == 0)
+ {
+ result = NI_SRCS_UNSAFE_SubtractByteOffset;
+ }
+ else if (strcmp(methodName, "Unbox") == 0)
+ {
+ result = NI_SRCS_UNSAFE_Unbox;
+ }
+ else if (strcmp(methodName, "Write") == 0)
+ {
+ result = NI_SRCS_UNSAFE_Write;
+ }
+ else if (strcmp(methodName, "WriteUnaligned") == 0)
+ {
+ result = NI_SRCS_UNSAFE_WriteUnaligned;
+ }
+ }
+ }
+ else if (strcmp(namespaceName, "InteropServices") == 0)
+ {
+ if (strcmp(className, "MemoryMarshal") == 0)
+ {
+ if (strcmp(methodName, "GetArrayDataReference") == 0)
+ {
+ result = NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference;
+ }
+ }
+ }
+ else if (strncmp(namespaceName, "Intrinsics", 10) == 0)
+ {
+ // We go down this path even when FEATURE_HW_INTRINSICS isn't enabled
+ // so we can specially handle IsSupported and recursive calls.
+
+ // This is required to appropriately handle the intrinsics on platforms
+ // which don't support them. On such a platform methods like Vector64.Create
+ // will be seen as `Intrinsic` and `mustExpand` due to having a code path
+ // which is recursive. When such a path is hit we expect it to be handled by
+ // the importer and we fire an assert if it wasn't and in previous versions
+ // of the JIT would fail fast. This was changed to throw a PNSE instead but
+ // we still assert as most intrinsics should have been recognized/handled.
+
+ // In order to avoid the assert, we specially handle the IsSupported checks
+ // (to better allow dead-code optimizations) and we explicitly throw a PNSE
+ // as we know that is the desired behavior for the HWIntrinsics when not
+ // supported. For cases like Vector64.Create, this is fine because it will
+ // be behind a relevant IsSupported check and will never be hit and the
+ // software fallback will be executed instead.
+
+ CLANG_FORMAT_COMMENT_ANCHOR;
#ifdef FEATURE_HW_INTRINSICS
- namespaceName += 25;
- const char* platformNamespaceName;
+ namespaceName += 10;
+ const char* platformNamespaceName;
#if defined(TARGET_XARCH)
- platformNamespaceName = ".X86";
+ platformNamespaceName = ".X86";
#elif defined(TARGET_ARM64)
- platformNamespaceName = ".Arm";
+ platformNamespaceName = ".Arm";
#else
#error Unsupported platform
#endif
- if ((namespaceName[0] == '\0') || (strcmp(namespaceName, platformNamespaceName) == 0))
- {
- CORINFO_SIG_INFO sig;
- info.compCompHnd->getMethodSig(method, &sig);
+ if ((namespaceName[0] == '\0') || (strcmp(namespaceName, platformNamespaceName) == 0))
+ {
+ CORINFO_SIG_INFO sig;
+ info.compCompHnd->getMethodSig(method, &sig);
- result = HWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName);
- }
+ result = HWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName);
+ }
#endif // FEATURE_HW_INTRINSICS
- if (result == NI_Illegal)
- {
- // This allows the relevant code paths to be dropped as dead code even
- // on platforms where FEATURE_HW_INTRINSICS is not supported.
+ if (result == NI_Illegal)
+ {
+ // This allows the relevant code paths to be dropped as dead code even
+ // on platforms where FEATURE_HW_INTRINSICS is not supported.
- if (strcmp(methodName, "get_IsSupported") == 0)
- {
- if (strncmp(className, "Vector", 6) == 0)
- {
- assert((strcmp(className, "Vector64`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
- (strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector512`1") == 0));
+ if (strcmp(methodName, "get_IsSupported") == 0)
+ {
+ if (strncmp(className, "Vector", 6) == 0)
+ {
+ assert(
+ (strcmp(className, "Vector64`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
+ (strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector512`1") == 0));
- result = NI_IsSupported_Type;
- }
- else
- {
- result = NI_IsSupported_False;
+ result = NI_IsSupported_Type;
+ }
+ else
+ {
+ result = NI_IsSupported_False;
+ }
+ }
+ else if (strcmp(methodName, "get_IsHardwareAccelerated") == 0)
+ {
+ result = NI_IsSupported_False;
+ }
+ else if (strcmp(methodName, "get_Count") == 0)
+ {
+ assert((strcmp(className, "Vector64`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
+ (strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector512`1") == 0));
+
+ result = NI_Vector_GetCount;
+ }
+ else if (gtIsRecursiveCall(method))
+ {
+ // For the framework itself, any recursive intrinsics will either be
+ // only supported on a single platform or will be guarded by a relevant
+ // IsSupported check so the throw PNSE will be valid or dropped.
+
+ result = NI_Throw_PlatformNotSupportedException;
+ }
+ }
}
}
- else if (strcmp(methodName, "get_IsHardwareAccelerated") == 0)
- {
- result = NI_IsSupported_False;
- }
- else if (strcmp(methodName, "get_Count") == 0)
+ else if (strcmp(namespaceName, "StubHelpers") == 0)
{
- assert((strcmp(className, "Vector64`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
- (strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector512`1") == 0));
-
- result = NI_Vector_GetCount;
+ if (strcmp(className, "StubHelpers") == 0)
+ {
+ if (strcmp(methodName, "GetStubContext") == 0)
+ {
+ result = NI_System_StubHelpers_GetStubContext;
+ }
+ else if (strcmp(methodName, "NextCallReturnAddress") == 0)
+ {
+ result = NI_System_StubHelpers_NextCallReturnAddress;
+ }
+ }
}
- else if (gtIsRecursiveCall(method))
+ else if (strcmp(namespaceName, "Threading") == 0)
{
- // For the framework itself, any recursive intrinsics will either be
- // only supported on a single platform or will be guarded by a relevant
- // IsSupported check so the throw PNSE will be valid or dropped.
-
- result = NI_Throw_PlatformNotSupportedException;
+ if (strcmp(className, "Interlocked") == 0)
+ {
+#ifndef TARGET_ARM64
+ // TODO-CQ: Implement for XArch (https://github.com/dotnet/runtime/issues/32239).
+ if (strcmp(methodName, "And") == 0)
+ {
+ result = NI_System_Threading_Interlocked_And;
+ }
+ else if (strcmp(methodName, "Or") == 0)
+ {
+ result = NI_System_Threading_Interlocked_Or;
+ }
+ else
+#endif
+ if (strcmp(methodName, "CompareExchange") == 0)
+ {
+ result = NI_System_Threading_Interlocked_CompareExchange;
+ }
+ else if (strcmp(methodName, "Exchange") == 0)
+ {
+ result = NI_System_Threading_Interlocked_Exchange;
+ }
+ else if (strcmp(methodName, "ExchangeAdd") == 0)
+ {
+ result = NI_System_Threading_Interlocked_ExchangeAdd;
+ }
+ else if (strcmp(methodName, "MemoryBarrier") == 0)
+ {
+ result = NI_System_Threading_Interlocked_MemoryBarrier;
+ }
+ else if (strcmp(methodName, "ReadMemoryBarrier") == 0)
+ {
+ result = NI_System_Threading_Interlocked_ReadMemoryBarrier;
+ }
+ }
+ else if (strcmp(className, "Thread") == 0)
+ {
+ if (strcmp(methodName, "get_CurrentThread") == 0)
+ {
+ result = NI_System_Threading_Thread_get_CurrentThread;
+ }
+ else if (strcmp(methodName, "get_ManagedThreadId") == 0)
+ {
+ result = NI_System_Threading_Thread_get_ManagedThreadId;
+ }
+ }
}
}
}
- else if (strcmp(namespaceName, "System.StubHelpers") == 0)
+ else if (strcmp(namespaceName, "Internal.Runtime") == 0)
{
- if (strcmp(className, "StubHelpers") == 0)
+ if (strcmp(className, "MethodTable") == 0)
{
- if (strcmp(methodName, "GetStubContext") == 0)
- {
- result = NI_System_StubHelpers_GetStubContext;
- }
- else if (strcmp(methodName, "NextCallReturnAddress") == 0)
+ if (strcmp(methodName, "Of") == 0)
{
- result = NI_System_StubHelpers_NextCallReturnAddress;
+ result = NI_Internal_Runtime_MethodTable_Of;
}
}
}