Unify instruction set definition (#33730)
authorDavid Wrighton <davidwr@microsoft.com>
Thu, 19 Mar 2020 16:29:19 +0000 (09:29 -0700)
committerGitHub <noreply@github.com>
Thu, 19 Mar 2020 16:29:19 +0000 (09:29 -0700)
* Unify instruction set definition
- Build simple DSL to describe the instruction set support of the compiler/jit/etc
- Parse DSL and produce data structures useable throughout our compilation environment
- This is in support of adding more granular instruction set support to crossgen2, but this change is pulled out into its own PR to ease reviewing cost
- Make it hard to mess up 64bit instruction set variants by adding helper function to fill them in.
- Add 64 bit variant names to 32bit instruction set enum to remove the need to add a large number of #ifdefs to the jit

32 files changed:
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
src/coreclr/src/inc/corinfo.h
src/coreclr/src/inc/corinfoinstructionset.h [new file with mode: 0644]
src/coreclr/src/inc/corjitflags.h
src/coreclr/src/inc/readytoruninstructionset.h [new file with mode: 0644]
src/coreclr/src/jit/compiler.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/ee_il_dll.cpp
src/coreclr/src/jit/hwintrinsic.cpp
src/coreclr/src/jit/hwintrinsic.h
src/coreclr/src/jit/hwintrinsicarm64.cpp
src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp
src/coreclr/src/jit/hwintrinsicxarch.cpp
src/coreclr/src/jit/instr.h
src/coreclr/src/jit/jitee.h
src/coreclr/src/jit/lsraarm64.cpp
src/coreclr/src/jit/lsraxarch.cpp
src/coreclr/src/jit/simdcodegenxarch.cpp
src/coreclr/src/pal/src/misc/jitsupport.cpp
src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs [new file with mode: 0644]
src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs [new file with mode: 0644]
src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt [new file with mode: 0644]
src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs [new file with mode: 0644]
src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/Program.cs
src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.bat
src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/gen.sh
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
src/coreclr/src/tools/crossgen2/jitinterface/jitwrapper.cpp
src/coreclr/src/vm/codeman.cpp
src/coreclr/src/zap/zapper.cpp

index c4a9f47..21c104b 100644 (file)
@@ -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", key, value.B, jitflags->GetFlagsRaw());
+    printf("GetJitFlags key %u sizeInBytes-%u jitFlags-%016llX instructionSetFlags-%016llX", key, value.B, jitflags->GetFlagsRaw(), jitflags->GetInstructionSetFlagsRaw());
     GetJitFlags->Unlock();
 }
 DWORD MethodContext::repGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes)
index 9978fac..741b12e 100644 (file)
@@ -217,11 +217,11 @@ TODO: Talk about initializing strutures before use
 #endif
 #endif
 
-SELECTANY const GUID JITEEVersionIdentifier = { /* c231d2d7-4764-4097-a9ef-5961041540df */
-    0xc231d2d7,
-    0x4764,
-    0x4097,
-    {0xa9, 0xef, 0x59, 0x61, 0x04, 0x15, 0x40, 0xdf}
+SELECTANY const GUID JITEEVersionIdentifier = { /* 54305fa1-a0d8-42e4-a6b4-b750a8143467 */
+    0x54305fa1,
+    0xa0d8,
+    0x42e4,
+    {0xa6, 0xb4, 0xb7, 0x50, 0xa8, 0x14, 0x34, 0x67}
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/coreclr/src/inc/corinfoinstructionset.h b/src/coreclr/src/inc/corinfoinstructionset.h
new file mode 100644 (file)
index 0000000..d43d743
--- /dev/null
@@ -0,0 +1,276 @@
+
+// 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
index 18f24b5..eac6f92 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef _COR_JIT_FLAGS_H_
 #define _COR_JIT_FLAGS_H_
 
+#include "corinfoinstructionset.h"
+
 class CORJIT_FLAGS
 {
 public:
@@ -40,7 +42,6 @@ public:
         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)
 
@@ -54,19 +55,10 @@ public:
 
         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,
@@ -106,57 +98,6 @@ public:
 
         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,
@@ -178,8 +119,6 @@ public:
         CORJIT_FLAG_UNUSED30                = 61,
         CORJIT_FLAG_UNUSED31                = 62,
         CORJIT_FLAG_UNUSED32                = 63
-
-#endif // !defined(TARGET_ARM64) &&!defined(TARGET_X86) && !defined(TARGET_AMD64)
     };
 
     CORJIT_FLAGS()
@@ -198,11 +137,28 @@ public:
     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)
@@ -223,16 +179,17 @@ public:
     void Add(const CORJIT_FLAGS& other)
     {
         corJitFlags |= other.corJitFlags;
+        instructionSetFlags.Add(other.instructionSetFlags);
     }
 
-    void Remove(const CORJIT_FLAGS& other)
+    bool IsEmpty() const
     {
-        corJitFlags &= ~other.corJitFlags;
+        return corJitFlags == 0 && instructionSetFlags.IsEmpty();
     }
 
-    bool IsEmpty() const
+    void EnsureValidInstructionSetSupport()
     {
-        return corJitFlags == 0;
+        instructionSetFlags = EnsureInstructionSetFlagsAreValid(instructionSetFlags);
     }
 
     // DO NOT USE THIS FUNCTION! (except in very restricted special cases)
@@ -241,9 +198,16 @@ public:
         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
