From 89c89dd5b9093dfb2ea7dc04e07b3e16738a3b72 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Tue, 4 Jan 2022 00:03:58 +0100 Subject: [PATCH] JIT and VM implementation for SHA instructions (#3) * JIT implementation for SHA instructions * Fix flags * Add `cpuid` check for SHA (29th bit) * Add EnableSHA config value * Add incomplete CodeGen method called `genSHAIntrinsic` --- src/coreclr/inc/corinfoinstructionset.h | 106 +++++++++++------ src/coreclr/inc/readytoruninstructionset.h | 1 + src/coreclr/jit/emitxarch.cpp | 5 + src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 19 +++ src/coreclr/jit/hwintrinsiclistxarch.h | 19 +++ src/coreclr/jit/instrsxarch.h | 15 ++- src/coreclr/jit/jitconfigvalues.h | 1 + .../Runtime/ReadyToRunInstructionSet.cs | 1 + .../Runtime/ReadyToRunInstructionSetHelper.cs | 8 ++ .../JitInterface/CorInfoInstructionSet.cs | 108 ++++++++++++------ .../ThunkGenerator/InstructionSetDesc.txt | 6 + src/coreclr/vm/codeman.cpp | 7 ++ 12 files changed, 226 insertions(+), 70 deletions(-) diff --git a/src/coreclr/inc/corinfoinstructionset.h b/src/coreclr/inc/corinfoinstructionset.h index 39003cb739852..3f4f1eda18a58 100644 --- a/src/coreclr/inc/corinfoinstructionset.h +++ b/src/coreclr/inc/corinfoinstructionset.h @@ -57,23 +57,27 @@ enum CORINFO_InstructionSet InstructionSet_Vector128=17, InstructionSet_Vector256=18, InstructionSet_AVXVNNI=19, - InstructionSet_X86Base_X64=20, - InstructionSet_SSE_X64=21, - InstructionSet_SSE2_X64=22, - InstructionSet_SSE3_X64=23, - InstructionSet_SSSE3_X64=24, - InstructionSet_SSE41_X64=25, - InstructionSet_SSE42_X64=26, - InstructionSet_AVX_X64=27, - InstructionSet_AVX2_X64=28, - InstructionSet_AES_X64=29, - InstructionSet_BMI1_X64=30, - InstructionSet_BMI2_X64=31, - InstructionSet_FMA_X64=32, - InstructionSet_LZCNT_X64=33, - InstructionSet_PCLMULQDQ_X64=34, - InstructionSet_POPCNT_X64=35, - InstructionSet_AVXVNNI_X64=36, + InstructionSet_Sha1=20, + InstructionSet_Sha256=21, + InstructionSet_SHA=22, + InstructionSet_X86Base_X64=23, + InstructionSet_SSE_X64=24, + InstructionSet_SSE2_X64=25, + InstructionSet_SSE3_X64=26, + InstructionSet_SSSE3_X64=27, + InstructionSet_SSE41_X64=28, + InstructionSet_SSE42_X64=29, + InstructionSet_AVX_X64=30, + InstructionSet_AVX2_X64=31, + InstructionSet_AES_X64=32, + InstructionSet_BMI1_X64=33, + InstructionSet_BMI2_X64=34, + InstructionSet_FMA_X64=35, + InstructionSet_LZCNT_X64=36, + InstructionSet_PCLMULQDQ_X64=37, + InstructionSet_POPCNT_X64=38, + InstructionSet_AVXVNNI_X64=39, + InstructionSet_SHA_X64=40, #endif // TARGET_AMD64 #ifdef TARGET_X86 InstructionSet_X86Base=1, @@ -95,23 +99,27 @@ enum CORINFO_InstructionSet InstructionSet_Vector128=17, InstructionSet_Vector256=18, InstructionSet_AVXVNNI=19, - InstructionSet_X86Base_X64=20, - InstructionSet_SSE_X64=21, - InstructionSet_SSE2_X64=22, - InstructionSet_SSE3_X64=23, - InstructionSet_SSSE3_X64=24, - InstructionSet_SSE41_X64=25, - InstructionSet_SSE42_X64=26, - InstructionSet_AVX_X64=27, - InstructionSet_AVX2_X64=28, - InstructionSet_AES_X64=29, - InstructionSet_BMI1_X64=30, - InstructionSet_BMI2_X64=31, - InstructionSet_FMA_X64=32, - InstructionSet_LZCNT_X64=33, - InstructionSet_PCLMULQDQ_X64=34, - InstructionSet_POPCNT_X64=35, - InstructionSet_AVXVNNI_X64=36, + InstructionSet_Sha1=20, + InstructionSet_Sha256=21, + InstructionSet_SHA=22, + InstructionSet_X86Base_X64=23, + InstructionSet_SSE_X64=24, + InstructionSet_SSE2_X64=25, + InstructionSet_SSE3_X64=26, + InstructionSet_SSSE3_X64=27, + InstructionSet_SSE41_X64=28, + InstructionSet_SSE42_X64=29, + InstructionSet_AVX_X64=30, + InstructionSet_AVX2_X64=31, + InstructionSet_AES_X64=32, + InstructionSet_BMI1_X64=33, + InstructionSet_BMI2_X64=34, + InstructionSet_FMA_X64=35, + InstructionSet_LZCNT_X64=36, + InstructionSet_PCLMULQDQ_X64=37, + InstructionSet_POPCNT_X64=38, + InstructionSet_AVXVNNI_X64=39, + InstructionSet_SHA_X64=40, #endif // TARGET_X86 }; @@ -211,6 +219,8 @@ struct CORINFO_InstructionSetFlags AddInstructionSet(InstructionSet_POPCNT_X64); if (HasInstructionSet(InstructionSet_AVXVNNI)) AddInstructionSet(InstructionSet_AVXVNNI_X64); + if (HasInstructionSet(InstructionSet_SHA)) + AddInstructionSet(InstructionSet_SHA_X64); #endif // TARGET_AMD64 #ifdef TARGET_X86 #endif // TARGET_X86 @@ -352,6 +362,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_AVXVNNI); if (resultflags.HasInstructionSet(InstructionSet_AVXVNNI_X64) && !resultflags.HasInstructionSet(InstructionSet_AVXVNNI)) resultflags.RemoveInstructionSet(InstructionSet_AVXVNNI_X64); + if (resultflags.HasInstructionSet(InstructionSet_SHA) && !resultflags.HasInstructionSet(InstructionSet_SHA_X64)) + resultflags.RemoveInstructionSet(InstructionSet_SHA); + if (resultflags.HasInstructionSet(InstructionSet_SHA_X64) && !resultflags.HasInstructionSet(InstructionSet_SHA)) + resultflags.RemoveInstructionSet(InstructionSet_SHA_X64); if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base)) resultflags.RemoveInstructionSet(InstructionSet_SSE); if (resultflags.HasInstructionSet(InstructionSet_SSE2) && !resultflags.HasInstructionSet(InstructionSet_SSE)) @@ -382,6 +396,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_POPCNT); if (resultflags.HasInstructionSet(InstructionSet_Vector256) && !resultflags.HasInstructionSet(InstructionSet_AVX)) resultflags.RemoveInstructionSet(InstructionSet_Vector256); + if (resultflags.HasInstructionSet(InstructionSet_Sha1) && !resultflags.HasInstructionSet(InstructionSet_SHA)) + resultflags.RemoveInstructionSet(InstructionSet_Sha1); + if (resultflags.HasInstructionSet(InstructionSet_Sha256) && !resultflags.HasInstructionSet(InstructionSet_SHA)) + resultflags.RemoveInstructionSet(InstructionSet_Sha256); #endif // TARGET_AMD64 #ifdef TARGET_X86 if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base)) @@ -414,6 +432,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_POPCNT); if (resultflags.HasInstructionSet(InstructionSet_Vector256) && !resultflags.HasInstructionSet(InstructionSet_AVX)) resultflags.RemoveInstructionSet(InstructionSet_Vector256); + if (resultflags.HasInstructionSet(InstructionSet_Sha1) && !resultflags.HasInstructionSet(InstructionSet_SHA)) + resultflags.RemoveInstructionSet(InstructionSet_Sha1); + if (resultflags.HasInstructionSet(InstructionSet_Sha256) && !resultflags.HasInstructionSet(InstructionSet_SHA)) + resultflags.RemoveInstructionSet(InstructionSet_Sha256); #endif // TARGET_X86 } while (!oldflags.Equals(resultflags)); @@ -544,6 +566,14 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet) return "AVXVNNI"; case InstructionSet_AVXVNNI_X64 : return "AVXVNNI_X64"; + case InstructionSet_Sha1 : + return "Sha1"; + case InstructionSet_Sha256 : + return "Sha256"; + case InstructionSet_SHA : + return "SHA"; + case InstructionSet_SHA_X64 : + return "SHA_X64"; #endif // TARGET_AMD64 #ifdef TARGET_X86 case InstructionSet_X86Base : @@ -584,6 +614,12 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet) return "Vector256"; case InstructionSet_AVXVNNI : return "AVXVNNI"; + case InstructionSet_Sha1 : + return "Sha1"; + case InstructionSet_Sha256 : + return "Sha256"; + case InstructionSet_SHA : + return "SHA"; #endif // TARGET_X86 default: @@ -632,6 +668,7 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst case READYTORUN_INSTRUCTION_Pclmulqdq: return InstructionSet_PCLMULQDQ; case READYTORUN_INSTRUCTION_Popcnt: return InstructionSet_POPCNT; case READYTORUN_INSTRUCTION_AvxVnni: return InstructionSet_AVXVNNI; + case READYTORUN_INSTRUCTION_Sha: return InstructionSet_SHA; #endif // TARGET_AMD64 #ifdef TARGET_X86 case READYTORUN_INSTRUCTION_X86Base: return InstructionSet_X86Base; @@ -651,6 +688,7 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst case READYTORUN_INSTRUCTION_Pclmulqdq: return InstructionSet_PCLMULQDQ; case READYTORUN_INSTRUCTION_Popcnt: return InstructionSet_POPCNT; case READYTORUN_INSTRUCTION_AvxVnni: return InstructionSet_AVXVNNI; + case READYTORUN_INSTRUCTION_Sha: return InstructionSet_SHA; #endif // TARGET_X86 default: diff --git a/src/coreclr/inc/readytoruninstructionset.h b/src/coreclr/inc/readytoruninstructionset.h index 1b66c6e520891..06e56452c41ad 100644 --- a/src/coreclr/inc/readytoruninstructionset.h +++ b/src/coreclr/inc/readytoruninstructionset.h @@ -34,6 +34,7 @@ enum ReadyToRunInstructionSet READYTORUN_INSTRUCTION_Dp=23, READYTORUN_INSTRUCTION_Rdm=24, READYTORUN_INSTRUCTION_AvxVnni=25, + READYTORUN_INSTRUCTION_Sha=26, }; diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 8b0ba91a873aa..af385f4298918 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -54,6 +54,11 @@ bool emitter::IsBMIInstruction(instruction ins) return (ins >= INS_FIRST_BMI_INSTRUCTION) && (ins <= INS_LAST_BMI_INSTRUCTION); } +bool emitter::IsSHAInstruction(instruction ins) +{ + return (ins >= INS_sha1msg1) && (ins <= INS_sha256rnds2); +} + regNumber emitter::getBmiRegNumber(instruction ins) { switch (ins) diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index cd9e0f8f8fc3d..d4d35d8224bba 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -397,6 +397,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case InstructionSet_BMI2_X64: genBMI1OrBMI2Intrinsic(node); break; + case InstructionSet_SHA: + genSHAIntrinsic(node); + break; case InstructionSet_FMA: genFMAIntrinsic(node); break; @@ -2023,6 +2026,22 @@ void CodeGen::genBMI1OrBMI2Intrinsic(GenTreeHWIntrinsic* node) genProduceReg(node); } +void CodeGen::genSHAIntrinsic(GenTreeHWIntrinsic* node) { + NamedIntrinsic intrinsicId = node->GetHWIntrinsicId(); + regNumber targetReg = node->GetRegNum(); + var_types targetType = node->TypeGet(); + instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, targetType); + emitter* emit = GetEmitter(); + + assert(targetReg != REG_NA); + + // TODO: Generate SHA Intrinsic + + genConsumeMultiOpOperands(node); + + genProduceReg(node); +} + //------------------------------------------------------------------------ // genFMAIntrinsic: Generates the code for an FMA hardware intrinsic node // diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index ce66b6e690604..aba6e992a108f 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -799,6 +799,25 @@ HARDWARE_INTRINSIC(SSE2, UCOMISD, HARDWARE_INTRINSIC(SSE41, PTEST, 16, 2, {INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX, PTEST, 0, 2, {INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_vtestps, INS_vtestpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// Sha1 Intrinsics +HARDWARE_INTRINSIC(Sha1, MessageSchedule1, 16, 2, {INS_invalid, INS_sha1msg1, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Sha1, MessageSchedule2, 16, 2, {INS_invalid, INS_sha1msg2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Sha1, NextE, 16, 2, {INS_invalid, INS_sha1nexte, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Sha1, FourRounds, 16, 3, {INS_invalid, INS_sha1rnds4, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// Sha256 Intrinsics +HARDWARE_INTRINSIC(Sha256, MessageSchedule1, 16, 2, {INS_invalid, INS_sha256msg1, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Sha256, MessageSchedule2, 16, 2, {INS_invalid, INS_sha256msg2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Sha256, TwoRounds, 16, 3, {INS_invalid, INS_sha256rnds2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) + #endif // FEATURE_HW_INTRINSIC #undef HARDWARE_INTRINSIC diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 458f919fe2793..612f7f2342dc5 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -621,6 +621,17 @@ INST3(lzcnt, "lzcnt", IUM_WR, BAD_CODE, BAD_CODE, // POPCNT INST3(popcnt, "popcnt", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xB8), Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Resets_CF ) +// SHA1 +INST3(sha1rnds4, "sha1rnds4", IUM_WR, BAD_CODE, BAD_CODE, 0xcc, INS_FLAGS_None ) +INST2(sha1nexte, "sha1nexte", IUM_WR, BAD_CODE, 0xc8, INS_FLAGS_None ) +INST2(sha1msg1, "sha1msg1", IUM_WR, BAD_CODE, 0xc9, INS_FLAGS_None ) +INST2(sha1msg2, "sha1msg2", IUM_WR, BAD_CODE, 0xca, INS_FLAGS_None ) + +// SHA256 +INST3(sha256rnds2, "sha256rnds2", IUM_WR, BAD_CODE, BAD_CODE, 0xcb, INS_FLAGS_None ) +INST2(sha256msg1, "sha256msg1", IUM_WR, BAD_CODE, 0xcc, INS_FLAGS_None ) +INST2(sha256msg2, "sha256msg2", IUM_WR, BAD_CODE, 0xcd, INS_FLAGS_NoneF ) + // id nm um mr mi flags INST2(ret, "ret", IUM_RD, 0x0000C3, 0x0000C2, INS_FLAGS_None ) INST2(loop, "loop", IUM_RD, BAD_CODE, 0x0000E2, INS_FLAGS_None ) @@ -635,9 +646,9 @@ INST2(ror_N, "ror", IUM_RW, 0x0008C0, 0x0008C0, INST2(rcl, "rcl", IUM_RW, 0x0010D2, BAD_CODE, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) INST2(rcl_1, "rcl", IUM_RW, 0x0010D0, 0x0010D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) -INST2(rcl_N, "rcl", IUM_RW, 0x0010C0, 0x0010C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcl_N, "rcl", IUM_RW, 0x0010C0, 0x0010C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) INST2(rcr, "rcr", IUM_RW, 0x0018D2, BAD_CODE, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) -INST2(rcr_1, "rcr", IUM_RW, 0x0018D0, 0x0018D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr_1, "rcr", IUM_RW, 0x0018D0, 0x0018D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) INST2(rcr_N, "rcr", IUM_RW, 0x0018C0, 0x0018C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) INST2(shl, "shl", IUM_RW, 0x0020D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) INST2(shl_1, "shl", IUM_RW, 0x0020D0, 0x0020D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 73b71a07a8c49..4fc37389c9815 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -303,6 +303,7 @@ CONFIG_INTEGER(EnableFMA, W("EnableFMA"), 1) // Enable FMA CONFIG_INTEGER(EnableAES, W("EnableAES"), 1) // Enable AES CONFIG_INTEGER(EnableBMI1, W("EnableBMI1"), 1) // Enable BMI1 CONFIG_INTEGER(EnableBMI2, W("EnableBMI2"), 1) // Enable BMI2 +CONFIG_INTEGER(EnableSHA, W("EnableSHA"), 1) // Enable SHA CONFIG_INTEGER(EnableLZCNT, W("EnableLZCNT"), 1) // Enable AES CONFIG_INTEGER(EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1) // Enable PCLMULQDQ CONFIG_INTEGER(EnablePOPCNT, W("EnablePOPCNT"), 1) // Enable POPCNT diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs index ea4aa13ded125..19a63ce4963f9 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs @@ -37,6 +37,7 @@ public enum ReadyToRunInstructionSet Dp=23, Rdm=24, AvxVnni=25, + Sha=26, } } diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs index ffc302a827567..205c055ed3508 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs @@ -88,6 +88,10 @@ public static class ReadyToRunInstructionSetHelper case InstructionSet.X64_Vector256: return null; case InstructionSet.X64_AVXVNNI: return ReadyToRunInstructionSet.AvxVnni; case InstructionSet.X64_AVXVNNI_X64: return ReadyToRunInstructionSet.AvxVnni; + case InstructionSet.X64_Sha1: return null; + case InstructionSet.X64_Sha256: return null; + case InstructionSet.X64_SHA: return ReadyToRunInstructionSet.Sha; + case InstructionSet.X64_SHA_X64: return ReadyToRunInstructionSet.Sha; default: throw new Exception("Unknown instruction set"); } @@ -133,6 +137,10 @@ public static class ReadyToRunInstructionSetHelper case InstructionSet.X86_Vector256: return null; case InstructionSet.X86_AVXVNNI: return ReadyToRunInstructionSet.AvxVnni; case InstructionSet.X86_AVXVNNI_X64: return null; + case InstructionSet.X86_Sha1: return null; + case InstructionSet.X86_Sha256: return null; + case InstructionSet.X86_SHA: return ReadyToRunInstructionSet.Sha; + case InstructionSet.X86_SHA_X64: return null; default: throw new Exception("Unknown instruction set"); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs index f1ffa0a0cd4eb..926399d444e8a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs @@ -56,23 +56,27 @@ public enum InstructionSet X64_Vector128=17, X64_Vector256=18, X64_AVXVNNI=19, - X64_X86Base_X64=20, - X64_SSE_X64=21, - X64_SSE2_X64=22, - X64_SSE3_X64=23, - X64_SSSE3_X64=24, - X64_SSE41_X64=25, - X64_SSE42_X64=26, - X64_AVX_X64=27, - X64_AVX2_X64=28, - X64_AES_X64=29, - X64_BMI1_X64=30, - X64_BMI2_X64=31, - X64_FMA_X64=32, - X64_LZCNT_X64=33, - X64_PCLMULQDQ_X64=34, - X64_POPCNT_X64=35, - X64_AVXVNNI_X64=36, + X64_Sha1=20, + X64_Sha256=21, + X64_SHA=22, + X64_X86Base_X64=23, + X64_SSE_X64=24, + X64_SSE2_X64=25, + X64_SSE3_X64=26, + X64_SSSE3_X64=27, + X64_SSE41_X64=28, + X64_SSE42_X64=29, + X64_AVX_X64=30, + X64_AVX2_X64=31, + X64_AES_X64=32, + X64_BMI1_X64=33, + X64_BMI2_X64=34, + X64_FMA_X64=35, + X64_LZCNT_X64=36, + X64_PCLMULQDQ_X64=37, + X64_POPCNT_X64=38, + X64_AVXVNNI_X64=39, + X64_SHA_X64=40, X86_X86Base=1, X86_SSE=2, X86_SSE2=3, @@ -92,23 +96,27 @@ public enum InstructionSet X86_Vector128=17, X86_Vector256=18, X86_AVXVNNI=19, - X86_X86Base_X64=20, - X86_SSE_X64=21, - X86_SSE2_X64=22, - X86_SSE3_X64=23, - X86_SSSE3_X64=24, - X86_SSE41_X64=25, - X86_SSE42_X64=26, - X86_AVX_X64=27, - X86_AVX2_X64=28, - X86_AES_X64=29, - X86_BMI1_X64=30, - X86_BMI2_X64=31, - X86_FMA_X64=32, - X86_LZCNT_X64=33, - X86_PCLMULQDQ_X64=34, - X86_POPCNT_X64=35, - X86_AVXVNNI_X64=36, + X86_Sha1=20, + X86_Sha256=21, + X86_SHA=22, + X86_X86Base_X64=23, + X86_SSE_X64=24, + X86_SSE2_X64=25, + X86_SSE3_X64=26, + X86_SSSE3_X64=27, + X86_SSE41_X64=28, + X86_SSE42_X64=29, + X86_AVX_X64=30, + X86_AVX2_X64=31, + X86_AES_X64=32, + X86_BMI1_X64=33, + X86_BMI2_X64=34, + X86_FMA_X64=35, + X86_LZCNT_X64=36, + X86_PCLMULQDQ_X64=37, + X86_POPCNT_X64=38, + X86_AVXVNNI_X64=39, + X86_SHA_X64=40, } @@ -306,6 +314,10 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X64_AVXVNNI_X64); if (resultflags.HasInstructionSet(InstructionSet.X64_AVXVNNI_X64)) resultflags.AddInstructionSet(InstructionSet.X64_AVXVNNI); + if (resultflags.HasInstructionSet(InstructionSet.X64_SHA)) + resultflags.AddInstructionSet(InstructionSet.X64_SHA_X64); + if (resultflags.HasInstructionSet(InstructionSet.X64_SHA_X64)) + resultflags.AddInstructionSet(InstructionSet.X64_SHA); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE)) resultflags.AddInstructionSet(InstructionSet.X64_X86Base); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE2)) @@ -336,6 +348,10 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X64_SSE42); if (resultflags.HasInstructionSet(InstructionSet.X64_Vector256)) resultflags.AddInstructionSet(InstructionSet.X64_AVX); + if (resultflags.HasInstructionSet(InstructionSet.X64_Sha1)) + resultflags.AddInstructionSet(InstructionSet.X64_SHA); + if (resultflags.HasInstructionSet(InstructionSet.X64_Sha256)) + resultflags.AddInstructionSet(InstructionSet.X64_SHA); break; case TargetArchitecture.X86: @@ -369,6 +385,10 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X86_SSE42); if (resultflags.HasInstructionSet(InstructionSet.X86_Vector256)) resultflags.AddInstructionSet(InstructionSet.X86_AVX); + if (resultflags.HasInstructionSet(InstructionSet.X86_Sha1)) + resultflags.AddInstructionSet(InstructionSet.X86_SHA); + if (resultflags.HasInstructionSet(InstructionSet.X86_Sha256)) + resultflags.AddInstructionSet(InstructionSet.X86_SHA); break; } @@ -459,6 +479,8 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X64_POPCNT); if (resultflags.HasInstructionSet(InstructionSet.X64_AVXVNNI_X64)) resultflags.AddInstructionSet(InstructionSet.X64_AVXVNNI); + if (resultflags.HasInstructionSet(InstructionSet.X64_SHA_X64)) + resultflags.AddInstructionSet(InstructionSet.X64_SHA); if (resultflags.HasInstructionSet(InstructionSet.X64_X86Base)) resultflags.AddInstructionSet(InstructionSet.X64_SSE); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE)) @@ -489,6 +511,10 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X64_POPCNT); if (resultflags.HasInstructionSet(InstructionSet.X64_AVX)) resultflags.AddInstructionSet(InstructionSet.X64_Vector256); + if (resultflags.HasInstructionSet(InstructionSet.X64_SHA)) + resultflags.AddInstructionSet(InstructionSet.X64_Sha1); + if (resultflags.HasInstructionSet(InstructionSet.X64_SHA)) + resultflags.AddInstructionSet(InstructionSet.X64_Sha256); break; case TargetArchitecture.X86: @@ -522,6 +548,10 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X86_POPCNT); if (resultflags.HasInstructionSet(InstructionSet.X86_AVX)) resultflags.AddInstructionSet(InstructionSet.X86_Vector256); + if (resultflags.HasInstructionSet(InstructionSet.X86_SHA)) + resultflags.AddInstructionSet(InstructionSet.X86_Sha1); + if (resultflags.HasInstructionSet(InstructionSet.X86_SHA)) + resultflags.AddInstructionSet(InstructionSet.X86_Sha256); break; } @@ -585,6 +615,9 @@ public static IEnumerable ArchitectureToValidInstructionSets yield return new InstructionSetInfo("Vector128", "", InstructionSet.X64_Vector128, false); yield return new InstructionSetInfo("Vector256", "", InstructionSet.X64_Vector256, false); yield return new InstructionSetInfo("avxvnni", "AvxVnni", InstructionSet.X64_AVXVNNI, true); + yield return new InstructionSetInfo("Sha1", "", InstructionSet.X64_Sha1, false); + yield return new InstructionSetInfo("Sha256", "", InstructionSet.X64_Sha256, false); + yield return new InstructionSetInfo("sha", "Sha", InstructionSet.X64_SHA, true); break; case TargetArchitecture.X86: @@ -607,6 +640,9 @@ public static IEnumerable ArchitectureToValidInstructionSets yield return new InstructionSetInfo("Vector128", "", InstructionSet.X86_Vector128, false); yield return new InstructionSetInfo("Vector256", "", InstructionSet.X86_Vector256, false); yield return new InstructionSetInfo("avxvnni", "AvxVnni", InstructionSet.X86_AVXVNNI, true); + yield return new InstructionSetInfo("Sha1", "", InstructionSet.X86_Sha1, false); + yield return new InstructionSetInfo("Sha256", "", InstructionSet.X86_Sha256, false); + yield return new InstructionSetInfo("sha", "Sha", InstructionSet.X86_SHA, true); break; } @@ -671,6 +707,8 @@ public void Set64BitInstructionSetVariants(TargetArchitecture architecture) AddInstructionSet(InstructionSet.X64_POPCNT_X64); if (HasInstructionSet(InstructionSet.X64_AVXVNNI)) AddInstructionSet(InstructionSet.X64_AVXVNNI_X64); + if (HasInstructionSet(InstructionSet.X64_SHA)) + AddInstructionSet(InstructionSet.X64_SHA_X64); break; case TargetArchitecture.X86: @@ -713,6 +751,7 @@ public void Set64BitInstructionSetVariantsUnconditionally(TargetArchitecture arc AddInstructionSet(InstructionSet.X64_PCLMULQDQ_X64); AddInstructionSet(InstructionSet.X64_POPCNT_X64); AddInstructionSet(InstructionSet.X64_AVXVNNI_X64); + AddInstructionSet(InstructionSet.X64_SHA_X64); break; case TargetArchitecture.X86: @@ -733,6 +772,7 @@ public void Set64BitInstructionSetVariantsUnconditionally(TargetArchitecture arc AddInstructionSet(InstructionSet.X86_PCLMULQDQ_X64); AddInstructionSet(InstructionSet.X86_POPCNT_X64); AddInstructionSet(InstructionSet.X86_AVXVNNI_X64); + AddInstructionSet(InstructionSet.X86_SHA_X64); break; } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt index 8bfdc9a9d86a7..1e89514b50778 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt @@ -41,6 +41,9 @@ instructionset ,X86 ,Popcnt , ,15 ,POPCNT ,popcnt instructionset ,X86 , , , ,Vector128, instructionset ,X86 , , , ,Vector256, instructionset ,X86 ,AvxVnni , ,25 ,AVXVNNI ,avxvnni +instructionset ,X86 , , , ,Sha1 , +instructionset ,X86 , , , ,Sha256 , +instructionset ,X86 ,Sha , ,26 ,SHA ,sha instructionset64bit,X86 ,X86Base instructionset64bit,X86 ,SSE @@ -59,6 +62,7 @@ instructionset64bit,X86 ,LZCNT instructionset64bit,X86 ,PCLMULQDQ instructionset64bit,X86 ,POPCNT instructionset64bit,X86 ,AVXVNNI +instructionset64bit,X86 ,SHA implication ,X86 ,SSE ,X86Base implication ,X86 ,SSE2 ,SSE @@ -75,6 +79,8 @@ implication ,X86 ,FMA ,AVX implication ,X86 ,PCLMULQDQ ,SSE2 implication ,X86 ,POPCNT ,SSE42 implication ,X86 ,Vector256 ,AVX +implication ,X86 ,Sha1 ,SHA +implication ,X86 ,Sha256 ,SHA ; Definition of X64 instruction sets definearch ,X64 ,64Bit ,X64 diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 56805d6a3534f..98bc9dbe4b9d5 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1309,6 +1309,8 @@ void EEJitManager::SetCpuInfo() // BMI1 - EBX bit 3 // CORJIT_FLAG_USE_BMI2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): // BMI2 - EBX bit 8 + // CORJIT_FLAG_USE_SHA if the following feature bit is set (input EAX of 0x07 and input ECX of 0): + // SHA - EBX bit 29 // CORJIT_FLAG_USE_LZCNT if the following feature bits are set (input EAX of 80000001H) // LZCNT - ECX bit 5 // synchronously updating VM and JIT. @@ -1422,6 +1424,11 @@ void EEJitManager::SetCpuInfo() { CPUCompileFlags.Set(InstructionSet_BMI2); } + + if ((cpuidInfo[EBX] & (1 << 29)) != 0) // SHA + { + CPUCompileFlags.Set(InstructionSet_SHA); + } } }