From bb83f1b2aed79b7bb21d5b494ce1d5018ba79dd8 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 20 Mar 2020 19:43:26 -0700 Subject: [PATCH] Revert "Unify instruction set definition (#33730)" (#33901) This reverts commit f80a5147ef7662c3238275568c9dad7655a9684f. --- .../superpmi-shared/methodcontext.cpp | 2 +- src/coreclr/src/inc/corinfo.h | 10 +- src/coreclr/src/inc/corinfoinstructionset.h | 276 -------- src/coreclr/src/inc/corjitflags.h | 98 ++- .../src/inc/readytoruninstructionset.h | 38 -- src/coreclr/src/jit/compiler.cpp | 286 +++++--- src/coreclr/src/jit/compiler.h | 12 +- src/coreclr/src/jit/ee_il_dll.cpp | 2 +- src/coreclr/src/jit/hwintrinsic.cpp | 14 +- src/coreclr/src/jit/hwintrinsic.h | 26 +- src/coreclr/src/jit/hwintrinsicarm64.cpp | 10 +- .../src/jit/hwintrinsiccodegenxarch.cpp | 10 +- src/coreclr/src/jit/hwintrinsicxarch.cpp | 10 +- src/coreclr/src/jit/instr.h | 65 ++ src/coreclr/src/jit/jitee.h | 140 +++- src/coreclr/src/jit/lsraarm64.cpp | 10 +- src/coreclr/src/jit/lsraxarch.cpp | 10 +- src/coreclr/src/jit/simdcodegenxarch.cpp | 5 + src/coreclr/src/pal/src/misc/jitsupport.cpp | 79 ++- .../Runtime/ReadyToRunInstructionSet.cs | 134 ---- .../tools/Common/JitInterface/CorInfoImpl.cs | 57 +- .../JitInterface/CorInfoInstructionSet.cs | 317 --------- .../tools/Common/JitInterface/CorInfoTypes.cs | 62 +- .../ThunkGenerator/InstructionSetDesc.txt | 81 --- .../ThunkGenerator/InstructionSetGenerator.cs | 645 ------------------ .../JitInterface/ThunkGenerator/Program.cs | 47 +- .../JitInterface/ThunkGenerator/gen.bat | 6 +- .../Common/JitInterface/ThunkGenerator/gen.sh | 3 +- .../ILCompiler.ReadyToRun.csproj | 3 - .../crossgen2/jitinterface/jitwrapper.cpp | 10 +- src/coreclr/src/vm/codeman.cpp | 51 +- src/coreclr/src/zap/zapper.cpp | 30 +- 32 files changed, 661 insertions(+), 1888 deletions(-) delete mode 100644 src/coreclr/src/inc/corinfoinstructionset.h delete mode 100644 src/coreclr/src/inc/readytoruninstructionset.h delete mode 100644 src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs delete mode 100644 src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs delete mode 100644 src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt delete mode 100644 src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 21c104b63db22..c4a9f4745cd13 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -1125,7 +1125,7 @@ void MethodContext::recGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes, DW void MethodContext::dmpGetJitFlags(DWORD key, DD value) { CORJIT_FLAGS* jitflags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A); - printf("GetJitFlags key %u sizeInBytes-%u jitFlags-%016llX instructionSetFlags-%016llX", key, value.B, jitflags->GetFlagsRaw(), jitflags->GetInstructionSetFlagsRaw()); + printf("GetJitFlags key %u sizeInBytes-%u jitFlags-%016llX", key, value.B, jitflags->GetFlagsRaw()); GetJitFlags->Unlock(); } DWORD MethodContext::repGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes) diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index 741b12e4f3afd..9978fac982c5c 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -217,11 +217,11 @@ TODO: Talk about initializing strutures before use #endif #endif -SELECTANY const GUID JITEEVersionIdentifier = { /* 54305fa1-a0d8-42e4-a6b4-b750a8143467 */ - 0x54305fa1, - 0xa0d8, - 0x42e4, - {0xa6, 0xb4, 0xb7, 0x50, 0xa8, 0x14, 0x34, 0x67} +SELECTANY const GUID JITEEVersionIdentifier = { /* c231d2d7-4764-4097-a9ef-5961041540df */ + 0xc231d2d7, + 0x4764, + 0x4097, + {0xa9, 0xef, 0x59, 0x61, 0x04, 0x15, 0x40, 0xdf} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/src/inc/corinfoinstructionset.h b/src/coreclr/src/inc/corinfoinstructionset.h deleted file mode 100644 index d43d743134f44..0000000000000 --- a/src/coreclr/src/inc/corinfoinstructionset.h +++ /dev/null @@ -1,276 +0,0 @@ - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -#ifndef CORINFOINSTRUCTIONSET_H -#define CORINFOINSTRUCTIONSET_H - -enum CORINFO_InstructionSet -{ - InstructionSet_ILLEGAL = 0, - InstructionSet_NONE = 63, -#ifdef TARGET_ARM64 - InstructionSet_ArmBase=1, - InstructionSet_ArmBase_Arm64=2, - InstructionSet_AdvSimd=3, - InstructionSet_AdvSimd_Arm64=4, - InstructionSet_Aes=5, - InstructionSet_Crc32=6, - InstructionSet_Crc32_Arm64=7, - InstructionSet_Sha1=8, - InstructionSet_Sha256=9, - InstructionSet_Atomics=10, - InstructionSet_Vector64=11, - InstructionSet_Vector128=12, -#endif // TARGET_ARM64 -#ifdef TARGET_AMD64 - InstructionSet_SSE=1, - InstructionSet_SSE2=2, - InstructionSet_SSE3=3, - InstructionSet_SSSE3=4, - InstructionSet_SSE41=5, - InstructionSet_SSE42=6, - InstructionSet_AVX=7, - InstructionSet_AVX2=8, - InstructionSet_AES=9, - InstructionSet_BMI1=10, - InstructionSet_BMI2=11, - InstructionSet_FMA=12, - InstructionSet_LZCNT=13, - InstructionSet_PCLMULQDQ=14, - InstructionSet_POPCNT=15, - InstructionSet_Vector128=16, - InstructionSet_Vector256=17, - InstructionSet_BMI1_X64=18, - InstructionSet_BMI2_X64=19, - InstructionSet_LZCNT_X64=20, - InstructionSet_POPCNT_X64=21, - InstructionSet_SSE_X64=22, - InstructionSet_SSE2_X64=23, - InstructionSet_SSE41_X64=24, - InstructionSet_SSE42_X64=25, -#endif // TARGET_AMD64 -#ifdef TARGET_X86 - InstructionSet_SSE=1, - InstructionSet_SSE2=2, - InstructionSet_SSE3=3, - InstructionSet_SSSE3=4, - InstructionSet_SSE41=5, - InstructionSet_SSE42=6, - InstructionSet_AVX=7, - InstructionSet_AVX2=8, - InstructionSet_AES=9, - InstructionSet_BMI1=10, - InstructionSet_BMI2=11, - InstructionSet_FMA=12, - InstructionSet_LZCNT=13, - InstructionSet_PCLMULQDQ=14, - InstructionSet_POPCNT=15, - InstructionSet_Vector128=16, - InstructionSet_Vector256=17, - InstructionSet_BMI1_X64=18, - InstructionSet_BMI2_X64=19, - InstructionSet_LZCNT_X64=20, - InstructionSet_POPCNT_X64=21, - InstructionSet_SSE_X64=22, - InstructionSet_SSE2_X64=23, - InstructionSet_SSE41_X64=24, - InstructionSet_SSE42_X64=25, -#endif // TARGET_X86 - -}; - -struct CORINFO_InstructionSetFlags -{ -private: - uint64_t _flags = 0; -public: - void AddInstructionSet(CORINFO_InstructionSet instructionSet) - { - _flags = _flags | (((uint64_t)1) << instructionSet); - } - - void RemoveInstructionSet(CORINFO_InstructionSet instructionSet) - { - _flags = _flags & ~(((uint64_t)1) << instructionSet); - } - - bool HasInstructionSet(CORINFO_InstructionSet instructionSet) const - { - return _flags & (((uint64_t)1) << instructionSet); - } - - bool Equals(CORINFO_InstructionSetFlags other) const - { - return _flags == other._flags; - } - - void Add(CORINFO_InstructionSetFlags other) - { - _flags |= other._flags; - } - - bool IsEmpty() const - { - return _flags == 0; - } - - void Reset() - { - _flags = 0; - } - - void Set64BitInstructionSetVariants() - { -#ifdef TARGET_ARM64 - if (HasInstructionSet(InstructionSet_ArmBase)) - AddInstructionSet(InstructionSet_ArmBase_Arm64); - if (HasInstructionSet(InstructionSet_AdvSimd)) - AddInstructionSet(InstructionSet_AdvSimd_Arm64); - if (HasInstructionSet(InstructionSet_Crc32)) - AddInstructionSet(InstructionSet_Crc32_Arm64); -#endif // TARGET_ARM64 -#ifdef TARGET_AMD64 - if (HasInstructionSet(InstructionSet_SSE)) - AddInstructionSet(InstructionSet_SSE_X64); - if (HasInstructionSet(InstructionSet_SSE2)) - AddInstructionSet(InstructionSet_SSE2_X64); - if (HasInstructionSet(InstructionSet_SSE41)) - AddInstructionSet(InstructionSet_SSE41_X64); - if (HasInstructionSet(InstructionSet_SSE42)) - AddInstructionSet(InstructionSet_SSE42_X64); - if (HasInstructionSet(InstructionSet_BMI1)) - AddInstructionSet(InstructionSet_BMI1_X64); - if (HasInstructionSet(InstructionSet_BMI2)) - AddInstructionSet(InstructionSet_BMI2_X64); - if (HasInstructionSet(InstructionSet_LZCNT)) - AddInstructionSet(InstructionSet_LZCNT_X64); - if (HasInstructionSet(InstructionSet_POPCNT)) - AddInstructionSet(InstructionSet_POPCNT_X64); -#endif // TARGET_AMD64 -#ifdef TARGET_X86 -#endif // TARGET_X86 - - } - - uint64_t GetFlagsRaw() - { - return _flags; - } - - void SetFromFlagsRaw(uint64_t flags) - { - _flags = flags; - } -}; - -inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_InstructionSetFlags input) -{ - CORINFO_InstructionSetFlags oldflags = input; - CORINFO_InstructionSetFlags resultflags = input; - do - { - oldflags = resultflags; -#ifdef TARGET_ARM64 - if (resultflags.HasInstructionSet(InstructionSet_ArmBase) && !resultflags.HasInstructionSet(InstructionSet_ArmBase_Arm64)) - resultflags.RemoveInstructionSet(InstructionSet_ArmBase); - if (resultflags.HasInstructionSet(InstructionSet_AdvSimd) && !resultflags.HasInstructionSet(InstructionSet_AdvSimd_Arm64)) - resultflags.RemoveInstructionSet(InstructionSet_AdvSimd); - if (resultflags.HasInstructionSet(InstructionSet_Crc32) && !resultflags.HasInstructionSet(InstructionSet_Crc32_Arm64)) - resultflags.RemoveInstructionSet(InstructionSet_Crc32); - if (resultflags.HasInstructionSet(InstructionSet_AdvSimd) && !resultflags.HasInstructionSet(InstructionSet_ArmBase)) - resultflags.RemoveInstructionSet(InstructionSet_AdvSimd); - if (resultflags.HasInstructionSet(InstructionSet_Aes) && !resultflags.HasInstructionSet(InstructionSet_ArmBase)) - resultflags.RemoveInstructionSet(InstructionSet_Aes); - if (resultflags.HasInstructionSet(InstructionSet_Crc32) && !resultflags.HasInstructionSet(InstructionSet_ArmBase)) - resultflags.RemoveInstructionSet(InstructionSet_Crc32); - if (resultflags.HasInstructionSet(InstructionSet_Sha1) && !resultflags.HasInstructionSet(InstructionSet_ArmBase)) - resultflags.RemoveInstructionSet(InstructionSet_Sha1); - if (resultflags.HasInstructionSet(InstructionSet_Sha256) && !resultflags.HasInstructionSet(InstructionSet_ArmBase)) - resultflags.RemoveInstructionSet(InstructionSet_Sha256); -#endif // TARGET_ARM64 -#ifdef TARGET_AMD64 - if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_SSE_X64)) - resultflags.RemoveInstructionSet(InstructionSet_SSE); - if (resultflags.HasInstructionSet(InstructionSet_SSE2) && !resultflags.HasInstructionSet(InstructionSet_SSE2_X64)) - resultflags.RemoveInstructionSet(InstructionSet_SSE2); - if (resultflags.HasInstructionSet(InstructionSet_SSE41) && !resultflags.HasInstructionSet(InstructionSet_SSE41_X64)) - resultflags.RemoveInstructionSet(InstructionSet_SSE41); - if (resultflags.HasInstructionSet(InstructionSet_SSE42) && !resultflags.HasInstructionSet(InstructionSet_SSE42_X64)) - resultflags.RemoveInstructionSet(InstructionSet_SSE42); - if (resultflags.HasInstructionSet(InstructionSet_BMI1) && !resultflags.HasInstructionSet(InstructionSet_BMI1_X64)) - resultflags.RemoveInstructionSet(InstructionSet_BMI1); - if (resultflags.HasInstructionSet(InstructionSet_BMI2) && !resultflags.HasInstructionSet(InstructionSet_BMI2_X64)) - resultflags.RemoveInstructionSet(InstructionSet_BMI2); - if (resultflags.HasInstructionSet(InstructionSet_LZCNT) && !resultflags.HasInstructionSet(InstructionSet_LZCNT_X64)) - resultflags.RemoveInstructionSet(InstructionSet_LZCNT); - if (resultflags.HasInstructionSet(InstructionSet_POPCNT) && !resultflags.HasInstructionSet(InstructionSet_POPCNT_X64)) - resultflags.RemoveInstructionSet(InstructionSet_POPCNT); - if (resultflags.HasInstructionSet(InstructionSet_SSE2) && !resultflags.HasInstructionSet(InstructionSet_SSE)) - resultflags.RemoveInstructionSet(InstructionSet_SSE2); - if (resultflags.HasInstructionSet(InstructionSet_SSE3) && !resultflags.HasInstructionSet(InstructionSet_SSE2)) - resultflags.RemoveInstructionSet(InstructionSet_SSE3); - if (resultflags.HasInstructionSet(InstructionSet_SSSE3) && !resultflags.HasInstructionSet(InstructionSet_SSE3)) - resultflags.RemoveInstructionSet(InstructionSet_SSSE3); - if (resultflags.HasInstructionSet(InstructionSet_SSE41) && !resultflags.HasInstructionSet(InstructionSet_SSSE3)) - resultflags.RemoveInstructionSet(InstructionSet_SSE41); - if (resultflags.HasInstructionSet(InstructionSet_SSE42) && !resultflags.HasInstructionSet(InstructionSet_SSE41)) - resultflags.RemoveInstructionSet(InstructionSet_SSE42); - if (resultflags.HasInstructionSet(InstructionSet_AVX) && !resultflags.HasInstructionSet(InstructionSet_SSE42)) - resultflags.RemoveInstructionSet(InstructionSet_AVX); - if (resultflags.HasInstructionSet(InstructionSet_AVX2) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_AVX2); - if (resultflags.HasInstructionSet(InstructionSet_AES) && !resultflags.HasInstructionSet(InstructionSet_SSE2)) - resultflags.RemoveInstructionSet(InstructionSet_AES); - if (resultflags.HasInstructionSet(InstructionSet_BMI1) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_BMI1); - if (resultflags.HasInstructionSet(InstructionSet_BMI2) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_BMI2); - if (resultflags.HasInstructionSet(InstructionSet_FMA) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_FMA); - if (resultflags.HasInstructionSet(InstructionSet_PCLMULQDQ) && !resultflags.HasInstructionSet(InstructionSet_SSE2)) - resultflags.RemoveInstructionSet(InstructionSet_PCLMULQDQ); - if (resultflags.HasInstructionSet(InstructionSet_POPCNT) && !resultflags.HasInstructionSet(InstructionSet_SSE42)) - resultflags.RemoveInstructionSet(InstructionSet_POPCNT); -#endif // TARGET_AMD64 -#ifdef TARGET_X86 - if (resultflags.HasInstructionSet(InstructionSet_SSE2) && !resultflags.HasInstructionSet(InstructionSet_SSE)) - resultflags.RemoveInstructionSet(InstructionSet_SSE2); - if (resultflags.HasInstructionSet(InstructionSet_SSE3) && !resultflags.HasInstructionSet(InstructionSet_SSE2)) - resultflags.RemoveInstructionSet(InstructionSet_SSE3); - if (resultflags.HasInstructionSet(InstructionSet_SSSE3) && !resultflags.HasInstructionSet(InstructionSet_SSE3)) - resultflags.RemoveInstructionSet(InstructionSet_SSSE3); - if (resultflags.HasInstructionSet(InstructionSet_SSE41) && !resultflags.HasInstructionSet(InstructionSet_SSSE3)) - resultflags.RemoveInstructionSet(InstructionSet_SSE41); - if (resultflags.HasInstructionSet(InstructionSet_SSE42) && !resultflags.HasInstructionSet(InstructionSet_SSE41)) - resultflags.RemoveInstructionSet(InstructionSet_SSE42); - if (resultflags.HasInstructionSet(InstructionSet_AVX) && !resultflags.HasInstructionSet(InstructionSet_SSE42)) - resultflags.RemoveInstructionSet(InstructionSet_AVX); - if (resultflags.HasInstructionSet(InstructionSet_AVX2) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_AVX2); - if (resultflags.HasInstructionSet(InstructionSet_AES) && !resultflags.HasInstructionSet(InstructionSet_SSE2)) - resultflags.RemoveInstructionSet(InstructionSet_AES); - if (resultflags.HasInstructionSet(InstructionSet_BMI1) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_BMI1); - if (resultflags.HasInstructionSet(InstructionSet_BMI2) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_BMI2); - if (resultflags.HasInstructionSet(InstructionSet_FMA) && !resultflags.HasInstructionSet(InstructionSet_AVX)) - resultflags.RemoveInstructionSet(InstructionSet_FMA); - if (resultflags.HasInstructionSet(InstructionSet_PCLMULQDQ) && !resultflags.HasInstructionSet(InstructionSet_SSE2)) - resultflags.RemoveInstructionSet(InstructionSet_PCLMULQDQ); - if (resultflags.HasInstructionSet(InstructionSet_POPCNT) && !resultflags.HasInstructionSet(InstructionSet_SSE42)) - resultflags.RemoveInstructionSet(InstructionSet_POPCNT); -#endif // TARGET_X86 - - } while (!oldflags.Equals(resultflags)); - return resultflags; -} - - - -#endif // CORINFOINSTRUCTIONSET_H diff --git a/src/coreclr/src/inc/corjitflags.h b/src/coreclr/src/inc/corjitflags.h index eac6f9277909d..18f24b52acdfb 100644 --- a/src/coreclr/src/inc/corjitflags.h +++ b/src/coreclr/src/inc/corjitflags.h @@ -17,8 +17,6 @@ #ifndef _COR_JIT_FLAGS_H_ #define _COR_JIT_FLAGS_H_ -#include "corinfoinstructionset.h" - class CORJIT_FLAGS { public: @@ -42,6 +40,7 @@ class CORJIT_FLAGS CORJIT_FLAG_TARGET_P4 = 9, CORJIT_FLAG_USE_FCOMI = 10, // Generated code may use fcomi(p) instruction CORJIT_FLAG_USE_CMOV = 11, // Generated code may use cmov instruction + CORJIT_FLAG_USE_SSE2 = 12, // Generated code may use SSE-2 instructions #else // !defined(TARGET_X86) @@ -55,10 +54,19 @@ class CORJIT_FLAGS CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement + #if defined(TARGET_X86) || defined(TARGET_AMD64) + + CORJIT_FLAG_USE_AVX = 14, + CORJIT_FLAG_USE_AVX2 = 15, + CORJIT_FLAG_USE_AVX_512 = 16, + + #else // !defined(TARGET_X86) && !defined(TARGET_AMD64) + CORJIT_FLAG_UNUSED7 = 14, CORJIT_FLAG_UNUSED8 = 15, CORJIT_FLAG_UNUSED9 = 16, + #endif // !defined(TARGET_X86) && !defined(TARGET_AMD64) #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) CORJIT_FLAG_FEATURE_SIMD = 17, @@ -98,6 +106,57 @@ class CORJIT_FLAGS CORJIT_FLAG_NO_INLINING = 42, // JIT should not inline any called method into this method +#if defined(TARGET_ARM64) + + CORJIT_FLAG_HAS_ARM64_AES = 43, // ID_AA64ISAR0_EL1.AES is 1 or better + CORJIT_FLAG_HAS_ARM64_ATOMICS = 44, // ID_AA64ISAR0_EL1.Atomic is 2 or better + CORJIT_FLAG_HAS_ARM64_CRC32 = 45, // ID_AA64ISAR0_EL1.CRC32 is 1 or better + CORJIT_FLAG_HAS_ARM64_DCPOP = 46, // ID_AA64ISAR1_EL1.DPB is 1 or better + CORJIT_FLAG_HAS_ARM64_DP = 47, // ID_AA64ISAR0_EL1.DP is 1 or better + CORJIT_FLAG_HAS_ARM64_FCMA = 48, // ID_AA64ISAR1_EL1.FCMA is 1 or better + CORJIT_FLAG_HAS_ARM64_FP = 49, // ID_AA64PFR0_EL1.FP is 0 or better + CORJIT_FLAG_HAS_ARM64_FP16 = 50, // ID_AA64PFR0_EL1.FP is 1 or better + CORJIT_FLAG_HAS_ARM64_JSCVT = 51, // ID_AA64ISAR1_EL1.JSCVT is 1 or better + CORJIT_FLAG_HAS_ARM64_LRCPC = 52, // ID_AA64ISAR1_EL1.LRCPC is 1 or better + CORJIT_FLAG_HAS_ARM64_PMULL = 53, // ID_AA64ISAR0_EL1.AES is 2 or better + CORJIT_FLAG_HAS_ARM64_SHA1 = 54, // ID_AA64ISAR0_EL1.SHA1 is 1 or better + CORJIT_FLAG_HAS_ARM64_SHA256 = 55, // ID_AA64ISAR0_EL1.SHA2 is 1 or better + CORJIT_FLAG_HAS_ARM64_SHA512 = 56, // ID_AA64ISAR0_EL1.SHA2 is 2 or better + CORJIT_FLAG_HAS_ARM64_SHA3 = 57, // ID_AA64ISAR0_EL1.SHA3 is 1 or better + CORJIT_FLAG_HAS_ARM64_ADVSIMD = 58, // ID_AA64PFR0_EL1.AdvSIMD is 0 or better + CORJIT_FLAG_HAS_ARM64_ADVSIMD_V81 = 59, // ID_AA64ISAR0_EL1.RDM is 1 or better + CORJIT_FLAG_HAS_ARM64_ADVSIMD_FP16 = 60, // ID_AA64PFR0_EL1.AdvSIMD is 1 or better + CORJIT_FLAG_HAS_ARM64_SM3 = 61, // ID_AA64ISAR0_EL1.SM3 is 1 or better + CORJIT_FLAG_HAS_ARM64_SM4 = 62, // ID_AA64ISAR0_EL1.SM4 is 1 or better + CORJIT_FLAG_HAS_ARM64_SVE = 63 // ID_AA64PFR0_EL1.SVE is 1 or better + +#elif defined(TARGET_X86) || defined(TARGET_AMD64) + + CORJIT_FLAG_USE_SSE3 = 43, + CORJIT_FLAG_USE_SSSE3 = 44, + CORJIT_FLAG_USE_SSE41 = 45, + CORJIT_FLAG_USE_SSE42 = 46, + CORJIT_FLAG_USE_AES = 47, + CORJIT_FLAG_USE_BMI1 = 48, + CORJIT_FLAG_USE_BMI2 = 49, + CORJIT_FLAG_USE_FMA = 50, + CORJIT_FLAG_USE_LZCNT = 51, + CORJIT_FLAG_USE_PCLMULQDQ = 52, + CORJIT_FLAG_USE_POPCNT = 53, + CORJIT_FLAG_UNUSED23 = 54, + CORJIT_FLAG_UNUSED24 = 55, + CORJIT_FLAG_UNUSED25 = 56, + CORJIT_FLAG_UNUSED26 = 57, + CORJIT_FLAG_UNUSED27 = 58, + CORJIT_FLAG_UNUSED28 = 59, + CORJIT_FLAG_UNUSED29 = 60, + CORJIT_FLAG_UNUSED30 = 61, + CORJIT_FLAG_UNUSED31 = 62, + CORJIT_FLAG_UNUSED32 = 63 + + +#else // !defined(TARGET_ARM64) &&!defined(TARGET_X86) && !defined(TARGET_AMD64) + CORJIT_FLAG_UNUSED12 = 43, CORJIT_FLAG_UNUSED13 = 44, CORJIT_FLAG_UNUSED14 = 45, @@ -119,6 +178,8 @@ class CORJIT_FLAGS CORJIT_FLAG_UNUSED30 = 61, CORJIT_FLAG_UNUSED31 = 62, CORJIT_FLAG_UNUSED32 = 63 + +#endif // !defined(TARGET_ARM64) &&!defined(TARGET_X86) && !defined(TARGET_AMD64) }; CORJIT_FLAGS() @@ -137,28 +198,11 @@ class CORJIT_FLAGS CORJIT_FLAGS(const CORJIT_FLAGS& other) { corJitFlags = other.corJitFlags; - instructionSetFlags = other.instructionSetFlags; } void Reset() { corJitFlags = 0; - instructionSetFlags.Reset(); - } - - void Set(CORINFO_InstructionSet instructionSet) - { - instructionSetFlags.AddInstructionSet(instructionSet); - } - - void Clear(CORINFO_InstructionSet instructionSet) - { - instructionSetFlags.RemoveInstructionSet(instructionSet); - } - - void Set64BitInstructionSetVariants() - { - instructionSetFlags.Set64BitInstructionSetVariants(); } void Set(CorJitFlag flag) @@ -179,17 +223,16 @@ class CORJIT_FLAGS void Add(const CORJIT_FLAGS& other) { corJitFlags |= other.corJitFlags; - instructionSetFlags.Add(other.instructionSetFlags); } - bool IsEmpty() const + void Remove(const CORJIT_FLAGS& other) { - return corJitFlags == 0 && instructionSetFlags.IsEmpty(); + corJitFlags &= ~other.corJitFlags; } - void EnsureValidInstructionSetSupport() + bool IsEmpty() const { - instructionSetFlags = EnsureInstructionSetFlagsAreValid(instructionSetFlags); + return corJitFlags == 0; } // DO NOT USE THIS FUNCTION! (except in very restricted special cases) @@ -198,16 +241,9 @@ class CORJIT_FLAGS return corJitFlags; } - // DO NOT USE THIS FUNCTION! (except in very restricted special cases) - unsigned __int64 GetInstructionSetFlagsRaw() - { - return instructionSetFlags.GetFlagsRaw(); - } - private: unsigned __int64 corJitFlags; - CORINFO_InstructionSetFlags instructionSetFlags; }; diff --git a/src/coreclr/src/inc/readytoruninstructionset.h b/src/coreclr/src/inc/readytoruninstructionset.h deleted file mode 100644 index 6e6f2549f9044..0000000000000 --- a/src/coreclr/src/inc/readytoruninstructionset.h +++ /dev/null @@ -1,38 +0,0 @@ - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -#ifndef READYTORUNINSTRUCTIONSET_H -#define READYTORUNINSTRUCTIONSET_H -enum ReadyToRunInstructionSet -{ - READYTORUN_INSTRUCTION_Sse=1, - READYTORUN_INSTRUCTION_Sse2=2, - READYTORUN_INSTRUCTION_Sse3=3, - READYTORUN_INSTRUCTION_Ssse3=4, - READYTORUN_INSTRUCTION_Sse41=5, - READYTORUN_INSTRUCTION_Sse42=6, - READYTORUN_INSTRUCTION_Avx=7, - READYTORUN_INSTRUCTION_Avx2=8, - READYTORUN_INSTRUCTION_Aes=9, - READYTORUN_INSTRUCTION_Bmi1=10, - READYTORUN_INSTRUCTION_Bmi2=11, - READYTORUN_INSTRUCTION_Fma=12, - READYTORUN_INSTRUCTION_Lzcnt=13, - READYTORUN_INSTRUCTION_Pclmulqdq=14, - READYTORUN_INSTRUCTION_Popcnt=15, - READYTORUN_INSTRUCTION_ArmBase=16, - READYTORUN_INSTRUCTION_AdvSimd=17, - READYTORUN_INSTRUCTION_Crc32=18, - READYTORUN_INSTRUCTION_Sha1=19, - READYTORUN_INSTRUCTION_Sha256=20, - READYTORUN_INSTRUCTION_Atomics=21, - -}; - -#endif // READYTORUNINSTRUCTIONSET_H diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index 0d4fc4a704dc2..6febed12de9fd 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -2193,179 +2193,250 @@ void Compiler::compSetProcessor() #endif // TARGET_X86 - CORINFO_InstructionSetFlags instructionSetFlags = jitFlags.GetInstructionSetFlags(); - +// Instruction set flags for Intel hardware intrinsics #ifdef TARGET_XARCH - // Instruction set flags for Intel hardware intrinsics opts.compSupportsISA = 0; if (JitConfig.EnableHWIntrinsic()) { // Dummy ISAs for simplifying the JIT code - instructionSetFlags.AddInstructionSet(InstructionSet_Vector128); - instructionSetFlags.AddInstructionSet(InstructionSet_Vector256); + opts.setSupportedISA(InstructionSet_Vector128); + opts.setSupportedISA(InstructionSet_Vector256); } - if (!JitConfig.EnableSSE()) + if (JitConfig.EnableSSE()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE); + opts.setSupportedISA(InstructionSet_SSE); #ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE_X64); -#endif + opts.setSupportedISA(InstructionSet_SSE_X64); +#endif // TARGET_AMD64 + + if (JitConfig.EnableSSE2()) + { + opts.setSupportedISA(InstructionSet_SSE2); +#ifdef TARGET_AMD64 + opts.setSupportedISA(InstructionSet_SSE2_X64); +#endif // TARGET_AMD64 + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AES) && JitConfig.EnableAES()) + { + opts.setSupportedISA(InstructionSet_AES); + } + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_PCLMULQDQ) && JitConfig.EnablePCLMULQDQ()) + { + opts.setSupportedISA(InstructionSet_PCLMULQDQ); + } + + // We need to additionaly check that COMPlus_EnableSSE3_4 is set, as that + // is a prexisting config flag that controls the SSE3+ ISAs + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSE3) && JitConfig.EnableSSE3() && JitConfig.EnableSSE3_4()) + { + opts.setSupportedISA(InstructionSet_SSE3); + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSSE3) && JitConfig.EnableSSSE3()) + { + opts.setSupportedISA(InstructionSet_SSSE3); + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSE41) && JitConfig.EnableSSE41()) + { + opts.setSupportedISA(InstructionSet_SSE41); +#ifdef TARGET_AMD64 + opts.setSupportedISA(InstructionSet_SSE41_X64); +#endif // TARGET_AMD64 + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSE42) && JitConfig.EnableSSE42()) + { + opts.setSupportedISA(InstructionSet_SSE42); +#ifdef TARGET_AMD64 + opts.setSupportedISA(InstructionSet_SSE42_X64); +#endif // TARGET_AMD64 + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_POPCNT) && JitConfig.EnablePOPCNT()) + { + opts.setSupportedISA(InstructionSet_POPCNT); +#ifdef TARGET_AMD64 + opts.setSupportedISA(InstructionSet_POPCNT_X64); +#endif // TARGET_AMD64 + } + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX) && JitConfig.EnableAVX()) + { + opts.setSupportedISA(InstructionSet_AVX); + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_FMA) && JitConfig.EnableFMA()) + { + opts.setSupportedISA(InstructionSet_FMA); + } + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2) && JitConfig.EnableAVX2()) + { + opts.setSupportedISA(InstructionSet_AVX2); + } + } + } + } + } + } + } } - if (!JitConfig.EnableSSE2()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_LZCNT) && JitConfig.EnableLZCNT()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE2); + opts.setSupportedISA(InstructionSet_LZCNT); #ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE2_X64); -#endif + opts.setSupportedISA(InstructionSet_LZCNT_X64); +#endif // TARGET_AMD64 + } + + // We currently need to also check that AVX is supported as that controls the support for the VEX encoding + // in the emitter. + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_BMI1) && JitConfig.EnableBMI1() && compSupports(InstructionSet_AVX)) + { + opts.setSupportedISA(InstructionSet_BMI1); +#ifdef TARGET_AMD64 + opts.setSupportedISA(InstructionSet_BMI1_X64); +#endif // TARGET_AMD64 + } + + // We currently need to also check that AVX is supported as that controls the support for the VEX encoding + // in the emitter. + if (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_BMI2) && JitConfig.EnableBMI2() && compSupports(InstructionSet_AVX)) + { + opts.setSupportedISA(InstructionSet_BMI2); +#ifdef TARGET_AMD64 + opts.setSupportedISA(InstructionSet_BMI2_X64); +#endif // TARGET_AMD64 } - if (!JitConfig.EnableAES()) + if (!compIsForInlining()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_AES); + if (canUseVexEncoding()) + { + codeGen->GetEmitter()->SetUseVEXEncoding(true); + // Assume each JITted method does not contain AVX instruction at first + codeGen->GetEmitter()->SetContainsAVX(false); + codeGen->GetEmitter()->SetContains256bitAVX(false); + } } +#endif // TARGET_XARCH - if (!JitConfig.EnablePCLMULQDQ()) +#if defined(TARGET_ARM64) + if (JitConfig.EnableHWIntrinsic()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_PCLMULQDQ); + // Dummy ISAs for simplifying the JIT code + opts.setSupportedISA(InstructionSet_ArmBase); + opts.setSupportedISA(InstructionSet_ArmBase_Arm64); + opts.setSupportedISA(InstructionSet_Vector64); + opts.setSupportedISA(InstructionSet_Vector128); } - // We need to additionaly check that COMPlus_EnableSSE3_4 is set, as that - // is a prexisting config flag that controls the SSE3+ ISAs - if (!JitConfig.EnableSSE3() || !JitConfig.EnableSSE3_4()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_AES) && JitConfig.EnableArm64Aes()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE3); + opts.setSupportedISA(InstructionSet_Aes); } - if (!JitConfig.EnableSSSE3()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ATOMICS) && JitConfig.EnableArm64Atomics()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSSE3); + opts.setSupportedISA(InstructionSet_Atomics); } - if (!JitConfig.EnableSSE41()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_CRC32) && JitConfig.EnableArm64Crc32()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE41); -#ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE41_X64); -#endif + opts.setSupportedISA(InstructionSet_Crc32); } - if (!JitConfig.EnableSSE42()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_DCPOP) && JitConfig.EnableArm64Dcpop()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE42); -#ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE42_X64); -#endif + opts.setSupportedISA(InstructionSet_Dcpop); } - if (!JitConfig.EnablePOPCNT()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_DP) && JitConfig.EnableArm64Dp()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_POPCNT); -#ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_POPCNT_X64); -#endif + opts.setSupportedISA(InstructionSet_Dp); } - if (!JitConfig.EnableAVX()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_FCMA) && JitConfig.EnableArm64Fcma()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX); + opts.setSupportedISA(InstructionSet_Fcma); } - if (!JitConfig.EnableFMA()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_FP) && JitConfig.EnableArm64Fp()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_FMA); + opts.setSupportedISA(InstructionSet_Fp); } - if (!JitConfig.EnableAVX2()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_FP16) && JitConfig.EnableArm64Fp16()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX2); + opts.setSupportedISA(InstructionSet_Fp16); } - if (!JitConfig.EnableLZCNT()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_JSCVT) && JitConfig.EnableArm64Jscvt()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_LZCNT); -#ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_LZCNT_X64); -#endif // TARGET_AMD64 + opts.setSupportedISA(InstructionSet_Jscvt); } - if (!JitConfig.EnableBMI1()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_LRCPC) && JitConfig.EnableArm64Lrcpc()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI1); -#ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI1_X64); -#endif // TARGET_AMD64 + opts.setSupportedISA(InstructionSet_Lrcpc); } - if (!JitConfig.EnableBMI2()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_PMULL) && JitConfig.EnableArm64Pmull()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI2); -#ifdef TARGET_AMD64 - instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI2_X64); -#endif // TARGET_AMD64 + opts.setSupportedISA(InstructionSet_Pmull); } -#endif // TARGET_XARCH -#if defined(TARGET_ARM64) - if (JitConfig.EnableHWIntrinsic()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA1) && JitConfig.EnableArm64Sha1()) { - // Dummy ISAs for simplifying the JIT code - instructionSetFlags.AddInstructionSet(InstructionSet_ArmBase); - instructionSetFlags.AddInstructionSet(InstructionSet_ArmBase_Arm64); - instructionSetFlags.AddInstructionSet(InstructionSet_Vector64); - instructionSetFlags.AddInstructionSet(InstructionSet_Vector128); + opts.setSupportedISA(InstructionSet_Sha1); } - if (!JitConfig.EnableArm64Aes()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA256) && JitConfig.EnableArm64Sha256()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_Aes); + opts.setSupportedISA(InstructionSet_Sha256); } - if (!JitConfig.EnableArm64Atomics()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA512) && JitConfig.EnableArm64Sha512()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_Atomics); + opts.setSupportedISA(InstructionSet_Sha512); } - if (!JitConfig.EnableArm64Crc32()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA3) && JitConfig.EnableArm64Sha3()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_Crc32); - instructionSetFlags.RemoveInstructionSet(InstructionSet_Crc32_Arm64); + opts.setSupportedISA(InstructionSet_Sha3); } - if (!JitConfig.EnableArm64Sha1()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD) && JitConfig.EnableArm64AdvSimd()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_Sha1); + opts.setSupportedISA(InstructionSet_AdvSimd); + opts.setSupportedISA(InstructionSet_AdvSimd_Arm64); } - if (!JitConfig.EnableArm64Sha256()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD_V81) && JitConfig.EnableArm64AdvSimd_v81()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_Sha256); + opts.setSupportedISA(InstructionSet_AdvSimd_v81); } - if (!JitConfig.EnableArm64AdvSimd()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD_FP16) && JitConfig.EnableArm64AdvSimd_Fp16()) { - instructionSetFlags.RemoveInstructionSet(InstructionSet_AdvSimd); - instructionSetFlags.RemoveInstructionSet(InstructionSet_AdvSimd_Arm64); + opts.setSupportedISA(InstructionSet_AdvSimd_Fp16); } -#endif - instructionSetFlags = EnsureInstructionSetFlagsAreValid(instructionSetFlags); - opts.setSupportedISAs(jitFlags.GetInstructionSetFlags()); + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SM3) && JitConfig.EnableArm64Sm3()) + { + opts.setSupportedISA(InstructionSet_Sm3); + } -#ifdef TARGET_XARCH - if (!compIsForInlining()) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SM4) && JitConfig.EnableArm64Sm4()) { - if (canUseVexEncoding()) - { - codeGen->GetEmitter()->SetUseVEXEncoding(true); - // Assume each JITted method does not contain AVX instruction at first - codeGen->GetEmitter()->SetContainsAVX(false); - codeGen->GetEmitter()->SetContains256bitAVX(false); - } + opts.setSupportedISA(InstructionSet_Sm4); } -#endif // TARGET_XARCH + + if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SVE) && JitConfig.EnableArm64Sve()) + { + opts.setSupportedISA(InstructionSet_Sve); + } +#endif } #ifdef PROFILING_SUPPORTED @@ -5283,11 +5354,28 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, // target default. Currently this is disabling all ARM64 architecture features except FP and SIMD, but this // should be altered to possibly enable all of them, when they are known to all work. - CORINFO_InstructionSetFlags defaultArm64Flags; - defaultArm64Flags.AddInstructionSet(InstructionSet_ArmBase); - defaultArm64Flags.AddInstructionSet(InstructionSet_AdvSimd); - defaultArm64Flags.Set64BitInstructionSetVariants(); - compileFlags->SetInstructionSetFlags(defaultArm64Flags); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_AES); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_ATOMICS); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_CRC32); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_DCPOP); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_DP); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_FCMA); + compileFlags->Set(JitFlags::JIT_FLAG_HAS_ARM64_FP); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_FP16); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_JSCVT); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_LRCPC); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_PMULL); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SHA1); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SHA256); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SHA512); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SHA3); + compileFlags->Set(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD_V81); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD_FP16); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SM3); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SM4); + compileFlags->Clear(JitFlags::JIT_FLAG_HAS_ARM64_SVE); + #endif // defined(TARGET_ARM64) } diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 64b719f160f98..109c9b43839d5 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3674,7 +3674,7 @@ class Compiler bool mustExpand); protected: - bool compSupportsHWIntrinsic(CORINFO_InstructionSet isa); + bool compSupportsHWIntrinsic(InstructionSet isa); GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, @@ -8272,7 +8272,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX return false; } - bool compSupports(CORINFO_InstructionSet isa) const + bool compSupports(InstructionSet isa) const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) return (opts.compSupportsISA & (1ULL << isa)) != 0; @@ -8381,13 +8381,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #if defined(TARGET_XARCH) || defined(TARGET_ARM64) uint64_t compSupportsISA; -#endif - void setSupportedISAs(CORINFO_InstructionSetFlags isas) + void setSupportedISA(InstructionSet isa) { -#if defined(TARGET_XARCH) || defined(TARGET_ARM64) - compSupportsISA = isas.GetFlagsRaw(); -#endif + compSupportsISA |= 1ULL << isa; } +#endif unsigned compFlags; // method attributes unsigned instrCount; diff --git a/src/coreclr/src/jit/ee_il_dll.cpp b/src/coreclr/src/jit/ee_il_dll.cpp index 78d3d8e59274a..4ac4c24dfde05 100644 --- a/src/coreclr/src/jit/ee_il_dll.cpp +++ b/src/coreclr/src/jit/ee_il_dll.cpp @@ -340,7 +340,7 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) #ifdef FEATURE_SIMD #if defined(TARGET_XARCH) if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_FEATURE_SIMD) && - jitFlags.GetInstructionSetFlags().HasInstructionSet(InstructionSet_AVX2)) + jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2)) { // Since the ISAs can be disabled individually and since they are hierarchical in nature (that is // disabling SSE also disables SSE2 through AVX2), we need to check each ISA in the hierarchy to diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 4af653b766e6b..4b8848bbf458c 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -302,7 +302,7 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, const char* enclosingClassName) { // TODO-Throughput: replace sequential search by binary search - CORINFO_InstructionSet isa = lookupIsa(className, enclosingClassName); + InstructionSet isa = lookupIsa(className, enclosingClassName); if (isa == InstructionSet_ILLEGAL) { @@ -584,7 +584,7 @@ GenTree* Compiler::addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* immO // // Return Value: // true iff the given instruction set is supported in the current compilation. -bool Compiler::compSupportsHWIntrinsic(CORINFO_InstructionSet isa) +bool Compiler::compSupportsHWIntrinsic(InstructionSet isa) { return JitConfig.EnableHWIntrinsic() && (featureSIMD || HWIntrinsicInfo::isScalarIsa(isa)) && ( @@ -629,11 +629,11 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, CORINFO_SIG_INFO* sig, bool mustExpand) { - CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsic); - HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); - int numArgs = sig->numArgs; - var_types retType = JITtype2varType(sig->retType); - var_types baseType = TYP_UNKNOWN; + InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsic); + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); + int numArgs = sig->numArgs; + var_types retType = JITtype2varType(sig->retType); + var_types baseType = TYP_UNKNOWN; if ((retType == TYP_STRUCT) && featureSIMD) { diff --git a/src/coreclr/src/jit/hwintrinsic.h b/src/coreclr/src/jit/hwintrinsic.h index b80dce7f1c0b0..2931c51813e1e 100644 --- a/src/coreclr/src/jit/hwintrinsic.h +++ b/src/coreclr/src/jit/hwintrinsic.h @@ -113,15 +113,15 @@ enum HWIntrinsicFlag : unsigned int struct HWIntrinsicInfo { - NamedIntrinsic id; - const char* name; - CORINFO_InstructionSet isa; - int ival; - unsigned simdSize; - int numArgs; - instruction ins[10]; - HWIntrinsicCategory category; - HWIntrinsicFlag flags; + NamedIntrinsic id; + const char* name; + InstructionSet isa; + int ival; + unsigned simdSize; + int numArgs; + instruction ins[10]; + HWIntrinsicCategory category; + HWIntrinsicFlag flags; static const HWIntrinsicInfo& lookup(NamedIntrinsic id); @@ -129,7 +129,7 @@ struct HWIntrinsicInfo const char* className, const char* methodName, const char* enclosingClassName); - static CORINFO_InstructionSet lookupIsa(const char* className, const char* enclosingClassName); + static InstructionSet lookupIsa(const char* className, const char* enclosingClassName); static unsigned lookupSimdSize(Compiler* comp, NamedIntrinsic id, CORINFO_SIG_INFO* sig); static int lookupNumArgs(const GenTreeHWIntrinsic* node); @@ -138,8 +138,8 @@ struct HWIntrinsicInfo static bool isImmOp(NamedIntrinsic id, const GenTree* op); static bool isInImmRange(NamedIntrinsic id, int ival); - static bool isFullyImplementedIsa(CORINFO_InstructionSet isa); - static bool isScalarIsa(CORINFO_InstructionSet isa); + static bool isFullyImplementedIsa(InstructionSet isa); + static bool isScalarIsa(InstructionSet isa); #ifdef TARGET_XARCH static bool isAVX2GatherIntrinsic(NamedIntrinsic id); @@ -157,7 +157,7 @@ struct HWIntrinsicInfo return lookup(id).name; } - static CORINFO_InstructionSet lookupIsa(NamedIntrinsic id) + static InstructionSet lookupIsa(NamedIntrinsic id) { return lookup(id).isa; } diff --git a/src/coreclr/src/jit/hwintrinsicarm64.cpp b/src/coreclr/src/jit/hwintrinsicarm64.cpp index 7f494ab96582f..1f7dde990cc7d 100644 --- a/src/coreclr/src/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsicarm64.cpp @@ -15,7 +15,7 @@ // // Return Value: // The 64-bit only InstructionSet associated with isa -static CORINFO_InstructionSet Arm64VersionOfIsa(CORINFO_InstructionSet isa) +static InstructionSet Arm64VersionOfIsa(InstructionSet isa) { switch (isa) { @@ -38,7 +38,7 @@ static CORINFO_InstructionSet Arm64VersionOfIsa(CORINFO_InstructionSet isa) // // Return Value: // The InstructionSet associated with className -static CORINFO_InstructionSet lookupInstructionSet(const char* className) +static InstructionSet lookupInstructionSet(const char* className) { assert(className != nullptr); @@ -99,7 +99,7 @@ static CORINFO_InstructionSet lookupInstructionSet(const char* className) // // Return Value: // The InstructionSet associated with className and enclosingClassName -CORINFO_InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const char* enclosingClassName) +InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const char* enclosingClassName) { assert(className != nullptr); @@ -153,7 +153,7 @@ bool HWIntrinsicInfo::isInImmRange(NamedIntrinsic id, int ival) // // Return Value: // true if isa is supported; otherwise, false -bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa) +bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa) { switch (isa) { @@ -188,7 +188,7 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa) // // Return Value: // true if isa is scalar; otherwise, false -bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa) +bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa) { switch (isa) { diff --git a/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp index cb5160e5cb937..1ba67be0bb2d9 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp @@ -79,11 +79,11 @@ static bool genIsTableDrivenHWIntrinsic(NamedIntrinsic intrinsicId, HWIntrinsicC // void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { - NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; - CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); - HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); - int ival = HWIntrinsicInfo::lookupIval(intrinsicId); - int numArgs = HWIntrinsicInfo::lookupNumArgs(node); + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); + int ival = HWIntrinsicInfo::lookupIval(intrinsicId); + int numArgs = HWIntrinsicInfo::lookupNumArgs(node); assert(HWIntrinsicInfo::RequiresCodegen(intrinsicId)); diff --git a/src/coreclr/src/jit/hwintrinsicxarch.cpp b/src/coreclr/src/jit/hwintrinsicxarch.cpp index 80b341f1c90ec..6aa59aa2bb7f6 100644 --- a/src/coreclr/src/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsicxarch.cpp @@ -15,7 +15,7 @@ // // Return Value: // The 64-bit only InstructionSet associated with isa -static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa) +static InstructionSet X64VersionOfIsa(InstructionSet isa) { switch (isa) { @@ -48,7 +48,7 @@ static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa) // // Return Value: // The InstructionSet associated with className -static CORINFO_InstructionSet lookupInstructionSet(const char* className) +static InstructionSet lookupInstructionSet(const char* className) { assert(className != nullptr); if (className[0] == 'A') @@ -147,7 +147,7 @@ static CORINFO_InstructionSet lookupInstructionSet(const char* className) // // Return Value: // The InstructionSet associated with className and enclosingClassName -CORINFO_InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const char* enclosingClassName) +InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const char* enclosingClassName) { assert(className != nullptr); @@ -253,7 +253,7 @@ bool HWIntrinsicInfo::isAVX2GatherIntrinsic(NamedIntrinsic id) // // Return Value: // true if isa is supported; otherwise, false -bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa) +bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa) { switch (isa) { @@ -302,7 +302,7 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa) // // Return Value: // true if isa is scalar; otherwise, false -bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa) +bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa) { switch (isa) { diff --git a/src/coreclr/src/jit/instr.h b/src/coreclr/src/jit/instr.h index 26ba6eec4ac01..0de79a4cc1387 100644 --- a/src/coreclr/src/jit/instr.h +++ b/src/coreclr/src/jit/instr.h @@ -292,6 +292,71 @@ enum emitAttr : unsigned #define EmitSize(x) (EA_ATTR(genTypeSize(TypeGet(x)))) +enum InstructionSet +{ + InstructionSet_ILLEGAL = 0, +#ifdef TARGET_XARCH + InstructionSet_Vector128, + InstructionSet_Vector256, + // Start linear order SIMD instruction sets + // These ISAs have strictly generation to generation order. + InstructionSet_SSE, + InstructionSet_SSE2, + InstructionSet_SSE3, + InstructionSet_SSSE3, + InstructionSet_SSE41, + InstructionSet_SSE42, + InstructionSet_AVX, + InstructionSet_AVX2, + // End linear order SIMD instruction sets. + InstructionSet_AES, + InstructionSet_BMI1, + InstructionSet_BMI2, + InstructionSet_FMA, + InstructionSet_LZCNT, + InstructionSet_PCLMULQDQ, + InstructionSet_POPCNT, + InstructionSet_BMI1_X64, + InstructionSet_BMI2_X64, + InstructionSet_LZCNT_X64, + InstructionSet_POPCNT_X64, + InstructionSet_SSE_X64, + InstructionSet_SSE2_X64, + InstructionSet_SSE41_X64, + InstructionSet_SSE42_X64, +#elif defined(TARGET_ARM) + InstructionSet_NEON, +#elif defined(TARGET_ARM64) + InstructionSet_AdvSimd, // ID_AA64PFR0_EL1.AdvSIMD is 0 or better + InstructionSet_AdvSimd_Arm64, + InstructionSet_AdvSimd_Fp16, // ID_AA64PFR0_EL1.AdvSIMD is 1 or better + InstructionSet_AdvSimd_v81, // ID_AA64ISAR0_EL1.RDM is 1 or better + InstructionSet_Aes, // ID_AA64ISAR0_EL1.AES is 1 or better + InstructionSet_ArmBase, + InstructionSet_ArmBase_Arm64, + InstructionSet_Atomics, // ID_AA64ISAR0_EL1.Atomic is 2 or better + InstructionSet_Crc32, // ID_AA64ISAR0_EL1.CRC32 is 1 or better + InstructionSet_Crc32_Arm64, + InstructionSet_Dcpop, // ID_AA64ISAR1_EL1.DPB is 1 or better + InstructionSet_Dp, // ID_AA64ISAR0_EL1.DP is 1 or better + InstructionSet_Fcma, // ID_AA64ISAR1_EL1.FCMA is 1 or better + InstructionSet_Fp, // ID_AA64PFR0_EL1.FP is 0 or better + InstructionSet_Fp16, // ID_AA64PFR0_EL1.FP is 1 or better + InstructionSet_Jscvt, // ID_AA64ISAR1_EL1.JSCVT is 1 or better + InstructionSet_Lrcpc, // ID_AA64ISAR1_EL1.LRCPC is 1 or better + InstructionSet_Pmull, // ID_AA64ISAR0_EL1.AES is 2 or better + InstructionSet_Sha1, // ID_AA64ISAR0_EL1.SHA1 is 1 or better + InstructionSet_Sha256, // ID_AA64ISAR0_EL1.SHA2 is 1 or better + InstructionSet_Sha512, // ID_AA64ISAR0_EL1.SHA2 is 2 or better + InstructionSet_Sha3, // ID_AA64ISAR0_EL1.SHA3 is 1 or better + InstructionSet_Sm3, // ID_AA64ISAR0_EL1.SM3 is 1 or better + InstructionSet_Sm4, // ID_AA64ISAR0_EL1.SM4 is 1 or better + InstructionSet_Sve, // ID_AA64PFR0_EL1.SVE is 1 or better + InstructionSet_Vector64, + InstructionSet_Vector128, +#endif + InstructionSet_NONE // No instruction set is available indicating an invalid value +}; // clang-format on /*****************************************************************************/ diff --git a/src/coreclr/src/jit/jitee.h b/src/coreclr/src/jit/jitee.h index 405ef9a7d7421..473bfc58ff123 100644 --- a/src/coreclr/src/jit/jitee.h +++ b/src/coreclr/src/jit/jitee.h @@ -27,6 +27,7 @@ class JitFlags JIT_FLAG_TARGET_P4 = 9, JIT_FLAG_USE_FCOMI = 10, // Generated code may use fcomi(p) instruction JIT_FLAG_USE_CMOV = 11, // Generated code may use cmov instruction + JIT_FLAG_USE_SSE2 = 12, // Generated code may use SSE-2 instructions #else // !defined(TARGET_X86) @@ -40,10 +41,20 @@ class JitFlags JIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement + #if defined(TARGET_X86) || defined(TARGET_AMD64) + + JIT_FLAG_USE_AVX = 14, + JIT_FLAG_USE_AVX2 = 15, + JIT_FLAG_USE_AVX_512 = 16, + + #else // !defined(TARGET_X86) && !defined(TARGET_AMD64) + JIT_FLAG_UNUSED7 = 14, JIT_FLAG_UNUSED8 = 15, JIT_FLAG_UNUSED9 = 16, + #endif // !defined(TARGET_X86) && !defined(TARGET_AMD64) + #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) JIT_FLAG_FEATURE_SIMD = 17, #else @@ -82,6 +93,57 @@ class JitFlags JIT_FLAG_NO_INLINING = 42, // JIT should not inline any called method into this method +#if defined(TARGET_ARM64) + + JIT_FLAG_HAS_ARM64_AES = 43, // ID_AA64ISAR0_EL1.AES is 1 or better + JIT_FLAG_HAS_ARM64_ATOMICS = 44, // ID_AA64ISAR0_EL1.Atomic is 2 or better + JIT_FLAG_HAS_ARM64_CRC32 = 45, // ID_AA64ISAR0_EL1.CRC32 is 1 or better + JIT_FLAG_HAS_ARM64_DCPOP = 46, // ID_AA64ISAR1_EL1.DPB is 1 or better + JIT_FLAG_HAS_ARM64_DP = 47, // ID_AA64ISAR0_EL1.DP is 1 or better + JIT_FLAG_HAS_ARM64_FCMA = 48, // ID_AA64ISAR1_EL1.FCMA is 1 or better + JIT_FLAG_HAS_ARM64_FP = 49, // ID_AA64PFR0_EL1.FP is 0 or better + JIT_FLAG_HAS_ARM64_FP16 = 50, // ID_AA64PFR0_EL1.FP is 1 or better + JIT_FLAG_HAS_ARM64_JSCVT = 51, // ID_AA64ISAR1_EL1.JSCVT is 1 or better + JIT_FLAG_HAS_ARM64_LRCPC = 52, // ID_AA64ISAR1_EL1.LRCPC is 1 or better + JIT_FLAG_HAS_ARM64_PMULL = 53, // ID_AA64ISAR0_EL1.AES is 2 or better + JIT_FLAG_HAS_ARM64_SHA1 = 54, // ID_AA64ISAR0_EL1.SHA1 is 1 or better + JIT_FLAG_HAS_ARM64_SHA256 = 55, // ID_AA64ISAR0_EL1.SHA2 is 1 or better + JIT_FLAG_HAS_ARM64_SHA512 = 56, // ID_AA64ISAR0_EL1.SHA2 is 2 or better + JIT_FLAG_HAS_ARM64_SHA3 = 57, // ID_AA64ISAR0_EL1.SHA3 is 1 or better + JIT_FLAG_HAS_ARM64_ADVSIMD = 58, // ID_AA64PFR0_EL1.AdvSIMD is 0 or better + JIT_FLAG_HAS_ARM64_ADVSIMD_V81 = 59, // ID_AA64ISAR0_EL1.RDM is 1 or better + JIT_FLAG_HAS_ARM64_ADVSIMD_FP16 = 60, // ID_AA64PFR0_EL1.AdvSIMD is 1 or better + JIT_FLAG_HAS_ARM64_SM3 = 61, // ID_AA64ISAR0_EL1.SM3 is 1 or better + JIT_FLAG_HAS_ARM64_SM4 = 62, // ID_AA64ISAR0_EL1.SM4 is 1 or better + JIT_FLAG_HAS_ARM64_SVE = 63 // ID_AA64PFR0_EL1.SVE is 1 or better + +#elif defined(TARGET_X86) || defined(TARGET_AMD64) + + JIT_FLAG_USE_SSE3 = 43, + JIT_FLAG_USE_SSSE3 = 44, + JIT_FLAG_USE_SSE41 = 45, + JIT_FLAG_USE_SSE42 = 46, + JIT_FLAG_USE_AES = 47, + JIT_FLAG_USE_BMI1 = 48, + JIT_FLAG_USE_BMI2 = 49, + JIT_FLAG_USE_FMA = 50, + JIT_FLAG_USE_LZCNT = 51, + JIT_FLAG_USE_PCLMULQDQ = 52, + JIT_FLAG_USE_POPCNT = 53, + JIT_FLAG_UNUSED23 = 54, + JIT_FLAG_UNUSED24 = 55, + JIT_FLAG_UNUSED25 = 56, + JIT_FLAG_UNUSED26 = 57, + JIT_FLAG_UNUSED27 = 58, + JIT_FLAG_UNUSED28 = 59, + JIT_FLAG_UNUSED29 = 60, + JIT_FLAG_UNUSED30 = 61, + JIT_FLAG_UNUSED31 = 62, + JIT_FLAG_UNUSED32 = 63 + + +#else // !defined(TARGET_ARM64) && !defined(TARGET_X86) && !defined(TARGET_AMD64) + JIT_FLAG_UNUSED12 = 43, JIT_FLAG_UNUSED13 = 44, JIT_FLAG_UNUSED14 = 45, @@ -104,6 +166,8 @@ class JitFlags JIT_FLAG_UNUSED31 = 62, JIT_FLAG_UNUSED32 = 63 +#endif // !defined(TARGET_ARM64) && !defined(TARGET_X86) && !defined(TARGET_AMD64) + }; // clang-format on @@ -123,16 +187,6 @@ class JitFlags m_jitFlags = 0; } - CORINFO_InstructionSetFlags GetInstructionSetFlags() const - { - return m_instructionSetFlags; - } - - void SetInstructionSetFlags(CORINFO_InstructionSetFlags instructionSetFlags) - { - m_instructionSetFlags = instructionSetFlags; - } - void Set(JitFlag flag) { m_jitFlags |= 1ULL << (unsigned __int64)flag; @@ -148,6 +202,16 @@ class JitFlags return (m_jitFlags & (1ULL << (unsigned __int64)flag)) != 0; } + void Add(const JitFlags& other) + { + m_jitFlags |= other.m_jitFlags; + } + + void Remove(const JitFlags& other) + { + m_jitFlags &= ~other.m_jitFlags; + } + bool IsEmpty() const { return m_jitFlags == 0; @@ -158,9 +222,8 @@ class JitFlags // We don't want to have to check every one, so we assume it is exactly the same values as the JitFlag // values defined in this type. m_jitFlags = flags.GetFlagsRaw(); - m_instructionSetFlags.SetFromFlagsRaw(flags.GetInstructionSetFlagsRaw()); - C_ASSERT(sizeof(JitFlags) == sizeof(CORJIT_FLAGS)); + C_ASSERT(sizeof(m_jitFlags) == sizeof(CORJIT_FLAGS)); #define FLAGS_EQUAL(a, b) C_ASSERT((unsigned)(a) == (unsigned)(b)) @@ -179,6 +242,15 @@ class JitFlags FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4, JIT_FLAG_TARGET_P4); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI, JIT_FLAG_USE_FCOMI); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV, JIT_FLAG_USE_CMOV); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2, JIT_FLAG_USE_SSE2); + +#endif + +#if defined(TARGET_X86) || defined(TARGET_AMD64) + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX, JIT_FLAG_USE_AVX); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2, JIT_FLAG_USE_AVX2); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX_512, JIT_FLAG_USE_AVX_512); #endif @@ -218,10 +290,50 @@ class JitFlags #endif // TARGET_ARM FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_NO_INLINING, JIT_FLAG_NO_INLINING); + +#if defined(TARGET_ARM64) + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_AES, JIT_FLAG_HAS_ARM64_AES); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ATOMICS, JIT_FLAG_HAS_ARM64_ATOMICS); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_CRC32, JIT_FLAG_HAS_ARM64_CRC32); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DCPOP, JIT_FLAG_HAS_ARM64_DCPOP); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DP, JIT_FLAG_HAS_ARM64_DP); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FCMA, JIT_FLAG_HAS_ARM64_FCMA); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP, JIT_FLAG_HAS_ARM64_FP); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP16, JIT_FLAG_HAS_ARM64_FP16); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_JSCVT, JIT_FLAG_HAS_ARM64_JSCVT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_LRCPC, JIT_FLAG_HAS_ARM64_LRCPC); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_PMULL, JIT_FLAG_HAS_ARM64_PMULL); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA1, JIT_FLAG_HAS_ARM64_SHA1); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA256, JIT_FLAG_HAS_ARM64_SHA256); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA512, JIT_FLAG_HAS_ARM64_SHA512); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA3, JIT_FLAG_HAS_ARM64_SHA3); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD, JIT_FLAG_HAS_ARM64_ADVSIMD); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD_V81, JIT_FLAG_HAS_ARM64_ADVSIMD_V81); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD_FP16, JIT_FLAG_HAS_ARM64_ADVSIMD_FP16); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM3, JIT_FLAG_HAS_ARM64_SM3); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM4, JIT_FLAG_HAS_ARM64_SM4); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SVE, JIT_FLAG_HAS_ARM64_SVE); + +#elif defined(TARGET_X86) || defined(TARGET_AMD64) + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3, JIT_FLAG_USE_SSE3); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSSE3, JIT_FLAG_USE_SSSE3); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE41, JIT_FLAG_USE_SSE41); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE42, JIT_FLAG_USE_SSE42); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AES, JIT_FLAG_USE_AES); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_BMI1, JIT_FLAG_USE_BMI1); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_BMI2, JIT_FLAG_USE_BMI2); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_FMA, JIT_FLAG_USE_FMA); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_LZCNT, JIT_FLAG_USE_LZCNT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_PCLMULQDQ, JIT_FLAG_USE_PCLMULQDQ); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_POPCNT, JIT_FLAG_USE_POPCNT); + +#endif // TARGET_X86 || TARGET_AMD64 + #undef FLAGS_EQUAL } private: - unsigned __int64 m_jitFlags; - CORINFO_InstructionSetFlags m_instructionSetFlags; + unsigned __int64 m_jitFlags; }; diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index b9de46de1910b..6a695a1185a0a 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -994,11 +994,11 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) // int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) { - NamedIntrinsic intrinsicId = intrinsicTree->gtHWIntrinsicId; - var_types baseType = intrinsicTree->gtSIMDBaseType; - CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); - HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); - int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree); + NamedIntrinsic intrinsicId = intrinsicTree->gtHWIntrinsicId; + var_types baseType = intrinsicTree->gtSIMDBaseType; + InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); + int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree); GenTree* op1 = intrinsicTree->gtGetOp1(); GenTree* op2 = intrinsicTree->gtGetOp2(); diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index 2578cd7fbdc92..19c914e614d91 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -2286,11 +2286,11 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) // int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) { - NamedIntrinsic intrinsicId = intrinsicTree->gtHWIntrinsicId; - var_types baseType = intrinsicTree->gtSIMDBaseType; - CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); - HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); - int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree); + NamedIntrinsic intrinsicId = intrinsicTree->gtHWIntrinsicId; + var_types baseType = intrinsicTree->gtSIMDBaseType; + InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); + int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree); // Set the AVX Flags if this instruction may use VEX encoding for SIMD operations. // Note that this may be true even if the ISA is not AVX (e.g. for platform-agnostic intrinsics diff --git a/src/coreclr/src/jit/simdcodegenxarch.cpp b/src/coreclr/src/jit/simdcodegenxarch.cpp index 8ca69e35be37a..d49fa6008451d 100644 --- a/src/coreclr/src/jit/simdcodegenxarch.cpp +++ b/src/coreclr/src/jit/simdcodegenxarch.cpp @@ -73,6 +73,11 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type { // AVX supports broadcast instructions to populate YMM reg with a single float/double value from memory. // AVX2 supports broadcast instructions to populate YMM reg with a single value from memory or mm reg. + // If we decide to use AVX2 only, we can remove this assert. + if (!compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_USE_AVX2)) + { + assert(baseType == TYP_FLOAT || baseType == TYP_DOUBLE); + } switch (baseType) { case TYP_FLOAT: diff --git a/src/coreclr/src/pal/src/misc/jitsupport.cpp b/src/coreclr/src/pal/src/misc/jitsupport.cpp index 70123f8d18faa..0da36ab8903a6 100644 --- a/src/coreclr/src/pal/src/misc/jitsupport.cpp +++ b/src/coreclr/src/pal/src/misc/jitsupport.cpp @@ -21,11 +21,11 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags) { _ASSERTE(flags); - CORJIT_FLAGS &CPUCompileFlags = *flags; #if defined(HOST_ARM64) #if HAVE_AUXV_HWCAP_H unsigned long hwCap = getauxval(AT_HWCAP); + CORJIT_FLAGS &CPUCompileFlags = *flags; // HWCAP_* flags are introduced by ARM into the Linux kernel as new extensions are published. // For a given kernel, some of these flags may not be present yet. // Use ifdef for each to allow for compilation with any vintage kernel. @@ -34,96 +34,95 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags) // available, using the latest kernel for release should be sufficient. #ifdef HWCAP_AES if (hwCap & HWCAP_AES) - CPUCompileFlags.Set(InstructionSet_Aes); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_AES); #endif #ifdef HWCAP_ATOMICS if (hwCap & HWCAP_ATOMICS) - CPUCompileFlags.Set(InstructionSet_Atomics); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ATOMICS); #endif #ifdef HWCAP_CRC32 if (hwCap & HWCAP_CRC32) - CPUCompileFlags.Set(InstructionSet_Crc32); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_CRC32); #endif #ifdef HWCAP_DCPOP -// if (hwCap & HWCAP_DCPOP) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DCPOP); + if (hwCap & HWCAP_DCPOP) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DCPOP); #endif #ifdef HWCAP_ASIMDDP -// if (hwCap & HWCAP_ASIMDDP) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DP); + if (hwCap & HWCAP_ASIMDDP) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DP); #endif #ifdef HWCAP_FCMA -// if (hwCap & HWCAP_FCMA) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FCMA); + if (hwCap & HWCAP_FCMA) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FCMA); #endif #ifdef HWCAP_FP -// if (hwCap & HWCAP_FP) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); + if (hwCap & HWCAP_FP) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); #endif #ifdef HWCAP_FPHP -// if (hwCap & HWCAP_FPHP) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP16); + if (hwCap & HWCAP_FPHP) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP16); #endif #ifdef HWCAP_JSCVT -// if (hwCap & HWCAP_JSCVT) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_JSCVT); + if (hwCap & HWCAP_JSCVT) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_JSCVT); #endif #ifdef HWCAP_LRCPC -// if (hwCap & HWCAP_LRCPC) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_LRCPC); + if (hwCap & HWCAP_LRCPC) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_LRCPC); #endif #ifdef HWCAP_PMULL -// if (hwCap & HWCAP_PMULL) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_PMULL); + if (hwCap & HWCAP_PMULL) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_PMULL); #endif #ifdef HWCAP_SHA1 if (hwCap & HWCAP_SHA1) - CPUCompileFlags.Set(InstructionSet_Sha1); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA1); #endif #ifdef HWCAP_SHA2 if (hwCap & HWCAP_SHA2) - CPUCompileFlags.Set(InstructionSet_Sha256); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA256); #endif #ifdef HWCAP_SHA512 -// if (hwCap & HWCAP_SHA512) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA512); + if (hwCap & HWCAP_SHA512) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA512); #endif #ifdef HWCAP_SHA3 -// if (hwCap & HWCAP_SHA3) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA3); + if (hwCap & HWCAP_SHA3) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA3); #endif #ifdef HWCAP_ASIMD if (hwCap & HWCAP_ASIMD) - CPUCompileFlags.Set(InstructionSet_AdvSimd); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD); #endif #ifdef HWCAP_ASIMDRDM -// if (hwCap & HWCAP_ASIMDRDM) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD_V81); + if (hwCap & HWCAP_ASIMDRDM) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD_V81); #endif #ifdef HWCAP_ASIMDHP -// if (hwCap & HWCAP_ASIMDHP) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD_FP16); + if (hwCap & HWCAP_ASIMDHP) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD_FP16); #endif #ifdef HWCAP_SM3 -// if (hwCap & HWCAP_SM3) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM3); + if (hwCap & HWCAP_SM3) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM3); #endif #ifdef HWCAP_SM4 -// if (hwCap & HWCAP_SM4) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM4); + if (hwCap & HWCAP_SM4) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM4); #endif #ifdef HWCAP_SVE -// if (hwCap & HWCAP_SVE) -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SVE); + if (hwCap & HWCAP_SVE) + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SVE); #endif #else // !HAVE_AUXV_HWCAP_H // CoreCLR SIMD and FP support is included in ARM64 baseline // On exceptional basis platforms may leave out support, but CoreCLR does not // yet support such platforms // Set baseline flags if OS has not exposed mechanism for us to determine CPU capabilities - CPUCompileFlags.Set(InstructionSet_AdvSimd); -// CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); #endif // HAVE_AUXV_HWCAP_H #endif // defined(HOST_ARM64) - CPUCompileFlags.Set64BitInstructionSetVariants(); } diff --git a/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs b/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs deleted file mode 100644 index aff37abdf06ac..0000000000000 --- a/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs +++ /dev/null @@ -1,134 +0,0 @@ - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -using System; -using System.Runtime.InteropServices; -using Internal.TypeSystem; - -namespace Internal.ReadyToRunConstants -{ - public enum ReadyToRunInstructionSet - { - Sse=1, - Sse2=2, - Sse3=3, - Ssse3=4, - Sse41=5, - Sse42=6, - Avx=7, - Avx2=8, - Aes=9, - Bmi1=10, - Bmi2=11, - Fma=12, - Lzcnt=13, - Pclmulqdq=14, - Popcnt=15, - ArmBase=16, - AdvSimd=17, - Crc32=18, - Sha1=19, - Sha256=20, - Atomics=21, - - } - - public static class ReadyToRunInstructionSetHelper - { - ReadyToRunInstructionSet? R2RInstructionSetFromJitInstructionSet(TargetArchitecture architecture, Internal.JitInterface.InstructionSet instructionSet) - { - switch (architecture) - { - - case TargetArchitecture.ARM64: - { - switch (instructionSet) - { - case InstructionSet.ARM64_ArmBase: return ReadyToRunInstructionSet.ArmBase; - case InstructionSet.ARM64_ArmBase_Arm64: return ReadyToRunInstructionSet.ArmBase; - case InstructionSet.ARM64_AdvSimd: return ReadyToRunInstructionSet.AdvSimd; - case InstructionSet.ARM64_AdvSimd_Arm64: return ReadyToRunInstructionSet.AdvSimd; - case InstructionSet.ARM64_Aes: return ReadyToRunInstructionSet.Aes; - case InstructionSet.ARM64_Crc32: return ReadyToRunInstructionSet.Crc32; - case InstructionSet.ARM64_Crc32_Arm64: return ReadyToRunInstructionSet.Crc32; - case InstructionSet.ARM64_Sha1: return ReadyToRunInstructionSet.Sha1; - case InstructionSet.ARM64_Sha256: return ReadyToRunInstructionSet.Sha256; - case InstructionSet.ARM64_Atomics: return ReadyToRunInstructionSet.Atomics; - case InstructionSet.ARM64_Vector64: return null; - case InstructionSet.ARM64_Vector128: return null; - - default: throw new Exception("Unknown instruction set"); - } - } - - case TargetArchitecture.X64: - { - switch (instructionSet) - { - case InstructionSet.X64_SSE: return ReadyToRunInstructionSet.Sse; - case InstructionSet.X64_SSE_X64: return ReadyToRunInstructionSet.Sse; - case InstructionSet.X64_SSE2: return ReadyToRunInstructionSet.Sse2; - case InstructionSet.X64_SSE2_X64: return ReadyToRunInstructionSet.Sse2; - case InstructionSet.X64_SSE3: return ReadyToRunInstructionSet.Sse3; - case InstructionSet.X64_SSSE3: return ReadyToRunInstructionSet.Ssse3; - case InstructionSet.X64_SSE41: return ReadyToRunInstructionSet.Sse41; - case InstructionSet.X64_SSE41_X64: return ReadyToRunInstructionSet.Sse41; - case InstructionSet.X64_SSE42: return ReadyToRunInstructionSet.Sse42; - case InstructionSet.X64_SSE42_X64: return ReadyToRunInstructionSet.Sse42; - case InstructionSet.X64_AVX: return ReadyToRunInstructionSet.Avx; - case InstructionSet.X64_AVX2: return ReadyToRunInstructionSet.Avx2; - case InstructionSet.X64_AES: return ReadyToRunInstructionSet.Aes; - case InstructionSet.X64_BMI1: return ReadyToRunInstructionSet.Bmi1; - case InstructionSet.X64_BMI1_X64: return ReadyToRunInstructionSet.Bmi1; - case InstructionSet.X64_BMI2: return ReadyToRunInstructionSet.Bmi2; - case InstructionSet.X64_BMI2_X64: return ReadyToRunInstructionSet.Bmi2; - case InstructionSet.X64_FMA: return ReadyToRunInstructionSet.Fma; - case InstructionSet.X64_LZCNT: return ReadyToRunInstructionSet.Lzcnt; - case InstructionSet.X64_LZCNT_X64: return ReadyToRunInstructionSet.Lzcnt; - case InstructionSet.X64_PCLMULQDQ: return ReadyToRunInstructionSet.Pclmulqdq; - case InstructionSet.X64_POPCNT: return ReadyToRunInstructionSet.Popcnt; - case InstructionSet.X64_POPCNT_X64: return ReadyToRunInstructionSet.Popcnt; - case InstructionSet.X64_Vector128: return null; - case InstructionSet.X64_Vector256: return null; - - default: throw new Exception("Unknown instruction set"); - } - } - - case TargetArchitecture.X86: - { - switch (instructionSet) - { - case InstructionSet.X86_SSE: return ReadyToRunInstructionSet.Sse; - case InstructionSet.X86_SSE2: return ReadyToRunInstructionSet.Sse2; - case InstructionSet.X86_SSE3: return ReadyToRunInstructionSet.Sse3; - case InstructionSet.X86_SSSE3: return ReadyToRunInstructionSet.Ssse3; - case InstructionSet.X86_SSE41: return ReadyToRunInstructionSet.Sse41; - case InstructionSet.X86_SSE42: return ReadyToRunInstructionSet.Sse42; - case InstructionSet.X86_AVX: return ReadyToRunInstructionSet.Avx; - case InstructionSet.X86_AVX2: return ReadyToRunInstructionSet.Avx2; - case InstructionSet.X86_AES: return ReadyToRunInstructionSet.Aes; - case InstructionSet.X86_BMI1: return ReadyToRunInstructionSet.Bmi1; - case InstructionSet.X86_BMI2: return ReadyToRunInstructionSet.Bmi2; - case InstructionSet.X86_FMA: return ReadyToRunInstructionSet.Fma; - case InstructionSet.X86_LZCNT: return ReadyToRunInstructionSet.Lzcnt; - case InstructionSet.X86_PCLMULQDQ: return ReadyToRunInstructionSet.Pclmulqdq; - case InstructionSet.X86_POPCNT: return ReadyToRunInstructionSet.Popcnt; - case InstructionSet.X86_Vector128: return null; - case InstructionSet.X86_Vector256: return null; - - default: throw new Exception("Unknown instruction set"); - } - } - - default: throw new Exception("Unknown architecture"); - } - } - } -} diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index 5dfeee4a7676e..1fadcd5cda5f1 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -2854,36 +2854,13 @@ private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes) if (targetArchitecture == TargetArchitecture.ARM && !_compilation.TypeSystemContext.Target.IsWindows) flags.Set(CorJitFlag.CORJIT_FLAG_RELATIVE_CODE_RELOCS); - if (targetArchitecture == TargetArchitecture.X86) - { - flags.Set(InstructionSet.X86_SSE); - flags.Set(InstructionSet.X86_SSE2); -#if !READYTORUN - // This list needs to match the list of intrinsics we can generate detection code for - // in HardwareIntrinsicHelpers.EmitIsSupportedIL. -#else - // For ReadyToRun, this list needs to match up with the behavior of FilterNamedIntrinsicMethodAttribs - // In particular, that this list of supported hardware will not generate non-SSE2 safe instruction - // sequences when paired with the behavior in FilterNamedIntrinsicMethodAttribs - if (isMethodDefinedInCoreLib()) -#endif - { - flags.Set(InstructionSet.X86_AES); - flags.Set(InstructionSet.X86_PCLMULQDQ); - flags.Set(InstructionSet.X86_SSE3); - flags.Set(InstructionSet.X86_SSSE3); - flags.Set(InstructionSet.X86_LZCNT); + if ((targetArchitecture == TargetArchitecture.X86 + || targetArchitecture == TargetArchitecture.X64) #if READYTORUN - flags.Set(InstructionSet.X86_SSE41); - flags.Set(InstructionSet.X86_SSE42); - flags.Set(InstructionSet.X86_POPCNT); + && isMethodDefinedInCoreLib() #endif - } - } - else if (targetArchitecture == TargetArchitecture.X64) + ) { - flags.Set(InstructionSet.X64_SSE); - flags.Set(InstructionSet.X64_SSE2); #if !READYTORUN // This list needs to match the list of intrinsics we can generate detection code for // in HardwareIntrinsicHelpers.EmitIsSupportedIL. @@ -2891,29 +2868,19 @@ private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes) // For ReadyToRun, this list needs to match up with the behavior of FilterNamedIntrinsicMethodAttribs // In particular, that this list of supported hardware will not generate non-SSE2 safe instruction // sequences when paired with the behavior in FilterNamedIntrinsicMethodAttribs - if (isMethodDefinedInCoreLib()) #endif - { - flags.Set(InstructionSet.X64_AES); - flags.Set(InstructionSet.X64_PCLMULQDQ); - flags.Set(InstructionSet.X64_SSE3); - flags.Set(InstructionSet.X64_SSSE3); - flags.Set(InstructionSet.X64_LZCNT); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_AES); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_PCLMULQDQ); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_SSE3); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_SSSE3); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_LZCNT); #if READYTORUN - flags.Set(InstructionSet.X64_SSE41); - flags.Set(InstructionSet.X64_SSE42); - flags.Set(InstructionSet.X64_POPCNT); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_SSE41); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_SSE42); + flags.Set(CorJitFlag.CORJIT_FLAG_USE_POPCNT); #endif - } - } - else if (targetArchitecture == TargetArchitecture.ARM64) - { - flags.Set(InstructionSet.ARM64_ArmBase); - flags.Set(InstructionSet.ARM64_AdvSimd); } - flags.Set64BitInstructionSetVariants(targetArchitecture); - if (this.MethodBeingCompiled.IsNativeCallable) { #if READYTORUN diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs deleted file mode 100644 index 470faeb0713ba..0000000000000 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs +++ /dev/null @@ -1,317 +0,0 @@ - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using Internal.TypeSystem; - -namespace Internal.JitInterface -{ - public enum InstructionSet - { - ILLEGAL = 0, - NONE = 63, - ARM64_ArmBase=1, - ARM64_ArmBase_Arm64=2, - ARM64_AdvSimd=3, - ARM64_AdvSimd_Arm64=4, - ARM64_Aes=5, - ARM64_Crc32=6, - ARM64_Crc32_Arm64=7, - ARM64_Sha1=8, - ARM64_Sha256=9, - ARM64_Atomics=10, - ARM64_Vector64=11, - ARM64_Vector128=12, - X64_SSE=1, - X64_SSE2=2, - X64_SSE3=3, - X64_SSSE3=4, - X64_SSE41=5, - X64_SSE42=6, - X64_AVX=7, - X64_AVX2=8, - X64_AES=9, - X64_BMI1=10, - X64_BMI2=11, - X64_FMA=12, - X64_LZCNT=13, - X64_PCLMULQDQ=14, - X64_POPCNT=15, - X64_Vector128=16, - X64_Vector256=17, - X64_BMI1_X64=18, - X64_BMI2_X64=19, - X64_LZCNT_X64=20, - X64_POPCNT_X64=21, - X64_SSE_X64=22, - X64_SSE2_X64=23, - X64_SSE41_X64=24, - X64_SSE42_X64=25, - X86_SSE=1, - X86_SSE2=2, - X86_SSE3=3, - X86_SSSE3=4, - X86_SSE41=5, - X86_SSE42=6, - X86_AVX=7, - X86_AVX2=8, - X86_AES=9, - X86_BMI1=10, - X86_BMI2=11, - X86_FMA=12, - X86_LZCNT=13, - X86_PCLMULQDQ=14, - X86_POPCNT=15, - X86_Vector128=16, - X86_Vector256=17, - X86_BMI1_X64=18, - X86_BMI2_X64=19, - X86_LZCNT_X64=20, - X86_POPCNT_X64=21, - X86_SSE_X64=22, - X86_SSE2_X64=23, - X86_SSE41_X64=24, - X86_SSE42_X64=25, - - } - - public struct InstructionSetFlags - { - ulong _flags; - - public void AddInstructionSet(InstructionSet instructionSet) - { - _flags = _flags | (((ulong)1) << (int)instructionSet); - } - - public void RemoveInstructionSet(InstructionSet instructionSet) - { - _flags = _flags & ~(((ulong)1) << (int)instructionSet); - } - - public bool HasInstructionSet(InstructionSet instructionSet) - { - return (_flags & (((ulong)1) << (int)instructionSet)) != 0; - } - - public bool Equals(InstructionSetFlags other) - { - return _flags == other._flags; - } - - public static InstructionSetFlags ExpandInstructionSetByImplication(TargetArchitecture architecture, InstructionSetFlags input) - { - InstructionSetFlags oldflags = input; - InstructionSetFlags resultflags = input; - do - { - oldflags = resultflags; - switch(architecture) - { - - case TargetArchitecture.ARM64: - if (resultflags.HasInstructionSet(InstructionSet.ARM64_ArmBase)) - resultflags.AddInstructionSet(InstructionSet.ARM64_ArmBase_Arm64); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_AdvSimd)) - resultflags.AddInstructionSet(InstructionSet.ARM64_AdvSimd_Arm64); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_Crc32)) - resultflags.AddInstructionSet(InstructionSet.ARM64_Crc32_Arm64); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_AdvSimd)) - resultflags.AddInstructionSet(InstructionSet.ARM64_ArmBase); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_Aes)) - resultflags.AddInstructionSet(InstructionSet.ARM64_ArmBase); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_Crc32)) - resultflags.AddInstructionSet(InstructionSet.ARM64_ArmBase); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_Sha1)) - resultflags.AddInstructionSet(InstructionSet.ARM64_ArmBase); - if (resultflags.HasInstructionSet(InstructionSet.ARM64_Sha256)) - resultflags.AddInstructionSet(InstructionSet.ARM64_ArmBase); - break; - - case TargetArchitecture.X64: - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE2)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE2_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE41)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE41_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE42)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE42_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_BMI1)) - resultflags.AddInstructionSet(InstructionSet.X64_BMI1_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_BMI2)) - resultflags.AddInstructionSet(InstructionSet.X64_BMI2_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_LZCNT)) - resultflags.AddInstructionSet(InstructionSet.X64_LZCNT_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_POPCNT)) - resultflags.AddInstructionSet(InstructionSet.X64_POPCNT_X64); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE2)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE3)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE2); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSSE3)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE3); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE41)) - resultflags.AddInstructionSet(InstructionSet.X64_SSSE3); - if (resultflags.HasInstructionSet(InstructionSet.X64_SSE42)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE41); - if (resultflags.HasInstructionSet(InstructionSet.X64_AVX)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE42); - if (resultflags.HasInstructionSet(InstructionSet.X64_AVX2)) - resultflags.AddInstructionSet(InstructionSet.X64_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X64_AES)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE2); - if (resultflags.HasInstructionSet(InstructionSet.X64_BMI1)) - resultflags.AddInstructionSet(InstructionSet.X64_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X64_BMI2)) - resultflags.AddInstructionSet(InstructionSet.X64_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X64_FMA)) - resultflags.AddInstructionSet(InstructionSet.X64_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X64_PCLMULQDQ)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE2); - if (resultflags.HasInstructionSet(InstructionSet.X64_POPCNT)) - resultflags.AddInstructionSet(InstructionSet.X64_SSE42); - break; - - case TargetArchitecture.X86: - if (resultflags.HasInstructionSet(InstructionSet.X86_SSE2)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE); - if (resultflags.HasInstructionSet(InstructionSet.X86_SSE3)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE2); - if (resultflags.HasInstructionSet(InstructionSet.X86_SSSE3)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE3); - if (resultflags.HasInstructionSet(InstructionSet.X86_SSE41)) - resultflags.AddInstructionSet(InstructionSet.X86_SSSE3); - if (resultflags.HasInstructionSet(InstructionSet.X86_SSE42)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE41); - if (resultflags.HasInstructionSet(InstructionSet.X86_AVX)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE42); - if (resultflags.HasInstructionSet(InstructionSet.X86_AVX2)) - resultflags.AddInstructionSet(InstructionSet.X86_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X86_AES)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE2); - if (resultflags.HasInstructionSet(InstructionSet.X86_BMI1)) - resultflags.AddInstructionSet(InstructionSet.X86_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X86_BMI2)) - resultflags.AddInstructionSet(InstructionSet.X86_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X86_FMA)) - resultflags.AddInstructionSet(InstructionSet.X86_AVX); - if (resultflags.HasInstructionSet(InstructionSet.X86_PCLMULQDQ)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE2); - if (resultflags.HasInstructionSet(InstructionSet.X86_POPCNT)) - resultflags.AddInstructionSet(InstructionSet.X86_SSE42); - break; - - } - } while (!oldflags.Equals(resultflags)); - return resultflags; - } - - public static IEnumerable> ArchitectureToValidInstructionSets(TargetArchitecture architecture) - { - switch (architecture) - { - - case TargetArchitecture.ARM64: - yield return new KeyValuePair("ArmBase", InstructionSet.ARM64_ArmBase); - yield return new KeyValuePair("AdvSimd", InstructionSet.ARM64_AdvSimd); - yield return new KeyValuePair("Aes", InstructionSet.ARM64_Aes); - yield return new KeyValuePair("Crc32", InstructionSet.ARM64_Crc32); - yield return new KeyValuePair("Sha1", InstructionSet.ARM64_Sha1); - yield return new KeyValuePair("Sha256", InstructionSet.ARM64_Sha256); - yield return new KeyValuePair("Atomics", InstructionSet.ARM64_Atomics); - yield return new KeyValuePair("Vector64", InstructionSet.ARM64_Vector64); - yield return new KeyValuePair("Vector128", InstructionSet.ARM64_Vector128); - break; - - case TargetArchitecture.X64: - yield return new KeyValuePair("Sse", InstructionSet.X64_SSE); - yield return new KeyValuePair("Sse2", InstructionSet.X64_SSE2); - yield return new KeyValuePair("Sse3", InstructionSet.X64_SSE3); - yield return new KeyValuePair("Ssse3", InstructionSet.X64_SSSE3); - yield return new KeyValuePair("Sse41", InstructionSet.X64_SSE41); - yield return new KeyValuePair("Sse42", InstructionSet.X64_SSE42); - yield return new KeyValuePair("Avx", InstructionSet.X64_AVX); - yield return new KeyValuePair("Avx2", InstructionSet.X64_AVX2); - yield return new KeyValuePair("Aes", InstructionSet.X64_AES); - yield return new KeyValuePair("Bmi1", InstructionSet.X64_BMI1); - yield return new KeyValuePair("Bmi2", InstructionSet.X64_BMI2); - yield return new KeyValuePair("Fma", InstructionSet.X64_FMA); - yield return new KeyValuePair("Lzcnt", InstructionSet.X64_LZCNT); - yield return new KeyValuePair("Pclmulqdq", InstructionSet.X64_PCLMULQDQ); - yield return new KeyValuePair("Popcnt", InstructionSet.X64_POPCNT); - yield return new KeyValuePair("Vector128", InstructionSet.X64_Vector128); - yield return new KeyValuePair("Vector256", InstructionSet.X64_Vector256); - break; - - case TargetArchitecture.X86: - yield return new KeyValuePair("Sse", InstructionSet.X86_SSE); - yield return new KeyValuePair("Sse2", InstructionSet.X86_SSE2); - yield return new KeyValuePair("Sse3", InstructionSet.X86_SSE3); - yield return new KeyValuePair("Ssse3", InstructionSet.X86_SSSE3); - yield return new KeyValuePair("Sse41", InstructionSet.X86_SSE41); - yield return new KeyValuePair("Sse42", InstructionSet.X86_SSE42); - yield return new KeyValuePair("Avx", InstructionSet.X86_AVX); - yield return new KeyValuePair("Avx2", InstructionSet.X86_AVX2); - yield return new KeyValuePair("Aes", InstructionSet.X86_AES); - yield return new KeyValuePair("Bmi1", InstructionSet.X86_BMI1); - yield return new KeyValuePair("Bmi2", InstructionSet.X86_BMI2); - yield return new KeyValuePair("Fma", InstructionSet.X86_FMA); - yield return new KeyValuePair("Lzcnt", InstructionSet.X86_LZCNT); - yield return new KeyValuePair("Pclmulqdq", InstructionSet.X86_PCLMULQDQ); - yield return new KeyValuePair("Popcnt", InstructionSet.X86_POPCNT); - yield return new KeyValuePair("Vector128", InstructionSet.X86_Vector128); - yield return new KeyValuePair("Vector256", InstructionSet.X86_Vector256); - break; - - } - } - - public void Set64BitInstructionSetVariants(TargetArchitecture architecture) - { - switch (architecture) - { - - case TargetArchitecture.ARM64: - if (HasInstructionSet(InstructionSet.ARM64_ArmBase)) - AddInstructionSet(InstructionSet.ARM64_ArmBase_Arm64); - if (HasInstructionSet(InstructionSet.ARM64_AdvSimd)) - AddInstructionSet(InstructionSet.ARM64_AdvSimd_Arm64); - if (HasInstructionSet(InstructionSet.ARM64_Crc32)) - AddInstructionSet(InstructionSet.ARM64_Crc32_Arm64); - break; - - case TargetArchitecture.X64: - if (HasInstructionSet(InstructionSet.X64_SSE)) - AddInstructionSet(InstructionSet.X64_SSE_X64); - if (HasInstructionSet(InstructionSet.X64_SSE2)) - AddInstructionSet(InstructionSet.X64_SSE2_X64); - if (HasInstructionSet(InstructionSet.X64_SSE41)) - AddInstructionSet(InstructionSet.X64_SSE41_X64); - if (HasInstructionSet(InstructionSet.X64_SSE42)) - AddInstructionSet(InstructionSet.X64_SSE42_X64); - if (HasInstructionSet(InstructionSet.X64_BMI1)) - AddInstructionSet(InstructionSet.X64_BMI1_X64); - if (HasInstructionSet(InstructionSet.X64_BMI2)) - AddInstructionSet(InstructionSet.X64_BMI2_X64); - if (HasInstructionSet(InstructionSet.X64_LZCNT)) - AddInstructionSet(InstructionSet.X64_LZCNT_X64); - if (HasInstructionSet(InstructionSet.X64_POPCNT)) - AddInstructionSet(InstructionSet.X64_POPCNT_X64); - break; - - case TargetArchitecture.X86: - break; - - } - } - } -} diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs index 64d4a0649dfa0..1647c4fb75da5 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; -using Internal.TypeSystem; namespace Internal.JitInterface { @@ -1297,6 +1296,9 @@ public enum CorJitFlag : uint CORJIT_FLAG_UNUSED4 = 11, CORJIT_FLAG_UNUSED5 = 12, CORJIT_FLAG_UNUSED6 = 13, + CORJIT_FLAG_USE_AVX = 14, + CORJIT_FLAG_USE_AVX2 = 15, + CORJIT_FLAG_USE_AVX_512 = 16, CORJIT_FLAG_FEATURE_SIMD = 17, CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter. CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation @@ -1323,12 +1325,49 @@ public enum CorJitFlag : uint CORJIT_FLAG_TIER1 = 40, // This is the final tier (for now) for tiered compilation which should generate high quality code CORJIT_FLAG_RELATIVE_CODE_RELOCS = 41, // JIT should generate PC-relative address computations instead of EE relocation records CORJIT_FLAG_NO_INLINING = 42, // JIT should not inline any called method into this method + +#region TARGET_ARM64 + CORJIT_FLAG_HAS_ARM64_AES = 43, // ID_AA64ISAR0_EL1.AES is 1 or better + CORJIT_FLAG_HAS_ARM64_ATOMICS = 44, // ID_AA64ISAR0_EL1.Atomic is 2 or better + CORJIT_FLAG_HAS_ARM64_CRC32 = 45, // ID_AA64ISAR0_EL1.CRC32 is 1 or better + CORJIT_FLAG_HAS_ARM64_DCPOP = 46, // ID_AA64ISAR1_EL1.DPB is 1 or better + CORJIT_FLAG_HAS_ARM64_DP = 47, // ID_AA64ISAR0_EL1.DP is 1 or better + CORJIT_FLAG_HAS_ARM64_FCMA = 48, // ID_AA64ISAR1_EL1.FCMA is 1 or better + CORJIT_FLAG_HAS_ARM64_FP = 49, // ID_AA64PFR0_EL1.FP is 0 or better + CORJIT_FLAG_HAS_ARM64_FP16 = 50, // ID_AA64PFR0_EL1.FP is 1 or better + CORJIT_FLAG_HAS_ARM64_JSCVT = 51, // ID_AA64ISAR1_EL1.JSCVT is 1 or better + CORJIT_FLAG_HAS_ARM64_LRCPC = 52, // ID_AA64ISAR1_EL1.LRCPC is 1 or better + CORJIT_FLAG_HAS_ARM64_PMULL = 53, // ID_AA64ISAR0_EL1.AES is 2 or better + CORJIT_FLAG_HAS_ARM64_SHA1 = 54, // ID_AA64ISAR0_EL1.SHA1 is 1 or better + CORJIT_FLAG_HAS_ARM64_SHA256 = 55, // ID_AA64ISAR0_EL1.SHA2 is 1 or better + CORJIT_FLAG_HAS_ARM64_SHA512 = 56, // ID_AA64ISAR0_EL1.SHA2 is 2 or better + CORJIT_FLAG_HAS_ARM64_SHA3 = 57, // ID_AA64ISAR0_EL1.SHA3 is 1 or better + CORJIT_FLAG_HAS_ARM64_SIMD = 58, // ID_AA64PFR0_EL1.AdvSIMD is 0 or better + CORJIT_FLAG_HAS_ARM64_SIMD_V81 = 59, // ID_AA64ISAR0_EL1.RDM is 1 or better + CORJIT_FLAG_HAS_ARM64_SIMD_FP16 = 60, // ID_AA64PFR0_EL1.AdvSIMD is 1 or better + CORJIT_FLAG_HAS_ARM64_SM3 = 61, // ID_AA64ISAR0_EL1.SM3 is 1 or better + CORJIT_FLAG_HAS_ARM64_SM4 = 62, // ID_AA64ISAR0_EL1.SM4 is 1 or better + CORJIT_FLAG_HAS_ARM64_SVE = 63, // ID_AA64PFR0_EL1.SVE is 1 or better +#endregion + +#region x86/x64 + CORJIT_FLAG_USE_SSE3 = 43, + CORJIT_FLAG_USE_SSSE3 = 44, + CORJIT_FLAG_USE_SSE41 = 45, + CORJIT_FLAG_USE_SSE42 = 46, + CORJIT_FLAG_USE_AES = 47, + CORJIT_FLAG_USE_BMI1 = 48, + CORJIT_FLAG_USE_BMI2 = 49, + CORJIT_FLAG_USE_FMA = 50, + CORJIT_FLAG_USE_LZCNT = 51, + CORJIT_FLAG_USE_PCLMULQDQ = 52, + CORJIT_FLAG_USE_POPCNT = 53, +#endregion } public struct CORJIT_FLAGS { private UInt64 _corJitFlags; - InstructionSetFlags _instructionSetFlags; public void Reset() { @@ -1340,11 +1379,6 @@ public void Set(CorJitFlag flag) _corJitFlags |= 1UL << (int)flag; } - public void Set(InstructionSet instructionSet) - { - _instructionSetFlags.AddInstructionSet(instructionSet); - } - public void Clear(CorJitFlag flag) { _corJitFlags &= ~(1UL << (int)flag); @@ -1355,9 +1389,19 @@ public bool IsSet(CorJitFlag flag) return (_corJitFlags & (1UL << (int)flag)) != 0; } - public void Set64BitInstructionSetVariants(TargetArchitecture architecture) + public void Add(ref CORJIT_FLAGS other) + { + _corJitFlags |= other._corJitFlags; + } + + public void Remove(ref CORJIT_FLAGS other) + { + _corJitFlags &= ~other._corJitFlags; + } + + public bool IsEmpty() { - _instructionSetFlags.Set64BitInstructionSetVariants(architecture); + return _corJitFlags == 0; } } } diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt deleted file mode 100644 index 9c8404fe8969f..0000000000000 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt +++ /dev/null @@ -1,81 +0,0 @@ -; Define the set of instruction sets available on a platform -; Format is -; -; Add new instruction set -; instructionset,,,,, -; -; Add jit 64bit architecture specific instruction set when instruction set is available -; instructionset64bit,, -; -; Add an instruction set implication (i.e, if instruction set A is present, then instruction set B must be present too.) -; implication,,, -; -; Copy instruction sets defined for other architecture at this point in the file. -; copyinstructionsets,, - -; Definition of X86 instruction sets - -definearch ,X86 ,32Bit ,X64 -instructionset ,X86 ,Sse , ,1 ,SSE -instructionset ,X86 ,Sse2 , ,2 ,SSE2 -implication ,X86 ,SSE2 ,SSE -instructionset ,X86 ,Sse3 , ,3 ,SSE3 -implication ,X86 ,SSE3 ,SSE2 -instructionset ,X86 ,Ssse3 , ,4 ,SSSE3 -implication ,X86 ,SSSE3 ,SSE3 -instructionset ,X86 ,Sse41 , ,5 ,SSE41 -implication ,X86 ,SSE41 ,SSSE3 -instructionset ,X86 ,Sse42 , ,6 ,SSE42 -implication ,X86 ,SSE42 ,SSE41 -instructionset ,X86 ,Avx , ,7 ,AVX -implication ,X86 ,AVX ,SSE42 -instructionset ,X86 ,Avx2 , ,8 ,AVX2 -implication ,X86 ,AVX2 ,AVX -instructionset ,X86 ,Aes , ,9 ,AES -implication ,X86 ,AES ,SSE2 -instructionset ,X86 ,Bmi1 , ,10 ,BMI1 -implication ,X86 ,BMI1 ,AVX -instructionset ,X86 ,Bmi2 , ,11 ,BMI2 -implication ,X86 ,BMI2 ,AVX -instructionset ,X86 ,Fma , ,12 ,FMA -implication ,X86 ,FMA ,AVX -instructionset ,X86 ,Lzcnt , ,13 ,LZCNT -instructionset ,X86 ,Pclmulqdq , ,14 ,PCLMULQDQ -implication ,X86 ,PCLMULQDQ ,SSE2 -instructionset ,X86 ,Popcnt , ,15 ,POPCNT -implication ,X86 ,POPCNT ,SSE42 -instructionset ,X86 , , , ,Vector128 -instructionset ,X86 , , , ,Vector256 - -; Definition of X64 instruction sets (Define ) -definearch ,X64 ,64Bit ,X64 -instructionset64bit,X86 ,BMI1 -instructionset64bit,X86 ,BMI2 -instructionset64bit,X86 ,LZCNT -instructionset64bit,X86 ,POPCNT -instructionset64bit,X86 ,SSE -instructionset64bit,X86 ,SSE2 -instructionset64bit,X86 ,SSE41 -instructionset64bit,X86 ,SSE42 - -copyinstructionsets,X86 ,X64 - -; Definition of the Arm64 instruction sets -definearch ,ARM64 ,64Bit ,Arm64 -instructionset ,ARM64 ,ArmBase , ,16 ,ArmBase -instructionset64bit,ARM64 ,ArmBase -instructionset ,ARM64 ,AdvSimd , ,17 ,AdvSimd -instructionset64bit,ARM64 ,AdvSimd -implication ,ARM64 ,AdvSimd ,ArmBase -instructionset ,ARM64 ,Aes , ,9 ,Aes -implication ,ARM64 ,Aes ,ArmBase -instructionset ,ARM64 ,Crc32 , ,18 ,Crc32 -instructionset64bit,ARM64 ,Crc32 -implication ,ARM64 ,Crc32 ,ArmBase -instructionset ,ARM64 ,Sha1 , ,19 ,Sha1 -implication ,ARM64 ,Sha1 ,ArmBase -instructionset ,ARM64 ,Sha256 , ,20 ,Sha256 -implication ,ARM64 ,Sha256 ,ArmBase -instructionset ,ARM64 , ,Atomics ,21 ,Atomics -instructionset ,ARM64 , , , ,Vector64 -instructionset ,ARM64 , , , ,Vector128 diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs deleted file mode 100644 index 3d5ea118732e3..0000000000000 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs +++ /dev/null @@ -1,645 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using System.Diagnostics; - -namespace Thunkerator -{ - public class InstructionSetGenerator - { - class InstructionSetInfo - { - public string Architecture { get; } - public string ManagedName { get; } - public string R2rName { get; } - public string R2rNumericValue { get; } - public string JitName { get; } - - public InstructionSetInfo(string architecture, string managedName, string r2rName, string r2rNumericValue, string jitName) - { - Architecture = architecture; - ManagedName = managedName; - R2rName = String.IsNullOrEmpty(r2rName) ? managedName : r2rName; - R2rNumericValue = r2rNumericValue; - JitName = jitName; - } - - public InstructionSetInfo(string architecture, InstructionSetInfo similarInstructionSet) - { - Architecture = architecture; - ManagedName = similarInstructionSet.ManagedName; - R2rName = similarInstructionSet.R2rName; - R2rNumericValue = similarInstructionSet.R2rNumericValue; - JitName = similarInstructionSet.JitName; - } - - public string PublicName - { - get - { - if (!String.IsNullOrEmpty(ManagedName)) - return ManagedName; - else if (!String.IsNullOrEmpty(R2rName)) - return R2rName; - else - return JitName; - } - } - } - - class InstructionSetImplication - { - public string Architecture { get; } - public string JitName { get; } - public string ImpliedJitName { get; } - - public InstructionSetImplication(string architecture, string jitName, string impliedJitName) - { - Architecture = architecture; - JitName = jitName; - ImpliedJitName = impliedJitName; - } - - public InstructionSetImplication(string architecture, InstructionSetImplication similarInstructionSet) - { - Architecture = architecture; - ImpliedJitName = similarInstructionSet.ImpliedJitName; - JitName = similarInstructionSet.JitName; - } - } - - List _instructionSets = new List(); - List _implications = new List(); - Dictionary> _64bitVariants = new Dictionary>(); - SortedDictionary _r2rNamesByName = new SortedDictionary(); - SortedDictionary _r2rNamesByNumber = new SortedDictionary(); - SortedSet _architectures = new SortedSet(); - Dictionary> _architectureJitNames = new Dictionary>(); - HashSet _64BitArchitectures = new HashSet(); - Dictionary _64BitVariantArchitectureJitNameSuffix = new Dictionary(); - - void ArchitectureEncountered(string arch) - { - if (!_64bitVariants.ContainsKey(arch)) - _64bitVariants.Add(arch, new HashSet()); - _architectures.Add(arch); - if (!_architectureJitNames.ContainsKey(arch)) - _architectureJitNames.Add(arch, new List()); - } - - void ValidateArchitectureEncountered(string arch) - { - if (!_architectures.Contains(arch)) - throw new Exception("Architecture not defined"); - } - - private string ArchToIfDefArch(string arch) - { - if (arch == "X64") - return "AMD64"; - return arch; - } - - - private string ArchToInstructionSetSuffixArch(string arch) - { - return _64BitVariantArchitectureJitNameSuffix[arch]; - } - - public bool ParseInput(TextReader tr) - { - int currentLineIndex = 1; - for (string currentLine = tr.ReadLine(); currentLine != null; currentLine = tr.ReadLine(), currentLineIndex++) - { - try - { - if (currentLine.Length == 0) - { - continue; // Its an empty line, ignore - } - - if (currentLine[0] == ';') - { - continue; // Its a comment - } - - string[] command = currentLine.Split(','); - for (int i = 0; i < command.Length; i++) - { - command[i] = command[i].Trim(); - } - switch(command[0]) - { - case "definearch": - if (command.Length != 4) - throw new Exception($"Incorrect number of args for definearch {command.Length}"); - ArchitectureEncountered(command[1]); - if (command[2] == "64Bit") - { - _64BitArchitectures.Add(command[1]); - } - else if (command[2] != "32Bit") - { - throw new Exception("Architecture must be 32Bit or 64Bit"); - } - _64BitVariantArchitectureJitNameSuffix[command[1]] = command[3]; - break; - case "instructionset": - if (command.Length != 6) - throw new Exception("Incorrect number of args for instructionset"); - ValidateArchitectureEncountered(command[1]); - _architectureJitNames[command[1]].Add(command[5]); - _instructionSets.Add(new InstructionSetInfo(command[1],command[2],command[3],command[4],command[5])); - break; - case "instructionset64bit": - if (command.Length != 3) - throw new Exception("Incorrect number of args for instructionset"); - ValidateArchitectureEncountered(command[1]); - _64bitVariants[command[1]].Add(command[2]); - _architectureJitNames[command[1]].Add(command[2] + "_" + ArchToInstructionSetSuffixArch(command[1])); - break; - case "implication": - if (command.Length != 4) - throw new Exception("Incorrect number of args for instructionset"); - ValidateArchitectureEncountered(command[1]); - _implications.Add(new InstructionSetImplication(command[1],command[2], command[3])); - break; - case "copyinstructionsets": - if (command.Length != 3) - throw new Exception("Incorrect number of args for instructionset"); - ValidateArchitectureEncountered(command[1]); - ValidateArchitectureEncountered(command[2]); - string arch = command[1]; - string targetarch = command[2]; - foreach (var val in _instructionSets.ToArray()) - { - if (val.Architecture != arch) - continue; - _instructionSets.Add(new InstructionSetInfo(targetarch, val)); - _architectureJitNames[targetarch].Add(val.JitName); - } - foreach (var val in _implications.ToArray()) - { - if (val.Architecture != arch) - continue; - _implications.Add(new InstructionSetImplication(targetarch, val)); - } - foreach (var val in _64bitVariants[arch]) - { - _64bitVariants[targetarch].Add(val); - _architectureJitNames[targetarch].Add(val + "_" + ArchToInstructionSetSuffixArch(targetarch)); - } - break; - default: - throw new Exception("Unknown command"); - } - } - catch (Exception e) - { - Console.Error.WriteLine("Error parsing line {0} : {1}", currentLineIndex, e.Message); - return false; - } - } - - foreach (var instructionSet in _instructionSets) - { - if (!String.IsNullOrEmpty(instructionSet.R2rName)) - { - int r2rValue = Int32.Parse(instructionSet.R2rNumericValue); - if (_r2rNamesByName.ContainsKey(instructionSet.R2rName)) - { - if (_r2rNamesByName[instructionSet.R2rName] != r2rValue) - throw new Exception("R2R name/number mismatch"); - } - else - { - _r2rNamesByName.Add(instructionSet.R2rName, r2rValue); - _r2rNamesByNumber.Add(r2rValue, instructionSet.R2rName); - } - } - } - - foreach (var architectureInfo in _architectureJitNames) - { - if (architectureInfo.Value.Count > 62) - { - throw new Exception("Too many instruction sets added. Scheme of using uint64_t as instruction mask will need updating"); - } - } - - return true; - } - - public void WriteManagedReadyToRunInstructionSet(TextWriter tr) - { - // Write header - tr.Write(@" -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -using System; -using System.Runtime.InteropServices; -using Internal.TypeSystem; - -namespace Internal.ReadyToRunConstants -{ - public enum ReadyToRunInstructionSet - { -"); - - foreach (var r2rEntry in _r2rNamesByNumber) - { - tr.WriteLine($" {r2rEntry.Value}={r2rEntry.Key},"); - } - tr.Write(@" - } - - public static class ReadyToRunInstructionSetHelper - { - ReadyToRunInstructionSet? R2RInstructionSetFromJitInstructionSet(TargetArchitecture architecture, Internal.JitInterface.InstructionSet instructionSet) - { - switch (architecture) - { -"); - foreach (string architecture in _architectures) - { - tr.Write($@" - case TargetArchitecture.{architecture}: - {{ - switch (instructionSet) - {{ -"); - foreach (var instructionSet in _instructionSets) - { - if (instructionSet.Architecture != architecture) continue; - - string r2rEnumerationValue; - if (!String.IsNullOrEmpty(instructionSet.R2rName)) - r2rEnumerationValue = $"ReadyToRunInstructionSet.{instructionSet.R2rName}"; - else - r2rEnumerationValue = $"null"; - - tr.WriteLine($" case InstructionSet.{architecture}_{instructionSet.JitName}: return {r2rEnumerationValue};"); - if (_64BitArchitectures.Contains(architecture) && _64bitVariants[architecture].Contains(instructionSet.JitName)) - tr.WriteLine($" case InstructionSet.{architecture}_{instructionSet.JitName}_{ArchToInstructionSetSuffixArch(architecture)}: return {r2rEnumerationValue};"); - } - - tr.Write(@" - default: throw new Exception(""Unknown instruction set""); - } - } -"); - } - - tr.Write(@" - default: throw new Exception(""Unknown architecture""); - } - } - } -} -"); - } - - public void WriteManagedJitInstructionSet(TextWriter tr) - { - // Write header - tr.Write(@" -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using Internal.TypeSystem; - -namespace Internal.JitInterface -{ - public enum InstructionSet - { - ILLEGAL = 0, - NONE = 63, -"); - foreach (string architecture in _architectures) - { - int counter = 1; - foreach (var jitName in _architectureJitNames[architecture]) - { - tr.WriteLine($" {architecture}_{jitName}={counter++},"); - } - } - - tr.Write(@" - } - - public struct InstructionSetFlags - { - ulong _flags; - - public void AddInstructionSet(InstructionSet instructionSet) - { - _flags = _flags | (((ulong)1) << (int)instructionSet); - } - - public void RemoveInstructionSet(InstructionSet instructionSet) - { - _flags = _flags & ~(((ulong)1) << (int)instructionSet); - } - - public bool HasInstructionSet(InstructionSet instructionSet) - { - return (_flags & (((ulong)1) << (int)instructionSet)) != 0; - } - - public bool Equals(InstructionSetFlags other) - { - return _flags == other._flags; - } - - public static InstructionSetFlags ExpandInstructionSetByImplication(TargetArchitecture architecture, InstructionSetFlags input) - { - InstructionSetFlags oldflags = input; - InstructionSetFlags resultflags = input; - do - { - oldflags = resultflags; - switch(architecture) - { -"); - foreach (string architecture in _architectures) - { - tr.Write($@" - case TargetArchitecture.{architecture}: -"); - foreach (var instructionSet in _instructionSets) - { - if (instructionSet.Architecture != architecture) continue; - if (_64BitArchitectures.Contains(architecture) && _64bitVariants[architecture].Contains(instructionSet.JitName)) - AddImplication(architecture, instructionSet.JitName, $"{instructionSet.JitName}_{ArchToInstructionSetSuffixArch(architecture)}"); - } - foreach (var implication in _implications) - { - if (implication.Architecture != architecture) continue; - AddImplication(architecture, implication.JitName, implication.ImpliedJitName); - } - tr.WriteLine(" break;"); - } - - tr.Write(@" - } - } while (!oldflags.Equals(resultflags)); - return resultflags; - } - - public static IEnumerable> ArchitectureToValidInstructionSets(TargetArchitecture architecture) - { - switch (architecture) - { -"); - foreach (string architecture in _architectures) - { - tr.Write($@" - case TargetArchitecture.{architecture}: -"); - foreach (var instructionSet in _instructionSets) - { - if (instructionSet.Architecture != architecture) continue; - tr.WriteLine($" yield return new KeyValuePair(\"{instructionSet.PublicName}\", InstructionSet.{architecture}_{instructionSet.JitName});"); - } - tr.WriteLine(" break;"); - } - tr.Write(@" - } - } - - public void Set64BitInstructionSetVariants(TargetArchitecture architecture) - { - switch (architecture) - { -"); - foreach (string architecture in _architectures) - { - tr.Write($@" - case TargetArchitecture.{architecture}: -"); - foreach (var instructionSet in _instructionSets) - { - if (instructionSet.Architecture != architecture) continue; - - if (_64BitArchitectures.Contains(architecture) && _64bitVariants[architecture].Contains(instructionSet.JitName)) - { - tr.WriteLine($" if (HasInstructionSet(InstructionSet.{architecture}_{instructionSet.JitName}))"); - tr.WriteLine($" AddInstructionSet(InstructionSet.{architecture}_{instructionSet.JitName}_{ArchToInstructionSetSuffixArch(architecture)});"); - } - } - - tr.WriteLine(" break;"); - } - tr.Write(@" - } - } - } -} -"); - return; - void AddImplication(string architecture, string jitName, string impliedJitName) - { - tr.WriteLine($" if (resultflags.HasInstructionSet(InstructionSet.{architecture}_{jitName}))"); - tr.WriteLine($" resultflags.AddInstructionSet(InstructionSet.{architecture}_{impliedJitName});"); - } - } - - public void WriteNativeCorInfoInstructionSet(TextWriter tr) - { - // Write header - tr.Write(@" -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -#ifndef CORINFOINSTRUCTIONSET_H -#define CORINFOINSTRUCTIONSET_H - -enum CORINFO_InstructionSet -{ - InstructionSet_ILLEGAL = 0, - InstructionSet_NONE = 63, -"); - foreach (string architecture in _architectures) - { - tr.WriteLine($"#ifdef TARGET_{ArchToIfDefArch(architecture)}"); - int counter = 1; - foreach (var jitName in _architectureJitNames[architecture]) - { - tr.WriteLine($" InstructionSet_{jitName}={counter++},"); - } - tr.WriteLine($"#endif // TARGET_{ArchToIfDefArch(architecture)}"); - } - tr.Write(@" -}; - -struct CORINFO_InstructionSetFlags -{ -private: - uint64_t _flags = 0; -public: - void AddInstructionSet(CORINFO_InstructionSet instructionSet) - { - _flags = _flags | (((uint64_t)1) << instructionSet); - } - - void RemoveInstructionSet(CORINFO_InstructionSet instructionSet) - { - _flags = _flags & ~(((uint64_t)1) << instructionSet); - } - - bool HasInstructionSet(CORINFO_InstructionSet instructionSet) const - { - return _flags & (((uint64_t)1) << instructionSet); - } - - bool Equals(CORINFO_InstructionSetFlags other) const - { - return _flags == other._flags; - } - - void Add(CORINFO_InstructionSetFlags other) - { - _flags |= other._flags; - } - - bool IsEmpty() const - { - return _flags == 0; - } - - void Reset() - { - _flags = 0; - } - - void Set64BitInstructionSetVariants() - { -"); - foreach (string architecture in _architectures) - { - tr.WriteLine($"#ifdef TARGET_{ArchToIfDefArch(architecture)}"); - foreach (var instructionSet in _instructionSets) - { - if (instructionSet.Architecture != architecture) continue; - - if (_64BitArchitectures.Contains(architecture) && _64bitVariants[architecture].Contains(instructionSet.JitName)) - { - tr.WriteLine($" if (HasInstructionSet(InstructionSet_{instructionSet.JitName}))"); - tr.WriteLine($" AddInstructionSet(InstructionSet_{instructionSet.JitName}_{ArchToInstructionSetSuffixArch(architecture)});"); - } - } - - tr.WriteLine($"#endif // TARGET_{ArchToIfDefArch(architecture)}"); - } - tr.Write(@" - } - - uint64_t GetFlagsRaw() - { - return _flags; - } - - void SetFromFlagsRaw(uint64_t flags) - { - _flags = flags; - } -}; - -inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_InstructionSetFlags input) -{ - CORINFO_InstructionSetFlags oldflags = input; - CORINFO_InstructionSetFlags resultflags = input; - do - { - oldflags = resultflags; -"); - foreach (string architecture in _architectures) - { - tr.WriteLine($"#ifdef TARGET_{ArchToIfDefArch(architecture)}"); - foreach (var instructionSet in _instructionSets) - { - if (instructionSet.Architecture != architecture) continue; - if (_64BitArchitectures.Contains(architecture) && _64bitVariants[architecture].Contains(instructionSet.JitName)) - AddImplication(architecture, instructionSet.JitName, $"{instructionSet.JitName}_{ArchToInstructionSetSuffixArch(architecture)}"); - } - foreach (var implication in _implications) - { - if (implication.Architecture != architecture) continue; - AddImplication(architecture, implication.JitName, implication.ImpliedJitName); - } - tr.WriteLine($"#endif // TARGET_{ArchToIfDefArch(architecture)}"); - } - tr.Write(@" - } while (!oldflags.Equals(resultflags)); - return resultflags; -} - - - -#endif // CORINFOINSTRUCTIONSET_H -"); - return; - - void AddImplication(string architecture, string jitName, string impliedJitName) - { - tr.WriteLine($" if (resultflags.HasInstructionSet(InstructionSet_{jitName}) && !resultflags.HasInstructionSet(InstructionSet_{impliedJitName}))"); - tr.WriteLine($" resultflags.RemoveInstructionSet(InstructionSet_{jitName});"); - } - } - - public void WriteNativeReadyToRunInstructionSet(TextWriter tr) - { - // Write header - tr.Write(@" -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// FROM /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt -// using /src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat - -#ifndef READYTORUNINSTRUCTIONSET_H -#define READYTORUNINSTRUCTIONSET_H -enum ReadyToRunInstructionSet -{ -"); - - foreach (var r2rEntry in _r2rNamesByNumber) - { - tr.WriteLine($" READYTORUN_INSTRUCTION_{r2rEntry.Value}={r2rEntry.Key},"); - } - tr.Write(@" -}; - -#endif // READYTORUNINSTRUCTIONSET_H -"); - } - } -} \ No newline at end of file diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/Program.cs b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/Program.cs index 94fa40662716d..78b513211cc4a 100644 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/Program.cs +++ b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/Program.cs @@ -493,49 +493,16 @@ class JitInterfaceWrapper static void Main(string[] args) { - if (args[0] == "InstructionSetGenerator") + IEnumerable functions = ParseInput(new StreamReader(args[0])); + using (TextWriter tw = new StreamWriter(args[1])) { - InstructionSetGenerator generator = new InstructionSetGenerator(); - if (!generator.ParseInput(new StreamReader(args[1]))) - return; - - using (TextWriter tw = new StreamWriter(args[2])) - { - Console.WriteLine("Generating {0}", args[2]); - generator.WriteManagedReadyToRunInstructionSet(tw); - } - - using (TextWriter tw = new StreamWriter(args[3])) - { - Console.WriteLine("Generating {0}", args[3]); - generator.WriteManagedJitInstructionSet(tw); - } - - using (TextWriter tw = new StreamWriter(args[4])) - { - Console.WriteLine("Generating {0}", args[4]); - generator.WriteNativeCorInfoInstructionSet(tw); - } - - using (TextWriter tw = new StreamWriter(args[5])) - { - Console.WriteLine("Generating {0}", args[5]); - generator.WriteNativeReadyToRunInstructionSet(tw); - } + Console.WriteLine("Generating {0}", args[1]); + WriteManagedThunkInterface(tw, functions); } - else + using (TextWriter tw = new StreamWriter(args[2])) { - IEnumerable functions = ParseInput(new StreamReader(args[0])); - using (TextWriter tw = new StreamWriter(args[1])) - { - Console.WriteLine("Generating {0}", args[1]); - WriteManagedThunkInterface(tw, functions); - } - using (TextWriter tw = new StreamWriter(args[2])) - { - Console.WriteLine("Generating {0}", args[2]); - WriteNativeWrapperInterface(tw, functions); - } + Console.WriteLine("Generating {0}", args[2]); + WriteNativeWrapperInterface(tw, functions); } } } diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat index f90ce4554e37a..46328b52d08ba 100644 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat +++ b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat @@ -1,4 +1,2 @@ -pushd %~dp0 -call ..\..\..\..\..\..\..\dotnet.cmd run -- ThunkInput.txt ..\CorInfoBase.cs ..\..\..\crossgen2\jitinterface\jitinterface.h -call ..\..\..\..\..\..\..\dotnet.cmd run -- InstructionSetGenerator InstructionSetDesc.txt ..\..\Internal\Runtime\ReadyToRunInstructionSet.cs ..\CorInfoInstructionSet.cs ..\..\..\..\inc\corinfoinstructionset.h ..\..\..\..\inc\readytoruninstructionset.h -popd \ No newline at end of file +cd /d %~dp0 +dotnet run -- ThunkInput.txt ..\CorInfoBase.cs ..\..\..\crossgen2\jitinterface\jitinterface.h \ No newline at end of file diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.sh b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.sh index 041e410ae98aa..59672c72d4156 100755 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.sh +++ b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.sh @@ -1,4 +1,3 @@ #!/usr/bin/env bash cd "$(dirname ${BASH_SOURCE[0]})" -../../../../../../../dotnet.sh run -- ThunkInput.txt ../CorInfoBase.cs ../../../crossgen2/jitinterface/jitinterface.h -../../../../../../../dotnet.sh run -- InstructionSetGenerator InstructionSetDesc.txt ../../Internal/Runtime/ReadyToRunInstructionSet.cs ../CorInfoInstructionSet.cs ../../../../inc/corinfoinstructionset.h ../../../../inc/readytoruninstructionset.h \ No newline at end of file +dotnet run -- ThunkInput.txt ../CorInfoBase.cs ../../../crossgen2/jitinterface/jitinterface.h diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index a1e95d8a19cdc..9c416513431dd 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -234,9 +234,6 @@ JitInterface\CorInfoTypes.cs - - JitInterface\CorInfoInstructionSet.cs - JitInterface\JitConfigProvider.cs diff --git a/src/coreclr/src/tools/crossgen2/jitinterface/jitwrapper.cpp b/src/coreclr/src/tools/crossgen2/jitinterface/jitwrapper.cpp index 621b291cf74c2..fbc0170276730 100644 --- a/src/coreclr/src/tools/crossgen2/jitinterface/jitwrapper.cpp +++ b/src/coreclr/src/tools/crossgen2/jitinterface/jitwrapper.cpp @@ -27,11 +27,11 @@ class CORJIT_FLAGS uint64_t corJitFlags; }; -static const GUID JITEEVersionIdentifier = { /* 54305fa1-a0d8-42e4-a6b4-b750a8143467 */ - 0x54305fa1, - 0xa0d8, - 0x42e4, - {0xa6, 0xb4, 0xb7, 0x50, 0xa8, 0x14, 0x34, 0x67} +static const GUID JITEEVersionIdentifier = { /* c231d2d7-4764-4097-a9ef-5961041540df */ + 0xc231d2d7, + 0x4764, + 0x4097, + {0xa9, 0xef, 0x59, 0x61, 0x04, 0x15, 0x40, 0xdf} }; class Jit diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 947bcf6eb6431..4a548638fed09 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1296,6 +1296,11 @@ void EEJitManager::SetCpuInfo() CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV); CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI); } + + if (CPU_X86_USE_SSE2(cpuInfo.dwFeatures)) + { + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2); + } #endif // TARGET_X86 #if defined(TARGET_X86) || defined(TARGET_AMD64) @@ -1367,48 +1372,46 @@ void EEJitManager::SetCpuInfo() if ((buffer[15] & 0x06) == 0x06) // SSE & SSE2 { - CPUCompileFlags.Set(InstructionSet_SSE); - CPUCompileFlags.Set(InstructionSet_SSE2); if ((buffer[11] & 0x02) != 0) // AESNI { - CPUCompileFlags.Set(InstructionSet_AES); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AES); } if ((buffer[8] & 0x02) != 0) // PCLMULQDQ { - CPUCompileFlags.Set(InstructionSet_PCLMULQDQ); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_PCLMULQDQ); } if ((buffer[8] & 0x01) != 0) // SSE3 { - CPUCompileFlags.Set(InstructionSet_SSE3); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3); if ((buffer[9] & 0x02) != 0) // SSSE3 { - CPUCompileFlags.Set(InstructionSet_SSSE3); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSSE3); if ((buffer[10] & 0x08) != 0) // SSE4.1 { - CPUCompileFlags.Set(InstructionSet_SSE41); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE41); if ((buffer[10] & 0x10) != 0) // SSE4.2 { - CPUCompileFlags.Set(InstructionSet_SSE42); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE42); if ((buffer[10] & 0x80) != 0) // POPCNT { - CPUCompileFlags.Set(InstructionSet_POPCNT); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_POPCNT); } if ((buffer[11] & 0x18) == 0x18) // AVX & OSXSAVE { if(DoesOSSupportAVX() && (xmmYmmStateSupport() == 1)) { - CPUCompileFlags.Set(InstructionSet_AVX); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX); if ((buffer[9] & 0x10) != 0) // FMA { - CPUCompileFlags.Set(InstructionSet_FMA); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FMA); } if (maxCpuId >= 0x07) @@ -1417,7 +1420,7 @@ void EEJitManager::SetCpuInfo() if ((buffer[4] & 0x20) != 0) // AVX2 { - CPUCompileFlags.Set(InstructionSet_AVX2); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2); } } } @@ -1436,7 +1439,7 @@ void EEJitManager::SetCpuInfo() if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SIMD16ByteOnly) != 0) { - CPUCompileFlags.Clear(InstructionSet_AVX2); + CPUCompileFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2); } } @@ -1446,16 +1449,14 @@ void EEJitManager::SetCpuInfo() if ((buffer[4] & 0x08) != 0) // BMI1 { - CPUCompileFlags.Set(InstructionSet_BMI1); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_BMI1); } if ((buffer[5] & 0x01) != 0) // BMI2 { - CPUCompileFlags.Set(InstructionSet_BMI2); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_BMI2); } } - - CPUCompileFlags.EnsureValidInstructionSetSupport(); } DWORD maxCpuIdEx = getcpuid(0x80000000, buffer); @@ -1470,7 +1471,7 @@ void EEJitManager::SetCpuInfo() if ((buffer[8] & 0x20) != 0) // LZCNT { - CPUCompileFlags.Set(InstructionSet_LZCNT); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_LZCNT); } } #endif // defined(TARGET_X86) || defined(TARGET_AMD64) @@ -1485,25 +1486,23 @@ void EEJitManager::SetCpuInfo() PAL_GetJitCpuCapabilityFlags(&CPUCompileFlags); #elif defined(HOST_64BIT) // FP and SIMD support are enabled by default - CPUCompileFlags.Set(InstructionSet_ArmBase); - CPUCompileFlags.Set(InstructionSet_AdvSimd); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); // PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE (30) if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) { - CPUCompileFlags.Set(InstructionSet_Aes); - CPUCompileFlags.Set(InstructionSet_Sha1); - CPUCompileFlags.Set(InstructionSet_Sha256); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_AES); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA1); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA256); } // PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE (31) if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) { - CPUCompileFlags.Set(InstructionSet_Crc32); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_CRC32); } #endif // HOST_64BIT #endif // TARGET_ARM64 - CPUCompileFlags.Set64BitInstructionSetVariants(); - m_CPUCompileFlags = CPUCompileFlags; } diff --git a/src/coreclr/src/zap/zapper.cpp b/src/coreclr/src/zap/zapper.cpp index 70388bd50018b..a11f605aa8380 100644 --- a/src/coreclr/src/zap/zapper.cpp +++ b/src/coreclr/src/zap/zapper.cpp @@ -1181,16 +1181,9 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) } // .NET Core requires SSE2. -#endif // TARGET_X86 + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2); -#if defined(TARGET_X86) || defined(TARGET_AMD64) - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE2); -#endif -#if defined(TARGET_ARM64) - m_pOpt->m_compilerFlags.Set(InstructionSet_ArmBase); - m_pOpt->m_compilerFlags.Set(InstructionSet_AdvSimd); -#endif +#endif // TARGET_X86 #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) // If we're crossgenning CoreLib, allow generating non-VEX intrinsics. The generated code might @@ -1205,24 +1198,21 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD); #if defined(TARGET_X86) || defined(TARGET_AMD64) - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE2); - m_pOpt->m_compilerFlags.Set(InstructionSet_AES); - m_pOpt->m_compilerFlags.Set(InstructionSet_PCLMULQDQ); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE3); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSSE3); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE41); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE42); - m_pOpt->m_compilerFlags.Set(InstructionSet_POPCNT); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AES); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_PCLMULQDQ); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSSE3); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE41); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE42); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_POPCNT); // Leaving out CORJIT_FLAGS::CORJIT_FLAG_USE_AVX, CORJIT_FLAGS::CORJIT_FLAG_USE_FMA // CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2, CORJIT_FLAGS::CORJIT_FLAG_USE_BMI1, // CORJIT_FLAGS::CORJIT_FLAG_USE_BMI2 on purpose - these require VEX encodings // and the JIT doesn't support generating code for methods with mixed encodings. - m_pOpt->m_compilerFlags.Set(InstructionSet_LZCNT); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_LZCNT); #endif // defined(TARGET_X86) || defined(TARGET_AMD64) } #endif // defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) - m_pOpt->m_compilerFlags.Set64BitInstructionSetVariants(); if ( m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO) && m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)