From ac51d7802ca5a2ca9285a8db38ef61b75273414d Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 11 Mar 2020 14:48:46 -0700 Subject: [PATCH] Support table driven importation for scalar hardware intrinsics (#33350) * Deleted `mustExpand` parameter that we were passing to methods that never used it. * Below xarch instructions are now imported with table driven logic: * NI_BMI1_AndNot * NI_BMI1_X64_AndNot * NI_BMI2_ParallelBitDeposit * NI_BMI2_ParallelBitExtract * NI_BMI2_X64_ParallelBitDeposit * NI_BMI2_X64_ParallelBitExtract * NI_BMI1_ExtractLowestSetBit * NI_BMI1_GetMaskUpToLowestSetBit * NI_BMI1_ResetLowestSetBit * NI_BMI1_TrailingZeroCount * NI_BMI1_X64_ExtractLowestSetBit * NI_BMI1_X64_GetMaskUpToLowestSetBit * NI_BMI1_X64_ResetLowestSetBit * NI_BMI1_X64_TrailingZeroCount * NI_BMI2_MultiplyNoFlags * NI_BMI2_X64_MultiplyNoFlags * InstructionSet_LZCNT * InstructionSet_LZCNT_X64 * InstructionSet_POPCNT * InstructionSet_POPCNT_X64 * NI_SSE42_Crc32 * NI_SSE42_X64_Crc32 * Below ARM instructions are now imported with table driven logic: * NI_ArmBase_LeadingZeroCount * NI_ArmBase_ReverseElementBits * NI_ArmBase_Arm64_LeadingSignCount * NI_ArmBase_Arm64_LeadingZeroCount * NI_ArmBase_Arm64_ReverseElementBits * NI_Sha1_FixedRotate * NI_Crc32_ComputeCrc32 * NI_Crc32_ComputeCrc32C * NI_Crc32_Arm64_ComputeCrc32 * NI_Crc32_Arm64_ComputeCrc32C * Updated the impIsTableDrivenHWIntrinsic() method to not check for `HW_Category_Scalar` anymore because almost all scalar intrinsic will be handled by table-driven. For scalar intrinsic which needs special handling I have tagged them with `HW_Flag_SpecialImport` to make sure they don't get imported using table-driven logic. * In `hwintrinsiccodegenarm64.cpp`, I have removed a condition of `HW_Category_Special` because no instruction of arm64 were tagged with this category. * I have created `getBaseTypeFromArgIfNeeded()` method that contains logic to extract `baesType` from args if the argument was flagged as one of `BaseTypeFromFirstArg` or `BaseTypeFromSecondArg`. This method is reused inside special handling of intrinsic for arm. --- src/coreclr/src/jit/compiler.h | 55 ++----- src/coreclr/src/jit/hwintrinsic.cpp | 143 +++++++++++------ src/coreclr/src/jit/hwintrinsicarm64.cpp | 71 +-------- src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp | 2 +- src/coreclr/src/jit/hwintrinsiclistarm64.h | 8 +- src/coreclr/src/jit/hwintrinsiclistxarch.h | 10 +- src/coreclr/src/jit/hwintrinsicxarch.cpp | 197 ++---------------------- 7 files changed, 138 insertions(+), 348 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 30f59fe..8b88349 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -2607,6 +2607,10 @@ public: var_types type, GenTree* op1, GenTree* op2, GenTree* op3, NamedIntrinsic hwIntrinsicID); GenTree* gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd); CORINFO_CLASS_HANDLE gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType); + var_types getBaseTypeFromArgIfNeeded(NamedIntrinsic intrinsic, + CORINFO_CLASS_HANDLE clsHnd, + CORINFO_SIG_INFO* sig, + var_types baseType); #endif // FEATURE_HW_INTRINSICS GenTreeLclFld* gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset); @@ -3668,8 +3672,7 @@ protected: GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); + CORINFO_SIG_INFO* sig); GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass); GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType); @@ -3679,48 +3682,12 @@ protected: GenTree* impBaseIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impSSEIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impSSE2Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impSSE42Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impAESIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impFMAIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impLZCNTIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); - GenTree* impPOPCNTIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); + 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* impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + #endif // TARGET_XARCH #endif // FEATURE_HW_INTRINSICS GenTree* impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd, diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 0ab533d..0aef729 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -42,6 +42,57 @@ const HWIntrinsicInfo& HWIntrinsicInfo::lookup(NamedIntrinsic id) } //------------------------------------------------------------------------ +// getBaseTypeFromArgIfNeeded: Get baseType of intrinsic from 1st or 2nd argument depending on the flag +// +// Arguments: +// intrinsic -- id of the intrinsic function. +// clsHnd -- class handle containing the intrinsic function. +// method -- method handle of the intrinsic function. +// sig -- signature of the intrinsic call. +// baseType -- Predetermined baseType, could be TYP_UNKNOWN +// +// Return Value: +// The basetype of intrinsic of it can be fetched from 1st or 2nd argument, else return baseType unmodified. +// +var_types Compiler::getBaseTypeFromArgIfNeeded(NamedIntrinsic intrinsic, + CORINFO_CLASS_HANDLE clsHnd, + CORINFO_SIG_INFO* sig, + var_types baseType) +{ + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); + + if (category == HW_Category_MemoryStore || HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic) || + HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic)) + { + CORINFO_ARG_LIST_HANDLE arg = sig->args; + + if ((category == HW_Category_MemoryStore) || HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic)) + { + arg = info.compCompHnd->getArgNext(arg); + } + + CORINFO_CLASS_HANDLE argClass = info.compCompHnd->getArgClass(sig, arg); + baseType = getBaseTypeAndSizeOfSIMDType(argClass); + + if (baseType == TYP_UNKNOWN) // the argument is not a vector + { + CORINFO_CLASS_HANDLE tmpClass; + CorInfoType corInfoType = strip(info.compCompHnd->getArgType(sig, arg, &tmpClass)); + + if (corInfoType == CORINFO_TYPE_PTR) + { + corInfoType = info.compCompHnd->getChildType(argClass, &tmpClass); + } + + baseType = JITtype2varType(corInfoType); + } + assert(baseType != TYP_UNKNOWN); + } + + return baseType; +} + +//------------------------------------------------------------------------ // impUnsupportedHWIntrinsic: returns a node for an unsupported HWIntrinsic // // Arguments: @@ -548,6 +599,7 @@ bool Compiler::compSupportsHWIntrinsic(InstructionSet isa) // impIsTableDrivenHWIntrinsic: // // Arguments: +// intrinsicId - HW intrinsic id // category - category of a HW intrinsic // // Return Value: @@ -555,18 +607,20 @@ bool Compiler::compSupportsHWIntrinsic(InstructionSet isa) // static bool impIsTableDrivenHWIntrinsic(NamedIntrinsic intrinsicId, HWIntrinsicCategory category) { - return (category != HW_Category_Special) && (category != HW_Category_Scalar) && - HWIntrinsicInfo::RequiresCodegen(intrinsicId) && !HWIntrinsicInfo::HasSpecialImport(intrinsicId); + return (category != HW_Category_Special) && HWIntrinsicInfo::RequiresCodegen(intrinsicId) && + !HWIntrinsicInfo::HasSpecialImport(intrinsicId); } //------------------------------------------------------------------------ // impHWIntrinsic: Import a hardware intrinsic as a GT_HWINTRINSIC node if possible // // Arguments: -// intrinsic -- id of the intrinsic function. -// method -- method handle of the intrinsic function. -// sig -- signature of the intrinsic call -// +// intrinsic -- id of the intrinsic function. +// clsHnd -- class handle containing the intrinsic function. +// method -- method handle of the intrinsic function. +// sig -- signature of the intrinsic call +// mustExpand -- true if the intrinsic must return a GenTree*; otherwise, false + // Return Value: // The GT_HWINTRINSIC node, or nullptr if not a supported intrinsic // @@ -634,56 +688,31 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, // table-driven importer of simple intrinsics if (impIsTableDrivenHWIntrinsic(intrinsic, category)) { - if ((category == HW_Category_MemoryStore) || HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic) || - HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic)) - { - CORINFO_ARG_LIST_HANDLE arg = sig->args; - - if ((category == HW_Category_MemoryStore) || HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic)) - { - arg = info.compCompHnd->getArgNext(arg); - } - - CORINFO_CLASS_HANDLE argClass = info.compCompHnd->getArgClass(sig, arg); - baseType = getBaseTypeAndSizeOfSIMDType(argClass); - - if (baseType == TYP_UNKNOWN) // the argument is not a vector - { - CORINFO_CLASS_HANDLE tmpClass; - CorInfoType corInfoType = strip(info.compCompHnd->getArgType(sig, arg, &tmpClass)); - - if (corInfoType == CORINFO_TYPE_PTR) - { - corInfoType = info.compCompHnd->getChildType(argClass, &tmpClass); - } - - baseType = JITtype2varType(corInfoType); - } - - assert(baseType != TYP_UNKNOWN); - } - + baseType = getBaseTypeFromArgIfNeeded(intrinsic, clsHnd, sig, baseType); unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); + bool isScalar = category == HW_Category_Scalar; CORINFO_ARG_LIST_HANDLE argList = sig->args; + var_types argType = TYP_UNKNOWN; CORINFO_CLASS_HANDLE argClass; - var_types argType = TYP_UNKNOWN; assert(numArgs >= 0); - if ((HWIntrinsicInfo::lookupIns(intrinsic, baseType) == INS_invalid) || - ((simdSize != 8) && (simdSize != 16) && (simdSize != 32))) + if (!isScalar && ((HWIntrinsicInfo::lookupIns(intrinsic, baseType) == INS_invalid) || + ((simdSize != 8) && (simdSize != 16) && (simdSize != 32)))) { assert(!"Unexpected HW Intrinsic"); return nullptr; } - GenTreeHWIntrinsic* retNode = nullptr; GenTree* op1 = nullptr; GenTree* op2 = nullptr; + GenTree* op3 = nullptr; + GenTreeHWIntrinsic* retNode = nullptr; switch (numArgs) { case 0: { + assert(!isScalar); retNode = gtNewSimdHWIntrinsicNode(retType, intrinsic, baseType, simdSize); break; } @@ -692,7 +721,8 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, { argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); op1 = getArgForHWIntrinsic(argType, argClass); - if ((category == HW_Category_MemoryLoad) && op1->OperIs(GT_CAST)) + + if (category == HW_Category_MemoryLoad && op1->OperIs(GT_CAST)) { // Although the API specifies a pointer, if what we have is a BYREF, that's what // we really want, so throw away the cast. @@ -701,22 +731,40 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, op1 = op1->gtGetOp1(); } } - retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize); + + retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, intrinsic) + : gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize); break; } case 2: { - argType = JITtype2varType( - strip(info.compCompHnd->getArgType(sig, info.compCompHnd->getArgNext(argList), &argClass))); - op2 = getArgForHWIntrinsic(argType, argClass); + CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList); + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); + op2 = getArgForHWIntrinsic(argType, argClass); op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand); argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); op1 = getArgForHWIntrinsic(argType, argClass); - retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, baseType, simdSize); + retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, op2, intrinsic) + : gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, baseType, simdSize); +#ifdef TARGET_XARCH + if (intrinsic == NI_SSE42_Crc32 || intrinsic == NI_SSE42_X64_Crc32) +#endif +#ifdef TARGET_ARM64 + if (intrinsic == NI_Crc32_ComputeCrc32 || intrinsic == NI_Crc32_ComputeCrc32C || + intrinsic == NI_Crc32_Arm64_ComputeCrc32 || intrinsic == NI_Crc32_Arm64_ComputeCrc32C) +#endif + { + // type of the second argument + CorInfoType corType = strip(info.compCompHnd->getArgType(sig, arg2, &argClass)); + + // TODO - currently we use the BaseType to bring the type of the second argument + // to the code generator. May encode the overload info in other way. + retNode->AsHWIntrinsic()->gtSIMDBaseType = JITtype2varType(corType); + } break; } @@ -738,7 +786,8 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); op1 = getArgForHWIntrinsic(argType, argClass); - retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, baseType, simdSize); + retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, op2, op3, intrinsic) + : gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, baseType, simdSize); #ifdef TARGET_XARCH if (intrinsic == NI_AVX2_GatherVector128 || intrinsic == NI_AVX2_GatherVector256) @@ -772,7 +821,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, return retNode; } - return impSpecialIntrinsic(intrinsic, clsHnd, method, sig, mustExpand); + return impSpecialIntrinsic(intrinsic, clsHnd, method, sig); } #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/src/jit/hwintrinsicarm64.cpp b/src/coreclr/src/jit/hwintrinsicarm64.cpp index d23a5c1..1f7dde9 100644 --- a/src/coreclr/src/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsicarm64.cpp @@ -228,9 +228,9 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT // // Arguments: // intrinsic -- id of the intrinsic function. +// clsHnd -- class handle containing the intrinsic function. // method -- method handle of the intrinsic function. // sig -- signature of the intrinsic call -// mustExpand -- true if the compiler is compiling the fallback(GT_CALL) of this intrinsics // // Return Value: // The GT_HWINTRINSIC node, or nullptr if not a supported intrinsic @@ -238,8 +238,7 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) + CORINFO_SIG_INFO* sig) { HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); int numArgs = sig->numArgs; @@ -260,32 +259,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } } - if (HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic) || HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic)) - { - CORINFO_ARG_LIST_HANDLE arg = sig->args; - - if (HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic)) - { - arg = info.compCompHnd->getArgNext(arg); - } - - CORINFO_CLASS_HANDLE argClass = info.compCompHnd->getArgClass(sig, arg); - baseType = getBaseTypeAndSizeOfSIMDType(argClass); - - if (baseType == TYP_UNKNOWN) // the argument is not a vector - { - CORINFO_CLASS_HANDLE tmpClass; - CorInfoType corInfoType = strip(info.compCompHnd->getArgType(sig, arg, &tmpClass)); + baseType = getBaseTypeFromArgIfNeeded(intrinsic, clsHnd, sig, baseType); - if (corInfoType == CORINFO_TYPE_PTR) - { - corInfoType = info.compCompHnd->getChildType(argClass, &tmpClass); - } - - baseType = JITtype2varType(corInfoType); - } - } - else if (baseType == TYP_UNKNOWN) + if (baseType == TYP_UNKNOWN) { if (category != HW_Category_Scalar) { @@ -304,11 +280,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, return nullptr; } - unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); - CORINFO_ARG_LIST_HANDLE argList = sig->args; - CORINFO_CLASS_HANDLE argClass; - var_types argType = TYP_UNKNOWN; - + unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); assert(numArgs >= 0); GenTree* retNode = nullptr; @@ -353,7 +325,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); break; } - case NI_Vector64_get_Count: case NI_Vector128_get_Count: { @@ -366,38 +337,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_ArmBase_LeadingZeroCount: - case NI_ArmBase_ReverseElementBits: - case NI_ArmBase_Arm64_LeadingSignCount: - case NI_ArmBase_Arm64_LeadingZeroCount: - case NI_ArmBase_Arm64_ReverseElementBits: - case NI_Sha1_FixedRotate: - { - assert(numArgs == 1); - argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); - op1 = getArgForHWIntrinsic(argType, argClass); - return gtNewScalarHWIntrinsicNode(baseType, op1, intrinsic); - } - - case NI_Crc32_ComputeCrc32: - case NI_Crc32_ComputeCrc32C: - case NI_Crc32_Arm64_ComputeCrc32: - case NI_Crc32_Arm64_ComputeCrc32C: - { - assert(numArgs == 2); - - argType = JITtype2varType( - strip(info.compCompHnd->getArgType(sig, info.compCompHnd->getArgNext(argList), &argClass))); - op2 = getArgForHWIntrinsic(argType, argClass); - - argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); - op1 = getArgForHWIntrinsic(argType, argClass); - - retNode = gtNewScalarHWIntrinsicNode(retType, op1, op2, intrinsic); - retNode->AsHWIntrinsic()->gtSIMDBaseType = baseType; - break; - } - default: { return nullptr; diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index 6908d97..178f760 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -35,7 +35,7 @@ struct HWIntrinsic final bool IsTableDriven() const { // TODO-Arm64-Cleanup - make more categories to the table-driven framework - bool isTableDrivenCategory = (category != HW_Category_Special) && (category != HW_Category_Helper); + bool isTableDrivenCategory = category != HW_Category_Helper; bool isTableDrivenFlag = !HWIntrinsicInfo::GeneratesMultipleIns(id) && !HWIntrinsicInfo::HasSpecialCodegen(id); return isTableDrivenCategory && isTableDrivenFlag; diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index 22d4c58..8be2793 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -200,16 +200,16 @@ HARDWARE_INTRINSIC(ArmBase_Arm64, ReverseElementBits, - // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // CRC32 Intrinsics -HARDWARE_INTRINSIC(Crc32, ComputeCrc32, -1, 0, 2, {INS_invalid, INS_crc32b, INS_invalid, INS_crc32h, INS_invalid, INS_crc32w, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(Crc32, ComputeCrc32C, -1, 0, 2, {INS_invalid, INS_crc32cb, INS_invalid, INS_crc32ch, INS_invalid, INS_crc32cw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32, ComputeCrc32, -1, 0, 2, {INS_invalid, INS_crc32b, INS_invalid, INS_crc32h, INS_invalid, INS_crc32w, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32, ComputeCrc32C, -1, 0, 2, {INS_invalid, INS_crc32cb, INS_invalid, INS_crc32ch, INS_invalid, INS_crc32cw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name ival SIMD size NumArg instructions Category Flags // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // CRC32 64-bit only Intrinsics -HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32x, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32C, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32cx, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32x, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32C, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32cx, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name ival SIMD size NumArg instructions Category Flags diff --git a/src/coreclr/src/jit/hwintrinsiclistxarch.h b/src/coreclr/src/jit/hwintrinsiclistxarch.h index 7bd8c15..9cb005b 100644 --- a/src/coreclr/src/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/src/jit/hwintrinsiclistxarch.h @@ -382,7 +382,7 @@ HARDWARE_INTRINSIC(SSE41_X64_Insert, "Insert", // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // SSE42 Intrinsics -HARDWARE_INTRINSIC(SSE42_Crc32, "Crc32", SSE42, -1, 0, 2, {INS_invalid, INS_crc32, INS_invalid, INS_crc32, INS_invalid, INS_crc32, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed) +HARDWARE_INTRINSIC(SSE42_Crc32, "Crc32", SSE42, -1, 0, 2, {INS_invalid, INS_crc32, INS_invalid, INS_crc32, INS_invalid, INS_crc32, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed) HARDWARE_INTRINSIC(SSE42_CompareGreaterThan, "CompareGreaterThan", SSE42, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** @@ -551,7 +551,7 @@ HARDWARE_INTRINSIC(BMI1_ExtractLowestSetBit, "ExtractLowe HARDWARE_INTRINSIC(BMI1_GetMaskUpToLowestSetBit, "GetMaskUpToLowestSetBit", BMI1, -1, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blsmsk, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(BMI1_ResetLowestSetBit, "ResetLowestSetBit", BMI1, -1, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blsr, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(BMI1_TrailingZeroCount, "TrailingZeroCount", BMI1, -1, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_tzcnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_MultiIns) -HARDWARE_INTRINSIC(BMI1_BitFieldExtract, "BitFieldExtract", BMI1, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bextr, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_MultiIns) +HARDWARE_INTRINSIC(BMI1_BitFieldExtract, "BitFieldExtract", BMI1, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bextr, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_MultiIns|HW_Flag_SpecialImport) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Intrinsic ID Function name ISA ival SIMD size NumArg instructions Category Flags @@ -563,7 +563,7 @@ HARDWARE_INTRINSIC(BMI1_X64_ExtractLowestSetBit, "ExtractLowe HARDWARE_INTRINSIC(BMI1_X64_GetMaskUpToLowestSetBit, "GetMaskUpToLowestSetBit", BMI1_X64, -1, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blsmsk, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(BMI1_X64_ResetLowestSetBit, "ResetLowestSetBit", BMI1_X64, -1, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blsr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(BMI1_X64_TrailingZeroCount, "TrailingZeroCount", BMI1_X64, -1, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_tzcnt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_MultiIns) -HARDWARE_INTRINSIC(BMI1_X64_BitFieldExtract, "BitFieldExtract", BMI1_X64, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bextr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_MultiIns) +HARDWARE_INTRINSIC(BMI1_X64_BitFieldExtract, "BitFieldExtract", BMI1_X64, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bextr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_MultiIns|HW_Flag_SpecialImport) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Intrinsic ID Function name ISA ival SIMD size NumArg instructions Category Flags @@ -572,7 +572,7 @@ HARDWARE_INTRINSIC(BMI1_X64_BitFieldExtract, "BitFieldExt // BMI2 Intrinsics HARDWARE_INTRINSIC(BMI2_ParallelBitDeposit, "ParallelBitDeposit", BMI2, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pdep, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(BMI2_ParallelBitExtract, "ParallelBitExtract", BMI2, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pext, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(BMI2_ZeroHighBits, "ZeroHighBits", BMI2, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bzhi, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(BMI2_ZeroHighBits, "ZeroHighBits", BMI2, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bzhi, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(BMI2_MultiplyNoFlags, "MultiplyNoFlags", BMI2, -1, 0, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mulx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoContainment|HW_Flag_MaybeMemoryStore|HW_Flag_MultiIns|HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** @@ -582,7 +582,7 @@ HARDWARE_INTRINSIC(BMI2_MultiplyNoFlags, "MultiplyNoF // BMI2 Intrinsics HARDWARE_INTRINSIC(BMI2_X64_ParallelBitDeposit, "ParallelBitDeposit", BMI2_X64, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pdep, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(BMI2_X64_ParallelBitExtract, "ParallelBitExtract", BMI2_X64, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pext, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(BMI2_X64_ZeroHighBits, "ZeroHighBits", BMI2_X64, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bzhi, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(BMI2_X64_ZeroHighBits, "ZeroHighBits", BMI2_X64, -1, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bzhi, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(BMI2_X64_MultiplyNoFlags, "MultiplyNoFlags", BMI2_X64, -1, 0, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mulx, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoContainment|HW_Flag_MaybeMemoryStore|HW_Flag_MultiIns|HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** diff --git a/src/coreclr/src/jit/hwintrinsicxarch.cpp b/src/coreclr/src/jit/hwintrinsicxarch.cpp index 4a12b5a..6aa59aa 100644 --- a/src/coreclr/src/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsicxarch.cpp @@ -366,9 +366,9 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT // // Arguments: // intrinsic -- id of the intrinsic function. +// clsHnd -- class handle containing the intrinsic function. // method -- method handle of the intrinsic function. // sig -- signature of the intrinsic call -// mustExpand -- true if the compiler is compiling the fallback(GT_CALL) of this intrinsics // // Return Value: // the expanded intrinsic. @@ -376,44 +376,27 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) + CORINFO_SIG_INFO* sig) { // other intrinsics need special importation switch (HWIntrinsicInfo::lookupIsa(intrinsic)) { case InstructionSet_Vector128: case InstructionSet_Vector256: - return impBaseIntrinsic(intrinsic, clsHnd, method, sig, mustExpand); + return impBaseIntrinsic(intrinsic, clsHnd, method, sig); case InstructionSet_SSE: - return impSSEIntrinsic(intrinsic, method, sig, mustExpand); + return impSSEIntrinsic(intrinsic, method, sig); case InstructionSet_SSE2: - return impSSE2Intrinsic(intrinsic, method, sig, mustExpand); - case InstructionSet_SSE42: - case InstructionSet_SSE42_X64: - return impSSE42Intrinsic(intrinsic, method, sig, mustExpand); + return impSSE2Intrinsic(intrinsic, method, sig); case InstructionSet_AVX: case InstructionSet_AVX2: - return impAvxOrAvx2Intrinsic(intrinsic, method, sig, mustExpand); + return impAvxOrAvx2Intrinsic(intrinsic, method, sig); - case InstructionSet_AES: - return impAESIntrinsic(intrinsic, method, sig, mustExpand); case InstructionSet_BMI1: case InstructionSet_BMI1_X64: case InstructionSet_BMI2: case InstructionSet_BMI2_X64: - return impBMI1OrBMI2Intrinsic(intrinsic, method, sig, mustExpand); - - case InstructionSet_FMA: - return impFMAIntrinsic(intrinsic, method, sig, mustExpand); - case InstructionSet_LZCNT: - case InstructionSet_LZCNT_X64: - return impLZCNTIntrinsic(intrinsic, method, sig, mustExpand); - case InstructionSet_PCLMULQDQ: - return impPCLMULQDQIntrinsic(intrinsic, method, sig, mustExpand); - case InstructionSet_POPCNT: - case InstructionSet_POPCNT_X64: - return impPOPCNTIntrinsic(intrinsic, method, sig, mustExpand); + return impBMI1OrBMI2Intrinsic(intrinsic, method, sig); default: return nullptr; } @@ -426,7 +409,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, // intrinsic -- id of the intrinsic function. // method -- method handle of the intrinsic function. // sig -- signature of the intrinsic call -// mustExpand -- true if the compiler is compiling the fallback(GT_CALL) of this intrinsics // // Return Value: // the expanded intrinsic. @@ -434,8 +416,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) + CORINFO_SIG_INFO* sig) { GenTree* retNode = nullptr; GenTree* op1 = nullptr; @@ -535,7 +516,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, if (getSIMDVectorRegisterByteLength() == YMM_REGSIZE_BYTES) { // Vector is TYP_SIMD32, so we should treat this as a call to Vector128.ToVector256 - return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig, mustExpand); + return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig); } assert(getSIMDVectorRegisterByteLength() == XMM_REGSIZE_BYTES); @@ -603,7 +584,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, case TYP_SIMD32: { // Vector is TYP_SIMD32, so we should treat this as a call to Vector256.GetLower - return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig, mustExpand); + return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig); } default: @@ -642,12 +623,12 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, if (intrinsic == NI_Vector256_AsVector) { - return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig, mustExpand); + return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig); } else { assert(intrinsic == NI_Vector256_AsVector256); - return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig, mustExpand); + return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig); } } @@ -1189,10 +1170,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, return retNode; } -GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) +GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { GenTree* retNode = nullptr; GenTree* op1 = nullptr; @@ -1232,10 +1210,7 @@ GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, return retNode; } -GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) +GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { GenTree* retNode = nullptr; GenTree* op1 = nullptr; @@ -1299,48 +1274,7 @@ GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, return retNode; } -GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - GenTree* retNode = nullptr; - GenTree* op1 = nullptr; - GenTree* op2 = nullptr; - var_types callType = JITtype2varType(sig->retType); - - CORINFO_ARG_LIST_HANDLE argList = sig->args; - CORINFO_CLASS_HANDLE argClass; - CorInfoType corType; - - switch (intrinsic) - { - case NI_SSE42_Crc32: - case NI_SSE42_X64_Crc32: - assert(sig->numArgs == 2); - op2 = impPopStack().val; - op1 = impPopStack().val; - argList = info.compCompHnd->getArgNext(argList); // the second argument - corType = strip(info.compCompHnd->getArgType(sig, argList, &argClass)); // type of the second argument - - retNode = gtNewScalarHWIntrinsicNode(callType, op1, op2, intrinsic); - - // TODO - currently we use the BaseType to bring the type of the second argument - // to the code generator. May encode the overload info in other way. - retNode->AsHWIntrinsic()->gtSIMDBaseType = JITtype2varType(corType); - break; - - default: - JITDUMP("Not implemented hardware intrinsic"); - break; - } - return retNode; -} - -GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) +GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { GenTree* retNode = nullptr; GenTree* op1 = nullptr; @@ -1411,38 +1345,12 @@ GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, return retNode; } -GenTree* Compiler::impAESIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - return nullptr; -} - -GenTree* Compiler::impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) +GenTree* Compiler::impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { var_types callType = JITtype2varType(sig->retType); switch (intrinsic) { - case NI_BMI1_AndNot: - case NI_BMI1_X64_AndNot: - case NI_BMI2_ParallelBitDeposit: - case NI_BMI2_ParallelBitExtract: - case NI_BMI2_X64_ParallelBitDeposit: - case NI_BMI2_X64_ParallelBitExtract: - { - assert(sig->numArgs == 2); - - GenTree* op2 = impPopStack().val; - GenTree* op1 = impPopStack().val; - - return gtNewScalarHWIntrinsicNode(callType, op1, op2, intrinsic); - } - case NI_BMI2_ZeroHighBits: case NI_BMI2_X64_ZeroHighBits: { @@ -1455,20 +1363,6 @@ GenTree* Compiler::impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, return gtNewScalarHWIntrinsicNode(callType, op2, op1, intrinsic); } - case NI_BMI1_ExtractLowestSetBit: - case NI_BMI1_GetMaskUpToLowestSetBit: - case NI_BMI1_ResetLowestSetBit: - case NI_BMI1_TrailingZeroCount: - case NI_BMI1_X64_ExtractLowestSetBit: - case NI_BMI1_X64_GetMaskUpToLowestSetBit: - case NI_BMI1_X64_ResetLowestSetBit: - case NI_BMI1_X64_TrailingZeroCount: - { - assert(sig->numArgs == 1); - GenTree* op1 = impPopStack().val; - return gtNewScalarHWIntrinsicNode(callType, op1, intrinsic); - } - case NI_BMI1_BitFieldExtract: case NI_BMI1_X64_BitFieldExtract: { @@ -1486,68 +1380,9 @@ GenTree* Compiler::impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, return gtNewScalarHWIntrinsicNode(callType, op2, op1, intrinsic); } - case NI_BMI2_MultiplyNoFlags: - case NI_BMI2_X64_MultiplyNoFlags: - { - assert(sig->numArgs == 2 || sig->numArgs == 3); - GenTree* op3 = nullptr; - if (sig->numArgs == 3) - { - op3 = impPopStack().val; - } - - GenTree* op2 = impPopStack().val; - GenTree* op1 = impPopStack().val; - - if (sig->numArgs == 3) - { - return gtNewScalarHWIntrinsicNode(callType, op1, op2, op3, intrinsic); - } - else - { - return gtNewScalarHWIntrinsicNode(callType, op1, op2, intrinsic); - } - } - default: return nullptr; } } -GenTree* Compiler::impFMAIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - return nullptr; -} - -GenTree* Compiler::impLZCNTIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - assert(sig->numArgs == 1); - var_types callType = JITtype2varType(sig->retType); - return gtNewScalarHWIntrinsicNode(callType, impPopStack().val, intrinsic); -} - -GenTree* Compiler::impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - return nullptr; -} - -GenTree* Compiler::impPOPCNTIntrinsic(NamedIntrinsic intrinsic, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - assert(sig->numArgs == 1); - var_types callType = JITtype2varType(sig->retType); - return gtNewScalarHWIntrinsicNode(callType, impPopStack().val, intrinsic); -} - #endif // FEATURE_HW_INTRINSICS -- 2.7.4