new file mode 100644 (file)
index 0000000..6e6f254
--- /dev/null
@@ -0,0 +1,38 @@
+
+// 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
index 6febed1..0d4fc4a 100644 (file)
@@ -2193,250 +2193,179 @@ void Compiler::compSetProcessor()
 
 #endif // TARGET_X86
 
-// Instruction set flags for Intel hardware intrinsics
+    CORINFO_InstructionSetFlags instructionSetFlags = jitFlags.GetInstructionSetFlags();
+
 #ifdef TARGET_XARCH
+    // Instruction set flags for Intel hardware intrinsics
     opts.compSupportsISA = 0;
 
     if (JitConfig.EnableHWIntrinsic())
     {
         // Dummy ISAs for simplifying the JIT code
-        opts.setSupportedISA(InstructionSet_Vector128);
-        opts.setSupportedISA(InstructionSet_Vector256);
+        instructionSetFlags.AddInstructionSet(InstructionSet_Vector128);
+        instructionSetFlags.AddInstructionSet(InstructionSet_Vector256);
     }
 
-    if (JitConfig.EnableSSE())
+    if (!JitConfig.EnableSSE())
     {
-        opts.setSupportedISA(InstructionSet_SSE);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE);
 #ifdef TARGET_AMD64
-        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 (jitFlags.IsSet(JitFlags::JIT_FLAG_USE_LZCNT) && JitConfig.EnableLZCNT())
-    {
-        opts.setSupportedISA(InstructionSet_LZCNT);
-#ifdef TARGET_AMD64
-        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
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE_X64);
+#endif
     }
 
-    // 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))
+    if (!JitConfig.EnableSSE2())
     {
-        opts.setSupportedISA(InstructionSet_BMI2);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE2);
 #ifdef TARGET_AMD64
-        opts.setSupportedISA(InstructionSet_BMI2_X64);
-#endif // TARGET_AMD64
-    }
-
-    if (!compIsForInlining())
-    {
-        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);
-        }
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE2_X64);
+#endif
     }
-#endif // TARGET_XARCH
 
-#if defined(TARGET_ARM64)
-    if (JitConfig.EnableHWIntrinsic())
+    if (!JitConfig.EnableAES())
     {
-        // Dummy ISAs for simplifying the JIT code
-        opts.setSupportedISA(InstructionSet_ArmBase);
-        opts.setSupportedISA(InstructionSet_ArmBase_Arm64);
-        opts.setSupportedISA(InstructionSet_Vector64);
-        opts.setSupportedISA(InstructionSet_Vector128);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_AES);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_AES) && JitConfig.EnableArm64Aes())
+    if (!JitConfig.EnablePCLMULQDQ())
     {
-        opts.setSupportedISA(InstructionSet_Aes);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_PCLMULQDQ);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ATOMICS) && JitConfig.EnableArm64Atomics())
+    // 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())
     {
-        opts.setSupportedISA(InstructionSet_Atomics);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE3);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_CRC32) && JitConfig.EnableArm64Crc32())
+    if (!JitConfig.EnableSSSE3())
     {
-        opts.setSupportedISA(InstructionSet_Crc32);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSSE3);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_DCPOP) && JitConfig.EnableArm64Dcpop())
+    if (!JitConfig.EnableSSE41())
     {
-        opts.setSupportedISA(InstructionSet_Dcpop);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE41);
+#ifdef TARGET_AMD64
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE41_X64);
+#endif
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_DP) && JitConfig.EnableArm64Dp())
+    if (!JitConfig.EnableSSE42())
     {
-        opts.setSupportedISA(InstructionSet_Dp);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE42);
+#ifdef TARGET_AMD64
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_SSE42_X64);
+#endif
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_FCMA) && JitConfig.EnableArm64Fcma())
+    if (!JitConfig.EnablePOPCNT())
     {
-        opts.setSupportedISA(InstructionSet_Fcma);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_POPCNT);
+#ifdef TARGET_AMD64
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_POPCNT_X64);
+#endif
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_FP) && JitConfig.EnableArm64Fp())
+    if (!JitConfig.EnableAVX())
     {
-        opts.setSupportedISA(InstructionSet_Fp);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_FP16) && JitConfig.EnableArm64Fp16())
+    if (!JitConfig.EnableFMA())
     {
-        opts.setSupportedISA(InstructionSet_Fp16);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_FMA);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_JSCVT) && JitConfig.EnableArm64Jscvt())
+    if (!JitConfig.EnableAVX2())
     {
-        opts.setSupportedISA(InstructionSet_Jscvt);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX2);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_LRCPC) && JitConfig.EnableArm64Lrcpc())
+    if (!JitConfig.EnableLZCNT())
     {
-        opts.setSupportedISA(InstructionSet_Lrcpc);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_LZCNT);
+#ifdef TARGET_AMD64
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_LZCNT_X64);
+#endif // TARGET_AMD64
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_PMULL) && JitConfig.EnableArm64Pmull())
+    if (!JitConfig.EnableBMI1())
     {
-        opts.setSupportedISA(InstructionSet_Pmull);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI1);
+#ifdef TARGET_AMD64
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI1_X64);
+#endif // TARGET_AMD64
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA1) && JitConfig.EnableArm64Sha1())
+    if (!JitConfig.EnableBMI2())
     {
-        opts.setSupportedISA(InstructionSet_Sha1);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI2);
+#ifdef TARGET_AMD64
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_BMI2_X64);
+#endif // TARGET_AMD64
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA256) && JitConfig.EnableArm64Sha256())
+#endif // TARGET_XARCH
+#if defined(TARGET_ARM64)
+    if (JitConfig.EnableHWIntrinsic())
     {
-        opts.setSupportedISA(InstructionSet_Sha256);
+        // Dummy ISAs for simplifying the JIT code
+        instructionSetFlags.AddInstructionSet(InstructionSet_ArmBase);
+        instructionSetFlags.AddInstructionSet(InstructionSet_ArmBase_Arm64);
+        instructionSetFlags.AddInstructionSet(InstructionSet_Vector64);
+        instructionSetFlags.AddInstructionSet(InstructionSet_Vector128);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA512) && JitConfig.EnableArm64Sha512())
+    if (!JitConfig.EnableArm64Aes())
     {
-        opts.setSupportedISA(InstructionSet_Sha512);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_Aes);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SHA3) && JitConfig.EnableArm64Sha3())
+    if (!JitConfig.EnableArm64Atomics())
     {
-        opts.setSupportedISA(InstructionSet_Sha3);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_Atomics);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD) && JitConfig.EnableArm64AdvSimd())
+    if (!JitConfig.EnableArm64Crc32())
     {
-        opts.setSupportedISA(InstructionSet_AdvSimd);
-        opts.setSupportedISA(InstructionSet_AdvSimd_Arm64);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_Crc32);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_Crc32_Arm64);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD_V81) && JitConfig.EnableArm64AdvSimd_v81())
+    if (!JitConfig.EnableArm64Sha1())
     {
-        opts.setSupportedISA(InstructionSet_AdvSimd_v81);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_Sha1);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_ADVSIMD_FP16) && JitConfig.EnableArm64AdvSimd_Fp16())
+    if (!JitConfig.EnableArm64Sha256())
     {
-        opts.setSupportedISA(InstructionSet_AdvSimd_Fp16);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_Sha256);
     }
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SM3) && JitConfig.EnableArm64Sm3())
+    if (!JitConfig.EnableArm64AdvSimd())
     {
-        opts.setSupportedISA(InstructionSet_Sm3);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_AdvSimd);
+        instructionSetFlags.RemoveInstructionSet(InstructionSet_AdvSimd_Arm64);
     }
