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)
#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}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
--- /dev/null
+
+// 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
#ifndef _COR_JIT_FLAGS_H_
#define _COR_JIT_FLAGS_H_
+#include "corinfoinstructionset.h"
+
class CORJIT_FLAGS
{
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)
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,
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,
CORJIT_FLAG_UNUSED30 = 61,
CORJIT_FLAG_UNUSED31 = 62,
CORJIT_FLAG_UNUSED32 = 63
-
-#endif // !defined(TARGET_ARM64) &&!defined(TARGET_X86) && !defined(TARGET_AMD64)
};
CORJIT_FLAGS()
CORJIT_FLAGS(const CORJIT_FLAGS& other)
{
corJitFlags = other.corJitFlags;
+ instructionSetFlags = other.instructionSetFlags;
}
void Reset()
{
corJitFlags = 0;
+ instructionSetFlags.Reset();
+ }
+
+ void Set(CORINFO_InstructionSet instructionSet)
+ {
+ instructionSetFlags.AddInstructionSet(instructionSet);
+ }
+
+ void Clear(CORINFO_InstructionSet instructionSet)
+ {
+ instructionSetFlags.RemoveInstructionSet(instructionSet);
+ }
+
+ void Set64BitInstructionSetVariants()
+ {
+ instructionSetFlags.Set64BitInstructionSetVariants();
}
void Set(CorJitFlag flag)
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)
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;
};
--- /dev/null
+
+// 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
#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
// 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)
}
bool mustExpand);
protected:
- bool compSupportsHWIntrinsic(InstructionSet isa);
+ bool compSupportsHWIntrinsic(CORINFO_InstructionSet isa);
GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
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;
#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;
#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
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)
{
//
// 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)) &&
(
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)
{
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);
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);
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);
return lookup(id).name;
}
- static InstructionSet lookupIsa(NamedIntrinsic id)
+ static CORINFO_InstructionSet lookupIsa(NamedIntrinsic id)
{
return lookup(id).isa;
}
//
// Return Value:
// The 64-bit only InstructionSet associated with isa
-static InstructionSet Arm64VersionOfIsa(InstructionSet isa)
+static CORINFO_InstructionSet Arm64VersionOfIsa(CORINFO_InstructionSet isa)
{
switch (isa)
{
//
// Return Value:
// The InstructionSet associated with className
-static InstructionSet lookupInstructionSet(const char* className)
+static CORINFO_InstructionSet lookupInstructionSet(const char* className)
{
assert(className != nullptr);
//
// 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);
//
// Return Value:
// true if isa is supported; otherwise, false
-bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa)
+bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa)
{
switch (isa)
{
//
// Return Value:
// true if isa is scalar; otherwise, false
-bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa)
+bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa)
{
switch (isa)
{
//
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));
//
// Return Value:
// The 64-bit only InstructionSet associated with isa
-static InstructionSet X64VersionOfIsa(InstructionSet isa)
+static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa)
{
switch (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')
//
// 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);
//
// Return Value:
// true if isa is supported; otherwise, false
-bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa)
+bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa)
{
switch (isa)
{
//
// Return Value:
// true if isa is scalar; otherwise, false
-bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa)
+bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa)
{
switch (isa)
{
#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
/*****************************************************************************/
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)
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
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,
JIT_FLAG_UNUSED31 = 62,
JIT_FLAG_UNUSED32 = 63
-#endif // !defined(TARGET_ARM64) && !defined(TARGET_X86) && !defined(TARGET_AMD64)
-
};
// clang-format on
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
// 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))
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
#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;
};
//
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();
//
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
{
// 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:
{
_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.
// 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();
}
--- /dev/null
+
+// 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");
+ }
+ }
+ }
+}
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.
// 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
--- /dev/null
+
+// 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;
+
+ }
+ }
+ }
+}
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
+using Internal.TypeSystem;
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
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()
{
_corJitFlags |= 1UL << (int)flag;
}
+ public void Set(InstructionSet instructionSet)
+ {
+ _instructionSetFlags.AddInstructionSet(instructionSet);
+ }
+
public void Clear(CorJitFlag flag)
{
_corJitFlags &= ~(1UL << (int)flag);
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);
}
}
}
--- /dev/null
+; 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
--- /dev/null
+// 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
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);
+ }
}
}
}
-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
#!/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
<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>
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
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)
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)
if ((buffer[4] & 0x20) != 0) // AVX2
{
- CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2);
+ CPUCompileFlags.Set(InstructionSet_AVX2);
}
}
}
if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SIMD16ByteOnly) != 0)
{
- CPUCompileFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2);
+ CPUCompileFlags.Clear(InstructionSet_AVX2);
}
}
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);
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)
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;
}
}
// .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
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)