From a332497a021c35d17079522eebb26680173962dd Mon Sep 17 00:00:00 2001 From: Debayan Ghosh Date: Wed, 28 Feb 2018 21:51:38 +0530 Subject: [PATCH] ARM64 SHA256 Crypto intrinsics implementation --- src/inc/corjitflags.h | 2 +- src/jit/emitarm64.cpp | 11 ++++++ src/jit/hwintrinsiclistArm64.h | 7 +++- src/jit/instr.h | 2 +- src/jit/instrsarm64.h | 12 +++++++ src/jit/jitee.h | 2 +- src/mscorlib/System.Private.CoreLib.csproj | 2 ++ .../Arm/Arm64/Sha256.PlatformNotSupported.cs | 41 ++++++++++++++++++++++ .../System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs | 41 ++++++++++++++++++++++ src/pal/src/misc/jitsupport.cpp | 2 +- 10 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs create mode 100644 src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs diff --git a/src/inc/corjitflags.h b/src/inc/corjitflags.h index da303b6..84fb42f 100644 --- a/src/inc/corjitflags.h +++ b/src/inc/corjitflags.h @@ -120,7 +120,7 @@ public: 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_SHA2 = 55, // ID_AA64ISAR0_EL1.SHA2 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 diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp index 1b41280..7d5af2e 100644 --- a/src/jit/emitarm64.cpp +++ b/src/jit/emitarm64.cpp @@ -4316,6 +4316,7 @@ void emitter::emitIns_R_R( fmt = IF_DR_2J; break; + case INS_sha256su0: case INS_sha1su1: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); @@ -5387,6 +5388,9 @@ void emitter::emitIns_R_R_R( fmt = IF_LS_3D; break; + case INS_sha256h: + case INS_sha256h2: + case INS_sha256su1: case INS_sha1su0: case INS_sha1c: case INS_sha1p: @@ -11438,6 +11442,13 @@ void emitter::emitDispIns( emitDispReg(id->idReg2(), EA_4BYTE, true); emitDispVectorReg(id->idReg3(), id->idInsOpt(), false); } + else if ((ins == INS_sha256h) || (ins == INS_sha256h2)) + { + // Qd Qn Vm (vector) + emitDispReg(id->idReg1(), size, true); + emitDispReg(id->idReg2(), size, true); + emitDispVectorReg(id->idReg3(), id->idInsOpt(), false); + } else { emitDispVectorReg(id->idReg1(), id->idInsOpt(), true); diff --git a/src/jit/hwintrinsiclistArm64.h b/src/jit/hwintrinsiclistArm64.h index 05d910f..ffc8d39 100644 --- a/src/jit/hwintrinsiclistArm64.h +++ b/src/jit/hwintrinsiclistArm64.h @@ -23,7 +23,7 @@ HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_JSCVT , Jscvt ) HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_LRCPC , Lrcpc ) HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_PMULL , Pmull ) HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_SHA1 , Sha1 ) -HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_SHA2 , Sha2 ) +HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_SHA256 , Sha256 ) HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_SHA512 , Sha512 ) HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_SHA3 , Sha3 ) HARDWARE_INTRINSIC_CLASS(JIT_FLAG_HAS_ARM64_SIMD , Simd ) @@ -94,6 +94,11 @@ HARDWARE_INTRINSIC(NI_ARM64_Sha1FixedRotate, Sha1, FixedRotate, HARDWARE_INTRINSIC(NI_ARM64_Sha1SchedulePart1, Sha1, SchedulePart1, SimdTernaryRMWOp, INS_invalid, INS_invalid, INS_sha1su0, None ) HARDWARE_INTRINSIC(NI_ARM64_Sha1SchedulePart2, Sha1, SchedulePart2, SimdBinaryRMWOp, INS_invalid, INS_invalid, INS_sha1su1, None ) +//Sha256 +HARDWARE_INTRINSIC(NI_ARM64_Sha256HashLower, Sha256, HashLower, SimdTernaryRMWOp, INS_invalid, INS_invalid, INS_sha256h, None ) +HARDWARE_INTRINSIC(NI_ARM64_Sha256HashUpper, Sha256, HashUpper, SimdTernaryRMWOp, INS_invalid, INS_invalid, INS_sha256h2, None ) +HARDWARE_INTRINSIC(NI_ARM64_Sha256SchedulePart1, Sha256, SchedulePart1, SimdBinaryRMWOp, INS_invalid, INS_invalid, INS_sha256su0, None ) +HARDWARE_INTRINSIC(NI_ARM64_Sha256SchedulePart2, Sha256, SchedulePart2, SimdTernaryRMWOp, INS_invalid, INS_invalid, INS_sha256su1, None ) #endif diff --git a/src/jit/instr.h b/src/jit/instr.h index 7838fa4..c7be413 100644 --- a/src/jit/instr.h +++ b/src/jit/instr.h @@ -314,7 +314,7 @@ enum InstructionSet 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_Sha2, // ID_AA64ISAR0_EL1.SHA2 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_Simd, // ID_AA64PFR0_EL1.AdvSIMD is 0 or better diff --git a/src/jit/instrsarm64.h b/src/jit/instrsarm64.h index ee5feae..8f5971b 100644 --- a/src/jit/instrsarm64.h +++ b/src/jit/instrsarm64.h @@ -935,6 +935,18 @@ INST1(sha1su0, "sha1su0", 0, 0, IF_DV_3F, 0x5E003000) INST1(sha1su1, "sha1su1", 0, 0, IF_DV_2P, 0x5E281800) // sha1su1 Vd.4S, Vn.4S DV_2P 0101111000101000 000110nnnnnddddd 5E28 1800 Vd.4S Vn.4S (vector) + +INST1(sha256h, "sha256h", 0, 0, IF_DV_3F, 0x5E004000) + // sha256h Qd,Qn,Vm.4S DV_3F 01011110000mmmmm 010000nnnnnddddd 5E00 4000 Qd Qn Vm.4S (vector) + +INST1(sha256h2, "sha256h2", 0, 0, IF_DV_3F, 0x5E005000) + // sha256h Qd,Qn,Vm.4S DV_3F 01011110000mmmmm 010100nnnnnddddd 5E00 5000 Qd Qn Vm.4S (vector) + +INST1(sha256su0, "sha256su0", 0, 0, IF_DV_2P, 0x5E282800) + // sha256su0 Vd.4S,Vn.4S DV_2P 0101111000101000 001010nnnnnddddd 5E28 2800 Vd.4S Vn.4S (vector) + +INST1(sha256su1, "sha256su1", 0, 0, IF_DV_3F, 0x5E006000) + // sha256su1 Vd.4S,Vn.4S,Vm.4S DV_3F 01011110000mmmmm 011000nnnnnddddd 5E00 6000 Vd.4S Vn.4S Vm.4S (vector) INST1(sbfm, "sbfm", 0, 0, IF_DI_2D, 0x13000000) // sbfm Rd,Rn,imr,ims DI_2D X00100110Nrrrrrr ssssssnnnnnddddd 1300 0000 imr, ims diff --git a/src/jit/jitee.h b/src/jit/jitee.h index b36e766..903b3cf 100644 --- a/src/jit/jitee.h +++ b/src/jit/jitee.h @@ -107,7 +107,7 @@ public: 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_SHA2 = 55, // ID_AA64ISAR0_EL1.SHA2 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_SIMD = 58, // ID_AA64PFR0_EL1.AdvSIMD is 0 or better diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj index 44a432f..1da5ccb 100644 --- a/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -300,11 +300,13 @@ + + diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs b/src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs new file mode 100644 index 0000000..052a1d2 --- /dev/null +++ b/src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs @@ -0,0 +1,41 @@ +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +namespace System.Runtime.Intrinsics.Arm.Arm64 +{ + /// + /// This class provides access to the Arm64 SHA256 Crypto intrinsics + /// + /// Arm64 CPU indicate support for this feature by setting + /// ID_AA64ISAR0_EL1.SHA2 is 1 or better + /// + [CLSCompliant(false)] + public static class Sha256 + { + public static bool IsSupported { get { return false; } } + + // + /// Performs SHA256 hash update (part 1). + /// vsha256hq_u32 (uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) + /// + public static Vector128 HashLower(Vector128 hash_abcd, Vector128 hash_efgh, Vector128 wk) { throw new PlatformNotSupportedException(); } + + // + /// Performs SHA256 hash update (part 2). + /// vsha256h2q_u32 (uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) + /// + public static Vector128 HashUpper(Vector128 hash_efgh, Vector128 hash_abcd, Vector128 wk) { throw new PlatformNotSupportedException(); } + + // + /// Performs SHA256 schedule update 0 + /// vsha256su0q_u32 (uint32x4_t w0_3, uint32x4_t w4_7) + /// + public static Vector128 SchedulePart1(Vector128 w0_3, Vector128 w4_7) { throw new PlatformNotSupportedException(); } + + // + /// Performs SHA256 schedule update 1 + /// vsha256su1q_u32 (uint32x4_t w0_3, uint32x4_t w8_11, uint32x4_t w12_15) + /// + public static Vector128 SchedulePart2(Vector128 w0_3, Vector128 w8_11, Vector128 w12_15) { throw new PlatformNotSupportedException(); } + } +} diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs b/src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs new file mode 100644 index 0000000..4e7e51d --- /dev/null +++ b/src/mscorlib/src/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs @@ -0,0 +1,41 @@ +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +namespace System.Runtime.Intrinsics.Arm.Arm64 +{ + /// + /// This class provides access to the Arm64 SHA256 Crypto intrinsics + /// + /// Arm64 CPU indicate support for this feature by setting + /// ID_AA64ISAR0_EL1.SHA2 is 1 or better + /// + [CLSCompliant(false)] + public static class Sha256 + { + public static bool IsSupported { get => IsSupported; } + + // + /// Performs SHA256 hash update (part 1). + /// vsha256hq_u32 (uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) + /// + public static Vector128 HashLower(Vector128 hash_abcd, Vector128 hash_efgh, Vector128 wk) => HashLower(hash_abcd, hash_efgh, wk); + + // + /// Performs SHA256 hash update (part 2). + /// vsha256h2q_u32 (uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) + /// + public static Vector128 HashUpper(Vector128 hash_efgh, Vector128 hash_abcd, Vector128 wk) => HashUpper(hash_efgh, hash_abcd, wk); + + // + /// Performs SHA256 schedule update 0 + /// vsha256su0q_u32 (uint32x4_t w0_3, uint32x4_t w4_7) + /// + public static Vector128 SchedulePart1(Vector128 w0_3, Vector128 w4_7) => SchedulePart1(w0_3, w4_7); + + // + /// Performs SHA256 schedule update 1 + /// vsha256su1q_u32 (uint32x4_t tw0_3, uint32x4_t w8_11, uint32x4_t w12_15) + /// + public static Vector128 SchedulePart2(Vector128 w0_3, Vector128 w8_11, Vector128 w12_15) => SchedulePart2(w0_3, w8_11, w12_15); + } +} diff --git a/src/pal/src/misc/jitsupport.cpp b/src/pal/src/misc/jitsupport.cpp index 917319d..d3d4f1e 100644 --- a/src/pal/src/misc/jitsupport.cpp +++ b/src/pal/src/misc/jitsupport.cpp @@ -86,7 +86,7 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags) #endif #ifdef HWCAP_SHA2 if (hwCap & HWCAP_SHA2) - CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA2); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA256); #endif #ifdef HWCAP_SHA512 if (hwCap & HWCAP_SHA512) -- 2.7.4