+#endif
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SM4) && JitConfig.EnableArm64Sm4())
-    {
-        opts.setSupportedISA(InstructionSet_Sm4);
-    }
+    instructionSetFlags = EnsureInstructionSetFlagsAreValid(instructionSetFlags);
+    opts.setSupportedISAs(jitFlags.GetInstructionSetFlags());
 
-    if (jitFlags.IsSet(JitFlags::JIT_FLAG_HAS_ARM64_SVE) && JitConfig.EnableArm64Sve())
+#ifdef TARGET_XARCH
+    if (!compIsForInlining())
     {
-        opts.setSupportedISA(InstructionSet_Sve);
+        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
+#endif // TARGET_XARCH
 }
 
 #ifdef PROFILING_SUPPORTED
@@ -5354,28 +5283,11 @@ 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.
 
-        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);
-
+        CORINFO_InstructionSetFlags defaultArm64Flags;
+        defaultArm64Flags.AddInstructionSet(InstructionSet_ArmBase);
+        defaultArm64Flags.AddInstructionSet(InstructionSet_AdvSimd);
+        defaultArm64Flags.Set64BitInstructionSetVariants();
+        compileFlags->SetInstructionSetFlags(defaultArm64Flags);
 #endif // defined(TARGET_ARM64)
     }
 
index 2a87d9c..9afa3fe 100644 (file)
@@ -3672,7 +3672,7 @@ protected:
                                        bool                  mustExpand);
 
 protected:
-    bool compSupportsHWIntrinsic(InstructionSet isa);
+    bool compSupportsHWIntrinsic(CORINFO_InstructionSet isa);
 
     GenTree* impSpecialIntrinsic(NamedIntrinsic        intrinsic,
                                  CORINFO_CLASS_HANDLE  clsHnd,
@@ -8270,7 +8270,7 @@ private:
         return false;
     }
 
-    bool compSupports(InstructionSet isa) const
+    bool compSupports(CORINFO_InstructionSet isa) const
     {
 #if defined(TARGET_XARCH) || defined(TARGET_ARM64)
         return (opts.compSupportsISA & (1ULL << isa)) != 0;
@@ -8379,11 +8379,13 @@ public:
 
 #if defined(TARGET_XARCH) || defined(TARGET_ARM64)
         uint64_t compSupportsISA;
-        void setSupportedISA(InstructionSet isa)
+#endif
+        void setSupportedISAs(CORINFO_InstructionSetFlags isas)
         {
-            compSupportsISA |= 1ULL << isa;
-        }
+#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
+            compSupportsISA = isas.GetFlagsRaw();
 #endif
+        }
 
         unsigned compFlags; // method attributes
         unsigned instrCount;
