Skip to content

Commit 89c89dd

Browse files
authored
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`
1 parent d9953f7 commit 89c89dd

12 files changed

+226
-70
lines changed

src/coreclr/inc/corinfoinstructionset.h

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,27 @@ enum CORINFO_InstructionSet
5757
InstructionSet_Vector128=17,
5858
InstructionSet_Vector256=18,
5959
InstructionSet_AVXVNNI=19,
60-
InstructionSet_X86Base_X64=20,
61-
InstructionSet_SSE_X64=21,
62-
InstructionSet_SSE2_X64=22,
63-
InstructionSet_SSE3_X64=23,
64-
InstructionSet_SSSE3_X64=24,
65-
InstructionSet_SSE41_X64=25,
66-
InstructionSet_SSE42_X64=26,
67-
InstructionSet_AVX_X64=27,
68-
InstructionSet_AVX2_X64=28,
69-
InstructionSet_AES_X64=29,
70-
InstructionSet_BMI1_X64=30,
71-
InstructionSet_BMI2_X64=31,
72-
InstructionSet_FMA_X64=32,
73-
InstructionSet_LZCNT_X64=33,
74-
InstructionSet_PCLMULQDQ_X64=34,
75-
InstructionSet_POPCNT_X64=35,
76-
InstructionSet_AVXVNNI_X64=36,
60+
InstructionSet_Sha1=20,
61+
InstructionSet_Sha256=21,
62+
InstructionSet_SHA=22,
63+
InstructionSet_X86Base_X64=23,
64+
InstructionSet_SSE_X64=24,
65+
InstructionSet_SSE2_X64=25,
66+
InstructionSet_SSE3_X64=26,
67+
InstructionSet_SSSE3_X64=27,
68+
InstructionSet_SSE41_X64=28,
69+
InstructionSet_SSE42_X64=29,
70+
InstructionSet_AVX_X64=30,
71+
InstructionSet_AVX2_X64=31,
72+
InstructionSet_AES_X64=32,
73+
InstructionSet_BMI1_X64=33,
74+
InstructionSet_BMI2_X64=34,
75+
InstructionSet_FMA_X64=35,
76+
InstructionSet_LZCNT_X64=36,
77+
InstructionSet_PCLMULQDQ_X64=37,
78+
InstructionSet_POPCNT_X64=38,
79+
InstructionSet_AVXVNNI_X64=39,
80+
InstructionSet_SHA_X64=40,
7781
#endif // TARGET_AMD64
7882
#ifdef TARGET_X86
7983
InstructionSet_X86Base=1,
@@ -95,23 +99,27 @@ enum CORINFO_InstructionSet
9599
InstructionSet_Vector128=17,
96100
InstructionSet_Vector256=18,
97101
InstructionSet_AVXVNNI=19,
98-
InstructionSet_X86Base_X64=20,
99-
InstructionSet_SSE_X64=21,
100-
InstructionSet_SSE2_X64=22,
101-
InstructionSet_SSE3_X64=23,
102-
InstructionSet_SSSE3_X64=24,
103-
InstructionSet_SSE41_X64=25,
104-
InstructionSet_SSE42_X64=26,
105-
InstructionSet_AVX_X64=27,
106-
InstructionSet_AVX2_X64=28,
107-
InstructionSet_AES_X64=29,
108-
InstructionSet_BMI1_X64=30,
109-
InstructionSet_BMI2_X64=31,
110-
InstructionSet_FMA_X64=32,
111-
InstructionSet_LZCNT_X64=33,
112-
InstructionSet_PCLMULQDQ_X64=34,
113-
InstructionSet_POPCNT_X64=35,
114-
InstructionSet_AVXVNNI_X64=36,
102+
InstructionSet_Sha1=20,
103+
InstructionSet_Sha256=21,
104+
InstructionSet_SHA=22,
105+
InstructionSet_X86Base_X64=23,
106+
InstructionSet_SSE_X64=24,
107+
InstructionSet_SSE2_X64=25,
108+
InstructionSet_SSE3_X64=26,
109+
InstructionSet_SSSE3_X64=27,
110+
InstructionSet_SSE41_X64=28,
111+
InstructionSet_SSE42_X64=29,
112+
InstructionSet_AVX_X64=30,
113+
InstructionSet_AVX2_X64=31,
114+
InstructionSet_AES_X64=32,
115+
InstructionSet_BMI1_X64=33,
116+
InstructionSet_BMI2_X64=34,
117+
InstructionSet_FMA_X64=35,
118+
InstructionSet_LZCNT_X64=36,
119+
InstructionSet_PCLMULQDQ_X64=37,
120+
InstructionSet_POPCNT_X64=38,
121+
InstructionSet_AVXVNNI_X64=39,
122+
InstructionSet_SHA_X64=40,
115123
#endif // TARGET_X86
116124

117125
};
@@ -211,6 +219,8 @@ struct CORINFO_InstructionSetFlags
211219
AddInstructionSet(InstructionSet_POPCNT_X64);
212220
if (HasInstructionSet(InstructionSet_AVXVNNI))
213221
AddInstructionSet(InstructionSet_AVXVNNI_X64);
222+
if (HasInstructionSet(InstructionSet_SHA))
223+
AddInstructionSet(InstructionSet_SHA_X64);
214224
#endif // TARGET_AMD64
215225
#ifdef TARGET_X86
216226
#endif // TARGET_X86
@@ -352,6 +362,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins
352362
resultflags.RemoveInstructionSet(InstructionSet_AVXVNNI);
353363
if (resultflags.HasInstructionSet(InstructionSet_AVXVNNI_X64) && !resultflags.HasInstructionSet(InstructionSet_AVXVNNI))
354364
resultflags.RemoveInstructionSet(InstructionSet_AVXVNNI_X64);
365+
if (resultflags.HasInstructionSet(InstructionSet_SHA) && !resultflags.HasInstructionSet(InstructionSet_SHA_X64))
366+
resultflags.RemoveInstructionSet(InstructionSet_SHA);
367+
if (resultflags.HasInstructionSet(InstructionSet_SHA_X64) && !resultflags.HasInstructionSet(InstructionSet_SHA))
368+
resultflags.RemoveInstructionSet(InstructionSet_SHA_X64);
355369
if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base))
356370
resultflags.RemoveInstructionSet(InstructionSet_SSE);
357371
if (resultflags.HasInstructionSet(InstructionSet_SSE2) && !resultflags.HasInstructionSet(InstructionSet_SSE))
@@ -382,6 +396,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins
382396
resultflags.RemoveInstructionSet(InstructionSet_POPCNT);
383397
if (resultflags.HasInstructionSet(InstructionSet_Vector256) && !resultflags.HasInstructionSet(InstructionSet_AVX))
384398
resultflags.RemoveInstructionSet(InstructionSet_Vector256);
399+
if (resultflags.HasInstructionSet(InstructionSet_Sha1) && !resultflags.HasInstructionSet(InstructionSet_SHA))
400+
resultflags.RemoveInstructionSet(InstructionSet_Sha1);
401+
if (resultflags.HasInstructionSet(InstructionSet_Sha256) && !resultflags.HasInstructionSet(InstructionSet_SHA))
402+
resultflags.RemoveInstructionSet(InstructionSet_Sha256);
385403
#endif // TARGET_AMD64
386404
#ifdef TARGET_X86
387405
if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base))
@@ -414,6 +432,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins
414432
resultflags.RemoveInstructionSet(InstructionSet_POPCNT);
415433
if (resultflags.HasInstructionSet(InstructionSet_Vector256) && !resultflags.HasInstructionSet(InstructionSet_AVX))
416434
resultflags.RemoveInstructionSet(InstructionSet_Vector256);
435+
if (resultflags.HasInstructionSet(InstructionSet_Sha1) && !resultflags.HasInstructionSet(InstructionSet_SHA))
436+
resultflags.RemoveInstructionSet(InstructionSet_Sha1);
437+
if (resultflags.HasInstructionSet(InstructionSet_Sha256) && !resultflags.HasInstructionSet(InstructionSet_SHA))
438+
resultflags.RemoveInstructionSet(InstructionSet_Sha256);
417439
#endif // TARGET_X86
418440

419441
} while (!oldflags.Equals(resultflags));
@@ -544,6 +566,14 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet)
544566
return "AVXVNNI";
545567
case InstructionSet_AVXVNNI_X64 :
546568
return "AVXVNNI_X64";
569+
case InstructionSet_Sha1 :
570+
return "Sha1";
571+
case InstructionSet_Sha256 :
572+
return "Sha256";
573+
case InstructionSet_SHA :
574+
return "SHA";
575+
case InstructionSet_SHA_X64 :
576+
return "SHA_X64";
547577
#endif // TARGET_AMD64
548578
#ifdef TARGET_X86
549579
case InstructionSet_X86Base :
@@ -584,6 +614,12 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet)
584614
return "Vector256";
585615
case InstructionSet_AVXVNNI :
586616
return "AVXVNNI";
617+
case InstructionSet_Sha1 :
618+
return "Sha1";
619+
case InstructionSet_Sha256 :
620+
return "Sha256";
621+
case InstructionSet_SHA :
622+
return "SHA";
587623
#endif // TARGET_X86
588624

589625
default:
@@ -632,6 +668,7 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst
632668
case READYTORUN_INSTRUCTION_Pclmulqdq: return InstructionSet_PCLMULQDQ;
633669
case READYTORUN_INSTRUCTION_Popcnt: return InstructionSet_POPCNT;
634670
case READYTORUN_INSTRUCTION_AvxVnni: return InstructionSet_AVXVNNI;
671+
case READYTORUN_INSTRUCTION_Sha: return InstructionSet_SHA;
635672
#endif // TARGET_AMD64
636673
#ifdef TARGET_X86
637674
case READYTORUN_INSTRUCTION_X86Base: return InstructionSet_X86Base;
@@ -651,6 +688,7 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst
651688
case READYTORUN_INSTRUCTION_Pclmulqdq: return InstructionSet_PCLMULQDQ;
652689
case READYTORUN_INSTRUCTION_Popcnt: return InstructionSet_POPCNT;
653690
case READYTORUN_INSTRUCTION_AvxVnni: return InstructionSet_AVXVNNI;
691+
case READYTORUN_INSTRUCTION_Sha: return InstructionSet_SHA;
654692
#endif // TARGET_X86
655693

656694
default:

src/coreclr/inc/readytoruninstructionset.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ enum ReadyToRunInstructionSet
3434
READYTORUN_INSTRUCTION_Dp=23,
3535
READYTORUN_INSTRUCTION_Rdm=24,
3636
READYTORUN_INSTRUCTION_AvxVnni=25,
37+
READYTORUN_INSTRUCTION_Sha=26,
3738

3839
};
3940

src/coreclr/jit/emitxarch.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ bool emitter::IsBMIInstruction(instruction ins)
5454
return (ins >= INS_FIRST_BMI_INSTRUCTION) && (ins <= INS_LAST_BMI_INSTRUCTION);
5555
}
5656

57+
bool emitter::IsSHAInstruction(instruction ins)
58+
{
59+
return (ins >= INS_sha1msg1) && (ins <= INS_sha256rnds2);
60+
}
61+
5762
regNumber emitter::getBmiRegNumber(instruction ins)
5863
{
5964
switch (ins)

src/coreclr/jit/hwintrinsiccodegenxarch.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
397397
case InstructionSet_BMI2_X64:
398398
genBMI1OrBMI2Intrinsic(node);
399399
break;
400+
case InstructionSet_SHA:
401+
genSHAIntrinsic(node);
402+
break;
400403
case InstructionSet_FMA:
401404
genFMAIntrinsic(node);
402405
break;
@@ -2023,6 +2026,22 @@ void CodeGen::genBMI1OrBMI2Intrinsic(GenTreeHWIntrinsic* node)
20232026
genProduceReg(node);
20242027
}
20252028

2029+
void CodeGen::genSHAIntrinsic(GenTreeHWIntrinsic* node) {
2030+
NamedIntrinsic intrinsicId = node->GetHWIntrinsicId();
2031+
regNumber targetReg = node->GetRegNum();
2032+
var_types targetType = node->TypeGet();
2033+
instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, targetType);
2034+
emitter* emit = GetEmitter();
2035+
2036+
assert(targetReg != REG_NA);
2037+
2038+
// TODO: Generate SHA Intrinsic
2039+
2040+
genConsumeMultiOpOperands(node);
2041+
2042+
genProduceReg(node);
2043+
}
2044+
20262045
//------------------------------------------------------------------------
20272046
// genFMAIntrinsic: Generates the code for an FMA hardware intrinsic node
20282047
//

src/coreclr/jit/hwintrinsiclistxarch.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,25 @@ HARDWARE_INTRINSIC(SSE2, UCOMISD,
799799
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)
800800
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)
801801

802+
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
803+
// ISA Function name SIMD size NumArg Instructions Category Flags
804+
// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
805+
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
806+
// Sha1 Intrinsics
807+
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)
808+
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)
809+
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)
810+
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)
811+
812+
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
813+
// ISA Function name SIMD size NumArg Instructions Category Flags
814+
// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
815+
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
816+
// Sha256 Intrinsics
817+
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)
818+
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)
819+
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)
820+
802821
#endif // FEATURE_HW_INTRINSIC
803822

804823
#undef HARDWARE_INTRINSIC

0 commit comments

Comments
 (0)