index 4ac4c24..78d3d8e 100644 (file)
@@ -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.IsSet(JitFlags::JIT_FLAG_USE_AVX2))
+        jitFlags.GetInstructionSetFlags().HasInstructionSet(InstructionSet_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
index 4b8848b..4af653b 100644 (file)
@@ -302,7 +302,7 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler*   comp,
                                          const char* enclosingClassName)
 {
     // TODO-Throughput: replace sequential search by binary search
-    InstructionSet isa = lookupIsa(className, enclosingClassName);
+    CORINFO_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(InstructionSet isa)
+bool Compiler::compSupportsHWIntrinsic(CORINFO_InstructionSet isa)
 {
     return JitConfig.EnableHWIntrinsic() && (featureSIMD || HWIntrinsicInfo::isScalarIsa(isa)) &&
            (
@@ -629,11 +629,11 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
                                   CORINFO_SIG_INFO*     sig,
                                   bool                  mustExpand)
 {
-    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;
+    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;
 
     if ((retType == TYP_STRUCT) && featureSIMD)
     {
index 2931c51..b80dce7 100644 (file)
@@ -113,15 +113,15 @@ enum HWIntrinsicFlag : unsigned int
 
 struct HWIntrinsicInfo
 {
-    NamedIntrinsic      id;
-    const char*         name;
-    InstructionSet      isa;
-    int                 ival;
-    unsigned            simdSize;
-    int                 numArgs;
-    instruction         ins[10];
-    HWIntrinsicCategory category;
-    HWIntrinsicFlag     flags;
+    NamedIntrinsic         id;
+    const char*            name;
+    CORINFO_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 InstructionSet lookupIsa(const char* className, const char* enclosingClassName);
+    static CORINFO_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(InstructionSet isa);
-    static bool isScalarIsa(InstructionSet isa);
+    static bool isFullyImplementedIsa(CORINFO_InstructionSet isa);
+    static bool isScalarIsa(CORINFO_InstructionSet isa);
 
 #ifdef TARGET_XARCH
     static bool isAVX2GatherIntrinsic(NamedIntrinsic id);
@@ -157,7 +157,7 @@ struct HWIntrinsicInfo
         return lookup(id).name;
     }
 
-    static InstructionSet lookupIsa(NamedIntrinsic id)
+    static CORINFO_InstructionSet lookupIsa(NamedIntrinsic id)
     {
         return lookup(id).isa;
     }
index 1f7dde9..7f494ab 100644 (file)
@@ -15,7 +15,7 @@
 //
 // Return Value:
 //    The 64-bit only InstructionSet associated with isa
-static InstructionSet Arm64VersionOfIsa(InstructionSet isa)
+static CORINFO_InstructionSet Arm64VersionOfIsa(CORINFO_InstructionSet isa)
 {
     switch (isa)
     {
@@ -38,7 +38,7 @@ static InstructionSet Arm64VersionOfIsa(InstructionSet isa)
 //
 // Return Value:
 //    The InstructionSet associated with className
-static InstructionSet lookupInstructionSet(const char* className)
+static CORINFO_InstructionSet lookupInstructionSet(const char* className)
 {
     assert(className != nullptr);
 
@@ -99,7 +99,7 @@ static InstructionSet lookupInstructionSet(const char* className)
 //
 // Return Value:
 //    The InstructionSet associated with className and enclosingClassName
-InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const char* enclosingClassName)
+CORINFO_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(InstructionSet isa)
+bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa)
 {
     switch (isa)
     {
@@ -188,7 +188,7 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa)
 //
 // Return Value:
 //    true if isa is scalar; otherwise, false
-bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa)
+bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa)
 {
     switch (isa)
     {
index 1ba67be..cb5160e 100644 (file)
@@ -79,11 +79,11 @@ static bool genIsTableDrivenHWIntrinsic(NamedIntrinsic intrinsicId, HWIntrinsicC
 //
 void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* 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);
+    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);
 
     assert(HWIntrinsicInfo::RequiresCodegen(intrinsicId));
 
index 6aa59aa..80b341f 100644 (file)
@@ -15,7 +15,7 @@
 //
 // Return Value:
 //    The 64-bit only InstructionSet associated with isa
-static InstructionSet X64VersionOfIsa(InstructionSet isa)
+static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa)
 {
     switch (isa)
     {
@@ -48,7 +48,7 @@ static InstructionSet X64VersionOfIsa(InstructionSet isa)
 //
 // Return Value:
 //    The InstructionSet associated with className
-static InstructionSet lookupInstructionSet(const char* className)
+static CORINFO_InstructionSet lookupInstructionSet(const char* className)
 {
     assert(className != nullptr);
     if (className[0] == 'A')
@@ -147,7 +147,7 @@ static InstructionSet lookupInstructionSet(const char* className)
 //
 // Return Value:
 //    The InstructionSet associated with className and enclosingClassName
-InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const char* enclosingClassName)
+CORINFO_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(InstructionSet isa)
+bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa)
 {
     switch (isa)
     {
@@ -302,7 +302,7 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa)
 //
 // Return Value:
 //    true if isa is scalar; otherwise, false
-bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa)
+bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa)
 {
     switch (isa)
     {
index 0de79a4..26ba6ee 100644 (file)
@@ -292,71 +292,6 @@ 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
 
 /*****************************************************************************/
index 473bfc5..405ef9a 100644 (file)
@@ -27,7 +27,6 @@ public:
         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)
 
@@ -41,20 +40,10 @@ public:
 
         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
@@ -93,57 +82,6 @@ public:
 
         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,
@@ -166,8 +104,6 @@ public:
         JIT_FLAG_UNUSED31                = 62,
         JIT_FLAG_UNUSED32                = 63
 
-#endif // !defined(TARGET_ARM64) && !defined(TARGET_X86) && !defined(TARGET_AMD64)
-
     };
     // clang-format on
 
@@ -187,29 +123,29 @@ public:
         m_jitFlags = 0;
     }
 
-    void Set(JitFlag flag)
+    CORINFO_InstructionSetFlags GetInstructionSetFlags() const
     {
-        m_jitFlags |= 1ULL << (unsigned __int64)flag;
+        return m_instructionSetFlags;
     }
 
-    void Clear(JitFlag flag)
+    void SetInstructionSetFlags(CORINFO_InstructionSetFlags instructionSetFlags)
     {
-        m_jitFlags &= ~(1ULL << (unsigned __int64)flag);
+        m_instructionSetFlags = instructionSetFlags;
     }
 
-    bool IsSet(JitFlag flag) const
+    void Set(JitFlag flag)
     {
-        return (m_jitFlags & (1ULL << (unsigned __int64)flag)) != 0;
+        m_jitFlags |= 1ULL << (unsigned __int64)flag;
     }
 
-    void Add(const JitFlags& other)
+    void Clear(JitFlag flag)
     {
-        m_jitFlags |= other.m_jitFlags;
+        m_jitFlags &= ~(1ULL << (unsigned __int64)flag);
     }
 
-    void Remove(const JitFlags& other)
+    bool IsSet(JitFlag flag) const
     {
-        m_jitFlags &= ~other.m_jitFlags;
+        return (m_jitFlags & (1ULL << (unsigned __int64)flag)) != 0;
     }
 
     bool IsEmpty() const
@@ -222,8 +158,9 @@ public:
         // 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(m_jitFlags) == sizeof(CORJIT_FLAGS));
+        C_ASSERT(sizeof(JitFlags) == sizeof(CORJIT_FLAGS));
 
 #define FLAGS_EQUAL(a, b) C_ASSERT((unsigned)(a) == (unsigned)(b))
 
@@ -242,15 +179,6 @@ public:
         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
 
@@ -290,50 +218,10 @@ public:
 #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;
+    unsigned __int64            m_jitFlags;
+    CORINFO_InstructionSetFlags m_instructionSetFlags;
 };
index 6a695a1..b9de46d 100644 (file)
@@ -994,11 +994,11 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree)
 //
 int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* 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);
+    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);
 
     GenTree* op1    = intrinsicTree->gtGetOp1();
     GenTree* op2    = intrinsicTree->gtGetOp2();
index 19c914e..2578cd7 100644 (file)
@@ -2286,11 +2286,11 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree)
 //
 int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* 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);
+    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);
 
     // 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
index d49fa60..8ca69e3 100644 (file)
@@ -73,11 +73,6 @@ 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:
index 0da36ab..70123f8 100644 (file)
@@ -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,95 +34,96 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags)
 // available, using the latest kernel for release should be sufficient.
 #ifdef HWCAP_AES
     if (hwCap & HWCAP_AES)
-        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_AES);
+        CPUCompileFlags.Set(InstructionSet_Aes);
 #endif
 #ifdef HWCAP_ATOMICS
     if (hwCap & HWCAP_ATOMICS)
-        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ATOMICS);
+        CPUCompileFlags.Set(InstructionSet_Atomics);
 #endif
 #ifdef HWCAP_CRC32
     if (hwCap & HWCAP_CRC32)
-        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_CRC32);
+        CPUCompileFlags.Set(InstructionSet_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(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA1);
+        CPUCompileFlags.Set(InstructionSet_Sha1);
 #endif
 #ifdef HWCAP_SHA2
     if (hwCap & HWCAP_SHA2)
-        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA256);
+        CPUCompileFlags.Set(InstructionSet_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(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD);
+        CPUCompileFlags.Set(InstructionSet_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(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD);
-    CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP);
+    CPUCompileFlags.Set(InstructionSet_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
new file mode 100644 (file)
index 0000000..aff37ab
--- /dev/null
@@ -0,0 +1,134 @@
+
+// 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");
+            }
+        }
+    }
+}
index 1fadcd5..5dfeee4 100644 (file)
@@ -2854,13 +2854,36 @@ namespace Internal.JitInterface
             if (targetArchitecture == TargetArchitecture.ARM && !_compilation.TypeSystemContext.Target.IsWindows)
                 flags.Set(CorJitFlag.CORJIT_FLAG_RELATIVE_CODE_RELOCS);
 
-            if ((targetArchitecture == TargetArchitecture.X86
-                || targetArchitecture == TargetArchitecture.X64)
+            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 READYTORUN
-                && isMethodDefinedInCoreLib()
+                    flags.Set(InstructionSet.X86_SSE41);
+                    flags.Set(InstructionSet.X86_SSE42);
+                    flags.Set(InstructionSet.X86_POPCNT);
 #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.
@@ -2868,19 +2891,29 @@ namespace Internal.JitInterface
                 // 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(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);
+                {
+                    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);
 #if READYTORUN
-                flags.Set(CorJitFlag.CORJIT_FLAG_USE_SSE41);
-                flags.Set(CorJitFlag.CORJIT_FLAG_USE_SSE42);
-                flags.Set(CorJitFlag.CORJIT_FLAG_USE_POPCNT);
+                    flags.Set(InstructionSet.X64_SSE41);
+                    flags.Set(InstructionSet.X64_SSE42);
+                    flags.Set(InstructionSet.X64_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
new file mode 100644 (file)
index 0000000..470faeb
--- /dev/null
@@ -0,0 +1,317 @@
+
+// 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<KeyValuePair<string,InstructionSet>> ArchitectureToValidInstructionSets(TargetArchitecture architecture)
+        {
+            switch (architecture)
+            {
+
+                case TargetArchitecture.ARM64:
+                    yield return new KeyValuePair<string, InstructionSet>("ArmBase", InstructionSet.ARM64_ArmBase);
+                    yield return new KeyValuePair<string, InstructionSet>("AdvSimd", InstructionSet.ARM64_AdvSimd);
+                    yield return new KeyValuePair<string, InstructionSet>("Aes", InstructionSet.ARM64_Aes);
+                    yield return new KeyValuePair<string, InstructionSet>("Crc32", InstructionSet.ARM64_Crc32);
+                    yield return new KeyValuePair<string, InstructionSet>("Sha1", InstructionSet.ARM64_Sha1);
+                    yield return new KeyValuePair<string, InstructionSet>("Sha256", InstructionSet.ARM64_Sha256);
+                    yield return new KeyValuePair<string, InstructionSet>("Atomics", InstructionSet.ARM64_Atomics);
+                    yield return new KeyValuePair<string, InstructionSet>("Vector64", InstructionSet.ARM64_Vector64);
+                    yield return new KeyValuePair<string, InstructionSet>("Vector128", InstructionSet.ARM64_Vector128);
+                    break;
+
+                case TargetArchitecture.X64:
+                    yield return new KeyValuePair<string, InstructionSet>("Sse", InstructionSet.X64_SSE);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse2", InstructionSet.X64_SSE2);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse3", InstructionSet.X64_SSE3);
+                    yield return new KeyValuePair<string, InstructionSet>("Ssse3", InstructionSet.X64_SSSE3);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse41", InstructionSet.X64_SSE41);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse42", InstructionSet.X64_SSE42);
+                    yield return new KeyValuePair<string, InstructionSet>("Avx", InstructionSet.X64_AVX);
+                    yield return new KeyValuePair<string, InstructionSet>("Avx2", InstructionSet.X64_AVX2);
+                    yield return new KeyValuePair<string, InstructionSet>("Aes", InstructionSet.X64_AES);
+                    yield return new KeyValuePair<string, InstructionSet>("Bmi1", InstructionSet.X64_BMI1);
+                    yield return new KeyValuePair<string, InstructionSet>("Bmi2", InstructionSet.X64_BMI2);
+                    yield return new KeyValuePair<string, InstructionSet>("Fma", InstructionSet.X64_FMA);
+                    yield return new KeyValuePair<string, InstructionSet>("Lzcnt", InstructionSet.X64_LZCNT);
+                    yield return new KeyValuePair<string, InstructionSet>("Pclmulqdq", InstructionSet.X64_PCLMULQDQ);
+                    yield return new KeyValuePair<string, InstructionSet>("Popcnt", InstructionSet.X64_POPCNT);
+                    yield return new KeyValuePair<string, InstructionSet>("Vector128", InstructionSet.X64_Vector128);
+                    yield return new KeyValuePair<string, InstructionSet>("Vector256", InstructionSet.X64_Vector256);
+                    break;
+
+                case TargetArchitecture.X86:
+                    yield return new KeyValuePair<string, InstructionSet>("Sse", InstructionSet.X86_SSE);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse2", InstructionSet.X86_SSE2);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse3", InstructionSet.X86_SSE3);
+                    yield return new KeyValuePair<string, InstructionSet>("Ssse3", InstructionSet.X86_SSSE3);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse41", InstructionSet.X86_SSE41);
+                    yield return new KeyValuePair<string, InstructionSet>("Sse42", InstructionSet.X86_SSE42);
+                    yield return new KeyValuePair<string, InstructionSet>("Avx", InstructionSet.X86_AVX);
+                    yield return new KeyValuePair<string, InstructionSet>("Avx2", InstructionSet.X86_AVX2);
+                    yield return new KeyValuePair<string, InstructionSet>("Aes", InstructionSet.X86_AES);
+                    yield return new KeyValuePair<string, InstructionSet>("Bmi1", InstructionSet.X86_BMI1);
+                    yield return new KeyValuePair<string, InstructionSet>("Bmi2", InstructionSet.X86_BMI2);
+                    yield return new KeyValuePair<string, InstructionSet>("Fma", InstructionSet.X86_FMA);
+                    yield return new KeyValuePair<string, InstructionSet>("Lzcnt", InstructionSet.X86_LZCNT);
+                    yield return new KeyValuePair<string, InstructionSet>("Pclmulqdq", InstructionSet.X86_PCLMULQDQ);
+                    yield return new KeyValuePair<string, InstructionSet>("Popcnt", InstructionSet.X86_POPCNT);
+                    yield return new KeyValuePair<string, InstructionSet>("Vector128", InstructionSet.X86_Vector128);
+                    yield return new KeyValuePair<string, InstructionSet>("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;
+
+            }
+        }
+    }
+}
index 1647c4f..64d4a06 100644 (file)
@@ -5,6 +5,7 @@
 using System;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
+using Internal.TypeSystem;
 
 namespace Internal.JitInterface
 {
@@ -1296,9 +1297,6 @@ namespace Internal.JitInterface
         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
@@ -1325,49 +1323,12 @@ namespace Internal.JitInterface
         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()
         {
@@ -1379,6 +1340,11 @@ namespace Internal.JitInterface
             _corJitFlags |= 1UL << (int)flag;
         }
 
+        public void Set(InstructionSet instructionSet)
+        {
+            _instructionSetFlags.AddInstructionSet(instructionSet);
+        }
+
         public void Clear(CorJitFlag flag)
         {
             _corJitFlags &= ~(1UL << (int)flag);
@@ -1389,19 +1355,9 @@ namespace Internal.JitInterface
             return (_corJitFlags & (1UL << (int)flag)) != 0;
         }
 
-        public void Add(ref CORJIT_FLAGS other)
-        {
-            _corJitFlags |= other._corJitFlags;
-        }
-
-        public void Remove(ref CORJIT_FLAGS other)
-        {
-            _corJitFlags &= ~other._corJitFlags;
-        }
-
-        public bool IsEmpty()
+        public void Set64BitInstructionSetVariants(TargetArchitecture architecture)
         {
-            return _corJitFlags == 0;
+            _instructionSetFlags.Set64BitInstructionSetVariants(architecture);
         }
     }
 }
diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
new file mode 100644 (file)
index 0000000..9c8404f
--- /dev/null
@@ -0,0 +1,81 @@
+; Define the set of instruction sets available on a platform
+; Format is 
+;
+; Add new instruction set
+; instructionset,<architecture>,<managed name>,<r2r name if different>,<R2R numeric value>, <jit instruction set name>
+;
+; Add jit 64bit architecture specific instruction set when instruction set is available
+; instructionset64bit,<architecture>,<jit instruction set name>
+;
+; Add an instruction set implication (i.e, if instruction set A is present, then instruction set B must be present too.)
+; implication,<architecture>,<jit instruction set name>,<implied jit instruction set name>
+;
+; Copy instruction sets defined for other architecture at this point in the file.
+; copyinstructionsets,<architecture>,<copytoarchitecture>
+
+; 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
new file mode 100644 (file)
index 0000000..3d5ea11
--- /dev/null
@@ -0,0 +1,645 @@
+// 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<InstructionSetInfo> _instructionSets = new List<InstructionSetInfo>();
+        List<InstructionSetImplication> _implications = new List<InstructionSetImplication>();
+        Dictionary<string, HashSet<string>> _64bitVariants = new Dictionary<string, HashSet<string>>();
+        SortedDictionary<string,int> _r2rNamesByName = new SortedDictionary<string,int>();
+        SortedDictionary<int,string> _r2rNamesByNumber = new SortedDictionary<int,string>();
+        SortedSet<string> _architectures = new SortedSet<string>();
+        Dictionary<string,List<string>> _architectureJitNames = new Dictionary<string,List<string>>();
+        HashSet<string> _64BitArchitectures = new HashSet<string>();
+        Dictionary<string,string> _64BitVariantArchitectureJitNameSuffix = new Dictionary<string,string>();
+
+        void ArchitectureEncountered(string arch)
+        {
+            if (!_64bitVariants.ContainsKey(arch))
+                _64bitVariants.Add(arch, new HashSet<string>());
+            _architectures.Add(arch);
+            if (!_architectureJitNames.ContainsKey(arch))
+                _architectureJitNames.Add(arch, new List<string>());
+        }
+
+        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<KeyValuePair<string,InstructionSet>> 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<string, InstructionSet>(\"{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
index 78b5132..94fa406 100644 (file)
@@ -493,16 +493,49 @@ public:
 
         static void Main(string[] args)
         {
-            IEnumerable<FunctionDecl> functions = ParseInput(new StreamReader(args[0]));
-            using (TextWriter tw = new StreamWriter(args[1]))
+            if (args[0] == "InstructionSetGenerator")
             {
-                Console.WriteLine("Generating {0}", args[1]);
-                WriteManagedThunkInterface(tw, functions);
+                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);
+                }
             }
-            using (TextWriter tw = new StreamWriter(args[2]))
+            else
             {
-                Console.WriteLine("Generating {0}", args[2]);
-                WriteNativeWrapperInterface(tw, functions);
+                IEnumerable<FunctionDecl> 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);
+                }
             }
         }
     }
index 46328b5..f90ce45 100644 (file)
@@ -1,2 +1,4 @@
-cd /d %~dp0
-dotnet run -- ThunkInput.txt ..\CorInfoBase.cs ..\..\..\crossgen2\jitinterface\jitinterface.h
\ No newline at end of file
+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
index 59672c7..041e410 100755 (executable)
@@ -1,3 +1,4 @@
 #!/usr/bin/env bash
 cd "$(dirname ${BASH_SOURCE[0]})"
-dotnet run -- ThunkInput.txt ../CorInfoBase.cs ../../../crossgen2/jitinterface/jitinterface.h
+../../../../../../../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
index 9c41651..a1e95d8 100644 (file)
     <Compile Include="..\..\Common\JitInterface\CorInfoTypes.cs">
       <Link>JitInterface\CorInfoTypes.cs</Link>
     </Compile>
+    <Compile Include="..\..\Common\JitInterface\CorInfoInstructionSet.cs">
+      <Link>JitInterface\CorInfoInstructionSet.cs</Link>
+    </Compile>
     <Compile Include="..\..\Common\JitInterface\JitConfigProvider.cs">
       <Link>JitInterface\JitConfigProvider.cs</Link>
     </Compile>
index fbc0170..621b291 100644 (file)
@@ -27,11 +27,11 @@ private:
     uint64_t corJitFlags;
 };
 
-static const GUID JITEEVersionIdentifier = { /* c231d2d7-4764-4097-a9ef-5961041540df */
-    0xc231d2d7,
-    0x4764,
-    0x4097,
-    {0xa9, 0xef, 0x59, 0x61, 0x04, 0x15, 0x40, 0xdf}
+static const GUID JITEEVersionIdentifier = { /* 54305fa1-a0d8-42e4-a6b4-b750a8143467 */
+    0x54305fa1,
+    0xa0d8,
+    0x42e4,
+    {0xa6, 0xb4, 0xb7, 0x50, 0xa8, 0x14, 0x34, 0x67}
 };
 
 class Jit
index 5b3fcb8..9b3a276 100644 (file)
@@ -1296,11 +1296,6 @@ 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)
@@ -1372,46 +1367,48 @@ 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(CORJIT_FLAGS::CORJIT_FLAG_USE_AES);
+                CPUCompileFlags.Set(InstructionSet_AES);
             }
 
             if ((buffer[8] & 0x02) != 0)                                    // PCLMULQDQ
             {
-                CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_PCLMULQDQ);
+                CPUCompileFlags.Set(InstructionSet_PCLMULQDQ);
             }
 
             if ((buffer[8] & 0x01) != 0)                                    // SSE3
             {
-                CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3);
+                CPUCompileFlags.Set(InstructionSet_SSE3);
 
                 if ((buffer[9] & 0x02) != 0)                                // SSSE3
                 {
-                    CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSSE3);
+                    CPUCompileFlags.Set(InstructionSet_SSSE3);
 
                     if ((buffer[10] & 0x08) != 0)                           // SSE4.1
                     {
-                        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE41);
+                        CPUCompileFlags.Set(InstructionSet_SSE41);
 
                         if ((buffer[10] & 0x10) != 0)                       // SSE4.2
                         {
-                            CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE42);
+                            CPUCompileFlags.Set(InstructionSet_SSE42);
 
                             if ((buffer[10] & 0x80) != 0)                   // POPCNT
                             {
-                                CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_POPCNT);
+                                CPUCompileFlags.Set(InstructionSet_POPCNT);
                             }
 
                             if ((buffer[11] & 0x18) == 0x18)                // AVX & OSXSAVE
                             {
                                 if(DoesOSSupportAVX() && (xmmYmmStateSupport() == 1))
                                 {
-                                    CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX);
+                                    CPUCompileFlags.Set(InstructionSet_AVX);
 
                                     if ((buffer[9] & 0x10) != 0)            // FMA
                                     {
-                                        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FMA);
+                                        CPUCompileFlags.Set(InstructionSet_FMA);
                                     }
 
                                     if (maxCpuId >= 0x07)
@@ -1420,7 +1417,7 @@ void EEJitManager::SetCpuInfo()
 
                                         if ((buffer[4] & 0x20) != 0)        // AVX2
                                         {
-                                            CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2);
+                                            CPUCompileFlags.Set(InstructionSet_AVX2);
                                         }
                                     }
                                 }
@@ -1439,7 +1436,7 @@ void EEJitManager::SetCpuInfo()
 
             if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SIMD16ByteOnly) != 0)
             {
-                CPUCompileFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2);
+                CPUCompileFlags.Clear(InstructionSet_AVX2);
             }
         }
 
@@ -1449,14 +1446,16 @@ void EEJitManager::SetCpuInfo()
 
             if ((buffer[4] & 0x08) != 0)            // BMI1
             {
-                CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_BMI1);
+                CPUCompileFlags.Set(InstructionSet_BMI1);
             }
 
             if ((buffer[5] & 0x01) != 0)            // BMI2
             {
-                CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_BMI2);
+                CPUCompileFlags.Set(InstructionSet_BMI2);
             }
         }
+
+        CPUCompileFlags.EnsureValidInstructionSetSupport();
     }
 
     DWORD maxCpuIdEx = getcpuid(0x80000000, buffer);
@@ -1471,7 +1470,7 @@ void EEJitManager::SetCpuInfo()
 
         if ((buffer[8] & 0x20) != 0)            // LZCNT
         {
-            CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_LZCNT);
+            CPUCompileFlags.Set(InstructionSet_LZCNT);
         }
     }
 #endif // defined(TARGET_X86) || defined(TARGET_AMD64)
@@ -1486,23 +1485,25 @@ void EEJitManager::SetCpuInfo()
     PAL_GetJitCpuCapabilityFlags(&CPUCompileFlags);
 #elif defined(HOST_64BIT)
     // FP and SIMD support are enabled by default
-    CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ADVSIMD);
-    CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP);
+    CPUCompileFlags.Set(InstructionSet_ArmBase);
+    CPUCompileFlags.Set(InstructionSet_AdvSimd);
     // PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE (30)
     if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))
     {
-        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);
+        CPUCompileFlags.Set(InstructionSet_Aes);
+        CPUCompileFlags.Set(InstructionSet_Sha1);
+        CPUCompileFlags.Set(InstructionSet_Sha256);
     }
     // PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE (31)
     if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))
     {
-        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_CRC32);
+        CPUCompileFlags.Set(InstructionSet_Crc32);
     }
 #endif // HOST_64BIT
 #endif // TARGET_ARM64
 
+    CPUCompileFlags.Set64BitInstructionSetVariants();
+
     m_CPUCompileFlags = CPUCompileFlags;
 }
 
index a11f605..70388bd 100644 (file)
@@ -1181,10 +1181,17 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo)
     }
 
     // .NET Core requires SSE2.
-    m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2);
-
 #endif // TARGET_X86
 
+#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
+
 #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64)
     // If we're crossgenning CoreLib, allow generating non-VEX intrinsics. The generated code might
     // not actually be supported by the processor at runtime so we compensate for it by
@@ -1198,21 +1205,24 @@ 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(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);
+        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);
         // 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(CORJIT_FLAGS::CORJIT_FLAG_USE_LZCNT);
+        m_pOpt->m_compilerFlags.Set(InstructionSet_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)