From 24b5d122af06f06af1784aff2bb480942fb02522 Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sat, 11 Jul 2026 23:22:26 +0100 Subject: [PATCH 01/10] Restructure SIMD into Facade/Backend layers, remove dispatch units Introduce src/Simd/ with a Facade/ subfolder (arch-agnostic selection) and a Backend/ subfolder (per-hash, per-arch SIMD kernels + runtime tier selection). Each hash's core unit keeps the scalar implementation and calls the SIMD path through its facade, so the cores carry no TCpuFeatures / HASHLIB_*_ASM knowledge. For all 12 primitives (SHA-1, SHA-256, SHA-512, SHA-3, Blake2B, Blake2S, Blake3, XXH3, Adler32, Argon2, Scrypt, CRC): - HlpSimd (Facade) picks the backend at compile time - HlpX86Backend SSE2/SSSE3/AVX2/SHA-NI/PCLMUL kernels + Select - HlpArmBackend NEON/SHA/PMULL kernels + Select Init-time slot selection is preserved: each core's initialization sets its function pointer once via the facade's Select, so TransformBlock pays zero per-call dispatch cost. --- .../Delphi/HashLib.BenchmarkConsole.dpr | 49 +- .../Delphi/HashLib.BenchmarkFMX.dpr | 49 +- .../Delphi.Tests/HashLib.Tests.Mobile.dpr | 49 +- .../Delphi.Tests/HashLib.Tests.Mobile.dproj | 49 +- HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr | 49 +- HashLib/src/Checksum/HlpAdler32.pas | 105 ++- HashLib/src/Checksum/HlpAdler32Dispatch.pas | 255 ------ HashLib/src/Checksum/HlpCRC.pas | 2 +- HashLib/src/Checksum/HlpCRC32Fast.pas | 2 +- .../{HlpCRCDispatch.pas => HlpCRCCore.pas} | 198 +---- HashLib/src/Crypto/HlpBlake2B.pas | 95 ++- HashLib/src/Crypto/HlpBlake2BDispatch.pas | 179 ---- HashLib/src/Crypto/HlpBlake2S.pas | 93 +- HashLib/src/Crypto/HlpBlake2SDispatch.pas | 177 ---- HashLib/src/Crypto/HlpBlake3.pas | 603 ++++++++++++- HashLib/src/Crypto/HlpBlake3Dispatch.pas | 795 ------------------ HashLib/src/Crypto/HlpSHA1.pas | 98 ++- HashLib/src/Crypto/HlpSHA1Dispatch.pas | 253 ------ HashLib/src/Crypto/HlpSHA2_256Base.pas | 97 ++- HashLib/src/Crypto/HlpSHA2_256Dispatch.pas | 272 ------ HashLib/src/Crypto/HlpSHA2_512Base.pas | 116 ++- HashLib/src/Crypto/HlpSHA3.pas | 399 ++++++++- HashLib/src/Crypto/HlpSHA3Dispatch.pas | 554 ------------ HashLib/src/Hash64/HlpXXHash3.pas | 133 ++- HashLib/src/Hash64/HlpXXHash3Dispatch.pas | 299 ------- .../Simd/Adler32/Adler32BlocksSse2_x86_64.inc | 4 +- .../Adler32/Adler32BlocksSsse3_x86_64.inc | 4 +- .../Argon2/Argon2FillBlockAvx2_x86_64.inc | 4 +- .../Argon2/Argon2FillBlockSse2_x86_64.inc | 4 +- .../Blake2B/Blake2BCompressNeon_aarch64.inc | 4 +- .../Blake2B/Blake2BCompressSse2_x86_64.inc | 4 +- .../Blake2S/Blake2SCompressAvx2_x86_64.inc | 4 +- .../Blake2S/Blake2SCompressSse2_x86_64.inc | 4 +- .../Simd/Blake3/Blake3CompressAvx2_x86_64.inc | 4 +- .../Simd/Blake3/Blake3CompressSse2_x86_64.inc | 4 +- .../Simd/Blake3/Blake3Hash4Neon_aarch64.inc | 4 +- .../Simd/Blake3/Blake3Hash4Sse2_x86_64.inc | 4 +- .../Simd/Blake3/Blake3Hash8Avx2_x86_64.inc | 4 +- .../Simd/CRC/CRCFoldForwardPclmul_x86_64.inc | 4 +- .../Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc | 4 +- .../CRC/CRCFoldReflectedPclmul_x86_64.inc | 4 +- .../CRC/CRCFoldReflectedVpclmul_x86_64.inc | 4 +- .../Simd/SHA1/SHA1CompressAvx2_x86_64.inc | 4 +- .../Simd/SHA1/SHA1CompressShaNi_x86_64.inc | 4 +- .../Simd/SHA1/SHA1CompressSse2_x86_64.inc | 4 +- .../Simd/SHA256/SHA256CompressAvx2_x86_64.inc | 4 +- .../SHA256/SHA256CompressShaNi_x86_64.inc | 4 +- .../Simd/SHA256/SHA256CompressSse2_x86_64.inc | 4 +- .../SHA3/KeccakF1600Avx2Absorb_x86_64.inc | 4 +- .../Simd/SHA3/KeccakF1600Avx2_x86_64.inc | 4 +- .../KeccakF1600CryptoExtAbsorb_aarch64.inc | 4 +- .../SHA3/KeccakF1600CryptoExt_aarch64.inc | 4 +- .../Simd/SHA512/SHA512CompressAvx2_x86_64.inc | 4 +- .../Simd/SHA512/SHA512CompressSse2_x86_64.inc | 4 +- HashLib/src/KDF/HlpArgon2Dispatch.pas | 185 ---- .../KDF/HlpPBKDF_Argon2NotBuildInAdapter.pas | 99 ++- .../KDF/HlpPBKDF_ScryptNotBuildInAdapter.pas | 164 +++- HashLib/src/KDF/HlpScryptDispatch.pas | 264 ------ .../Packages/Delphi/HashLib4PascalPackage.dpk | 49 +- .../Packages/FPC/HashLib4PascalPackage.lpk | 152 +++- .../Packages/FPC/HashLib4PascalPackage.pas | 43 +- .../src/Simd/Backend/HlpAdler32ArmBackend.pas | 60 ++ .../src/Simd/Backend/HlpAdler32X86Backend.pas | 116 +++ .../src/Simd/Backend/HlpArgon2ArmBackend.pas | 54 ++ .../src/Simd/Backend/HlpArgon2X86Backend.pas | 79 ++ .../src/Simd/Backend/HlpBlake2BArmBackend.pas | 55 ++ .../src/Simd/Backend/HlpBlake2BX86Backend.pas | 82 ++ .../src/Simd/Backend/HlpBlake2SArmBackend.pas | 55 ++ .../src/Simd/Backend/HlpBlake2SX86Backend.pas | 82 ++ .../src/Simd/Backend/HlpBlake3ArmBackend.pas | 107 +++ .../src/Simd/Backend/HlpBlake3X86Backend.pas | 186 ++++ HashLib/src/Simd/Backend/HlpCRCArmBackend.pas | 70 ++ HashLib/src/Simd/Backend/HlpCRCX86Backend.pas | 148 ++++ .../src/Simd/Backend/HlpSHA1ArmBackend.pas | 58 ++ .../src/Simd/Backend/HlpSHA1X86Backend.pas | 137 +++ .../Simd/Backend/HlpSHA2_256ArmBackend.pas | 58 ++ .../Simd/Backend/HlpSHA2_256X86Backend.pas | 164 ++++ .../Simd/Backend/HlpSHA2_512ArmBackend.pas | 58 ++ .../Backend/HlpSHA2_512X86Backend.pas} | 200 +---- .../src/Simd/Backend/HlpSHA3ArmBackend.pas | 83 ++ .../src/Simd/Backend/HlpSHA3X86Backend.pas | 136 +++ .../src/Simd/Backend/HlpScryptArmBackend.pas | 49 ++ .../src/Simd/Backend/HlpScryptX86Backend.pas | 79 ++ .../src/Simd/Backend/HlpXXHash3ArmBackend.pas | 105 +++ .../src/Simd/Backend/HlpXXHash3X86Backend.pas | 182 ++++ HashLib/src/Simd/Facade/HlpAdler32Simd.pas | 46 + HashLib/src/Simd/Facade/HlpArgon2Simd.pas | 46 + HashLib/src/Simd/Facade/HlpBlake2BSimd.pas | 46 + HashLib/src/Simd/Facade/HlpBlake2SSimd.pas | 46 + HashLib/src/Simd/Facade/HlpBlake3Simd.pas | 70 ++ HashLib/src/Simd/Facade/HlpCRCSimd.pas | 54 ++ HashLib/src/Simd/Facade/HlpSHA1Simd.pas | 48 ++ HashLib/src/Simd/Facade/HlpSHA2_256Simd.pas | 48 ++ HashLib/src/Simd/Facade/HlpSHA2_512Simd.pas | 48 ++ HashLib/src/Simd/Facade/HlpSHA3Simd.pas | 58 ++ HashLib/src/Simd/Facade/HlpScryptSimd.pas | 46 + HashLib/src/Simd/Facade/HlpXXHash3Simd.pas | 82 ++ 97 files changed, 5304 insertions(+), 3779 deletions(-) delete mode 100644 HashLib/src/Checksum/HlpAdler32Dispatch.pas rename HashLib/src/Checksum/{HlpCRCDispatch.pas => HlpCRCCore.pas} (65%) delete mode 100644 HashLib/src/Crypto/HlpBlake2BDispatch.pas delete mode 100644 HashLib/src/Crypto/HlpBlake2SDispatch.pas delete mode 100644 HashLib/src/Crypto/HlpBlake3Dispatch.pas delete mode 100644 HashLib/src/Crypto/HlpSHA1Dispatch.pas delete mode 100644 HashLib/src/Crypto/HlpSHA2_256Dispatch.pas delete mode 100644 HashLib/src/Crypto/HlpSHA3Dispatch.pas delete mode 100644 HashLib/src/Hash64/HlpXXHash3Dispatch.pas delete mode 100644 HashLib/src/KDF/HlpArgon2Dispatch.pas delete mode 100644 HashLib/src/KDF/HlpScryptDispatch.pas create mode 100644 HashLib/src/Simd/Backend/HlpAdler32ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpArgon2ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpBlake2BArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpBlake2SArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpBlake3ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpCRCArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpCRCX86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas rename HashLib/src/{Crypto/HlpSHA2_512Dispatch.pas => Simd/Backend/HlpSHA2_512X86Backend.pas} (51%) create mode 100644 HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpScryptArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpScryptX86Backend.pas create mode 100644 HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas create mode 100644 HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas create mode 100644 HashLib/src/Simd/Facade/HlpAdler32Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpArgon2Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpBlake2BSimd.pas create mode 100644 HashLib/src/Simd/Facade/HlpBlake2SSimd.pas create mode 100644 HashLib/src/Simd/Facade/HlpBlake3Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpCRCSimd.pas create mode 100644 HashLib/src/Simd/Facade/HlpSHA1Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpSHA2_256Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpSHA2_512Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpSHA3Simd.pas create mode 100644 HashLib/src/Simd/Facade/HlpScryptSimd.pas create mode 100644 HashLib/src/Simd/Facade/HlpXXHash3Simd.pas diff --git a/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr b/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr index 56afdff..87d331a 100644 --- a/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr +++ b/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr @@ -20,9 +20,14 @@ uses HlpHMACNotBuildInAdapter in '..\..\HashLib\src\Base\HlpHMACNotBuildInAdapter.pas', HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas', HlpAdler32 in '..\..\HashLib\src\Checksum\HlpAdler32.pas', - HlpAdler32Dispatch in '..\..\HashLib\src\Checksum\HlpAdler32Dispatch.pas', + HlpAdler32Simd in '..\..\HashLib\src\Simd\Facade\HlpAdler32Simd.pas', + HlpAdler32X86Backend in '..\..\HashLib\src\Simd\Backend\HlpAdler32X86Backend.pas', + HlpAdler32ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpAdler32ArmBackend.pas', HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas', - HlpCRCDispatch in '..\..\HashLib\src\Checksum\HlpCRCDispatch.pas', + HlpCRCCore in '..\..\HashLib\src\Checksum\HlpCRCCore.pas', + HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', + HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', + HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', @@ -45,27 +50,39 @@ uses HlpRIPEMD320 in '..\..\HashLib\src\Crypto\HlpRIPEMD320.pas', HlpSHA0 in '..\..\HashLib\src\Crypto\HlpSHA0.pas', HlpSHA1 in '..\..\HashLib\src\Crypto\HlpSHA1.pas', - HlpSHA1Dispatch in '..\..\HashLib\src\Crypto\HlpSHA1Dispatch.pas', + HlpSHA1Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA1Simd.pas', + HlpSHA1X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA1X86Backend.pas', + HlpSHA1ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA1ArmBackend.pas', HlpSHA2_224 in '..\..\HashLib\src\Crypto\HlpSHA2_224.pas', HlpSHA2_256 in '..\..\HashLib\src\Crypto\HlpSHA2_256.pas', - HlpSHA2_256Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_256Dispatch.pas', - HlpSHA2_512Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_512Dispatch.pas', + HlpSHA2_256Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_256Simd.pas', + HlpSHA2_256X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256X86Backend.pas', + HlpSHA2_256ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256ArmBackend.pas', + HlpSHA2_512Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_512Simd.pas', + HlpSHA2_512X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512X86Backend.pas', + HlpSHA2_512ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512ArmBackend.pas', HlpSHA2_256Base in '..\..\HashLib\src\Crypto\HlpSHA2_256Base.pas', HlpSHA2_384 in '..\..\HashLib\src\Crypto\HlpSHA2_384.pas', HlpSHA2_512 in '..\..\HashLib\src\Crypto\HlpSHA2_512.pas', HlpSHA2_512_224 in '..\..\HashLib\src\Crypto\HlpSHA2_512_224.pas', HlpSHA2_512_256 in '..\..\HashLib\src\Crypto\HlpSHA2_512_256.pas', HlpSHA2_512Base in '..\..\HashLib\src\Crypto\HlpSHA2_512Base.pas', - HlpSHA3Dispatch in '..\..\HashLib\src\Crypto\HlpSHA3Dispatch.pas', + HlpSHA3Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA3Simd.pas', + HlpSHA3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA3X86Backend.pas', + HlpSHA3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA3ArmBackend.pas', HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas', HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas', HlpTiger in '..\..\HashLib\src\Crypto\HlpTiger.pas', HlpTiger2 in '..\..\HashLib\src\Crypto\HlpTiger2.pas', HlpWhirlPool in '..\..\HashLib\src\Crypto\HlpWhirlPool.pas', HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas', - HlpBlake2BDispatch in '..\..\HashLib\src\Crypto\HlpBlake2BDispatch.pas', + HlpBlake2BSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2BSimd.pas', + HlpBlake2BX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BX86Backend.pas', + HlpBlake2BArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BArmBackend.pas', HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas', - HlpBlake2SDispatch in '..\..\HashLib\src\Crypto\HlpBlake2SDispatch.pas', + HlpBlake2SSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2SSimd.pas', + HlpBlake2SX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SX86Backend.pas', + HlpBlake2SArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SArmBackend.pas', HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas', HlpBlake2BParams in '..\..\HashLib\src\Crypto\Blake2BParams\HlpBlake2BParams.pas', HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas', @@ -96,7 +113,9 @@ uses HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas', HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas', HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas', - HlpXXHash3Dispatch in '..\..\HashLib\src\Hash64\HlpXXHash3Dispatch.pas', + HlpXXHash3Simd in '..\..\HashLib\src\Simd\Facade\HlpXXHash3Simd.pas', + HlpXXHash3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3X86Backend.pas', + HlpXXHash3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3ArmBackend.pas', HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas', HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas', HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas', @@ -111,14 +130,20 @@ uses HlpIBlake2SParams in '..\..\HashLib\src\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas', HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas', HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas', - HlpBlake3Dispatch in '..\..\HashLib\src\Crypto\HlpBlake3Dispatch.pas', + HlpBlake3Simd in '..\..\HashLib\src\Simd\Facade\HlpBlake3Simd.pas', + HlpBlake3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake3X86Backend.pas', + HlpBlake3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake3ArmBackend.pas', HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas', HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas', HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas', - HlpArgon2Dispatch in '..\..\HashLib\src\KDF\HlpArgon2Dispatch.pas', + HlpArgon2Simd in '..\..\HashLib\src\Simd\Facade\HlpArgon2Simd.pas', + HlpArgon2X86Backend in '..\..\HashLib\src\Simd\Backend\HlpArgon2X86Backend.pas', + HlpArgon2ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpArgon2ArmBackend.pas', HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas', HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas', - HlpScryptDispatch in '..\..\HashLib\src\KDF\HlpScryptDispatch.pas', + HlpScryptSimd in '..\..\HashLib\src\Simd\Facade\HlpScryptSimd.pas', + HlpScryptX86Backend in '..\..\HashLib\src\Simd\Backend\HlpScryptX86Backend.pas', + HlpScryptArmBackend in '..\..\HashLib\src\Simd\Backend\HlpScryptArmBackend.pas', HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas', HlpBitOperations in '..\..\HashLib\src\Utils\HlpBitOperations.pas', HlpBinaryPrimitives in '..\..\HashLib\src\Utils\HlpBinaryPrimitives.pas', diff --git a/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr b/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr index 66c0bfc..9417f11 100644 --- a/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr +++ b/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr @@ -19,9 +19,14 @@ uses HlpHMACNotBuildInAdapter in '..\..\HashLib\src\Base\HlpHMACNotBuildInAdapter.pas', HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas', HlpAdler32 in '..\..\HashLib\src\Checksum\HlpAdler32.pas', - HlpAdler32Dispatch in '..\..\HashLib\src\Checksum\HlpAdler32Dispatch.pas', + HlpAdler32Simd in '..\..\HashLib\src\Simd\Facade\HlpAdler32Simd.pas', + HlpAdler32X86Backend in '..\..\HashLib\src\Simd\Backend\HlpAdler32X86Backend.pas', + HlpAdler32ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpAdler32ArmBackend.pas', HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas', - HlpCRCDispatch in '..\..\HashLib\src\Checksum\HlpCRCDispatch.pas', + HlpCRCCore in '..\..\HashLib\src\Checksum\HlpCRCCore.pas', + HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', + HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', + HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', @@ -44,27 +49,39 @@ uses HlpRIPEMD320 in '..\..\HashLib\src\Crypto\HlpRIPEMD320.pas', HlpSHA0 in '..\..\HashLib\src\Crypto\HlpSHA0.pas', HlpSHA1 in '..\..\HashLib\src\Crypto\HlpSHA1.pas', - HlpSHA1Dispatch in '..\..\HashLib\src\Crypto\HlpSHA1Dispatch.pas', + HlpSHA1Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA1Simd.pas', + HlpSHA1X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA1X86Backend.pas', + HlpSHA1ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA1ArmBackend.pas', HlpSHA2_224 in '..\..\HashLib\src\Crypto\HlpSHA2_224.pas', HlpSHA2_256 in '..\..\HashLib\src\Crypto\HlpSHA2_256.pas', - HlpSHA2_256Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_256Dispatch.pas', - HlpSHA2_512Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_512Dispatch.pas', + HlpSHA2_256Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_256Simd.pas', + HlpSHA2_256X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256X86Backend.pas', + HlpSHA2_256ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256ArmBackend.pas', + HlpSHA2_512Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_512Simd.pas', + HlpSHA2_512X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512X86Backend.pas', + HlpSHA2_512ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512ArmBackend.pas', HlpSHA2_256Base in '..\..\HashLib\src\Crypto\HlpSHA2_256Base.pas', HlpSHA2_384 in '..\..\HashLib\src\Crypto\HlpSHA2_384.pas', HlpSHA2_512 in '..\..\HashLib\src\Crypto\HlpSHA2_512.pas', HlpSHA2_512_224 in '..\..\HashLib\src\Crypto\HlpSHA2_512_224.pas', HlpSHA2_512_256 in '..\..\HashLib\src\Crypto\HlpSHA2_512_256.pas', HlpSHA2_512Base in '..\..\HashLib\src\Crypto\HlpSHA2_512Base.pas', - HlpSHA3Dispatch in '..\..\HashLib\src\Crypto\HlpSHA3Dispatch.pas', + HlpSHA3Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA3Simd.pas', + HlpSHA3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA3X86Backend.pas', + HlpSHA3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA3ArmBackend.pas', HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas', HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas', HlpTiger in '..\..\HashLib\src\Crypto\HlpTiger.pas', HlpTiger2 in '..\..\HashLib\src\Crypto\HlpTiger2.pas', HlpWhirlPool in '..\..\HashLib\src\Crypto\HlpWhirlPool.pas', HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas', - HlpBlake2BDispatch in '..\..\HashLib\src\Crypto\HlpBlake2BDispatch.pas', + HlpBlake2BSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2BSimd.pas', + HlpBlake2BX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BX86Backend.pas', + HlpBlake2BArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BArmBackend.pas', HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas', - HlpBlake2SDispatch in '..\..\HashLib\src\Crypto\HlpBlake2SDispatch.pas', + HlpBlake2SSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2SSimd.pas', + HlpBlake2SX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SX86Backend.pas', + HlpBlake2SArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SArmBackend.pas', HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas', HlpBlake2BParams in '..\..\HashLib\src\Crypto\Blake2BParams\HlpBlake2BParams.pas', HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas', @@ -95,7 +112,9 @@ uses HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas', HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas', HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas', - HlpXXHash3Dispatch in '..\..\HashLib\src\Hash64\HlpXXHash3Dispatch.pas', + HlpXXHash3Simd in '..\..\HashLib\src\Simd\Facade\HlpXXHash3Simd.pas', + HlpXXHash3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3X86Backend.pas', + HlpXXHash3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3ArmBackend.pas', HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas', HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas', HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas', @@ -110,14 +129,20 @@ uses HlpIBlake2SParams in '..\..\HashLib\src\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas', HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas', HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas', - HlpBlake3Dispatch in '..\..\HashLib\src\Crypto\HlpBlake3Dispatch.pas', + HlpBlake3Simd in '..\..\HashLib\src\Simd\Facade\HlpBlake3Simd.pas', + HlpBlake3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake3X86Backend.pas', + HlpBlake3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake3ArmBackend.pas', HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas', HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas', HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas', - HlpArgon2Dispatch in '..\..\HashLib\src\KDF\HlpArgon2Dispatch.pas', + HlpArgon2Simd in '..\..\HashLib\src\Simd\Facade\HlpArgon2Simd.pas', + HlpArgon2X86Backend in '..\..\HashLib\src\Simd\Backend\HlpArgon2X86Backend.pas', + HlpArgon2ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpArgon2ArmBackend.pas', HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas', HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas', - HlpScryptDispatch in '..\..\HashLib\src\KDF\HlpScryptDispatch.pas', + HlpScryptSimd in '..\..\HashLib\src\Simd\Facade\HlpScryptSimd.pas', + HlpScryptX86Backend in '..\..\HashLib\src\Simd\Backend\HlpScryptX86Backend.pas', + HlpScryptArmBackend in '..\..\HashLib\src\Simd\Backend\HlpScryptArmBackend.pas', HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas', HlpBitOperations in '..\..\HashLib\src\Utils\HlpBitOperations.pas', HlpBinaryPrimitives in '..\..\HashLib\src\Utils\HlpBinaryPrimitives.pas', diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr index 6a548b6..a78eb47 100644 --- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr +++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr @@ -21,9 +21,14 @@ uses HlpHMACNotBuildInAdapter in '..\..\HashLib\src\Base\HlpHMACNotBuildInAdapter.pas', HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas', HlpAdler32 in '..\..\HashLib\src\Checksum\HlpAdler32.pas', - HlpAdler32Dispatch in '..\..\HashLib\src\Checksum\HlpAdler32Dispatch.pas', + HlpAdler32Simd in '..\..\HashLib\src\Simd\Facade\HlpAdler32Simd.pas', + HlpAdler32X86Backend in '..\..\HashLib\src\Simd\Backend\HlpAdler32X86Backend.pas', + HlpAdler32ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpAdler32ArmBackend.pas', HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas', - HlpCRCDispatch in '..\..\HashLib\src\Checksum\HlpCRCDispatch.pas', + HlpCRCCore in '..\..\HashLib\src\Checksum\HlpCRCCore.pas', + HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', + HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', + HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', @@ -46,27 +51,39 @@ uses HlpRIPEMD320 in '..\..\HashLib\src\Crypto\HlpRIPEMD320.pas', HlpSHA0 in '..\..\HashLib\src\Crypto\HlpSHA0.pas', HlpSHA1 in '..\..\HashLib\src\Crypto\HlpSHA1.pas', - HlpSHA1Dispatch in '..\..\HashLib\src\Crypto\HlpSHA1Dispatch.pas', + HlpSHA1Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA1Simd.pas', + HlpSHA1X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA1X86Backend.pas', + HlpSHA1ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA1ArmBackend.pas', HlpSHA2_224 in '..\..\HashLib\src\Crypto\HlpSHA2_224.pas', HlpSHA2_256 in '..\..\HashLib\src\Crypto\HlpSHA2_256.pas', - HlpSHA2_256Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_256Dispatch.pas', - HlpSHA2_512Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_512Dispatch.pas', + HlpSHA2_256Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_256Simd.pas', + HlpSHA2_256X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256X86Backend.pas', + HlpSHA2_256ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256ArmBackend.pas', + HlpSHA2_512Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_512Simd.pas', + HlpSHA2_512X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512X86Backend.pas', + HlpSHA2_512ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512ArmBackend.pas', HlpSHA2_256Base in '..\..\HashLib\src\Crypto\HlpSHA2_256Base.pas', HlpSHA2_384 in '..\..\HashLib\src\Crypto\HlpSHA2_384.pas', HlpSHA2_512 in '..\..\HashLib\src\Crypto\HlpSHA2_512.pas', HlpSHA2_512_224 in '..\..\HashLib\src\Crypto\HlpSHA2_512_224.pas', HlpSHA2_512_256 in '..\..\HashLib\src\Crypto\HlpSHA2_512_256.pas', HlpSHA2_512Base in '..\..\HashLib\src\Crypto\HlpSHA2_512Base.pas', - HlpSHA3Dispatch in '..\..\HashLib\src\Crypto\HlpSHA3Dispatch.pas', + HlpSHA3Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA3Simd.pas', + HlpSHA3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA3X86Backend.pas', + HlpSHA3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA3ArmBackend.pas', HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas', HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas', HlpTiger in '..\..\HashLib\src\Crypto\HlpTiger.pas', HlpTiger2 in '..\..\HashLib\src\Crypto\HlpTiger2.pas', HlpWhirlPool in '..\..\HashLib\src\Crypto\HlpWhirlPool.pas', HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas', - HlpBlake2BDispatch in '..\..\HashLib\src\Crypto\HlpBlake2BDispatch.pas', + HlpBlake2BSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2BSimd.pas', + HlpBlake2BX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BX86Backend.pas', + HlpBlake2BArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BArmBackend.pas', HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas', - HlpBlake2SDispatch in '..\..\HashLib\src\Crypto\HlpBlake2SDispatch.pas', + HlpBlake2SSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2SSimd.pas', + HlpBlake2SX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SX86Backend.pas', + HlpBlake2SArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SArmBackend.pas', HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas', HlpBlake2BParams in '..\..\HashLib\src\Crypto\Blake2BParams\HlpBlake2BParams.pas', HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas', @@ -97,7 +114,9 @@ uses HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas', HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas', HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas', - HlpXXHash3Dispatch in '..\..\HashLib\src\Hash64\HlpXXHash3Dispatch.pas', + HlpXXHash3Simd in '..\..\HashLib\src\Simd\Facade\HlpXXHash3Simd.pas', + HlpXXHash3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3X86Backend.pas', + HlpXXHash3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3ArmBackend.pas', HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas', HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas', HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas', @@ -112,14 +131,20 @@ uses HlpIBlake2SParams in '..\..\HashLib\src\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas', HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas', HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas', - HlpBlake3Dispatch in '..\..\HashLib\src\Crypto\HlpBlake3Dispatch.pas', + HlpBlake3Simd in '..\..\HashLib\src\Simd\Facade\HlpBlake3Simd.pas', + HlpBlake3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake3X86Backend.pas', + HlpBlake3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake3ArmBackend.pas', HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas', HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas', HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas', - HlpArgon2Dispatch in '..\..\HashLib\src\KDF\HlpArgon2Dispatch.pas', + HlpArgon2Simd in '..\..\HashLib\src\Simd\Facade\HlpArgon2Simd.pas', + HlpArgon2X86Backend in '..\..\HashLib\src\Simd\Backend\HlpArgon2X86Backend.pas', + HlpArgon2ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpArgon2ArmBackend.pas', HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas', HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas', - HlpScryptDispatch in '..\..\HashLib\src\KDF\HlpScryptDispatch.pas', + HlpScryptSimd in '..\..\HashLib\src\Simd\Facade\HlpScryptSimd.pas', + HlpScryptX86Backend in '..\..\HashLib\src\Simd\Backend\HlpScryptX86Backend.pas', + HlpScryptArmBackend in '..\..\HashLib\src\Simd\Backend\HlpScryptArmBackend.pas', HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas', HlpBitOperations in '..\..\HashLib\src\Utils\HlpBitOperations.pas', HlpBinaryPrimitives in '..\..\HashLib\src\Utils\HlpBinaryPrimitives.pas', diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj index 9de9700..5ea340f 100644 --- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj +++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj @@ -361,9 +361,14 @@ - + + + - + + + + @@ -386,27 +391,39 @@ - + + + - - + + + + + + - + + + - + + + - + + + @@ -437,7 +454,9 @@ - + + + @@ -452,14 +471,20 @@ - + + + - + + + - + + + diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr b/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr index a179273..6b9016c 100644 --- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr +++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr @@ -38,9 +38,14 @@ uses HlpHMACNotBuildInAdapter in '..\..\HashLib\src\Base\HlpHMACNotBuildInAdapter.pas', HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas', HlpAdler32 in '..\..\HashLib\src\Checksum\HlpAdler32.pas', - HlpAdler32Dispatch in '..\..\HashLib\src\Checksum\HlpAdler32Dispatch.pas', + HlpAdler32Simd in '..\..\HashLib\src\Simd\Facade\HlpAdler32Simd.pas', + HlpAdler32X86Backend in '..\..\HashLib\src\Simd\Backend\HlpAdler32X86Backend.pas', + HlpAdler32ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpAdler32ArmBackend.pas', HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas', - HlpCRCDispatch in '..\..\HashLib\src\Checksum\HlpCRCDispatch.pas', + HlpCRCCore in '..\..\HashLib\src\Checksum\HlpCRCCore.pas', + HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', + HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', + HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', @@ -63,27 +68,39 @@ uses HlpRIPEMD320 in '..\..\HashLib\src\Crypto\HlpRIPEMD320.pas', HlpSHA0 in '..\..\HashLib\src\Crypto\HlpSHA0.pas', HlpSHA1 in '..\..\HashLib\src\Crypto\HlpSHA1.pas', - HlpSHA1Dispatch in '..\..\HashLib\src\Crypto\HlpSHA1Dispatch.pas', + HlpSHA1Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA1Simd.pas', + HlpSHA1X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA1X86Backend.pas', + HlpSHA1ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA1ArmBackend.pas', HlpSHA2_224 in '..\..\HashLib\src\Crypto\HlpSHA2_224.pas', HlpSHA2_256 in '..\..\HashLib\src\Crypto\HlpSHA2_256.pas', - HlpSHA2_256Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_256Dispatch.pas', - HlpSHA2_512Dispatch in '..\..\HashLib\src\Crypto\HlpSHA2_512Dispatch.pas', + HlpSHA2_256Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_256Simd.pas', + HlpSHA2_256X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256X86Backend.pas', + HlpSHA2_256ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_256ArmBackend.pas', + HlpSHA2_512Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA2_512Simd.pas', + HlpSHA2_512X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512X86Backend.pas', + HlpSHA2_512ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA2_512ArmBackend.pas', HlpSHA2_256Base in '..\..\HashLib\src\Crypto\HlpSHA2_256Base.pas', HlpSHA2_384 in '..\..\HashLib\src\Crypto\HlpSHA2_384.pas', HlpSHA2_512 in '..\..\HashLib\src\Crypto\HlpSHA2_512.pas', HlpSHA2_512_224 in '..\..\HashLib\src\Crypto\HlpSHA2_512_224.pas', HlpSHA2_512_256 in '..\..\HashLib\src\Crypto\HlpSHA2_512_256.pas', HlpSHA2_512Base in '..\..\HashLib\src\Crypto\HlpSHA2_512Base.pas', - HlpSHA3Dispatch in '..\..\HashLib\src\Crypto\HlpSHA3Dispatch.pas', + HlpSHA3Simd in '..\..\HashLib\src\Simd\Facade\HlpSHA3Simd.pas', + HlpSHA3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpSHA3X86Backend.pas', + HlpSHA3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpSHA3ArmBackend.pas', HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas', HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas', HlpTiger in '..\..\HashLib\src\Crypto\HlpTiger.pas', HlpTiger2 in '..\..\HashLib\src\Crypto\HlpTiger2.pas', HlpWhirlPool in '..\..\HashLib\src\Crypto\HlpWhirlPool.pas', HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas', - HlpBlake2BDispatch in '..\..\HashLib\src\Crypto\HlpBlake2BDispatch.pas', + HlpBlake2BSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2BSimd.pas', + HlpBlake2BX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BX86Backend.pas', + HlpBlake2BArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2BArmBackend.pas', HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas', - HlpBlake2SDispatch in '..\..\HashLib\src\Crypto\HlpBlake2SDispatch.pas', + HlpBlake2SSimd in '..\..\HashLib\src\Simd\Facade\HlpBlake2SSimd.pas', + HlpBlake2SX86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SX86Backend.pas', + HlpBlake2SArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake2SArmBackend.pas', HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas', HlpBlake2BParams in '..\..\HashLib\src\Crypto\Blake2BParams\HlpBlake2BParams.pas', HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas', @@ -114,7 +131,9 @@ uses HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas', HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas', HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas', - HlpXXHash3Dispatch in '..\..\HashLib\src\Hash64\HlpXXHash3Dispatch.pas', + HlpXXHash3Simd in '..\..\HashLib\src\Simd\Facade\HlpXXHash3Simd.pas', + HlpXXHash3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3X86Backend.pas', + HlpXXHash3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpXXHash3ArmBackend.pas', HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas', HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas', HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas', @@ -129,14 +148,20 @@ uses HlpIBlake2SParams in '..\..\HashLib\src\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas', HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas', HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas', - HlpBlake3Dispatch in '..\..\HashLib\src\Crypto\HlpBlake3Dispatch.pas', + HlpBlake3Simd in '..\..\HashLib\src\Simd\Facade\HlpBlake3Simd.pas', + HlpBlake3X86Backend in '..\..\HashLib\src\Simd\Backend\HlpBlake3X86Backend.pas', + HlpBlake3ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpBlake3ArmBackend.pas', HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas', HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas', HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas', - HlpArgon2Dispatch in '..\..\HashLib\src\KDF\HlpArgon2Dispatch.pas', + HlpArgon2Simd in '..\..\HashLib\src\Simd\Facade\HlpArgon2Simd.pas', + HlpArgon2X86Backend in '..\..\HashLib\src\Simd\Backend\HlpArgon2X86Backend.pas', + HlpArgon2ArmBackend in '..\..\HashLib\src\Simd\Backend\HlpArgon2ArmBackend.pas', HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas', HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas', - HlpScryptDispatch in '..\..\HashLib\src\KDF\HlpScryptDispatch.pas', + HlpScryptSimd in '..\..\HashLib\src\Simd\Facade\HlpScryptSimd.pas', + HlpScryptX86Backend in '..\..\HashLib\src\Simd\Backend\HlpScryptX86Backend.pas', + HlpScryptArmBackend in '..\..\HashLib\src\Simd\Backend\HlpScryptArmBackend.pas', HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas', HlpBitOperations in '..\..\HashLib\src\Utils\HlpBitOperations.pas', HlpBinaryPrimitives in '..\..\HashLib\src\Utils\HlpBinaryPrimitives.pas', diff --git a/HashLib/src/Checksum/HlpAdler32.pas b/HashLib/src/Checksum/HlpAdler32.pas index b7b6a15..fc78f24 100644 --- a/HashLib/src/Checksum/HlpAdler32.pas +++ b/HashLib/src/Checksum/HlpAdler32.pas @@ -13,6 +13,19 @@ interface HlpHashResult, HlpIHashResult; +type + TAdler32UpdateProc = procedure(AData: PByte; ALength: UInt32; ASums: Pointer); + TAdler32ProcessBlocksProc = procedure(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + +var + Adler32_Update: TAdler32UpdateProc; + +// Shared SIMD chunking driver, exposed so each backend's Update wrapper can feed +// it the backend's block-processing kernel. +procedure Adler32_Update_Simd(AData: PByte; ALength: UInt32; ASums: Pointer; + AProcessBlocks: TAdler32ProcessBlocksProc); + type TAdler32 = class sealed(THash, IChecksum, IHash32, ITransformBlock) @@ -33,7 +46,94 @@ TAdler32 = class sealed(THash, IChecksum, IHash32, ITransformBlock) implementation uses - HlpAdler32Dispatch; + HlpAdler32Simd; + +const + ModAdler = UInt32(65521); + NMAX = UInt32(5552); + // MAX_BLOCKS_PER_CHUNK = NMAX div UInt32(32); // 173 + + Adler32Constants: array [0 .. 63] of Byte = ( + // Offset 0..31: weights [32,31,...,1] + // SSE2/SSSE3 use as two 16-byte halves; AVX2 uses full 32 bytes. + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + // Offset 32..63: ones_16 (16-bit value 1 in little-endian, repeated) + // SSSE3 uses first 16 bytes; AVX2 uses all 32 bytes. + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + ); + +// ============================================================================= +// Scalar fallback implementation +// ============================================================================= + +procedure Adler32_Update_Scalar(AData: PByte; ALength: UInt32; ASums: Pointer); +var + LChunkLen: UInt32; + LPSumA, LPSumB: PUInt32; +begin + LPSumA := PUInt32(ASums); + LPSumB := PUInt32(PByte(ASums) + SizeOf(UInt32)); + + while ALength > 0 do + begin + LChunkLen := ALength; + if LChunkLen > NMAX then + LChunkLen := NMAX; + Dec(ALength, LChunkLen); + + while LChunkLen > 0 do + begin + LPSumA^ := LPSumA^ + AData^; + LPSumB^ := LPSumB^ + LPSumA^; + Inc(AData); + Dec(LChunkLen); + end; + + LPSumA^ := LPSumA^ mod ModAdler; + LPSumB^ := LPSumB^ mod ModAdler; + end; +end; + +procedure Adler32_Update_Simd(AData: PByte; ALength: UInt32; ASums: Pointer; + AProcessBlocks: TAdler32ProcessBlocksProc); +const + BLOCK_SIZE = UInt32(32); +var + LChunkLen, LBlocks: UInt32; + LPSumA, LPSumB: PUInt32; +begin + LPSumA := PUInt32(ASums); + LPSumB := PUInt32(PByte(ASums) + SizeOf(UInt32)); + + while ALength > 0 do + begin + LChunkLen := ALength; + if LChunkLen > NMAX then + LChunkLen := NMAX; + Dec(ALength, LChunkLen); + + LBlocks := LChunkLen div BLOCK_SIZE; + if LBlocks > 0 then + begin + AProcessBlocks(AData, LBlocks, ASums, @Adler32Constants[0]); + Inc(AData, LBlocks * BLOCK_SIZE); + Dec(LChunkLen, LBlocks * BLOCK_SIZE); + end; + + while LChunkLen > 0 do + begin + LPSumA^ := LPSumA^ + AData^; + LPSumB^ := LPSumB^ + LPSumA^; + Inc(AData); + Dec(LChunkLen); + end; + + LPSumA^ := LPSumA^ mod ModAdler; + LPSumB^ := LPSumB^ mod ModAdler; + end; +end; { TAdler32 } @@ -87,4 +187,7 @@ function TAdler32.TransformFinal: IHashResult; Initialize(); end; +initialization + Adler32_Update := TAdler32Simd.Select(@Adler32_Update_Scalar); + end. diff --git a/HashLib/src/Checksum/HlpAdler32Dispatch.pas b/HashLib/src/Checksum/HlpAdler32Dispatch.pas deleted file mode 100644 index ad92822..0000000 --- a/HashLib/src/Checksum/HlpAdler32Dispatch.pas +++ /dev/null @@ -1,255 +0,0 @@ -unit HlpAdler32Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TAdler32UpdateProc = procedure(AData: PByte; ALength: UInt32; ASums: Pointer); - -var - Adler32_Update: TAdler32UpdateProc; - -implementation - -uses - HlpCpuFeatures, - HlpSimdLevels; - -const - ModAdler = UInt32(65521); - NMAX = UInt32(5552); - // MAX_BLOCKS_PER_CHUNK = NMAX div UInt32(32); // 173 - - Adler32Constants: array [0 .. 63] of Byte = ( - // Offset 0..31: weights [32,31,...,1] - // SSE2/SSSE3 use as two 16-byte halves; AVX2 uses full 32 bytes. - 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, - 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, - // Offset 32..63: ones_16 (16-bit value 1 in little-endian, repeated) - // SSSE3 uses first 16 bytes; AVX2 uses all 32 bytes. - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 - ); - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure Adler32_Update_Scalar(AData: PByte; ALength: UInt32; ASums: Pointer); -var - LChunkLen: UInt32; - LPSumA, LPSumB: PUInt32; -begin - LPSumA := PUInt32(ASums); - LPSumB := PUInt32(PByte(ASums) + SizeOf(UInt32)); - - while ALength > 0 do - begin - LChunkLen := ALength; - if LChunkLen > NMAX then - LChunkLen := NMAX; - Dec(ALength, LChunkLen); - - while LChunkLen > 0 do - begin - LPSumA^ := LPSumA^ + AData^; - LPSumB^ := LPSumB^ + LPSumA^; - Inc(AData); - Dec(LChunkLen); - end; - - LPSumA^ := LPSumA^ mod ModAdler; - LPSumB^ := LPSumB^ mod ModAdler; - end; -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2, SSSE3 -// x86_64: AVX2, SSSE3, SSE2 -// aarch64: NEON -// ============================================================================= - -{$IF DEFINED(HASHLIB_X86_SIMD) OR DEFINED(HASHLIB_ARM_SIMD)} - -type - TProcessBlocksProc = procedure(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - -procedure Adler32_Update_Simd(AData: PByte; ALength: UInt32; ASums: Pointer; - AProcessBlocks: TProcessBlocksProc); -const - BLOCK_SIZE = UInt32(32); -var - LChunkLen, LBlocks: UInt32; - LPSumA, LPSumB: PUInt32; -begin - LPSumA := PUInt32(ASums); - LPSumB := PUInt32(PByte(ASums) + SizeOf(UInt32)); - - while ALength > 0 do - begin - LChunkLen := ALength; - if LChunkLen > NMAX then - LChunkLen := NMAX; - Dec(ALength, LChunkLen); - - LBlocks := LChunkLen div BLOCK_SIZE; - if LBlocks > 0 then - begin - AProcessBlocks(AData, LBlocks, ASums, @Adler32Constants[0]); - Inc(AData, LBlocks * BLOCK_SIZE); - Dec(LChunkLen, LBlocks * BLOCK_SIZE); - end; - - while LChunkLen > 0 do - begin - LPSumA^ := LPSumA^ + AData^; - LPSumB^ := LPSumB^ + LPSumA^; - Inc(AData); - Dec(LChunkLen); - end; - - LPSumA^ := LPSumA^ mod ModAdler; - LPSumB^ := LPSumB^ mod ModAdler; - end; -end; - -{$IFEND} - -{$IFDEF HASHLIB_X86_SIMD} - -{$IFDEF HASHLIB_I386_ASM} - -procedure Adler32_ProcessBlocks_Sse2(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\Adler32\Adler32BlocksSse2_i386.inc} -end; - -procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\Adler32\Adler32BlocksSsse3_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure Adler32_ProcessBlocks_Sse2(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Adler32\Adler32BlocksSse2_x86_64.inc} -end; - -procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Adler32\Adler32BlocksSsse3_x86_64.inc} -end; - -procedure Adler32_ProcessBlocks_Avx2(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Adler32\Adler32BlocksAvx2_x86_64.inc} -end; - -procedure Adler32_Update_Ssse3(AData: PByte; ALength: UInt32; ASums: Pointer); -begin - Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Ssse3); -end; - -procedure Adler32_Update_Avx2(AData: PByte; ALength: UInt32; ASums: Pointer); -begin - Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Avx2); -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -procedure Adler32_Update_Sse2(AData: PByte; ALength: UInt32; ASums: Pointer); -begin - Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Sse2); -end; - -{$IFDEF HASHLIB_I386_ASM} - -procedure Adler32_Update_Ssse3(AData: PByte; ALength: UInt32; ASums: Pointer); -begin - Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Ssse3); -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$ENDIF HASHLIB_X86_SIMD} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure Adler32_ProcessBlocks_Neon(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\Adler32\Adler32BlocksNeon_aarch64.inc} -end; - -{$IFDEF HASHLIB_ARM_SIMD} - -procedure Adler32_Update_Neon(AData: PByte; ALength: UInt32; ASums: Pointer); -begin - Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Neon); -end; - -{$ENDIF HASHLIB_ARM_SIMD} - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - Adler32_Update := @Adler32_Update_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSSE3: - begin - Adler32_Update := @Adler32_Update_Ssse3; - end; - TX86SimdLevel.SSE2: - begin - Adler32_Update := @Adler32_Update_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - Adler32_Update := @Adler32_Update_Avx2; - end; - TX86SimdLevel.SSSE3: - begin - Adler32_Update := @Adler32_Update_Ssse3; - end; - TX86SimdLevel.SSE2: - begin - Adler32_Update := @Adler32_Update_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - TArmSimdLevel.NEON: - begin - Adler32_Update := @Adler32_Update_Neon; - end; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Checksum/HlpCRC.pas b/HashLib/src/Checksum/HlpCRC.pas index 1a697e9..cb12017 100644 --- a/HashLib/src/Checksum/HlpCRC.pas +++ b/HashLib/src/Checksum/HlpCRC.pas @@ -18,7 +18,7 @@ interface HlpHashResult, HlpIHashResult, HlpICRC, - HlpCRCDispatch; + HlpCRCCore; resourcestring SUnSupportedCRCType = 'UnSupported CRC Type: "%s"'; diff --git a/HashLib/src/Checksum/HlpCRC32Fast.pas b/HashLib/src/Checksum/HlpCRC32Fast.pas index f75a8c3..b073dbb 100644 --- a/HashLib/src/Checksum/HlpCRC32Fast.pas +++ b/HashLib/src/Checksum/HlpCRC32Fast.pas @@ -12,7 +12,7 @@ interface HlpIHashInfo, HlpHashResult, HlpIHashResult, - HlpCRCDispatch; + HlpCRCCore; type diff --git a/HashLib/src/Checksum/HlpCRCDispatch.pas b/HashLib/src/Checksum/HlpCRCCore.pas similarity index 65% rename from HashLib/src/Checksum/HlpCRCDispatch.pas rename to HashLib/src/Checksum/HlpCRCCore.pas index edd6e6d..bcd99b2 100644 --- a/HashLib/src/Checksum/HlpCRCDispatch.pas +++ b/HashLib/src/Checksum/HlpCRCCore.pas @@ -1,4 +1,4 @@ -unit HlpCRCDispatch; +unit HlpCRCCore; { CRC fold dispatch (scalar + SIMD + PCLMUL) and fast reflected-CRC32 update. @@ -48,6 +48,15 @@ interface TCRCFoldFunc = function(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; + // Tier-selection result: the three fold entry points plus whether they use + // carry-less multiply (PCLMUL/VPCLMUL/PMULL) rather than table slicing. + TCRCFoldSelection = record + Reflected: TCRCFoldFunc; + Fwd: TCRCFoldFunc; + Reflected32: TCRCFoldFunc; + UsesCarrylessMul: Boolean; + end; + procedure CRCDispatch_InitRuntimeCtx(const Table: THashLibMatrixUInt64Array; APoly: UInt64; AWidth: Int32; AReflected: Boolean; out Ctx: TCRCFoldRuntimeCtx); overload; @@ -77,12 +86,7 @@ procedure CRC_UpdateViaBitSerial(AData: PByte; ADataLength, AIndex: Int32; implementation uses - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= + HlpCRCSimd; function CrcTableU64(const Row: Pointer; B: Byte): UInt64; inline; begin @@ -350,180 +354,22 @@ procedure CRC_UpdateViaBitSerial(AData: PByte; ADataLength, AIndex: Int32; end; // ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: VPCLMULQDQ, PCLMULQDQ, SSE2 -// aarch64: PMULL -// ============================================================================= - -{$IFDEF HASHLIB_X86_64_ASM} - -function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflectedSse2_x86_64.inc} -end; - -function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldForwardSse2_x86_64.inc} -end; - -function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflected32Sse2_x86_64.inc} -end; - -{$ELSE} - -{$IFDEF HASHLIB_I386_ASM} - -function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflectedSse2_i386.inc} -end; - -function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\CRC\CRCFoldForwardSse2_i386.inc} -end; - -function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflected32Sse2_i386.inc} -end; - -{$ELSE} - -function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; -begin - Result := CRC_Fold_Reflected_Scalar(AData, ALength, AState, AConstants); -end; - -function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; -begin - Result := CRC_Fold_Forward_Scalar(AData, ALength, AState, AConstants); -end; - -function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; -begin - Result := CRC_Fold_Reflected32_Scalar(AData, ALength, AState, AConstants); -end; - -{$ENDIF HASHLIB_I386_ASM} -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflectedPclmul_x86_64.inc} -end; - -function CRC_Fold_Reflected_Vpclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflectedVpclmul_x86_64.inc} -end; - -function CRC_Fold_Forward_Pclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldForwardPclmul_x86_64.inc} -end; - -function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\CRC\CRCFoldForwardVpclmul_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -function CRC_Fold_Reflected_Pmull(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\CRC\CRCFoldReflectedPmull_aarch64.inc} -end; - -function CRC_Fold_Forward_Pmull(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\CRC\CRCFoldForwardPmull_aarch64.inc} -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization +// Fold routine selection (once, at init) // ============================================================================= -procedure InitDispatch(); - - procedure BindSse2CrcFold; - begin - CRC_Fold_Reflected := @CRC_Fold_Reflected_Sse2; - CRC_Fold_Forward := @CRC_Fold_Forward_Sse2; - CRC_Fold_Reflected32 := @CRC_Fold_Reflected32_Sse2; - end; - +procedure InitCRCFold(); +var + LSel: TCRCFoldSelection; begin - CRC_Fold_Reflected := @CRC_Fold_Reflected_Scalar; - CRC_Fold_Forward := @CRC_Fold_Forward_Scalar; - CRC_Fold_Reflected32 := @CRC_Fold_Reflected32_Scalar; - CRC_Fold_UsesCarrylessMul := False; - -{$IFDEF HASHLIB_AARCH64_ASM} - if TCpuFeatures.Arm.HasPMULL() then - begin - CRC_Fold_Reflected := @CRC_Fold_Reflected_Pmull; - CRC_Fold_Forward := @CRC_Fold_Forward_Pmull; - CRC_Fold_Reflected32 := @CRC_Fold_Reflected_Pmull; - CRC_Fold_UsesCarrylessMul := True; - Exit; - end; -{$ENDIF HASHLIB_AARCH64_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - if TCpuFeatures.X86.HasVPCLMULQDQ() then - begin - CRC_Fold_Reflected := @CRC_Fold_Reflected_Vpclmul; - CRC_Fold_Forward := @CRC_Fold_Forward_Vpclmul; - CRC_Fold_Reflected32 := @CRC_Fold_Reflected_Vpclmul; - CRC_Fold_UsesCarrylessMul := True; - Exit; - end; - if TCpuFeatures.X86.HasPCLMULQDQ() then - begin - CRC_Fold_Reflected := @CRC_Fold_Reflected_Pclmul; - CRC_Fold_Forward := @CRC_Fold_Forward_Pclmul; - CRC_Fold_Reflected32 := @CRC_Fold_Reflected_Pclmul; - CRC_Fold_UsesCarrylessMul := True; - Exit; - end; -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_X86_SIMD} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - BindSse2CrcFold; - end; -{$ENDIF HASHLIB_X86_SIMD} + LSel := TCRCSimd.Select(@CRC_Fold_Reflected_Scalar, + @CRC_Fold_Forward_Scalar, @CRC_Fold_Reflected32_Scalar); + CRC_Fold_Reflected := LSel.Reflected; + CRC_Fold_Forward := LSel.Fwd; + CRC_Fold_Reflected32 := LSel.Reflected32; + CRC_Fold_UsesCarrylessMul := LSel.UsesCarrylessMul; end; initialization - InitDispatch(); + InitCRCFold(); end. diff --git a/HashLib/src/Crypto/HlpBlake2B.pas b/HashLib/src/Crypto/HlpBlake2B.pas index 582a36c..ffa60e6 100644 --- a/HashLib/src/Crypto/HlpBlake2B.pas +++ b/HashLib/src/Crypto/HlpBlake2B.pas @@ -18,6 +18,20 @@ interface HlpArrayUtils, HlpHashLibTypes; +type + TBlake2BCompressProc = procedure(AState, AMsg, ACounterFlags, AIV: Pointer); + +var + Blake2B_Compress: TBlake2BCompressProc; + +const + Blake2BIV: array [0 .. 7] of UInt64 = ( + UInt64($6A09E667F3BCC908), UInt64($BB67AE8584CAA73B), + UInt64($3C6EF372FE94F82B), UInt64($A54FF53A5F1D36F1), + UInt64($510E527FADE682D1), UInt64($9B05688C2B3E6C1F), + UInt64($1F83D9ABFB41BD6B), UInt64($5BE0CD19137E2179) + ); + resourcestring SInvalidConfigLength = 'Config Length Must Be 8 Words'; SConfigNil = 'Config Cannot Be nil'; @@ -222,7 +236,79 @@ TBlake2BMACNotBuildInAdapter = class sealed(THash, IBlake2BMAC, implementation uses - HlpBlake2BDispatch; + HlpBitOperations, + HlpBlake2BSimd; + +const + Blake2BSigma: array [0 .. 11, 0 .. 15] of Int32 = ( + (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), + (11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), + (7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), + (9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), + (2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), + (12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), + (13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), + (6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), + (10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0), + (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3) + ); + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure Blake2B_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); +var + LV: array [0 .. 15] of UInt64; + LPState, LPMsg, LPCounterFlags, LPIV: PByte; + LRound, I: Int32; + + procedure G(AA, AB, AC, AD, AMsgIdx0, AMsgIdx1: Int32); + begin + LV[AA] := LV[AA] + LV[AB] + PUInt64(LPMsg + AMsgIdx0 * SizeOf(UInt64))^; + LV[AD] := TBitOperations.RotateRight64(LV[AD] xor LV[AA], 32); + LV[AC] := LV[AC] + LV[AD]; + LV[AB] := TBitOperations.RotateRight64(LV[AB] xor LV[AC], 24); + LV[AA] := LV[AA] + LV[AB] + PUInt64(LPMsg + AMsgIdx1 * SizeOf(UInt64))^; + LV[AD] := TBitOperations.RotateRight64(LV[AD] xor LV[AA], 16); + LV[AC] := LV[AC] + LV[AD]; + LV[AB] := TBitOperations.RotateRight64(LV[AB] xor LV[AC], 63); + end; + +begin + LPState := PByte(AState); + LPMsg := PByte(AMsg); + LPCounterFlags := PByte(ACounterFlags); + LPIV := PByte(AIV); + + for I := 0 to 7 do + LV[I] := PUInt64(LPState + I * SizeOf(UInt64))^; + for I := 0 to 7 do + LV[I + 8] := PUInt64(LPIV + I * SizeOf(UInt64))^; + + LV[12] := LV[12] xor PUInt64(LPCounterFlags)^; + LV[13] := LV[13] xor PUInt64(LPCounterFlags + SizeOf(UInt64))^; + LV[14] := LV[14] xor PUInt64(LPCounterFlags + 2 * SizeOf(UInt64))^; + LV[15] := LV[15] xor PUInt64(LPCounterFlags + 3 * SizeOf(UInt64))^; + + for LRound := 0 to 11 do + begin + G(0, 4, 8, 12, Blake2BSigma[LRound, 0], Blake2BSigma[LRound, 1]); + G(1, 5, 9, 13, Blake2BSigma[LRound, 2], Blake2BSigma[LRound, 3]); + G(2, 6, 10, 14, Blake2BSigma[LRound, 4], Blake2BSigma[LRound, 5]); + G(3, 7, 11, 15, Blake2BSigma[LRound, 6], Blake2BSigma[LRound, 7]); + G(0, 5, 10, 15, Blake2BSigma[LRound, 8], Blake2BSigma[LRound, 9]); + G(1, 6, 11, 12, Blake2BSigma[LRound, 10], Blake2BSigma[LRound, 11]); + G(2, 7, 8, 13, Blake2BSigma[LRound, 12], Blake2BSigma[LRound, 13]); + G(3, 4, 9, 14, Blake2BSigma[LRound, 14], Blake2BSigma[LRound, 15]); + end; + + for I := 0 to 7 do + PUInt64(LPState + I * SizeOf(UInt64))^ := + PUInt64(LPState + I * SizeOf(UInt64))^ xor (LV[I] xor LV[I + 8]); +end; type // Self-contained Blake2XB squeeze engine. Owns the finalized root digest and @@ -394,8 +480,8 @@ procedure TBlake2B.Compress(ABlock: PByte; AStart: Int32); LCounterFlags[1] := FCounter1; LCounterFlags[2] := FFinalizationFlag0; LCounterFlags[3] := FFinalizationFlag1; - HlpBlake2BDispatch.Blake2B_Compress(@FState[0], @FM[0], - @LCounterFlags[0], @HlpBlake2BDispatch.Blake2BIV[0]); + Blake2B_Compress(@FState[0], @FM[0], + @LCounterFlags[0], @Blake2BIV[0]); end; constructor TBlake2B.Create(const AConfig: IBlake2BConfig); @@ -988,4 +1074,7 @@ function TBlake2BMACNotBuildInAdapter.TransformFinal: IHashResult; Result := FHash.TransformFinal(); end; +initialization + Blake2B_Compress := TBlake2BSimd.Select(@Blake2B_Compress_Scalar); + end. diff --git a/HashLib/src/Crypto/HlpBlake2BDispatch.pas b/HashLib/src/Crypto/HlpBlake2BDispatch.pas deleted file mode 100644 index 29c2dbc..0000000 --- a/HashLib/src/Crypto/HlpBlake2BDispatch.pas +++ /dev/null @@ -1,179 +0,0 @@ -unit HlpBlake2BDispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TBlake2BCompressProc = procedure(AState, AMsg, ACounterFlags, AIV: Pointer); - -const - Blake2BIV: array [0 .. 7] of UInt64 = ( - UInt64($6A09E667F3BCC908), UInt64($BB67AE8584CAA73B), - UInt64($3C6EF372FE94F82B), UInt64($A54FF53A5F1D36F1), - UInt64($510E527FADE682D1), UInt64($9B05688C2B3E6C1F), - UInt64($1F83D9ABFB41BD6B), UInt64($5BE0CD19137E2179) - ); - -var - Blake2B_Compress: TBlake2BCompressProc; - -implementation - -uses - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -const - Blake2BSigma: array [0 .. 11, 0 .. 15] of Int32 = ( - (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), - (11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), - (7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), - (9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), - (2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), - (12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), - (13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), - (6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), - (10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0), - (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3) - ); - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure Blake2B_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); -var - LV: array [0 .. 15] of UInt64; - LPState, LPMsg, LPCounterFlags, LPIV: PByte; - LRound, I: Int32; - - procedure G(AA, AB, AC, AD, AMsgIdx0, AMsgIdx1: Int32); - begin - LV[AA] := LV[AA] + LV[AB] + PUInt64(LPMsg + AMsgIdx0 * SizeOf(UInt64))^; - LV[AD] := TBitOperations.RotateRight64(LV[AD] xor LV[AA], 32); - LV[AC] := LV[AC] + LV[AD]; - LV[AB] := TBitOperations.RotateRight64(LV[AB] xor LV[AC], 24); - LV[AA] := LV[AA] + LV[AB] + PUInt64(LPMsg + AMsgIdx1 * SizeOf(UInt64))^; - LV[AD] := TBitOperations.RotateRight64(LV[AD] xor LV[AA], 16); - LV[AC] := LV[AC] + LV[AD]; - LV[AB] := TBitOperations.RotateRight64(LV[AB] xor LV[AC], 63); - end; - -begin - LPState := PByte(AState); - LPMsg := PByte(AMsg); - LPCounterFlags := PByte(ACounterFlags); - LPIV := PByte(AIV); - - for I := 0 to 7 do - LV[I] := PUInt64(LPState + I * SizeOf(UInt64))^; - for I := 0 to 7 do - LV[I + 8] := PUInt64(LPIV + I * SizeOf(UInt64))^; - - LV[12] := LV[12] xor PUInt64(LPCounterFlags)^; - LV[13] := LV[13] xor PUInt64(LPCounterFlags + SizeOf(UInt64))^; - LV[14] := LV[14] xor PUInt64(LPCounterFlags + 2 * SizeOf(UInt64))^; - LV[15] := LV[15] xor PUInt64(LPCounterFlags + 3 * SizeOf(UInt64))^; - - for LRound := 0 to 11 do - begin - G(0, 4, 8, 12, Blake2BSigma[LRound, 0], Blake2BSigma[LRound, 1]); - G(1, 5, 9, 13, Blake2BSigma[LRound, 2], Blake2BSigma[LRound, 3]); - G(2, 6, 10, 14, Blake2BSigma[LRound, 4], Blake2BSigma[LRound, 5]); - G(3, 7, 11, 15, Blake2BSigma[LRound, 6], Blake2BSigma[LRound, 7]); - G(0, 5, 10, 15, Blake2BSigma[LRound, 8], Blake2BSigma[LRound, 9]); - G(1, 6, 11, 12, Blake2BSigma[LRound, 10], Blake2BSigma[LRound, 11]); - G(2, 7, 8, 13, Blake2BSigma[LRound, 12], Blake2BSigma[LRound, 13]); - G(3, 4, 9, 14, Blake2BSigma[LRound, 14], Blake2BSigma[LRound, 15]); - end; - - for I := 0 to 7 do - PUInt64(LPState + I * SizeOf(UInt64))^ := - PUInt64(LPState + I * SizeOf(UInt64))^ xor (LV[I] xor LV[I + 8]); -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: AVX2, SSE2 -// aarch64: NEON -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\Blake2B\Blake2BCompressSse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Blake2B\Blake2BCompressSse2_x86_64.inc} -end; - -procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Blake2B\Blake2BCompressAvx2_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure Blake2B_Compress_Neon(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\Blake2B\Blake2BCompressNeon_aarch64.inc} -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - Blake2B_Compress := @Blake2B_Compress_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - Blake2B_Compress := @Blake2B_Compress_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - Blake2B_Compress := @Blake2B_Compress_Avx2; - end; - TX86SimdLevel.SSE2: - begin - Blake2B_Compress := @Blake2B_Compress_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - TArmSimdLevel.NEON: - begin - Blake2B_Compress := @Blake2B_Compress_Neon; - end; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Crypto/HlpBlake2S.pas b/HashLib/src/Crypto/HlpBlake2S.pas index d9b2a04..6949997 100644 --- a/HashLib/src/Crypto/HlpBlake2S.pas +++ b/HashLib/src/Crypto/HlpBlake2S.pas @@ -18,6 +18,20 @@ interface HlpArrayUtils, HlpHashLibTypes; +type + TBlake2SCompressProc = procedure(AState, AMsg, ACounterFlags, AIV: Pointer); + +var + Blake2S_Compress: TBlake2SCompressProc; + +const + Blake2SIV: array [0 .. 7] of UInt32 = ( + UInt32($6A09E667), UInt32($BB67AE85), + UInt32($3C6EF372), UInt32($A54FF53A), + UInt32($510E527F), UInt32($9B05688C), + UInt32($1F83D9AB), UInt32($5BE0CD19) + ); + resourcestring SInvalidConfigLength = 'Config Length Must Be 8 Words'; SConfigNil = 'Config Cannot Be nil'; @@ -220,7 +234,77 @@ TBlake2SMACNotBuildInAdapter = class sealed(THash, IBlake2SMAC, implementation uses - HlpBlake2SDispatch; + HlpBitOperations, + HlpBlake2SSimd; + +const + Blake2SSigma: array [0 .. 9, 0 .. 15] of Int32 = ( + (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), + (11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), + (7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), + (9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), + (2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), + (12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), + (13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), + (6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), + (10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0) + ); + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure Blake2S_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); +var + LV: array [0 .. 15] of UInt32; + LPState, LPMsg, LPCounterFlags, LPIV: PByte; + LRound, I: Int32; + + procedure G(AA, AB, AC, AD, AMsgIdx0, AMsgIdx1: Int32); + begin + LV[AA] := LV[AA] + LV[AB] + PUInt32(LPMsg + AMsgIdx0 * SizeOf(UInt32))^; + LV[AD] := TBitOperations.RotateRight32(LV[AD] xor LV[AA], 16); + LV[AC] := LV[AC] + LV[AD]; + LV[AB] := TBitOperations.RotateRight32(LV[AB] xor LV[AC], 12); + LV[AA] := LV[AA] + LV[AB] + PUInt32(LPMsg + AMsgIdx1 * SizeOf(UInt32))^; + LV[AD] := TBitOperations.RotateRight32(LV[AD] xor LV[AA], 8); + LV[AC] := LV[AC] + LV[AD]; + LV[AB] := TBitOperations.RotateRight32(LV[AB] xor LV[AC], 7); + end; + +begin + LPState := PByte(AState); + LPMsg := PByte(AMsg); + LPCounterFlags := PByte(ACounterFlags); + LPIV := PByte(AIV); + + for I := 0 to 7 do + LV[I] := PUInt32(LPState + I * SizeOf(UInt32))^; + for I := 0 to 7 do + LV[I + 8] := PUInt32(LPIV + I * SizeOf(UInt32))^; + + LV[12] := LV[12] xor PUInt32(LPCounterFlags)^; + LV[13] := LV[13] xor PUInt32(LPCounterFlags + SizeOf(UInt32))^; + LV[14] := LV[14] xor PUInt32(LPCounterFlags + 2 * SizeOf(UInt32))^; + LV[15] := LV[15] xor PUInt32(LPCounterFlags + 3 * SizeOf(UInt32))^; + + for LRound := 0 to 9 do + begin + G(0, 4, 8, 12, Blake2SSigma[LRound, 0], Blake2SSigma[LRound, 1]); + G(1, 5, 9, 13, Blake2SSigma[LRound, 2], Blake2SSigma[LRound, 3]); + G(2, 6, 10, 14, Blake2SSigma[LRound, 4], Blake2SSigma[LRound, 5]); + G(3, 7, 11, 15, Blake2SSigma[LRound, 6], Blake2SSigma[LRound, 7]); + G(0, 5, 10, 15, Blake2SSigma[LRound, 8], Blake2SSigma[LRound, 9]); + G(1, 6, 11, 12, Blake2SSigma[LRound, 10], Blake2SSigma[LRound, 11]); + G(2, 7, 8, 13, Blake2SSigma[LRound, 12], Blake2SSigma[LRound, 13]); + G(3, 4, 9, 14, Blake2SSigma[LRound, 14], Blake2SSigma[LRound, 15]); + end; + + for I := 0 to 7 do + PUInt32(LPState + I * SizeOf(UInt32))^ := + PUInt32(LPState + I * SizeOf(UInt32))^ xor (LV[I] xor LV[I + 8]); +end; type // Self-contained Blake2XS squeeze engine. Owns the finalized root digest and @@ -392,8 +476,8 @@ procedure TBlake2S.Compress(ABlock: PByte; AStart: Int32); LCounterFlags[1] := FCounter1; LCounterFlags[2] := FFinalizationFlag0; LCounterFlags[3] := FFinalizationFlag1; - HlpBlake2SDispatch.Blake2S_Compress(@FState[0], @FM[0], - @LCounterFlags[0], @HlpBlake2SDispatch.Blake2SIV[0]); + Blake2S_Compress(@FState[0], @FM[0], + @LCounterFlags[0], @Blake2SIV[0]); end; constructor TBlake2S.Create(const AConfig: IBlake2SConfig); @@ -984,4 +1068,7 @@ function TBlake2SMACNotBuildInAdapter.TransformFinal: IHashResult; Result := FHash.TransformFinal(); end; +initialization + Blake2S_Compress := TBlake2SSimd.Select(@Blake2S_Compress_Scalar); + end. diff --git a/HashLib/src/Crypto/HlpBlake2SDispatch.pas b/HashLib/src/Crypto/HlpBlake2SDispatch.pas deleted file mode 100644 index 4afb7f8..0000000 --- a/HashLib/src/Crypto/HlpBlake2SDispatch.pas +++ /dev/null @@ -1,177 +0,0 @@ -unit HlpBlake2SDispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TBlake2SCompressProc = procedure(AState, AMsg, ACounterFlags, AIV: Pointer); - -const - Blake2SIV: array [0 .. 7] of UInt32 = ( - UInt32($6A09E667), UInt32($BB67AE85), - UInt32($3C6EF372), UInt32($A54FF53A), - UInt32($510E527F), UInt32($9B05688C), - UInt32($1F83D9AB), UInt32($5BE0CD19) - ); - -var - Blake2S_Compress: TBlake2SCompressProc; - -implementation - -uses - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -const - Blake2SSigma: array [0 .. 9, 0 .. 15] of Int32 = ( - (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), - (11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), - (7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), - (9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), - (2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), - (12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), - (13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), - (6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), - (10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0) - ); - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure Blake2S_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); -var - LV: array [0 .. 15] of UInt32; - LPState, LPMsg, LPCounterFlags, LPIV: PByte; - LRound, I: Int32; - - procedure G(AA, AB, AC, AD, AMsgIdx0, AMsgIdx1: Int32); - begin - LV[AA] := LV[AA] + LV[AB] + PUInt32(LPMsg + AMsgIdx0 * SizeOf(UInt32))^; - LV[AD] := TBitOperations.RotateRight32(LV[AD] xor LV[AA], 16); - LV[AC] := LV[AC] + LV[AD]; - LV[AB] := TBitOperations.RotateRight32(LV[AB] xor LV[AC], 12); - LV[AA] := LV[AA] + LV[AB] + PUInt32(LPMsg + AMsgIdx1 * SizeOf(UInt32))^; - LV[AD] := TBitOperations.RotateRight32(LV[AD] xor LV[AA], 8); - LV[AC] := LV[AC] + LV[AD]; - LV[AB] := TBitOperations.RotateRight32(LV[AB] xor LV[AC], 7); - end; - -begin - LPState := PByte(AState); - LPMsg := PByte(AMsg); - LPCounterFlags := PByte(ACounterFlags); - LPIV := PByte(AIV); - - for I := 0 to 7 do - LV[I] := PUInt32(LPState + I * SizeOf(UInt32))^; - for I := 0 to 7 do - LV[I + 8] := PUInt32(LPIV + I * SizeOf(UInt32))^; - - LV[12] := LV[12] xor PUInt32(LPCounterFlags)^; - LV[13] := LV[13] xor PUInt32(LPCounterFlags + SizeOf(UInt32))^; - LV[14] := LV[14] xor PUInt32(LPCounterFlags + 2 * SizeOf(UInt32))^; - LV[15] := LV[15] xor PUInt32(LPCounterFlags + 3 * SizeOf(UInt32))^; - - for LRound := 0 to 9 do - begin - G(0, 4, 8, 12, Blake2SSigma[LRound, 0], Blake2SSigma[LRound, 1]); - G(1, 5, 9, 13, Blake2SSigma[LRound, 2], Blake2SSigma[LRound, 3]); - G(2, 6, 10, 14, Blake2SSigma[LRound, 4], Blake2SSigma[LRound, 5]); - G(3, 7, 11, 15, Blake2SSigma[LRound, 6], Blake2SSigma[LRound, 7]); - G(0, 5, 10, 15, Blake2SSigma[LRound, 8], Blake2SSigma[LRound, 9]); - G(1, 6, 11, 12, Blake2SSigma[LRound, 10], Blake2SSigma[LRound, 11]); - G(2, 7, 8, 13, Blake2SSigma[LRound, 12], Blake2SSigma[LRound, 13]); - G(3, 4, 9, 14, Blake2SSigma[LRound, 14], Blake2SSigma[LRound, 15]); - end; - - for I := 0 to 7 do - PUInt32(LPState + I * SizeOf(UInt32))^ := - PUInt32(LPState + I * SizeOf(UInt32))^ xor (LV[I] xor LV[I + 8]); -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: AVX2, SSE2 -// aarch64: NEON -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\Blake2S\Blake2SCompressSse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Blake2S\Blake2SCompressSse2_x86_64.inc} -end; - -procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Blake2S\Blake2SCompressAvx2_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure Blake2S_Compress_Neon(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\Blake2S\Blake2SCompressNeon_aarch64.inc} -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - Blake2S_Compress := @Blake2S_Compress_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - Blake2S_Compress := @Blake2S_Compress_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - Blake2S_Compress := @Blake2S_Compress_Avx2; - end; - TX86SimdLevel.SSE2: - begin - Blake2S_Compress := @Blake2S_Compress_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - TArmSimdLevel.NEON: - begin - Blake2S_Compress := @Blake2S_Compress_Neon; - end; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Crypto/HlpBlake3.pas b/HashLib/src/Crypto/HlpBlake3.pas index 8a85fc9..a37a8ac 100644 --- a/HashLib/src/Crypto/HlpBlake3.pas +++ b/HashLib/src/Crypto/HlpBlake3.pas @@ -17,6 +17,21 @@ interface HlpArrayUtils, HlpHashLibTypes; +type + TBlake3CompressProc = procedure(AState, AMsg, ACV, ACounterFlags: Pointer); + TBlake3HashManyProc = procedure(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); + +var + Blake3_Compress: TBlake3CompressProc; + Blake3_HashMany: TBlake3HashManyProc; + Blake3_ParallelDegree: Int32; + +// Scalar HashMany reference, exposed so the SIMD backends can delegate their +// sub-parallel-degree remainder to it. +procedure Blake3_HashMany_Scalar(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); + resourcestring SInvalidXOFSize = 'XOFSize in Bits must be Multiples of 8 and be Greater than Zero Bytes'; @@ -250,7 +265,588 @@ TBlake3XOF = class sealed(TBlake3, IXOF, IXOFStream) implementation uses - HlpBlake3Dispatch; + HlpBitOperations, + HlpBlake3Simd; + +const + Blake3IV: array [0 .. 3] of UInt32 = ( + UInt32($6A09E667), UInt32($BB67AE85), + UInt32($3C6EF372), UInt32($A54FF53A) + ); + + FlagChunkStart = UInt32(1 shl 0); + FlagChunkEnd = UInt32(1 shl 1); + +// ============================================================================= +// Scalar fallback implementation (fully unrolled, 7 rounds, inlined G) +// ============================================================================= + +procedure Blake3_Compress_Scalar(AState, AMsg, ACV, ACounterFlags: Pointer); +var + LV0, LV1, LV2, LV3, LV4, LV5, LV6, LV7: UInt32; + LV8, LV9, LV10, LV11, LV12, LV13, LV14, LV15: UInt32; + LPMsg, LPCV, LPCounterFlags, LPState: PCardinal; +begin + LPMsg := PCardinal(AMsg); + LPCV := PCardinal(ACV); + LPCounterFlags := PCardinal(ACounterFlags); + LPState := PCardinal(AState); + + // Initialize state from chaining value + LV0 := LPCV[0]; + LV1 := LPCV[1]; + LV2 := LPCV[2]; + LV3 := LPCV[3]; + LV4 := LPCV[4]; + LV5 := LPCV[5]; + LV6 := LPCV[6]; + LV7 := LPCV[7]; + // Initialize counter half from IV and counter/flags + LV8 := Blake3IV[0]; + LV9 := Blake3IV[1]; + LV10 := Blake3IV[2]; + LV11 := Blake3IV[3]; + LV12 := LPCounterFlags[0]; + LV13 := LPCounterFlags[1]; + LV14 := LPCounterFlags[2]; + LV15 := LPCounterFlags[3]; + + // Round 0 + LV0 := LV0 + LV4 + LPMsg[0]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[1]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[2]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[3]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[4]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[5]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[6]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[7]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[8]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[9]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[10]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[11]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[12]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[13]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[14]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[15]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Round 1 + LV0 := LV0 + LV4 + LPMsg[2]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[6]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[3]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[10]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[7]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[0]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[4]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[13]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[1]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[11]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[12]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[5]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[9]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[14]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[15]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[8]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Round 2 + LV0 := LV0 + LV4 + LPMsg[3]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[4]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[10]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[12]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[13]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[2]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[7]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[14]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[6]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[5]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[9]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[0]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[11]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[15]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[8]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[1]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Round 3 + LV0 := LV0 + LV4 + LPMsg[10]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[7]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[12]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[9]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[14]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[3]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[13]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[15]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[4]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[0]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[11]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[2]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[5]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[8]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[1]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[6]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Round 4 + LV0 := LV0 + LV4 + LPMsg[12]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[13]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[9]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[11]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[15]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[10]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[14]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[8]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[7]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[2]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[5]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[3]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[0]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[1]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[6]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[4]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Round 5 + LV0 := LV0 + LV4 + LPMsg[9]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[14]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[11]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[5]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[8]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[12]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[15]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[1]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[13]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[3]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[0]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[10]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[2]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[6]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[4]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[7]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Round 6 + LV0 := LV0 + LV4 + LPMsg[11]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); + LV0 := LV0 + LV4 + LPMsg[15]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); + LV8 := LV8 + LV12; + LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); + LV1 := LV1 + LV5 + LPMsg[5]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); + LV1 := LV1 + LV5 + LPMsg[0]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); + LV9 := LV9 + LV13; + LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); + LV2 := LV2 + LV6 + LPMsg[1]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); + LV2 := LV2 + LV6 + LPMsg[9]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); + LV10 := LV10 + LV14; + LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); + LV3 := LV3 + LV7 + LPMsg[8]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); + LV3 := LV3 + LV7 + LPMsg[6]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); + LV11 := LV11 + LV15; + LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); + LV0 := LV0 + LV5 + LPMsg[14]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); + LV0 := LV0 + LV5 + LPMsg[10]; + LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); + LV10 := LV10 + LV15; + LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); + LV1 := LV1 + LV6 + LPMsg[2]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); + LV1 := LV1 + LV6 + LPMsg[12]; + LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); + LV11 := LV11 + LV12; + LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); + LV2 := LV2 + LV7 + LPMsg[3]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); + LV2 := LV2 + LV7 + LPMsg[4]; + LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); + LV8 := LV8 + LV13; + LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); + LV3 := LV3 + LV4 + LPMsg[7]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); + LV3 := LV3 + LV4 + LPMsg[13]; + LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); + LV9 := LV9 + LV14; + LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); + + // Finalization: XOR top and bottom halves + LPState[0] := LV0 xor LV8; + LPState[1] := LV1 xor LV9; + LPState[2] := LV2 xor LV10; + LPState[3] := LV3 xor LV11; + LPState[4] := LV4 xor LV12; + LPState[5] := LV5 xor LV13; + LPState[6] := LV6 xor LV14; + LPState[7] := LV7 xor LV15; + LPState[8] := LV8 xor LPCV[0]; + LPState[9] := LV9 xor LPCV[1]; + LPState[10] := LV10 xor LPCV[2]; + LPState[11] := LV11 xor LPCV[3]; + LPState[12] := LV12 xor LPCV[4]; + LPState[13] := LV13 xor LPCV[5]; + LPState[14] := LV14 xor LPCV[6]; + LPState[15] := LV15 xor LPCV[7]; +end; + +// ============================================================================= +// Scalar HashMany fallback (sequential, no parallelism) +// ============================================================================= + +procedure Blake3_HashMany_Scalar(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); +var + LChunk, LBlock: Int32; + LCV: array [0 .. 7] of UInt32; + LBlockWords: array [0 .. 15] of UInt32; + LState: array [0 .. 15] of UInt32; + LCounterFlags: array [0 .. 3] of UInt32; + LBlockFlags: UInt32; + LPInput, LPOut: PByte; +begin + LPInput := PByte(AInput); + LPOut := PByte(AOut); + + for LChunk := 0 to ANumChunks - 1 do + begin + // Initialize CV from key/IV + System.Move(AKey^, LCV[0], 8 * System.SizeOf(UInt32)); + + // Process 16 blocks per chunk + for LBlock := 0 to 15 do + begin + TBinaryPrimitives.CopyUInt32LittleEndian(LPInput, 0, @LBlockWords[0], 0, 64); + + // Set flags for this block + LBlockFlags := AFlags; + if LBlock = 0 then + LBlockFlags := LBlockFlags or FlagChunkStart; + if LBlock = 15 then + LBlockFlags := LBlockFlags or FlagChunkEnd; + + LCounterFlags[0] := UInt32(ACounter); + LCounterFlags[1] := UInt32(ACounter shr 32); + LCounterFlags[2] := 64; // BlockLen = 64 + LCounterFlags[3] := LBlockFlags; + + Blake3_Compress(@LState[0], @LBlockWords[0], @LCV[0], @LCounterFlags[0]); + + // Extract chaining value (first 8 words of output) + if LBlock < 15 then + System.Move(LState[0], LCV[0], 8 * System.SizeOf(UInt32)); + + System.Inc(LPInput, 64); + end; + + // Write final chaining value for this chunk + System.Move(LState[0], LPOut^, 8 * System.SizeOf(UInt32)); + System.Inc(LPOut, 8 * System.SizeOf(UInt32)); + System.Inc(ACounter); + end; +end; { TBlake3.TBlake3Node } @@ -910,4 +1506,9 @@ function TBlake3XOF.TransformFinal: IHashResult; Result := THashResult.Create(LBuffer); end; +initialization + Blake3_Compress := TBlake3Simd.SelectCompress(@Blake3_Compress_Scalar); + Blake3_HashMany := TBlake3Simd.SelectHashMany(@Blake3_HashMany_Scalar); + Blake3_ParallelDegree := TBlake3Simd.SelectParallelDegree(1); + end. diff --git a/HashLib/src/Crypto/HlpBlake3Dispatch.pas b/HashLib/src/Crypto/HlpBlake3Dispatch.pas deleted file mode 100644 index a065a7d..0000000 --- a/HashLib/src/Crypto/HlpBlake3Dispatch.pas +++ /dev/null @@ -1,795 +0,0 @@ -unit HlpBlake3Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TBlake3CompressProc = procedure(AState, AMsg, ACV, ACounterFlags: Pointer); - - // Hash N complete chunks in parallel. - // AInput: pointer to N * 1024 bytes of contiguous input - // AKey: pointer to 8 x UInt32 key/IV - // AOut: pointer to N * 8 x UInt32 output chaining values - // ANumChunks: number of chunks to hash - // ACounter: starting chunk counter - // AFlags: base flags (chunk start/end handled internally) - TBlake3HashManyProc = procedure(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - -var - Blake3_Compress: TBlake3CompressProc; - Blake3_HashMany: TBlake3HashManyProc; - Blake3_ParallelDegree: Int32; - -implementation - -uses - HlpBinaryPrimitives, - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -const - Blake3IV: array [0 .. 3] of UInt32 = ( - UInt32($6A09E667), UInt32($BB67AE85), - UInt32($3C6EF372), UInt32($A54FF53A) - ); - - FlagChunkStart = UInt32(1 shl 0); - FlagChunkEnd = UInt32(1 shl 1); - -// ============================================================================= -// Scalar fallback implementation (fully unrolled, 7 rounds, inlined G) -// ============================================================================= - -procedure Blake3_Compress_Scalar(AState, AMsg, ACV, ACounterFlags: Pointer); -var - LV0, LV1, LV2, LV3, LV4, LV5, LV6, LV7: UInt32; - LV8, LV9, LV10, LV11, LV12, LV13, LV14, LV15: UInt32; - LPMsg, LPCV, LPCounterFlags, LPState: PCardinal; -begin - LPMsg := PCardinal(AMsg); - LPCV := PCardinal(ACV); - LPCounterFlags := PCardinal(ACounterFlags); - LPState := PCardinal(AState); - - // Initialize state from chaining value - LV0 := LPCV[0]; - LV1 := LPCV[1]; - LV2 := LPCV[2]; - LV3 := LPCV[3]; - LV4 := LPCV[4]; - LV5 := LPCV[5]; - LV6 := LPCV[6]; - LV7 := LPCV[7]; - // Initialize counter half from IV and counter/flags - LV8 := Blake3IV[0]; - LV9 := Blake3IV[1]; - LV10 := Blake3IV[2]; - LV11 := Blake3IV[3]; - LV12 := LPCounterFlags[0]; - LV13 := LPCounterFlags[1]; - LV14 := LPCounterFlags[2]; - LV15 := LPCounterFlags[3]; - - // Round 0 - LV0 := LV0 + LV4 + LPMsg[0]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[1]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[2]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[3]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[4]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[5]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[6]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[7]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[8]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[9]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[10]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[11]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[12]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[13]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[14]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[15]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Round 1 - LV0 := LV0 + LV4 + LPMsg[2]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[6]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[3]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[10]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[7]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[0]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[4]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[13]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[1]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[11]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[12]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[5]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[9]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[14]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[15]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[8]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Round 2 - LV0 := LV0 + LV4 + LPMsg[3]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[4]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[10]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[12]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[13]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[2]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[7]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[14]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[6]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[5]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[9]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[0]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[11]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[15]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[8]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[1]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Round 3 - LV0 := LV0 + LV4 + LPMsg[10]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[7]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[12]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[9]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[14]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[3]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[13]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[15]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[4]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[0]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[11]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[2]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[5]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[8]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[1]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[6]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Round 4 - LV0 := LV0 + LV4 + LPMsg[12]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[13]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[9]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[11]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[15]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[10]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[14]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[8]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[7]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[2]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[5]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[3]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[0]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[1]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[6]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[4]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Round 5 - LV0 := LV0 + LV4 + LPMsg[9]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[14]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[11]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[5]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[8]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[12]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[15]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[1]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[13]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[3]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[0]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[10]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[2]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[6]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[4]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[7]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Round 6 - LV0 := LV0 + LV4 + LPMsg[11]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 16); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 12); - LV0 := LV0 + LV4 + LPMsg[15]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV0, 8); - LV8 := LV8 + LV12; - LV4 := TBitOperations.RotateRight32(LV4 xor LV8, 7); - LV1 := LV1 + LV5 + LPMsg[5]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 16); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 12); - LV1 := LV1 + LV5 + LPMsg[0]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV1, 8); - LV9 := LV9 + LV13; - LV5 := TBitOperations.RotateRight32(LV5 xor LV9, 7); - LV2 := LV2 + LV6 + LPMsg[1]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 16); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 12); - LV2 := LV2 + LV6 + LPMsg[9]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV2, 8); - LV10 := LV10 + LV14; - LV6 := TBitOperations.RotateRight32(LV6 xor LV10, 7); - LV3 := LV3 + LV7 + LPMsg[8]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 16); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 12); - LV3 := LV3 + LV7 + LPMsg[6]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV3, 8); - LV11 := LV11 + LV15; - LV7 := TBitOperations.RotateRight32(LV7 xor LV11, 7); - LV0 := LV0 + LV5 + LPMsg[14]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 16); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 12); - LV0 := LV0 + LV5 + LPMsg[10]; - LV15 := TBitOperations.RotateRight32(LV15 xor LV0, 8); - LV10 := LV10 + LV15; - LV5 := TBitOperations.RotateRight32(LV5 xor LV10, 7); - LV1 := LV1 + LV6 + LPMsg[2]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 16); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 12); - LV1 := LV1 + LV6 + LPMsg[12]; - LV12 := TBitOperations.RotateRight32(LV12 xor LV1, 8); - LV11 := LV11 + LV12; - LV6 := TBitOperations.RotateRight32(LV6 xor LV11, 7); - LV2 := LV2 + LV7 + LPMsg[3]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 16); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 12); - LV2 := LV2 + LV7 + LPMsg[4]; - LV13 := TBitOperations.RotateRight32(LV13 xor LV2, 8); - LV8 := LV8 + LV13; - LV7 := TBitOperations.RotateRight32(LV7 xor LV8, 7); - LV3 := LV3 + LV4 + LPMsg[7]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 16); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 12); - LV3 := LV3 + LV4 + LPMsg[13]; - LV14 := TBitOperations.RotateRight32(LV14 xor LV3, 8); - LV9 := LV9 + LV14; - LV4 := TBitOperations.RotateRight32(LV4 xor LV9, 7); - - // Finalization: XOR top and bottom halves - LPState[0] := LV0 xor LV8; - LPState[1] := LV1 xor LV9; - LPState[2] := LV2 xor LV10; - LPState[3] := LV3 xor LV11; - LPState[4] := LV4 xor LV12; - LPState[5] := LV5 xor LV13; - LPState[6] := LV6 xor LV14; - LPState[7] := LV7 xor LV15; - LPState[8] := LV8 xor LPCV[0]; - LPState[9] := LV9 xor LPCV[1]; - LPState[10] := LV10 xor LPCV[2]; - LPState[11] := LV11 xor LPCV[3]; - LPState[12] := LV12 xor LPCV[4]; - LPState[13] := LV13 xor LPCV[5]; - LPState[14] := LV14 xor LPCV[6]; - LPState[15] := LV15 xor LPCV[7]; -end; - -// ============================================================================= -// Scalar HashMany fallback (sequential, no parallelism) -// ============================================================================= - -procedure Blake3_HashMany_Scalar(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); -var - LChunk, LBlock: Int32; - LCV: array [0 .. 7] of UInt32; - LBlockWords: array [0 .. 15] of UInt32; - LState: array [0 .. 15] of UInt32; - LCounterFlags: array [0 .. 3] of UInt32; - LBlockFlags: UInt32; - LPInput, LPOut: PByte; -begin - LPInput := PByte(AInput); - LPOut := PByte(AOut); - - for LChunk := 0 to ANumChunks - 1 do - begin - // Initialize CV from key/IV - System.Move(AKey^, LCV[0], 8 * System.SizeOf(UInt32)); - - // Process 16 blocks per chunk - for LBlock := 0 to 15 do - begin - TBinaryPrimitives.CopyUInt32LittleEndian(LPInput, 0, @LBlockWords[0], 0, 64); - - // Set flags for this block - LBlockFlags := AFlags; - if LBlock = 0 then - LBlockFlags := LBlockFlags or FlagChunkStart; - if LBlock = 15 then - LBlockFlags := LBlockFlags or FlagChunkEnd; - - LCounterFlags[0] := UInt32(ACounter); - LCounterFlags[1] := UInt32(ACounter shr 32); - LCounterFlags[2] := 64; // BlockLen = 64 - LCounterFlags[3] := LBlockFlags; - - Blake3_Compress(@LState[0], @LBlockWords[0], @LCV[0], @LCounterFlags[0]); - - // Extract chaining value (first 8 words of output) - if LBlock < 15 then - System.Move(LState[0], LCV[0], 8 * System.SizeOf(UInt32)); - - System.Inc(LPInput, 64); - end; - - // Write final chaining value for this chunk - System.Move(LState[0], LPOut^, 8 * System.SizeOf(UInt32)); - System.Inc(LPOut, 8 * System.SizeOf(UInt32)); - System.Inc(ACounter); - end; -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: AVX2, SSE2 -// aarch64: NEON -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\Blake3\Blake3CompressSse2_i386.inc} -end; - -procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\Include\Simd\Common\HlpSimdProc6Begin_i386.inc} - {$I ..\Include\Simd\Blake3\Blake3Hash4Sse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Blake3\Blake3CompressSse2_x86_64.inc} -end; - -procedure Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Blake3\Blake3CompressAvx2_x86_64.inc} -end; - -procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} - {$I ..\Include\Simd\Blake3\Blake3Hash4Sse2_x86_64.inc} -end; - -procedure Blake3_Hash8_Avx2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} - {$I ..\Include\Simd\Blake3\Blake3Hash8Avx2_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_X86_SIMD} - -// SSE2 hash_many: hash4 -> delegate remainder to scalar hash_many -procedure Blake3_HashMany_Sse2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); -var - LPInput, LPOut: PByte; -begin - LPInput := PByte(AInput); - LPOut := PByte(AOut); - while ANumChunks >= 4 do - begin - Blake3_Hash4_Sse2(LPInput, AKey, LPOut, 4, ACounter, AFlags); - System.Inc(LPInput, 4 * 1024); - System.Inc(LPOut, 4 * 32); - System.Inc(ACounter, 4); - System.Dec(ANumChunks, 4); - end; - if ANumChunks > 0 then - Blake3_HashMany_Scalar(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); -end; - -{$ENDIF HASHLIB_X86_SIMD} - -{$IFDEF HASHLIB_X86_64_ASM} - -// AVX2 hash_many: hash8 -> delegate remainder to SSE2 hash_many (x64 only; after shared Sse2) -procedure Blake3_HashMany_Avx2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); -var - LPInput, LPOut: PByte; -begin - LPInput := PByte(AInput); - LPOut := PByte(AOut); - while ANumChunks >= 8 do - begin - Blake3_Hash8_Avx2(LPInput, AKey, LPOut, 8, ACounter, AFlags); - System.Inc(LPInput, 8 * 1024); - System.Inc(LPOut, 8 * 32); - System.Inc(ACounter, 8); - System.Dec(ANumChunks, 8); - end; - if ANumChunks > 0 then - Blake3_HashMany_Sse2(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure Blake3_Compress_Neon(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\Blake3\Blake3CompressNeon_aarch64.inc} -end; - -procedure Blake3_Hash4_Neon(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\Include\Simd\Common\HlpSimdProc6Begin_aarch64.inc} - {$I ..\Include\Simd\Blake3\Blake3Hash4Neon_aarch64.inc} -end; - -// NEON hash_many: hash4 -> delegate remainder to scalar hash_many -procedure Blake3_HashMany_Neon(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); -var - LPInput, LPOut: PByte; -begin - LPInput := PByte(AInput); - LPOut := PByte(AOut); - while ANumChunks >= 4 do - begin - Blake3_Hash4_Neon(LPInput, AKey, LPOut, 4, ACounter, AFlags); - System.Inc(LPInput, 4 * 1024); - System.Inc(LPOut, 4 * 32); - System.Inc(ACounter, 4); - System.Dec(ANumChunks, 4); - end; - if ANumChunks > 0 then - Blake3_HashMany_Scalar(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - Blake3_Compress := @Blake3_Compress_Scalar; - Blake3_HashMany := @Blake3_HashMany_Scalar; - Blake3_ParallelDegree := 1; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - Blake3_Compress := @Blake3_Compress_Sse2; - Blake3_HashMany := @Blake3_HashMany_Sse2; - Blake3_ParallelDegree := 4; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - Blake3_Compress := @Blake3_Compress_Avx2; - Blake3_HashMany := @Blake3_HashMany_Avx2; - Blake3_ParallelDegree := 8; - end; - TX86SimdLevel.SSE2: - begin - Blake3_Compress := @Blake3_Compress_Sse2; - Blake3_HashMany := @Blake3_HashMany_Sse2; - Blake3_ParallelDegree := 4; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - TArmSimdLevel.NEON: - begin - Blake3_Compress := @Blake3_Compress_Neon; - Blake3_HashMany := @Blake3_HashMany_Neon; - Blake3_ParallelDegree := 4; - end; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Crypto/HlpSHA1.pas b/HashLib/src/Crypto/HlpSHA1.pas index ae06b8d..b52c80b 100644 --- a/HashLib/src/Crypto/HlpSHA1.pas +++ b/HashLib/src/Crypto/HlpSHA1.pas @@ -8,8 +8,23 @@ interface HlpBitOperations, HlpHashLibTypes, HlpSHA0, - HlpIHash, - HlpSHA1Dispatch; + HlpIHash; + +type + TSHA1CompressProc = procedure(AState, AData: Pointer; ANumBlocks: UInt32); + +var + SHA1_Compress: TSHA1CompressProc; + +const + // K round constants, each replicated across four lanes for the SIMD kernels; + // the scalar reference reads one per group ([0], [4], [8], [12]). + K_SHA1: array [0 .. 15] of UInt32 = ( + $5A827999, $5A827999, $5A827999, $5A827999, + $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, + $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, + $CA62C1D6, $CA62C1D6, $CA62C1D6, $CA62C1D6 + ); type TSHA1 = class sealed(TSHA0) @@ -29,6 +44,82 @@ TSHA1 = class sealed(TSHA0) implementation +uses + HlpBinaryPrimitives, + HlpSHA1Simd; + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure SHA1_Compress_Scalar(AState, AData: Pointer; ANumBlocks: UInt32); +var + LPState: PCardinal; + LPData: PByte; + LA, LB, LC, LD, LE, LT: UInt32; + LW: array [0 .. 79] of UInt32; + LRound: Int32; +begin + LPState := PCardinal(AState); + LPData := PByte(AData); + + while ANumBlocks > 0 do + begin + TBinaryPrimitives.CopyUInt32BigEndian(LPData, 0, @LW[0], 0, 64); + + for LRound := 16 to 79 do + begin + LT := LW[LRound - 3] xor LW[LRound - 8] xor LW[LRound - 14] + xor LW[LRound - 16]; + LW[LRound] := TBitOperations.RotateLeft32(LT, 1); + end; + + LA := LPState[0]; LB := LPState[1]; LC := LPState[2]; + LD := LPState[3]; LE := LPState[4]; + + for LRound := 0 to 19 do + begin + LT := TBitOperations.RotateLeft32(LA, 5) + (LD xor (LB and (LC xor LD))) + + LE + K_SHA1[0] + LW[LRound]; + LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); + LB := LA; LA := LT; + end; + + for LRound := 20 to 39 do + begin + LT := TBitOperations.RotateLeft32(LA, 5) + (LB xor LC xor LD) + + LE + K_SHA1[4] + LW[LRound]; + LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); + LB := LA; LA := LT; + end; + + for LRound := 40 to 59 do + begin + LT := TBitOperations.RotateLeft32(LA, 5) + + ((LB and LC) or (LD and (LB or LC))) + + LE + K_SHA1[8] + LW[LRound]; + LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); + LB := LA; LA := LT; + end; + + for LRound := 60 to 79 do + begin + LT := TBitOperations.RotateLeft32(LA, 5) + (LB xor LC xor LD) + + LE + K_SHA1[12] + LW[LRound]; + LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); + LB := LA; LA := LT; + end; + + LPState[0] := LPState[0] + LA; LPState[1] := LPState[1] + LB; + LPState[2] := LPState[2] + LC; LPState[3] := LPState[3] + LD; + LPState[4] := LPState[4] + LE; + + System.FillChar(LW, System.SizeOf(LW), 0); + System.Inc(LPData, 64); + System.Dec(ANumBlocks); + end; +end; + { TSHA1 } function TSHA1.Clone(): IHash; @@ -241,4 +332,7 @@ procedure TSHA1.Expand(AData: PCardinal); {$ENDIF USE_UNROLLED_VARIANT} end; +initialization + SHA1_Compress := TSHA1Simd.Select(@SHA1_Compress_Scalar); + end. diff --git a/HashLib/src/Crypto/HlpSHA1Dispatch.pas b/HashLib/src/Crypto/HlpSHA1Dispatch.pas deleted file mode 100644 index 0c8da7a..0000000 --- a/HashLib/src/Crypto/HlpSHA1Dispatch.pas +++ /dev/null @@ -1,253 +0,0 @@ -unit HlpSHA1Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TSHA1CompressProc = procedure(AState, AData: Pointer; ANumBlocks: UInt32); - -var - SHA1_Compress: TSHA1CompressProc; - -const - // K round constants replicated 4x for SIMD. - // Layout: K_00_19 (16B) at 0, K_20_39 at 16, K_40_59 at 32, K_60_79 at 48. - K_SHA1: array [0 .. 15] of UInt32 = ( - $5A827999, $5A827999, $5A827999, $5A827999, - $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, - $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, - $CA62C1D6, $CA62C1D6, $CA62C1D6, $CA62C1D6 - ); - -{$IFDEF HASHLIB_X86_SIMD} - // BSWAP32 shuffle mask for pshufb (x86 SIMD only): byte-swaps and reverses - // dword order in one shuffle (sha1rnds4 reads its four words in reverse). Not a - // SHA-1 constant; used only by the SHA-NI kernel. ARM byte-swaps with REV32 and - // needs no mask table. - BSWAP32_MASK: array [0 .. 3] of UInt32 = ( - $0C0D0E0F, $08090A0B, $04050607, $00010203 - ); - - // Doubled SHA-1 round constants plus the AVX2 byte-swap masks, shared by the - // AVX2 and SSE2 SIMD-schedule SHA-1 kernels. Each round constant fills a 128-bit - // lane (its four dwords) and is stored twice so one table feeds both the 256-bit - // AVX2 read and the 128-bit SSE2 reads (both read at a 32-byte stride, skipping - // the duplicate halves). Only the AVX2 kernel uses the appended masks: the - // byte-swap mask (BSWAP32 pattern, twice) then a whole-vector reverse mask; the - // SSE2 kernel computes its byte-swap and needs no mask. Read unaligned, so no - // special alignment is required. - K_SHA1_Doubled: array [0 .. 43] of UInt32 = ( - $5A827999, $5A827999, $5A827999, $5A827999, - $5A827999, $5A827999, $5A827999, $5A827999, - $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, - $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, - $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, - $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, - $CA62C1D6, $CA62C1D6, $CA62C1D6, $CA62C1D6, - $CA62C1D6, $CA62C1D6, $CA62C1D6, $CA62C1D6, - $00010203, $04050607, $08090A0B, $0C0D0E0F, - $00010203, $04050607, $08090A0B, $0C0D0E0F, - $0C0D0E0F, $08090A0B, $04050607, $00010203 - ); -{$ENDIF HASHLIB_X86_SIMD} - -implementation - -uses - HlpBinaryPrimitives, - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure SHA1_Compress_Scalar(AState, AData: Pointer; ANumBlocks: UInt32); -var - LPState: PCardinal; - LPData: PByte; - LA, LB, LC, LD, LE, LT: UInt32; - LW: array [0 .. 79] of UInt32; - LRound: Int32; -begin - LPState := PCardinal(AState); - LPData := PByte(AData); - - while ANumBlocks > 0 do - begin - TBinaryPrimitives.CopyUInt32BigEndian(LPData, 0, @LW[0], 0, 64); - - for LRound := 16 to 79 do - begin - LT := LW[LRound - 3] xor LW[LRound - 8] xor LW[LRound - 14] - xor LW[LRound - 16]; - LW[LRound] := TBitOperations.RotateLeft32(LT, 1); - end; - - LA := LPState[0]; LB := LPState[1]; LC := LPState[2]; - LD := LPState[3]; LE := LPState[4]; - - for LRound := 0 to 19 do - begin - LT := TBitOperations.RotateLeft32(LA, 5) + (LD xor (LB and (LC xor LD))) - + LE + $5A827999 + LW[LRound]; - LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); - LB := LA; LA := LT; - end; - - for LRound := 20 to 39 do - begin - LT := TBitOperations.RotateLeft32(LA, 5) + (LB xor LC xor LD) - + LE + $6ED9EBA1 + LW[LRound]; - LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); - LB := LA; LA := LT; - end; - - for LRound := 40 to 59 do - begin - LT := TBitOperations.RotateLeft32(LA, 5) + - ((LB and LC) or (LD and (LB or LC))) - + LE + $8F1BBCDC + LW[LRound]; - LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); - LB := LA; LA := LT; - end; - - for LRound := 60 to 79 do - begin - LT := TBitOperations.RotateLeft32(LA, 5) + (LB xor LC xor LD) - + LE + $CA62C1D6 + LW[LRound]; - LE := LD; LD := LC; LC := TBitOperations.RotateLeft32(LB, 30); - LB := LA; LA := LT; - end; - - LPState[0] := LPState[0] + LA; LPState[1] := LPState[1] + LB; - LPState[2] := LPState[2] + LC; LPState[3] := LPState[3] + LD; - LPState[4] := LPState[4] + LE; - - System.FillChar(LW, System.SizeOf(LW), 0); - System.Inc(LPData, 64); - System.Dec(ANumBlocks); - end; -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: ShaNi, AVX2, SSE2 -// aarch64: SHA1 Crypto Extensions -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\SHA1\SHA1CompressSse2_i386.inc} -end; - -procedure SHA1_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_Sse2(AState, AData, ANumBlocks, @K_SHA1_Doubled); -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure SHA1_Compress_ShaNi(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants, AMask: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\Include\Simd\SHA1\SHA1CompressShaNi_x86_64.inc} -end; - -procedure SHA1_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_ShaNi(AState, AData, ANumBlocks, @K_SHA1, @BSWAP32_MASK); -end; - -procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\SHA1\SHA1CompressSse2_x86_64.inc} -end; - -procedure SHA1_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_Sse2(AState, AData, ANumBlocks, @K_SHA1_Doubled); -end; - -procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\SHA1\SHA1CompressAvx2_x86_64.inc} -end; - -procedure SHA1_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_Avx2(AState, AData, ANumBlocks, @K_SHA1_Doubled); -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure SHA1_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\SHA1\SHA1CompressCryptoExt_aarch64.inc} -end; - -procedure SHA1_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_CryptoExt(AState, AData, ANumBlocks, @K_SHA1); -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - SHA1_Compress := @SHA1_Compress_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - SHA1_Compress := @SHA1_Compress_Sse2_Wrap; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - if TCpuFeatures.X86.HasSHANI() then - begin - SHA1_Compress := @SHA1_Compress_ShaNi_Wrap; - Exit; - end; - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - SHA1_Compress := @SHA1_Compress_Avx2_Wrap; - end; - TX86SimdLevel.SSE2: - begin - SHA1_Compress := @SHA1_Compress_Sse2_Wrap; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - if TCpuFeatures.Arm.HasSHA1() then - begin - SHA1_Compress := @SHA1_Compress_CryptoExt_Wrap; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Crypto/HlpSHA2_256Base.pas b/HashLib/src/Crypto/HlpSHA2_256Base.pas index 3848efb..078b152 100644 --- a/HashLib/src/Crypto/HlpSHA2_256Base.pas +++ b/HashLib/src/Crypto/HlpSHA2_256Base.pas @@ -8,8 +8,39 @@ interface HlpBinaryPrimitives, HlpHashLibTypes, HlpIHashInfo, - HlpHashCryptoNotBuildIn, - HlpSHA2_256Dispatch; + HlpHashCryptoNotBuildIn; + +type + // Block compression contract shared by the scalar reference implementation and + // every SIMD backend: hash ANumBlocks consecutive 64-byte blocks into AState. + TSHA256CompressProc = procedure(AState, AData: Pointer; ANumBlocks: UInt32); + +var + // The active SHA-256 block-compression routine. Assigned once at unit + // initialization to the best implementation the running CPU supports (see the + // SIMD facade); defaults to the scalar reference on non-accelerated targets. + SHA256_Compress: TSHA256CompressProc; + +const + // K256 round constants (64 UInt32 = 256 bytes). + K256: array [0 .. 63] of UInt32 = ( + $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, + $D807AA98, $12835B01, $243185BE, $550C7DC3, + $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, + $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, + $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, + $983E5152, $A831C66D, $B00327C8, $BF597FC7, + $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, + $650A7354, $766A0ABB, $81C2C92E, $92722C85, + $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, + $D192E819, $D6990624, $F40E3585, $106AA070, + $19A4C116, $1E376C08, $2748774C, $34B0BCB5, + $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, + $748F82EE, $78A5636F, $84C87814, $8CC70208, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2 + ); type TSHA2_256Base = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock) @@ -31,6 +62,65 @@ TSHA2_256Base = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock) implementation +uses + HlpBitOperations, + HlpSHA2_256Simd; + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure SHA256_Compress_Scalar(AState, AData: Pointer; ANumBlocks: UInt32); +var + LPState: PCardinal; + LPData: PByte; + LA, LB, LC, LD, LE, LF, LG, LH, LT1, LT2: UInt32; + LW: array [0 .. 63] of UInt32; + LRound: Int32; +begin + LPState := PCardinal(AState); + LPData := PByte(AData); + + while ANumBlocks > 0 do + begin + TBinaryPrimitives.CopyUInt32BigEndian(LPData, 0, @LW[0], 0, 64); + + for LRound := 16 to 63 do + begin + LT1 := LW[LRound - 2]; + LT2 := LW[LRound - 15]; + LW[LRound] := (TBitOperations.RotateRight32(LT1, 17) xor TBitOperations.RotateRight32(LT1, 19) + xor (LT1 shr 10)) + LW[LRound - 7] + + (TBitOperations.RotateRight32(LT2, 7) xor TBitOperations.RotateRight32(LT2, 18) + xor (LT2 shr 3)) + LW[LRound - 16]; + end; + + LA := LPState[0]; LB := LPState[1]; LC := LPState[2]; LD := LPState[3]; + LE := LPState[4]; LF := LPState[5]; LG := LPState[6]; LH := LPState[7]; + + for LRound := 0 to 63 do + begin + LT1 := LH + (TBitOperations.RotateRight32(LE, 6) xor TBitOperations.RotateRight32(LE, 11) + xor TBitOperations.RotateRight32(LE, 25)) + ((LE and LF) xor (not LE and LG)) + + K256[LRound] + LW[LRound]; + LT2 := (TBitOperations.RotateRight32(LA, 2) xor TBitOperations.RotateRight32(LA, 13) + xor TBitOperations.RotateRight32(LA, 22)) + + ((LA and LB) xor (LA and LC) xor (LB and LC)); + LH := LG; LG := LF; LF := LE; LE := LD + LT1; + LD := LC; LC := LB; LB := LA; LA := LT1 + LT2; + end; + + LPState[0] := LPState[0] + LA; LPState[1] := LPState[1] + LB; + LPState[2] := LPState[2] + LC; LPState[3] := LPState[3] + LD; + LPState[4] := LPState[4] + LE; LPState[5] := LPState[5] + LF; + LPState[6] := LPState[6] + LG; LPState[7] := LPState[7] + LH; + + System.FillChar(LW, System.SizeOf(LW), 0); + System.Inc(LPData, 64); + System.Dec(ANumBlocks); + end; +end; + { TSHA2_256Base } constructor TSHA2_256Base.Create(AHashSize: Int32); @@ -109,4 +199,7 @@ procedure TSHA2_256Base.TransformBytes(const AData: THashLibByteArray; end; end; +initialization + SHA256_Compress := TSHA2_256Simd.Select(@SHA256_Compress_Scalar); + end. diff --git a/HashLib/src/Crypto/HlpSHA2_256Dispatch.pas b/HashLib/src/Crypto/HlpSHA2_256Dispatch.pas deleted file mode 100644 index 55c5463..0000000 --- a/HashLib/src/Crypto/HlpSHA2_256Dispatch.pas +++ /dev/null @@ -1,272 +0,0 @@ -unit HlpSHA2_256Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TSHA256CompressProc = procedure(AState, AData: Pointer; ANumBlocks: UInt32); - -var - SHA256_Compress: TSHA256CompressProc; - -const - // K256 round constants (64 UInt32 = 256 bytes) - K256: array [0 .. 63] of UInt32 = ( - $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, - $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, - $D807AA98, $12835B01, $243185BE, $550C7DC3, - $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, - $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, - $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, - $983E5152, $A831C66D, $B00327C8, $BF597FC7, - $C6E00BF3, $D5A79147, $06CA6351, $14292967, - $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, - $650A7354, $766A0ABB, $81C2C92E, $92722C85, - $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, - $D192E819, $D6990624, $F40E3585, $106AA070, - $19A4C116, $1E376C08, $2748774C, $34B0BCB5, - $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, - $748F82EE, $78A5636F, $84C87814, $8CC70208, - $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2 - ); - -{$IFDEF HASHLIB_X86_SIMD} - // BSWAP32 shuffle mask for pshufb (x86 SIMD only): reverses bytes within each - // dword. Not a SHA-256 constant; used only by the SHA-NI kernel. ARM byte-swaps - // with REV32 and needs no mask table. - BSWAP32_MASK: array [0 .. 3] of UInt32 = ( - $00010203, $04050607, $08090A0B, $0C0D0E0F - ); - - // Doubled K256 round constants plus the three AVX2 message-schedule masks, - // shared by the AVX2 and SSE2 SIMD-schedule SHA-256 kernels. Each 128-bit K256 - // quadruple is stored twice so one table feeds both the 256-bit AVX2 lanes and - // the 128-bit SSE2 reads (both read at a 32-byte stride, skipping the duplicate - // halves). Only the AVX2 kernel uses the appended masks: the byte-swap mask - // (BSWAP32 pattern, twice) occupies [128..135] and the two schedule shuffle - // masks follow at [136..143] and [144..151]; the SSE2 kernel computes its - // byte-swap and needs no mask. Derived from K256. - K256_Doubled: array [0 .. 151] of UInt32 = ( - $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, - $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, - $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, - $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, - $D807AA98, $12835B01, $243185BE, $550C7DC3, - $D807AA98, $12835B01, $243185BE, $550C7DC3, - $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, - $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, - $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, - $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, - $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, - $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, - $983E5152, $A831C66D, $B00327C8, $BF597FC7, - $983E5152, $A831C66D, $B00327C8, $BF597FC7, - $C6E00BF3, $D5A79147, $06CA6351, $14292967, - $C6E00BF3, $D5A79147, $06CA6351, $14292967, - $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, - $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, - $650A7354, $766A0ABB, $81C2C92E, $92722C85, - $650A7354, $766A0ABB, $81C2C92E, $92722C85, - $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, - $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, - $D192E819, $D6990624, $F40E3585, $106AA070, - $D192E819, $D6990624, $F40E3585, $106AA070, - $19A4C116, $1E376C08, $2748774C, $34B0BCB5, - $19A4C116, $1E376C08, $2748774C, $34B0BCB5, - $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, - $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, - $748F82EE, $78A5636F, $84C87814, $8CC70208, - $748F82EE, $78A5636F, $84C87814, $8CC70208, - $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2, - $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2, - $00010203, $04050607, $08090A0B, $0C0D0E0F, - $00010203, $04050607, $08090A0B, $0C0D0E0F, - $03020100, $0B0A0908, $FFFFFFFF, $FFFFFFFF, - $03020100, $0B0A0908, $FFFFFFFF, $FFFFFFFF, - $FFFFFFFF, $FFFFFFFF, $03020100, $0B0A0908, - $FFFFFFFF, $FFFFFFFF, $03020100, $0B0A0908 - ); -{$ENDIF HASHLIB_X86_SIMD} - -implementation - -uses - HlpBinaryPrimitives, - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure SHA256_Compress_Scalar(AState, AData: Pointer; ANumBlocks: UInt32); -var - LPState: PCardinal; - LPData: PByte; - LA, LB, LC, LD, LE, LF, LG, LH, LT1, LT2: UInt32; - LW: array [0 .. 63] of UInt32; - LRound: Int32; -begin - LPState := PCardinal(AState); - LPData := PByte(AData); - - while ANumBlocks > 0 do - begin - TBinaryPrimitives.CopyUInt32BigEndian(LPData, 0, @LW[0], 0, 64); - - for LRound := 16 to 63 do - begin - LT1 := LW[LRound - 2]; - LT2 := LW[LRound - 15]; - LW[LRound] := (TBitOperations.RotateRight32(LT1, 17) xor TBitOperations.RotateRight32(LT1, 19) - xor (LT1 shr 10)) + LW[LRound - 7] + - (TBitOperations.RotateRight32(LT2, 7) xor TBitOperations.RotateRight32(LT2, 18) - xor (LT2 shr 3)) + LW[LRound - 16]; - end; - - LA := LPState[0]; LB := LPState[1]; LC := LPState[2]; LD := LPState[3]; - LE := LPState[4]; LF := LPState[5]; LG := LPState[6]; LH := LPState[7]; - - for LRound := 0 to 63 do - begin - LT1 := LH + (TBitOperations.RotateRight32(LE, 6) xor TBitOperations.RotateRight32(LE, 11) - xor TBitOperations.RotateRight32(LE, 25)) + ((LE and LF) xor (not LE and LG)) - + K256[LRound] + LW[LRound]; - LT2 := (TBitOperations.RotateRight32(LA, 2) xor TBitOperations.RotateRight32(LA, 13) - xor TBitOperations.RotateRight32(LA, 22)) + - ((LA and LB) xor (LA and LC) xor (LB and LC)); - LH := LG; LG := LF; LF := LE; LE := LD + LT1; - LD := LC; LC := LB; LB := LA; LA := LT1 + LT2; - end; - - LPState[0] := LPState[0] + LA; LPState[1] := LPState[1] + LB; - LPState[2] := LPState[2] + LC; LPState[3] := LPState[3] + LD; - LPState[4] := LPState[4] + LE; LPState[5] := LPState[5] + LF; - LPState[6] := LPState[6] + LG; LPState[7] := LPState[7] + LH; - - System.FillChar(LW, System.SizeOf(LW), 0); - System.Inc(LPData, 64); - System.Dec(ANumBlocks); - end; -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: ShaNi, AVX2, SSE2 -// aarch64: SHA256 Crypto Extensions -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\SHA256\SHA256CompressSse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure SHA256_Compress_ShaNi(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants, AMask: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\Include\Simd\SHA256\SHA256CompressShaNi_x86_64.inc} -end; - -procedure SHA256_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA256_Compress_ShaNi(AState, AData, ANumBlocks, @K256, @BSWAP32_MASK); -end; - -procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\SHA256\SHA256CompressSse2_x86_64.inc} -end; - -procedure SHA256_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\SHA256\SHA256CompressAvx2_x86_64.inc} -end; - -procedure SHA256_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA256_Compress_Avx2(AState, AData, ANumBlocks, @K256_Doubled); -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_X86_SIMD} - -procedure SHA256_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA256_Compress_Sse2(AState, AData, ANumBlocks, @K256_Doubled); -end; - -{$ENDIF HASHLIB_X86_SIMD} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure SHA256_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\SHA256\SHA256CompressCryptoExt_aarch64.inc} -end; - -procedure SHA256_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA256_Compress_CryptoExt(AState, AData, ANumBlocks, @K256); -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - SHA256_Compress := @SHA256_Compress_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - SHA256_Compress := @SHA256_Compress_Sse2_Wrap; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - if TCpuFeatures.X86.HasSHANI() then - begin - SHA256_Compress := @SHA256_Compress_ShaNi_Wrap; - Exit; - end; - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - SHA256_Compress := @SHA256_Compress_Avx2_Wrap; - end; - TX86SimdLevel.SSE2: - begin - SHA256_Compress := @SHA256_Compress_Sse2_Wrap; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - if TCpuFeatures.Arm.HasSHA256() then - begin - SHA256_Compress := @SHA256_Compress_CryptoExt_Wrap; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Crypto/HlpSHA2_512Base.pas b/HashLib/src/Crypto/HlpSHA2_512Base.pas index ac923d4..f26e8e1 100644 --- a/HashLib/src/Crypto/HlpSHA2_512Base.pas +++ b/HashLib/src/Crypto/HlpSHA2_512Base.pas @@ -8,8 +8,58 @@ interface HlpBinaryPrimitives, HlpHashLibTypes, HlpIHashInfo, - HlpHashCryptoNotBuildIn, - HlpSHA2_512Dispatch; + HlpHashCryptoNotBuildIn; + +type + TSHA512CompressProc = procedure(AState, AData: Pointer; ANumBlocks: UInt32); + +var + SHA512_Compress: TSHA512CompressProc; + +const + // K512 round constants (80 UInt64 = 640 bytes). + K512: array [0 .. 79] of UInt64 = ( + UInt64($428A2F98D728AE22), UInt64($7137449123EF65CD), + UInt64($B5C0FBCFEC4D3B2F), UInt64($E9B5DBA58189DBBC), + UInt64($3956C25BF348B538), UInt64($59F111F1B605D019), + UInt64($923F82A4AF194F9B), UInt64($AB1C5ED5DA6D8118), + UInt64($D807AA98A3030242), UInt64($12835B0145706FBE), + UInt64($243185BE4EE4B28C), UInt64($550C7DC3D5FFB4E2), + UInt64($72BE5D74F27B896F), UInt64($80DEB1FE3B1696B1), + UInt64($9BDC06A725C71235), UInt64($C19BF174CF692694), + UInt64($E49B69C19EF14AD2), UInt64($EFBE4786384F25E3), + UInt64($0FC19DC68B8CD5B5), UInt64($240CA1CC77AC9C65), + UInt64($2DE92C6F592B0275), UInt64($4A7484AA6EA6E483), + UInt64($5CB0A9DCBD41FBD4), UInt64($76F988DA831153B5), + UInt64($983E5152EE66DFAB), UInt64($A831C66D2DB43210), + UInt64($B00327C898FB213F), UInt64($BF597FC7BEEF0EE4), + UInt64($C6E00BF33DA88FC2), UInt64($D5A79147930AA725), + UInt64($06CA6351E003826F), UInt64($142929670A0E6E70), + UInt64($27B70A8546D22FFC), UInt64($2E1B21385C26C926), + UInt64($4D2C6DFC5AC42AED), UInt64($53380D139D95B3DF), + UInt64($650A73548BAF63DE), UInt64($766A0ABB3C77B2A8), + UInt64($81C2C92E47EDAEE6), UInt64($92722C851482353B), + UInt64($A2BFE8A14CF10364), UInt64($A81A664BBC423001), + UInt64($C24B8B70D0F89791), UInt64($C76C51A30654BE30), + UInt64($D192E819D6EF5218), UInt64($D69906245565A910), + UInt64($F40E35855771202A), UInt64($106AA07032BBD1B8), + UInt64($19A4C116B8D2D0C8), UInt64($1E376C085141AB53), + UInt64($2748774CDF8EEB99), UInt64($34B0BCB5E19B48A8), + UInt64($391C0CB3C5C95A63), UInt64($4ED8AA4AE3418ACB), + UInt64($5B9CCA4F7763E373), UInt64($682E6FF3D6B2B8A3), + UInt64($748F82EE5DEFB2FC), UInt64($78A5636F43172F60), + UInt64($84C87814A1F0AB72), UInt64($8CC702081A6439EC), + UInt64($90BEFFFA23631E28), UInt64($A4506CEBDE82BDE9), + UInt64($BEF9A3F7B2C67915), UInt64($C67178F2E372532B), + UInt64($CA273ECEEA26619C), UInt64($D186B8C721C0C207), + UInt64($EADA7DD6CDE0EB1E), UInt64($F57D4F7FEE6ED178), + UInt64($06F067AA72176FBA), UInt64($0A637DC5A2C898A6), + UInt64($113F9804BEF90DAE), UInt64($1B710B35131C471B), + UInt64($28DB77F523047D84), UInt64($32CAAB7B40C72493), + UInt64($3C9EBE0A15C9BEBC), UInt64($431D67C49C100D4C), + UInt64($4CC5D4BECB3E42B6), UInt64($597F299CFC657E2A), + UInt64($5FCB6FAB3AD6FAEC), UInt64($6C44198C4A475817) + ); type TSHA2_512Base = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock) @@ -31,6 +81,65 @@ TSHA2_512Base = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock) implementation +uses + HlpBitOperations, + HlpSHA2_512Simd; + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure SHA512_Compress_Scalar(AState, AData: Pointer; ANumBlocks: UInt32); +var + LPState: PUInt64; + LPData: PByte; + LA, LB, LC, LD, LE, LF, LG, LH, LT1, LT2: UInt64; + LW: array [0 .. 79] of UInt64; + LRound: Int32; +begin + LPState := PUInt64(AState); + LPData := PByte(AData); + + while ANumBlocks > 0 do + begin + TBinaryPrimitives.CopyUInt64BigEndian(LPData, 0, @LW[0], 0, 128); + + for LRound := 16 to 79 do + begin + LT1 := LW[LRound - 2]; + LT2 := LW[LRound - 15]; + LW[LRound] := (TBitOperations.RotateRight64(LT1, 19) xor TBitOperations.RotateRight64(LT1, 61) + xor (LT1 shr 6)) + LW[LRound - 7] + + (TBitOperations.RotateRight64(LT2, 1) xor TBitOperations.RotateRight64(LT2, 8) + xor (LT2 shr 7)) + LW[LRound - 16]; + end; + + LA := LPState[0]; LB := LPState[1]; LC := LPState[2]; LD := LPState[3]; + LE := LPState[4]; LF := LPState[5]; LG := LPState[6]; LH := LPState[7]; + + for LRound := 0 to 79 do + begin + LT1 := LH + (TBitOperations.RotateRight64(LE, 14) xor TBitOperations.RotateRight64(LE, 18) + xor TBitOperations.RotateRight64(LE, 41)) + ((LE and LF) xor (not LE and LG)) + + K512[LRound] + LW[LRound]; + LT2 := (TBitOperations.RotateRight64(LA, 28) xor TBitOperations.RotateRight64(LA, 34) + xor TBitOperations.RotateRight64(LA, 39)) + + ((LA and LB) xor (LA and LC) xor (LB and LC)); + LH := LG; LG := LF; LF := LE; LE := LD + LT1; + LD := LC; LC := LB; LB := LA; LA := LT1 + LT2; + end; + + LPState[0] := LPState[0] + LA; LPState[1] := LPState[1] + LB; + LPState[2] := LPState[2] + LC; LPState[3] := LPState[3] + LD; + LPState[4] := LPState[4] + LE; LPState[5] := LPState[5] + LF; + LPState[6] := LPState[6] + LG; LPState[7] := LPState[7] + LH; + + System.FillChar(LW, System.SizeOf(LW), 0); + System.Inc(LPData, 128); + System.Dec(ANumBlocks); + end; +end; + { TSHA2_512Base } constructor TSHA2_512Base.Create(AHashSize: Int32); @@ -117,4 +226,7 @@ procedure TSHA2_512Base.TransformBytes(const AData: THashLibByteArray; end; end; +initialization + SHA512_Compress := TSHA2_512Simd.Select(@SHA512_Compress_Scalar); + end. diff --git a/HashLib/src/Crypto/HlpSHA3.pas b/HashLib/src/Crypto/HlpSHA3.pas index be73975..c23687e 100644 --- a/HashLib/src/Crypto/HlpSHA3.pas +++ b/HashLib/src/Crypto/HlpSHA3.pas @@ -16,8 +16,33 @@ interface HlpConverters, HlpHashSize, HlpArrayUtils, - HlpHashLibTypes, - HlpSHA3Dispatch; + HlpHashLibTypes; + +type + TKeccakF1600Proc = procedure(AState: Pointer); + TKeccakF1600AbsorbProc = procedure(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); + +var + KeccakF1600_Permute: TKeccakF1600Proc; + KeccakF1600_Absorb: TKeccakF1600AbsorbProc; + +const + // Keccak-F1600 round constants (24 UInt64). Shared by the scalar reference and + // the AArch64 crypto-extension kernels. + RC: array [0 .. 23] of UInt64 = ( + UInt64($0000000000000001), UInt64($0000000000008082), + UInt64($800000000000808A), UInt64($8000000080008000), + UInt64($000000000000808B), UInt64($0000000080000001), + UInt64($8000000080008081), UInt64($8000000000008009), + UInt64($000000000000008A), UInt64($0000000000000088), + UInt64($0000000080008009), UInt64($000000008000000A), + UInt64($000000008000808B), UInt64($800000000000008B), + UInt64($8000000000008089), UInt64($8000000000008003), + UInt64($8000000000008002), UInt64($8000000000000080), + UInt64($000000000000800A), UInt64($800000008000000A), + UInt64($8000000080008081), UInt64($8000000000008080), + UInt64($0000000080000001), UInt64($8000000080008008)); resourcestring SInvalidXOFSize = @@ -379,6 +404,372 @@ TKMAC256XOF = class sealed(TKMAC256, IKMAC, IXOF, IXOFStream) implementation +uses + HlpBitOperations, + HlpSHA3Simd; + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure KeccakF1600_Scalar(AState: Pointer); +var + LPState: PUInt64; + LDa, LDe, LDi, LDo, LDu: UInt64; +{$IFDEF USE_UNROLLED_VARIANT} + Aba, Abe, Abi, Abo, Abu, Aga, Age, Agi, Ago, Agu, Aka, Ake, Aki, Ako, Aku, + Ama, Ame, Ami, Amo, Amu, Asa, Ase, Asi, Aso, Asu, BCa, BCe, BCi, BCo, BCu, + Eba, Ebe, Ebi, Ebo, Ebu, Ega, Ege, Egi, Ego, Egu, Eka, Eke, Eki, Eko, Eku, + Ema, Eme, Emi, Emo, Emu, Esa, Ese, Esi, Eso, Esu: UInt64; + LRound: Int32; +{$ELSE} + LColA, LColE, LColI, LColO, LColU: UInt64; + LTemp: array [0 .. 24] of UInt64; + LRound: Int32; +{$ENDIF USE_UNROLLED_VARIANT} +begin + LPState := PUInt64(AState); + +{$IFDEF USE_UNROLLED_VARIANT} + Aba := LPState[0]; + Abe := LPState[1]; + Abi := LPState[2]; + Abo := LPState[3]; + Abu := LPState[4]; + Aga := LPState[5]; + Age := LPState[6]; + Agi := LPState[7]; + Ago := LPState[8]; + Agu := LPState[9]; + Aka := LPState[10]; + Ake := LPState[11]; + Aki := LPState[12]; + Ako := LPState[13]; + Aku := LPState[14]; + Ama := LPState[15]; + Ame := LPState[16]; + Ami := LPState[17]; + Amo := LPState[18]; + Amu := LPState[19]; + Asa := LPState[20]; + Ase := LPState[21]; + Asi := LPState[22]; + Aso := LPState[23]; + Asu := LPState[24]; + + LRound := 0; + while LRound < 24 do + begin + BCa := Aba xor Aga xor Aka xor Ama xor Asa; + BCe := Abe xor Age xor Ake xor Ame xor Ase; + BCi := Abi xor Agi xor Aki xor Ami xor Asi; + BCo := Abo xor Ago xor Ako xor Amo xor Aso; + BCu := Abu xor Agu xor Aku xor Amu xor Asu; + + LDa := BCu xor TBitOperations.RotateLeft64(BCe, 1); + LDe := BCa xor TBitOperations.RotateLeft64(BCi, 1); + LDi := BCe xor TBitOperations.RotateLeft64(BCo, 1); + LDo := BCi xor TBitOperations.RotateLeft64(BCu, 1); + LDu := BCo xor TBitOperations.RotateLeft64(BCa, 1); + + Aba := Aba xor LDa; + BCa := Aba; + Age := Age xor LDe; + BCe := TBitOperations.RotateLeft64(Age, 44); + Aki := Aki xor LDi; + BCi := TBitOperations.RotateLeft64(Aki, 43); + Amo := Amo xor LDo; + BCo := TBitOperations.RotateLeft64(Amo, 21); + Asu := Asu xor LDu; + BCu := TBitOperations.RotateLeft64(Asu, 14); + Eba := BCa xor ((not BCe) and BCi); + Eba := Eba xor UInt64(RC[LRound]); + Ebe := BCe xor ((not BCi) and BCo); + Ebi := BCi xor ((not BCo) and BCu); + Ebo := BCo xor ((not BCu) and BCa); + Ebu := BCu xor ((not BCa) and BCe); + + Abo := Abo xor LDo; + BCa := TBitOperations.RotateLeft64(Abo, 28); + Agu := Agu xor LDu; + BCe := TBitOperations.RotateLeft64(Agu, 20); + Aka := Aka xor LDa; + BCi := TBitOperations.RotateLeft64(Aka, 3); + Ame := Ame xor LDe; + BCo := TBitOperations.RotateLeft64(Ame, 45); + Asi := Asi xor LDi; + BCu := TBitOperations.RotateLeft64(Asi, 61); + Ega := BCa xor ((not BCe) and BCi); + Ege := BCe xor ((not BCi) and BCo); + Egi := BCi xor ((not BCo) and BCu); + Ego := BCo xor ((not BCu) and BCa); + Egu := BCu xor ((not BCa) and BCe); + + Abe := Abe xor LDe; + BCa := TBitOperations.RotateLeft64(Abe, 1); + Agi := Agi xor LDi; + BCe := TBitOperations.RotateLeft64(Agi, 6); + Ako := Ako xor LDo; + BCi := TBitOperations.RotateLeft64(Ako, 25); + Amu := Amu xor LDu; + BCo := TBitOperations.RotateLeft64(Amu, 8); + Asa := Asa xor LDa; + BCu := TBitOperations.RotateLeft64(Asa, 18); + Eka := BCa xor ((not BCe) and BCi); + Eke := BCe xor ((not BCi) and BCo); + Eki := BCi xor ((not BCo) and BCu); + Eko := BCo xor ((not BCu) and BCa); + Eku := BCu xor ((not BCa) and BCe); + + Abu := Abu xor LDu; + BCa := TBitOperations.RotateLeft64(Abu, 27); + Aga := Aga xor LDa; + BCe := TBitOperations.RotateLeft64(Aga, 36); + Ake := Ake xor LDe; + BCi := TBitOperations.RotateLeft64(Ake, 10); + Ami := Ami xor LDi; + BCo := TBitOperations.RotateLeft64(Ami, 15); + Aso := Aso xor LDo; + BCu := TBitOperations.RotateLeft64(Aso, 56); + Ema := BCa xor ((not BCe) and BCi); + Eme := BCe xor ((not BCi) and BCo); + Emi := BCi xor ((not BCo) and BCu); + Emo := BCo xor ((not BCu) and BCa); + Emu := BCu xor ((not BCa) and BCe); + + Abi := Abi xor LDi; + BCa := TBitOperations.RotateLeft64(Abi, 62); + Ago := Ago xor LDo; + BCe := TBitOperations.RotateLeft64(Ago, 55); + Aku := Aku xor LDu; + BCi := TBitOperations.RotateLeft64(Aku, 39); + Ama := Ama xor LDa; + BCo := TBitOperations.RotateLeft64(Ama, 41); + Ase := Ase xor LDe; + BCu := TBitOperations.RotateLeft64(Ase, 2); + Esa := BCa xor ((not BCe) and BCi); + Ese := BCe xor ((not BCi) and BCo); + Esi := BCi xor ((not BCo) and BCu); + Eso := BCo xor ((not BCu) and BCa); + Esu := BCu xor ((not BCa) and BCe); + + BCa := Eba xor Ega xor Eka xor Ema xor Esa; + BCe := Ebe xor Ege xor Eke xor Eme xor Ese; + BCi := Ebi xor Egi xor Eki xor Emi xor Esi; + BCo := Ebo xor Ego xor Eko xor Emo xor Eso; + BCu := Ebu xor Egu xor Eku xor Emu xor Esu; + + LDa := BCu xor TBitOperations.RotateLeft64(BCe, 1); + LDe := BCa xor TBitOperations.RotateLeft64(BCi, 1); + LDi := BCe xor TBitOperations.RotateLeft64(BCo, 1); + LDo := BCi xor TBitOperations.RotateLeft64(BCu, 1); + LDu := BCo xor TBitOperations.RotateLeft64(BCa, 1); + + Eba := Eba xor LDa; + BCa := Eba; + Ege := Ege xor LDe; + BCe := TBitOperations.RotateLeft64(Ege, 44); + Eki := Eki xor LDi; + BCi := TBitOperations.RotateLeft64(Eki, 43); + Emo := Emo xor LDo; + BCo := TBitOperations.RotateLeft64(Emo, 21); + Esu := Esu xor LDu; + BCu := TBitOperations.RotateLeft64(Esu, 14); + Aba := BCa xor ((not BCe) and BCi); + Aba := Aba xor UInt64(RC[LRound + 1]); + Abe := BCe xor ((not BCi) and BCo); + Abi := BCi xor ((not BCo) and BCu); + Abo := BCo xor ((not BCu) and BCa); + Abu := BCu xor ((not BCa) and BCe); + + Ebo := Ebo xor LDo; + BCa := TBitOperations.RotateLeft64(Ebo, 28); + Egu := Egu xor LDu; + BCe := TBitOperations.RotateLeft64(Egu, 20); + Eka := Eka xor LDa; + BCi := TBitOperations.RotateLeft64(Eka, 3); + Eme := Eme xor LDe; + BCo := TBitOperations.RotateLeft64(Eme, 45); + Esi := Esi xor LDi; + BCu := TBitOperations.RotateLeft64(Esi, 61); + Aga := BCa xor ((not BCe) and BCi); + Age := BCe xor ((not BCi) and BCo); + Agi := BCi xor ((not BCo) and BCu); + Ago := BCo xor ((not BCu) and BCa); + Agu := BCu xor ((not BCa) and BCe); + + Ebe := Ebe xor LDe; + BCa := TBitOperations.RotateLeft64(Ebe, 1); + Egi := Egi xor LDi; + BCe := TBitOperations.RotateLeft64(Egi, 6); + Eko := Eko xor LDo; + BCi := TBitOperations.RotateLeft64(Eko, 25); + Emu := Emu xor LDu; + BCo := TBitOperations.RotateLeft64(Emu, 8); + Esa := Esa xor LDa; + BCu := TBitOperations.RotateLeft64(Esa, 18); + Aka := BCa xor ((not BCe) and BCi); + Ake := BCe xor ((not BCi) and BCo); + Aki := BCi xor ((not BCo) and BCu); + Ako := BCo xor ((not BCu) and BCa); + Aku := BCu xor ((not BCa) and BCe); + + Ebu := Ebu xor LDu; + BCa := TBitOperations.RotateLeft64(Ebu, 27); + Ega := Ega xor LDa; + BCe := TBitOperations.RotateLeft64(Ega, 36); + Eke := Eke xor LDe; + BCi := TBitOperations.RotateLeft64(Eke, 10); + Emi := Emi xor LDi; + BCo := TBitOperations.RotateLeft64(Emi, 15); + Eso := Eso xor LDo; + BCu := TBitOperations.RotateLeft64(Eso, 56); + Ama := BCa xor ((not BCe) and BCi); + Ame := BCe xor ((not BCi) and BCo); + Ami := BCi xor ((not BCo) and BCu); + Amo := BCo xor ((not BCu) and BCa); + Amu := BCu xor ((not BCa) and BCe); + + Ebi := Ebi xor LDi; + BCa := TBitOperations.RotateLeft64(Ebi, 62); + Ego := Ego xor LDo; + BCe := TBitOperations.RotateLeft64(Ego, 55); + Eku := Eku xor LDu; + BCi := TBitOperations.RotateLeft64(Eku, 39); + Ema := Ema xor LDa; + BCo := TBitOperations.RotateLeft64(Ema, 41); + Ese := Ese xor LDe; + BCu := TBitOperations.RotateLeft64(Ese, 2); + Asa := BCa xor ((not BCe) and BCi); + Ase := BCe xor ((not BCi) and BCo); + Asi := BCi xor ((not BCo) and BCu); + Aso := BCo xor ((not BCu) and BCa); + Asu := BCu xor ((not BCa) and BCe); + + System.Inc(LRound, 2); + end; + + LPState[0] := Aba; + LPState[1] := Abe; + LPState[2] := Abi; + LPState[3] := Abo; + LPState[4] := Abu; + LPState[5] := Aga; + LPState[6] := Age; + LPState[7] := Agi; + LPState[8] := Ago; + LPState[9] := Agu; + LPState[10] := Aka; + LPState[11] := Ake; + LPState[12] := Aki; + LPState[13] := Ako; + LPState[14] := Aku; + LPState[15] := Ama; + LPState[16] := Ame; + LPState[17] := Ami; + LPState[18] := Amo; + LPState[19] := Amu; + LPState[20] := Asa; + LPState[21] := Ase; + LPState[22] := Asi; + LPState[23] := Aso; + LPState[24] := Asu; + +{$ELSE} + for LRound := 0 to 23 do + begin + LColA := LPState[00] xor LPState[05] xor LPState[10] xor LPState[15] + xor LPState[20]; + LColE := LPState[01] xor LPState[06] xor LPState[11] xor LPState[16] + xor LPState[21]; + LColI := LPState[02] xor LPState[07] xor LPState[12] xor LPState[17] + xor LPState[22]; + LColO := LPState[03] xor LPState[08] xor LPState[13] xor LPState[18] + xor LPState[23]; + LColU := LPState[04] xor LPState[09] xor LPState[14] xor LPState[19] + xor LPState[24]; + LDa := TBitOperations.RotateLeft64(LColA, 1) xor LColO; + LDe := TBitOperations.RotateLeft64(LColE, 1) xor LColU; + LDi := TBitOperations.RotateLeft64(LColI, 1) xor LColA; + LDo := TBitOperations.RotateLeft64(LColO, 1) xor LColE; + LDu := TBitOperations.RotateLeft64(LColU, 1) xor LColI; + LTemp[00] := LPState[00] xor LDe; + LTemp[01] := TBitOperations.RotateLeft64(LPState[06] xor LDi, 44); + LTemp[02] := TBitOperations.RotateLeft64(LPState[12] xor LDo, 43); + LTemp[03] := TBitOperations.RotateLeft64(LPState[18] xor LDu, 21); + LTemp[04] := TBitOperations.RotateLeft64(LPState[24] xor LDa, 14); + LTemp[05] := TBitOperations.RotateLeft64(LPState[03] xor LDu, 28); + LTemp[06] := TBitOperations.RotateLeft64(LPState[09] xor LDa, 20); + LTemp[07] := TBitOperations.RotateLeft64(LPState[10] xor LDe, 3); + LTemp[08] := TBitOperations.RotateLeft64(LPState[16] xor LDi, 45); + LTemp[09] := TBitOperations.RotateLeft64(LPState[22] xor LDo, 61); + LTemp[10] := TBitOperations.RotateLeft64(LPState[01] xor LDi, 1); + LTemp[11] := TBitOperations.RotateLeft64(LPState[07] xor LDo, 6); + LTemp[12] := TBitOperations.RotateLeft64(LPState[13] xor LDu, 25); + LTemp[13] := TBitOperations.RotateLeft64(LPState[19] xor LDa, 8); + LTemp[14] := TBitOperations.RotateLeft64(LPState[20] xor LDe, 18); + LTemp[15] := TBitOperations.RotateLeft64(LPState[04] xor LDa, 27); + LTemp[16] := TBitOperations.RotateLeft64(LPState[05] xor LDe, 36); + LTemp[17] := TBitOperations.RotateLeft64(LPState[11] xor LDi, 10); + LTemp[18] := TBitOperations.RotateLeft64(LPState[17] xor LDo, 15); + LTemp[19] := TBitOperations.RotateLeft64(LPState[23] xor LDu, 56); + LTemp[20] := TBitOperations.RotateLeft64(LPState[02] xor LDo, 62); + LTemp[21] := TBitOperations.RotateLeft64(LPState[08] xor LDu, 55); + LTemp[22] := TBitOperations.RotateLeft64(LPState[14] xor LDa, 39); + LTemp[23] := TBitOperations.RotateLeft64(LPState[15] xor LDe, 41); + LTemp[24] := TBitOperations.RotateLeft64(LPState[21] xor LDi, 2); + LPState[00] := LTemp[00] xor ((not LTemp[01]) and LTemp[02]); + LPState[01] := LTemp[01] xor ((not LTemp[02]) and LTemp[03]); + LPState[02] := LTemp[02] xor ((not LTemp[03]) and LTemp[04]); + LPState[03] := LTemp[03] xor ((not LTemp[04]) and LTemp[00]); + LPState[04] := LTemp[04] xor ((not LTemp[00]) and LTemp[01]); + LPState[05] := LTemp[05] xor ((not LTemp[06]) and LTemp[07]); + LPState[06] := LTemp[06] xor ((not LTemp[07]) and LTemp[08]); + LPState[07] := LTemp[07] xor ((not LTemp[08]) and LTemp[09]); + LPState[08] := LTemp[08] xor ((not LTemp[09]) and LTemp[05]); + LPState[09] := LTemp[09] xor ((not LTemp[05]) and LTemp[06]); + LPState[10] := LTemp[10] xor ((not LTemp[11]) and LTemp[12]); + LPState[11] := LTemp[11] xor ((not LTemp[12]) and LTemp[13]); + LPState[12] := LTemp[12] xor ((not LTemp[13]) and LTemp[14]); + LPState[13] := LTemp[13] xor ((not LTemp[14]) and LTemp[10]); + LPState[14] := LTemp[14] xor ((not LTemp[10]) and LTemp[11]); + LPState[15] := LTemp[15] xor ((not LTemp[16]) and LTemp[17]); + LPState[16] := LTemp[16] xor ((not LTemp[17]) and LTemp[18]); + LPState[17] := LTemp[17] xor ((not LTemp[18]) and LTemp[19]); + LPState[18] := LTemp[18] xor ((not LTemp[19]) and LTemp[15]); + LPState[19] := LTemp[19] xor ((not LTemp[15]) and LTemp[16]); + LPState[20] := LTemp[20] xor ((not LTemp[21]) and LTemp[22]); + LPState[21] := LTemp[21] xor ((not LTemp[22]) and LTemp[23]); + LPState[22] := LTemp[22] xor ((not LTemp[23]) and LTemp[24]); + LPState[23] := LTemp[23] xor ((not LTemp[24]) and LTemp[20]); + LPState[24] := LTemp[24] xor ((not LTemp[20]) and LTemp[21]); + LPState[00] := LPState[00] xor RC[LRound]; + end; + + System.FillChar(LTemp, System.SizeOf(LTemp), UInt64(0)); +{$ENDIF USE_UNROLLED_VARIANT} +end; + +procedure KeccakF1600_Absorb_Scalar(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); +var + LPState: PUInt64; + LData: array [0 .. 20] of UInt64; + LBlockSizeWords, I, J: Int32; +begin + LPState := PUInt64(AState); + LBlockSizeWords := ABlockSize shr 3; + for I := 0 to ABlockCount - 1 do + begin + TBinaryPrimitives.CopyUInt64LittleEndian(AData, 0, @LData[0], 0, ABlockSize); + for J := 0 to LBlockSizeWords - 1 do + LPState[J] := LPState[J] xor LData[J]; + KeccakF1600_Scalar(AState); + System.Inc(AData, ABlockSize); + end; + System.FillChar(LData, System.SizeOf(LData), UInt64(0)); +end; + type // Self-contained SHAKE/Keccak squeeze engine. Owns a copy of the finalized // Keccak state and produces an unbounded byte stream; the size cap (if any) @@ -1496,4 +1887,8 @@ function TKeccak.GetHashMode(): TSHA3.THashMode; Result := TSHA3.THashMode.Keccak; end; +initialization + KeccakF1600_Permute := TSHA3Simd.SelectPermute(@KeccakF1600_Scalar); + KeccakF1600_Absorb := TSHA3Simd.SelectAbsorb(@KeccakF1600_Absorb_Scalar); + end. diff --git a/HashLib/src/Crypto/HlpSHA3Dispatch.pas b/HashLib/src/Crypto/HlpSHA3Dispatch.pas deleted file mode 100644 index 6381e48..0000000 --- a/HashLib/src/Crypto/HlpSHA3Dispatch.pas +++ /dev/null @@ -1,554 +0,0 @@ -unit HlpSHA3Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TKeccakF1600Proc = procedure(AState: Pointer); - TKeccakF1600AbsorbProc = procedure(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32); - -var - KeccakF1600_Permute: TKeccakF1600Proc; - KeccakF1600_Absorb: TKeccakF1600AbsorbProc; - -implementation - -uses - HlpBinaryPrimitives, - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Round constants -// ============================================================================= - -const - RC: array [0 .. 23] of UInt64 = ( - UInt64($0000000000000001), UInt64($0000000000008082), - UInt64($800000000000808A), UInt64($8000000080008000), - UInt64($000000000000808B), UInt64($0000000080000001), - UInt64($8000000080008081), UInt64($8000000000008009), - UInt64($000000000000008A), UInt64($0000000000000088), - UInt64($0000000080008009), UInt64($000000008000000A), - UInt64($000000008000808B), UInt64($800000000000008B), - UInt64($8000000000008089), UInt64($8000000000008003), - UInt64($8000000000008002), UInt64($8000000000000080), - UInt64($000000000000800A), UInt64($800000008000000A), - UInt64($8000000080008081), UInt64($8000000000008080), - UInt64($0000000080000001), UInt64($8000000080008008)); - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure KeccakF1600_Scalar(AState: Pointer); -var - LPState: PUInt64; - LDa, LDe, LDi, LDo, LDu: UInt64; -{$IFDEF USE_UNROLLED_VARIANT} - Aba, Abe, Abi, Abo, Abu, Aga, Age, Agi, Ago, Agu, Aka, Ake, Aki, Ako, Aku, - Ama, Ame, Ami, Amo, Amu, Asa, Ase, Asi, Aso, Asu, BCa, BCe, BCi, BCo, BCu, - Eba, Ebe, Ebi, Ebo, Ebu, Ega, Ege, Egi, Ego, Egu, Eka, Eke, Eki, Eko, Eku, - Ema, Eme, Emi, Emo, Emu, Esa, Ese, Esi, Eso, Esu: UInt64; - LRound: Int32; -{$ELSE} - LColA, LColE, LColI, LColO, LColU: UInt64; - LTemp: array [0 .. 24] of UInt64; - LRound: Int32; -{$ENDIF USE_UNROLLED_VARIANT} -begin - LPState := PUInt64(AState); - -{$IFDEF USE_UNROLLED_VARIANT} - Aba := LPState[0]; - Abe := LPState[1]; - Abi := LPState[2]; - Abo := LPState[3]; - Abu := LPState[4]; - Aga := LPState[5]; - Age := LPState[6]; - Agi := LPState[7]; - Ago := LPState[8]; - Agu := LPState[9]; - Aka := LPState[10]; - Ake := LPState[11]; - Aki := LPState[12]; - Ako := LPState[13]; - Aku := LPState[14]; - Ama := LPState[15]; - Ame := LPState[16]; - Ami := LPState[17]; - Amo := LPState[18]; - Amu := LPState[19]; - Asa := LPState[20]; - Ase := LPState[21]; - Asi := LPState[22]; - Aso := LPState[23]; - Asu := LPState[24]; - - LRound := 0; - while LRound < 24 do - begin - BCa := Aba xor Aga xor Aka xor Ama xor Asa; - BCe := Abe xor Age xor Ake xor Ame xor Ase; - BCi := Abi xor Agi xor Aki xor Ami xor Asi; - BCo := Abo xor Ago xor Ako xor Amo xor Aso; - BCu := Abu xor Agu xor Aku xor Amu xor Asu; - - LDa := BCu xor TBitOperations.RotateLeft64(BCe, 1); - LDe := BCa xor TBitOperations.RotateLeft64(BCi, 1); - LDi := BCe xor TBitOperations.RotateLeft64(BCo, 1); - LDo := BCi xor TBitOperations.RotateLeft64(BCu, 1); - LDu := BCo xor TBitOperations.RotateLeft64(BCa, 1); - - Aba := Aba xor LDa; - BCa := Aba; - Age := Age xor LDe; - BCe := TBitOperations.RotateLeft64(Age, 44); - Aki := Aki xor LDi; - BCi := TBitOperations.RotateLeft64(Aki, 43); - Amo := Amo xor LDo; - BCo := TBitOperations.RotateLeft64(Amo, 21); - Asu := Asu xor LDu; - BCu := TBitOperations.RotateLeft64(Asu, 14); - Eba := BCa xor ((not BCe) and BCi); - Eba := Eba xor UInt64(RC[LRound]); - Ebe := BCe xor ((not BCi) and BCo); - Ebi := BCi xor ((not BCo) and BCu); - Ebo := BCo xor ((not BCu) and BCa); - Ebu := BCu xor ((not BCa) and BCe); - - Abo := Abo xor LDo; - BCa := TBitOperations.RotateLeft64(Abo, 28); - Agu := Agu xor LDu; - BCe := TBitOperations.RotateLeft64(Agu, 20); - Aka := Aka xor LDa; - BCi := TBitOperations.RotateLeft64(Aka, 3); - Ame := Ame xor LDe; - BCo := TBitOperations.RotateLeft64(Ame, 45); - Asi := Asi xor LDi; - BCu := TBitOperations.RotateLeft64(Asi, 61); - Ega := BCa xor ((not BCe) and BCi); - Ege := BCe xor ((not BCi) and BCo); - Egi := BCi xor ((not BCo) and BCu); - Ego := BCo xor ((not BCu) and BCa); - Egu := BCu xor ((not BCa) and BCe); - - Abe := Abe xor LDe; - BCa := TBitOperations.RotateLeft64(Abe, 1); - Agi := Agi xor LDi; - BCe := TBitOperations.RotateLeft64(Agi, 6); - Ako := Ako xor LDo; - BCi := TBitOperations.RotateLeft64(Ako, 25); - Amu := Amu xor LDu; - BCo := TBitOperations.RotateLeft64(Amu, 8); - Asa := Asa xor LDa; - BCu := TBitOperations.RotateLeft64(Asa, 18); - Eka := BCa xor ((not BCe) and BCi); - Eke := BCe xor ((not BCi) and BCo); - Eki := BCi xor ((not BCo) and BCu); - Eko := BCo xor ((not BCu) and BCa); - Eku := BCu xor ((not BCa) and BCe); - - Abu := Abu xor LDu; - BCa := TBitOperations.RotateLeft64(Abu, 27); - Aga := Aga xor LDa; - BCe := TBitOperations.RotateLeft64(Aga, 36); - Ake := Ake xor LDe; - BCi := TBitOperations.RotateLeft64(Ake, 10); - Ami := Ami xor LDi; - BCo := TBitOperations.RotateLeft64(Ami, 15); - Aso := Aso xor LDo; - BCu := TBitOperations.RotateLeft64(Aso, 56); - Ema := BCa xor ((not BCe) and BCi); - Eme := BCe xor ((not BCi) and BCo); - Emi := BCi xor ((not BCo) and BCu); - Emo := BCo xor ((not BCu) and BCa); - Emu := BCu xor ((not BCa) and BCe); - - Abi := Abi xor LDi; - BCa := TBitOperations.RotateLeft64(Abi, 62); - Ago := Ago xor LDo; - BCe := TBitOperations.RotateLeft64(Ago, 55); - Aku := Aku xor LDu; - BCi := TBitOperations.RotateLeft64(Aku, 39); - Ama := Ama xor LDa; - BCo := TBitOperations.RotateLeft64(Ama, 41); - Ase := Ase xor LDe; - BCu := TBitOperations.RotateLeft64(Ase, 2); - Esa := BCa xor ((not BCe) and BCi); - Ese := BCe xor ((not BCi) and BCo); - Esi := BCi xor ((not BCo) and BCu); - Eso := BCo xor ((not BCu) and BCa); - Esu := BCu xor ((not BCa) and BCe); - - BCa := Eba xor Ega xor Eka xor Ema xor Esa; - BCe := Ebe xor Ege xor Eke xor Eme xor Ese; - BCi := Ebi xor Egi xor Eki xor Emi xor Esi; - BCo := Ebo xor Ego xor Eko xor Emo xor Eso; - BCu := Ebu xor Egu xor Eku xor Emu xor Esu; - - LDa := BCu xor TBitOperations.RotateLeft64(BCe, 1); - LDe := BCa xor TBitOperations.RotateLeft64(BCi, 1); - LDi := BCe xor TBitOperations.RotateLeft64(BCo, 1); - LDo := BCi xor TBitOperations.RotateLeft64(BCu, 1); - LDu := BCo xor TBitOperations.RotateLeft64(BCa, 1); - - Eba := Eba xor LDa; - BCa := Eba; - Ege := Ege xor LDe; - BCe := TBitOperations.RotateLeft64(Ege, 44); - Eki := Eki xor LDi; - BCi := TBitOperations.RotateLeft64(Eki, 43); - Emo := Emo xor LDo; - BCo := TBitOperations.RotateLeft64(Emo, 21); - Esu := Esu xor LDu; - BCu := TBitOperations.RotateLeft64(Esu, 14); - Aba := BCa xor ((not BCe) and BCi); - Aba := Aba xor UInt64(RC[LRound + 1]); - Abe := BCe xor ((not BCi) and BCo); - Abi := BCi xor ((not BCo) and BCu); - Abo := BCo xor ((not BCu) and BCa); - Abu := BCu xor ((not BCa) and BCe); - - Ebo := Ebo xor LDo; - BCa := TBitOperations.RotateLeft64(Ebo, 28); - Egu := Egu xor LDu; - BCe := TBitOperations.RotateLeft64(Egu, 20); - Eka := Eka xor LDa; - BCi := TBitOperations.RotateLeft64(Eka, 3); - Eme := Eme xor LDe; - BCo := TBitOperations.RotateLeft64(Eme, 45); - Esi := Esi xor LDi; - BCu := TBitOperations.RotateLeft64(Esi, 61); - Aga := BCa xor ((not BCe) and BCi); - Age := BCe xor ((not BCi) and BCo); - Agi := BCi xor ((not BCo) and BCu); - Ago := BCo xor ((not BCu) and BCa); - Agu := BCu xor ((not BCa) and BCe); - - Ebe := Ebe xor LDe; - BCa := TBitOperations.RotateLeft64(Ebe, 1); - Egi := Egi xor LDi; - BCe := TBitOperations.RotateLeft64(Egi, 6); - Eko := Eko xor LDo; - BCi := TBitOperations.RotateLeft64(Eko, 25); - Emu := Emu xor LDu; - BCo := TBitOperations.RotateLeft64(Emu, 8); - Esa := Esa xor LDa; - BCu := TBitOperations.RotateLeft64(Esa, 18); - Aka := BCa xor ((not BCe) and BCi); - Ake := BCe xor ((not BCi) and BCo); - Aki := BCi xor ((not BCo) and BCu); - Ako := BCo xor ((not BCu) and BCa); - Aku := BCu xor ((not BCa) and BCe); - - Ebu := Ebu xor LDu; - BCa := TBitOperations.RotateLeft64(Ebu, 27); - Ega := Ega xor LDa; - BCe := TBitOperations.RotateLeft64(Ega, 36); - Eke := Eke xor LDe; - BCi := TBitOperations.RotateLeft64(Eke, 10); - Emi := Emi xor LDi; - BCo := TBitOperations.RotateLeft64(Emi, 15); - Eso := Eso xor LDo; - BCu := TBitOperations.RotateLeft64(Eso, 56); - Ama := BCa xor ((not BCe) and BCi); - Ame := BCe xor ((not BCi) and BCo); - Ami := BCi xor ((not BCo) and BCu); - Amo := BCo xor ((not BCu) and BCa); - Amu := BCu xor ((not BCa) and BCe); - - Ebi := Ebi xor LDi; - BCa := TBitOperations.RotateLeft64(Ebi, 62); - Ego := Ego xor LDo; - BCe := TBitOperations.RotateLeft64(Ego, 55); - Eku := Eku xor LDu; - BCi := TBitOperations.RotateLeft64(Eku, 39); - Ema := Ema xor LDa; - BCo := TBitOperations.RotateLeft64(Ema, 41); - Ese := Ese xor LDe; - BCu := TBitOperations.RotateLeft64(Ese, 2); - Asa := BCa xor ((not BCe) and BCi); - Ase := BCe xor ((not BCi) and BCo); - Asi := BCi xor ((not BCo) and BCu); - Aso := BCo xor ((not BCu) and BCa); - Asu := BCu xor ((not BCa) and BCe); - - System.Inc(LRound, 2); - end; - - LPState[0] := Aba; - LPState[1] := Abe; - LPState[2] := Abi; - LPState[3] := Abo; - LPState[4] := Abu; - LPState[5] := Aga; - LPState[6] := Age; - LPState[7] := Agi; - LPState[8] := Ago; - LPState[9] := Agu; - LPState[10] := Aka; - LPState[11] := Ake; - LPState[12] := Aki; - LPState[13] := Ako; - LPState[14] := Aku; - LPState[15] := Ama; - LPState[16] := Ame; - LPState[17] := Ami; - LPState[18] := Amo; - LPState[19] := Amu; - LPState[20] := Asa; - LPState[21] := Ase; - LPState[22] := Asi; - LPState[23] := Aso; - LPState[24] := Asu; - -{$ELSE} - for LRound := 0 to 23 do - begin - LColA := LPState[00] xor LPState[05] xor LPState[10] xor LPState[15] - xor LPState[20]; - LColE := LPState[01] xor LPState[06] xor LPState[11] xor LPState[16] - xor LPState[21]; - LColI := LPState[02] xor LPState[07] xor LPState[12] xor LPState[17] - xor LPState[22]; - LColO := LPState[03] xor LPState[08] xor LPState[13] xor LPState[18] - xor LPState[23]; - LColU := LPState[04] xor LPState[09] xor LPState[14] xor LPState[19] - xor LPState[24]; - LDa := TBitOperations.RotateLeft64(LColA, 1) xor LColO; - LDe := TBitOperations.RotateLeft64(LColE, 1) xor LColU; - LDi := TBitOperations.RotateLeft64(LColI, 1) xor LColA; - LDo := TBitOperations.RotateLeft64(LColO, 1) xor LColE; - LDu := TBitOperations.RotateLeft64(LColU, 1) xor LColI; - LTemp[00] := LPState[00] xor LDe; - LTemp[01] := TBitOperations.RotateLeft64(LPState[06] xor LDi, 44); - LTemp[02] := TBitOperations.RotateLeft64(LPState[12] xor LDo, 43); - LTemp[03] := TBitOperations.RotateLeft64(LPState[18] xor LDu, 21); - LTemp[04] := TBitOperations.RotateLeft64(LPState[24] xor LDa, 14); - LTemp[05] := TBitOperations.RotateLeft64(LPState[03] xor LDu, 28); - LTemp[06] := TBitOperations.RotateLeft64(LPState[09] xor LDa, 20); - LTemp[07] := TBitOperations.RotateLeft64(LPState[10] xor LDe, 3); - LTemp[08] := TBitOperations.RotateLeft64(LPState[16] xor LDi, 45); - LTemp[09] := TBitOperations.RotateLeft64(LPState[22] xor LDo, 61); - LTemp[10] := TBitOperations.RotateLeft64(LPState[01] xor LDi, 1); - LTemp[11] := TBitOperations.RotateLeft64(LPState[07] xor LDo, 6); - LTemp[12] := TBitOperations.RotateLeft64(LPState[13] xor LDu, 25); - LTemp[13] := TBitOperations.RotateLeft64(LPState[19] xor LDa, 8); - LTemp[14] := TBitOperations.RotateLeft64(LPState[20] xor LDe, 18); - LTemp[15] := TBitOperations.RotateLeft64(LPState[04] xor LDa, 27); - LTemp[16] := TBitOperations.RotateLeft64(LPState[05] xor LDe, 36); - LTemp[17] := TBitOperations.RotateLeft64(LPState[11] xor LDi, 10); - LTemp[18] := TBitOperations.RotateLeft64(LPState[17] xor LDo, 15); - LTemp[19] := TBitOperations.RotateLeft64(LPState[23] xor LDu, 56); - LTemp[20] := TBitOperations.RotateLeft64(LPState[02] xor LDo, 62); - LTemp[21] := TBitOperations.RotateLeft64(LPState[08] xor LDu, 55); - LTemp[22] := TBitOperations.RotateLeft64(LPState[14] xor LDa, 39); - LTemp[23] := TBitOperations.RotateLeft64(LPState[15] xor LDe, 41); - LTemp[24] := TBitOperations.RotateLeft64(LPState[21] xor LDi, 2); - LPState[00] := LTemp[00] xor ((not LTemp[01]) and LTemp[02]); - LPState[01] := LTemp[01] xor ((not LTemp[02]) and LTemp[03]); - LPState[02] := LTemp[02] xor ((not LTemp[03]) and LTemp[04]); - LPState[03] := LTemp[03] xor ((not LTemp[04]) and LTemp[00]); - LPState[04] := LTemp[04] xor ((not LTemp[00]) and LTemp[01]); - LPState[05] := LTemp[05] xor ((not LTemp[06]) and LTemp[07]); - LPState[06] := LTemp[06] xor ((not LTemp[07]) and LTemp[08]); - LPState[07] := LTemp[07] xor ((not LTemp[08]) and LTemp[09]); - LPState[08] := LTemp[08] xor ((not LTemp[09]) and LTemp[05]); - LPState[09] := LTemp[09] xor ((not LTemp[05]) and LTemp[06]); - LPState[10] := LTemp[10] xor ((not LTemp[11]) and LTemp[12]); - LPState[11] := LTemp[11] xor ((not LTemp[12]) and LTemp[13]); - LPState[12] := LTemp[12] xor ((not LTemp[13]) and LTemp[14]); - LPState[13] := LTemp[13] xor ((not LTemp[14]) and LTemp[10]); - LPState[14] := LTemp[14] xor ((not LTemp[10]) and LTemp[11]); - LPState[15] := LTemp[15] xor ((not LTemp[16]) and LTemp[17]); - LPState[16] := LTemp[16] xor ((not LTemp[17]) and LTemp[18]); - LPState[17] := LTemp[17] xor ((not LTemp[18]) and LTemp[19]); - LPState[18] := LTemp[18] xor ((not LTemp[19]) and LTemp[15]); - LPState[19] := LTemp[19] xor ((not LTemp[15]) and LTemp[16]); - LPState[20] := LTemp[20] xor ((not LTemp[21]) and LTemp[22]); - LPState[21] := LTemp[21] xor ((not LTemp[22]) and LTemp[23]); - LPState[22] := LTemp[22] xor ((not LTemp[23]) and LTemp[24]); - LPState[23] := LTemp[23] xor ((not LTemp[24]) and LTemp[20]); - LPState[24] := LTemp[24] xor ((not LTemp[20]) and LTemp[21]); - LPState[00] := LPState[00] xor RC[LRound]; - end; - - System.FillChar(LTemp, System.SizeOf(LTemp), UInt64(0)); -{$ENDIF USE_UNROLLED_VARIANT} -end; - -// ============================================================================= -// Scalar absorb: XOR + permute loop (no SIMD) -// ============================================================================= - -procedure KeccakF1600_Absorb_Scalar(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32); -var - LPState: PUInt64; - LData: array [0 .. 20] of UInt64; - LBlockSizeWords, I, J: Int32; -begin - LPState := PUInt64(AState); - LBlockSizeWords := ABlockSize shr 3; - for I := 0 to ABlockCount - 1 do - begin - TBinaryPrimitives.CopyUInt64LittleEndian(AData, 0, @LData[0], 0, ABlockSize); - for J := 0 to LBlockSizeWords - 1 do - LPState[J] := LPState[J] xor LData[J]; - KeccakF1600_Scalar(AState); - System.Inc(AData, ABlockSize); - end; - System.FillChar(LData, System.SizeOf(LData), UInt64(0)); -end; - -// ============================================================================= -// SIMD implementations -// -// i386: — -// x86_64: AVX2 -// aarch64: SHA3 Crypto Extensions -// ============================================================================= - -{$IFDEF HASHLIB_X86_64_ASM} - -const - K_KECCAK: packed record - RhotatesLeft: array [0..23] of UInt64; - RhotatesRight: array [0..23] of UInt64; - Iotas: array [0..95] of UInt64; - Jagged: array [0..24] of Int32; - end = ( - RhotatesLeft: ( - 3, 18, 36, 41, // ymm2: [2][0] [4][0] [1][0] [3][0] - 1, 62, 28, 27, // ymm1: [0][1] [0][2] [0][3] [0][4] - 45, 6, 56, 39, // ymm3: [3][1] [1][2] [4][3] [2][4] - 10, 61, 55, 8, // ymm4: [2][1] [4][2] [1][3] [3][4] - 2, 15, 25, 20, // ymm5: [4][1] [3][2] [2][3] [1][4] - 44, 43, 21, 14); // ymm6: [1][1] [2][2] [3][3] [4][4] - RhotatesRight: ( - 61, 46, 28, 23, - 63, 2, 36, 37, - 19, 58, 8, 25, - 54, 3, 9, 56, - 62, 49, 39, 44, - 20, 21, 43, 50); - Iotas: ( - UInt64($0000000000000001), UInt64($0000000000000001), UInt64($0000000000000001), UInt64($0000000000000001), - UInt64($0000000000008082), UInt64($0000000000008082), UInt64($0000000000008082), UInt64($0000000000008082), - UInt64($800000000000808A), UInt64($800000000000808A), UInt64($800000000000808A), UInt64($800000000000808A), - UInt64($8000000080008000), UInt64($8000000080008000), UInt64($8000000080008000), UInt64($8000000080008000), - UInt64($000000000000808B), UInt64($000000000000808B), UInt64($000000000000808B), UInt64($000000000000808B), - UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), - UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), - UInt64($8000000000008009), UInt64($8000000000008009), UInt64($8000000000008009), UInt64($8000000000008009), - UInt64($000000000000008A), UInt64($000000000000008A), UInt64($000000000000008A), UInt64($000000000000008A), - UInt64($0000000000000088), UInt64($0000000000000088), UInt64($0000000000000088), UInt64($0000000000000088), - UInt64($0000000080008009), UInt64($0000000080008009), UInt64($0000000080008009), UInt64($0000000080008009), - UInt64($000000008000000A), UInt64($000000008000000A), UInt64($000000008000000A), UInt64($000000008000000A), - UInt64($000000008000808B), UInt64($000000008000808B), UInt64($000000008000808B), UInt64($000000008000808B), - UInt64($800000000000008B), UInt64($800000000000008B), UInt64($800000000000008B), UInt64($800000000000008B), - UInt64($8000000000008089), UInt64($8000000000008089), UInt64($8000000000008089), UInt64($8000000000008089), - UInt64($8000000000008003), UInt64($8000000000008003), UInt64($8000000000008003), UInt64($8000000000008003), - UInt64($8000000000008002), UInt64($8000000000008002), UInt64($8000000000008002), UInt64($8000000000008002), - UInt64($8000000000000080), UInt64($8000000000000080), UInt64($8000000000000080), UInt64($8000000000000080), - UInt64($000000000000800A), UInt64($000000000000800A), UInt64($000000000000800A), UInt64($000000000000800A), - UInt64($800000008000000A), UInt64($800000008000000A), UInt64($800000008000000A), UInt64($800000008000000A), - UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), - UInt64($8000000000008080), UInt64($8000000000008080), UInt64($8000000000008080), UInt64($8000000000008080), - UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), - UInt64($8000000080008008), UInt64($8000000080008008), UInt64($8000000080008008), UInt64($8000000080008008)); - Jagged: ( - 0, 32, 40, 48, 56, 80, 192, 104, 144, 184, - 64, 128, 200, 176, 120, 88, 96, 168, 208, 152, - 72, 160, 136, 112, 216) - ); - -procedure KeccakF1600_Avx2(AState: Pointer; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\Include\Simd\SHA3\KeccakF1600Avx2_x86_64.inc} -end; - -procedure KeccakF1600_Avx2_Wrap(AState: Pointer); -begin - KeccakF1600_Avx2(AState, @K_KECCAK); -end; - -procedure KeccakF1600_Avx2_Absorb(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\Include\Simd\SHA3\KeccakF1600Avx2Absorb_x86_64.inc} -end; - -procedure KeccakF1600_Avx2_Absorb_Wrap(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32); -begin - KeccakF1600_Avx2_Absorb(AState, AData, ABlockCount, ABlockSize, @K_KECCAK); -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -// FEAT_SHA3 (ARMv8.2 crypto extension) kernels. Unlike the AVX2 path these -// reuse the plain RC round-constant table directly (the asm broadcasts each -// 64-bit iota with ld1r), so no separate packed constant block is needed. - -procedure KeccakF1600_CryptoExt(AState: Pointer; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} - {$I ..\Include\Simd\SHA3\KeccakF1600CryptoExt_aarch64.inc} -end; - -procedure KeccakF1600_CryptoExt_Wrap(AState: Pointer); -begin - KeccakF1600_CryptoExt(AState, @RC); -end; - -procedure KeccakF1600_CryptoExt_Absorb(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc5Begin_aarch64.inc} - {$I ..\Include\Simd\SHA3\KeccakF1600CryptoExtAbsorb_aarch64.inc} -end; - -procedure KeccakF1600_CryptoExt_Absorb_Wrap(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32); -begin - KeccakF1600_CryptoExt_Absorb(AState, AData, ABlockCount, ABlockSize, @RC); -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - KeccakF1600_Permute := @KeccakF1600_Scalar; - KeccakF1600_Absorb := @KeccakF1600_Absorb_Scalar; -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2]) of - TX86SimdLevel.AVX2: - begin - KeccakF1600_Permute := @KeccakF1600_Avx2_Wrap; - KeccakF1600_Absorb := @KeccakF1600_Avx2_Absorb_Wrap; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - if TCpuFeatures.Arm.HasSHA3() then - begin - KeccakF1600_Permute := @KeccakF1600_CryptoExt_Wrap; - KeccakF1600_Absorb := @KeccakF1600_CryptoExt_Absorb_Wrap; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Hash64/HlpXXHash3.pas b/HashLib/src/Hash64/HlpXXHash3.pas index 043a919..e6aaab6 100644 --- a/HashLib/src/Hash64/HlpXXHash3.pas +++ b/HashLib/src/Hash64/HlpXXHash3.pas @@ -14,6 +14,26 @@ interface HlpIHashResult, HlpBitOperations; +type + TXXH3Accumulate512Proc = procedure(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); + TXXH3AccumulateProc = procedure(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32); + TXXH3ScrambleAccProc = procedure(AAcc: Pointer; ASecret: Pointer); + TXXH3InitSecretProc = procedure(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); + +var + XXH3_Accumulate512: TXXH3Accumulate512Proc; + XXH3_Accumulate: TXXH3AccumulateProc; + XXH3_ScrambleAcc: TXXH3ScrambleAccProc; + XXH3_InitSecret: TXXH3InitSecretProc; + +// Generic stripe-accumulation loop, exposed so the SIMD backends can drive their +// own Accumulate512 kernel over ANbStripes stripes. +procedure XXH3_Accumulate_Loop(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32; AAcc512: TXXH3Accumulate512Proc); + resourcestring SInvalidKeyLength = 'KeyLength Must Be Equal to %d'; @@ -21,11 +41,8 @@ interface TXXH3AccArray = array [0 .. 7] of UInt64; TXXH3Core = class sealed(TObject) - public - const - XXH3_SECRET_DEFAULT_SIZE = Int32(192); XXH3_SECRET_SIZE_MIN = Int32(136); XXH_STRIPE_LEN = Int32(64); @@ -111,11 +128,9 @@ TXXH3Core = class sealed(TObject) end; TXXHash3 = class sealed(THash, IHash64, IHashWithKey, ITransformBlock) - strict private var FKey, FHash: UInt64; - const CKEY = UInt64(0); @@ -124,9 +139,7 @@ TXXHash3 = class sealed(THash, IHash64, IHashWithKey, ITransformBlock) procedure SetKey(const AValue: THashLibByteArray); inline; type - TXXH3_State = record - private var FAcc: TXXH3AccArray; @@ -180,7 +193,97 @@ TXXH3_State = record implementation uses - HlpXXHash3Dispatch; + HlpXXHash3Simd; + +const + XXH_STRIPE_LEN = 64; + XXH_ACC_NB = 8; + XXH_SECRET_CONSUME_RATE = 8; + XXH_PRIME32_1 = UInt32($9E3779B1); + +// ============================================================================= +// Scalar fallback implementations +// ============================================================================= + +procedure XXH3_Accumulate512_Scalar(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); +var + LPAcc: PUInt64; + LPInput, LPSecret: PByte; + I: Int32; + LDataVal, LDataKey: UInt64; +begin + LPAcc := PUInt64(AAcc); + LPInput := PByte(AInput); + LPSecret := PByte(ASecret); + for I := 0 to XXH_ACC_NB - 1 do + begin + LDataVal := TBinaryPrimitives.ReadUInt64LittleEndian(LPInput, I * 8); + LDataKey := LDataVal xor TBinaryPrimitives.ReadUInt64LittleEndian(LPSecret, I * 8); + PUInt64(PByte(LPAcc) + (I xor 1) * 8)^ := + PUInt64(PByte(LPAcc) + (I xor 1) * 8)^ + LDataVal; + PUInt64(PByte(LPAcc) + I * 8)^ := + PUInt64(PByte(LPAcc) + I * 8)^ + + UInt64(UInt32(LDataKey)) * UInt64(UInt32(LDataKey shr 32)); + end; +end; + +procedure XXH3_ScrambleAcc_Scalar(AAcc: Pointer; ASecret: Pointer); +var + LPAcc: PUInt64; + LPSecret: PByte; + I: Int32; + LKey64, LAcc64: UInt64; +begin + LPAcc := PUInt64(AAcc); + LPSecret := PByte(ASecret); + for I := 0 to XXH_ACC_NB - 1 do + begin + LKey64 := TBinaryPrimitives.ReadUInt64LittleEndian(LPSecret, I * 8); + LAcc64 := PUInt64(PByte(LPAcc) + I * 8)^; + LAcc64 := LAcc64 xor (LAcc64 shr 47); + LAcc64 := LAcc64 xor LKey64; + LAcc64 := LAcc64 * XXH_PRIME32_1; + PUInt64(PByte(LPAcc) + I * 8)^ := LAcc64; + end; +end; + +procedure XXH3_InitSecret_Scalar(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); +var + I: Int32; + LPSrc, LPDst: PByte; +begin + LPSrc := PByte(ADefaultSecret); + LPDst := PByte(ACustomSecret); + for I := 0 to (192 div 16) - 1 do + begin + PUInt64(LPDst + 16 * I)^ := + TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I) + ASeed; + PUInt64(LPDst + 16 * I + 8)^ := + TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I + 8) - ASeed; + end; +end; + +procedure XXH3_Accumulate_Scalar(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32); +var + N: Int32; +begin + for N := 0 to ANbStripes - 1 do + XXH3_Accumulate512_Scalar(AAcc, PByte(AInput) + N * XXH_STRIPE_LEN, + PByte(ASecret) + N * XXH_SECRET_CONSUME_RATE); +end; + +procedure XXH3_Accumulate_Loop(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32; AAcc512: TXXH3Accumulate512Proc); +var + N: Int32; +begin + for N := 0 to ANbStripes - 1 do + AAcc512(AAcc, PByte(AInput) + N * XXH_STRIPE_LEN, + PByte(ASecret) + N * XXH_SECRET_CONSUME_RATE); +end; { TXXH3Core } @@ -287,7 +390,7 @@ class procedure TXXH3Core.XXH3_scalarRound(var AAcc: TXXH3AccArray; class procedure TXXH3Core.XXH3_accumulate_512(var AAcc: TXXH3AccArray; AInput, ASecret: PByte); begin - HlpXXHash3Dispatch.XXH3_Accumulate512(@AAcc[0], AInput, ASecret); + HlpXXHash3.XXH3_Accumulate512(@AAcc[0], AInput, ASecret); end; class procedure TXXH3Core.XXH3_scalarScrambleRound(var AAcc: TXXH3AccArray; @@ -306,13 +409,13 @@ class procedure TXXH3Core.XXH3_scalarScrambleRound(var AAcc: TXXH3AccArray; class procedure TXXH3Core.XXH3_scrambleAcc(var AAcc: TXXH3AccArray; ASecret: PByte); begin - HlpXXHash3Dispatch.XXH3_ScrambleAcc(@AAcc[0], ASecret); + HlpXXHash3.XXH3_ScrambleAcc(@AAcc[0], ASecret); end; class procedure TXXH3Core.XXH3_accumulate(var AAcc: TXXH3AccArray; AInput, ASecret: PByte; ANbStripes: Int32); begin - HlpXXHash3Dispatch.XXH3_Accumulate(@AAcc[0], AInput, ASecret, ANbStripes); + HlpXXHash3.XXH3_Accumulate(@AAcc[0], AInput, ASecret, ANbStripes); end; class procedure TXXH3Core.XXH3_hashLong_internal_loop( @@ -345,7 +448,7 @@ class procedure TXXH3Core.XXH3_hashLong_internal_loop( class procedure TXXH3Core.XXH3_initCustomSecret(ACustomSecret: PByte; ASeed: UInt64); begin - HlpXXHash3Dispatch.XXH3_InitSecret(ACustomSecret, @XXH3_SECRET[0], ASeed); + HlpXXHash3.XXH3_InitSecret(ACustomSecret, @XXH3_SECRET[0], ASeed); end; class procedure TXXH3Core.XXH3_consumeStripes(var AAcc: TXXH3AccArray; @@ -747,4 +850,10 @@ function TXXHash3.TransformFinal: IHashResult; Initialize(); end; +initialization + XXH3_Accumulate512 := TXXHash3Simd.SelectAccumulate512(@XXH3_Accumulate512_Scalar); + XXH3_Accumulate := TXXHash3Simd.SelectAccumulate(@XXH3_Accumulate_Scalar); + XXH3_ScrambleAcc := TXXHash3Simd.SelectScrambleAcc(@XXH3_ScrambleAcc_Scalar); + XXH3_InitSecret := TXXHash3Simd.SelectInitSecret(@XXH3_InitSecret_Scalar); + end. diff --git a/HashLib/src/Hash64/HlpXXHash3Dispatch.pas b/HashLib/src/Hash64/HlpXXHash3Dispatch.pas deleted file mode 100644 index 608f9c2..0000000 --- a/HashLib/src/Hash64/HlpXXHash3Dispatch.pas +++ /dev/null @@ -1,299 +0,0 @@ -unit HlpXXHash3Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TXXH3Accumulate512Proc = procedure(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - TXXH3AccumulateProc = procedure(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer; ANbStripes: Int32); - TXXH3ScrambleAccProc = procedure(AAcc: Pointer; ASecret: Pointer); - TXXH3InitSecretProc = procedure(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - -var - XXH3_Accumulate512: TXXH3Accumulate512Proc; - XXH3_Accumulate: TXXH3AccumulateProc; - XXH3_ScrambleAcc: TXXH3ScrambleAccProc; - XXH3_InitSecret: TXXH3InitSecretProc; - -implementation - -uses - HlpBinaryPrimitives, - HlpCpuFeatures, - HlpSimdLevels; - -const - XXH_STRIPE_LEN = 64; - XXH_ACC_NB = 8; - XXH_SECRET_CONSUME_RATE = 8; - XXH_PRIME32_1 = UInt32($9E3779B1); - -// ============================================================================= -// Scalar fallback implementations -// ============================================================================= - -procedure XXH3_Accumulate512_Scalar(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); -var - LPAcc: PUInt64; - LPInput, LPSecret: PByte; - I: Int32; - LDataVal, LDataKey: UInt64; -begin - LPAcc := PUInt64(AAcc); - LPInput := PByte(AInput); - LPSecret := PByte(ASecret); - for I := 0 to XXH_ACC_NB - 1 do - begin - LDataVal := TBinaryPrimitives.ReadUInt64LittleEndian(LPInput, I * 8); - LDataKey := LDataVal xor TBinaryPrimitives.ReadUInt64LittleEndian(LPSecret, I * 8); - PUInt64(PByte(LPAcc) + (I xor 1) * 8)^ := - PUInt64(PByte(LPAcc) + (I xor 1) * 8)^ + LDataVal; - PUInt64(PByte(LPAcc) + I * 8)^ := - PUInt64(PByte(LPAcc) + I * 8)^ + - UInt64(UInt32(LDataKey)) * UInt64(UInt32(LDataKey shr 32)); - end; -end; - -procedure XXH3_ScrambleAcc_Scalar(AAcc: Pointer; ASecret: Pointer); -var - LPAcc: PUInt64; - LPSecret: PByte; - I: Int32; - LKey64, LAcc64: UInt64; -begin - LPAcc := PUInt64(AAcc); - LPSecret := PByte(ASecret); - for I := 0 to XXH_ACC_NB - 1 do - begin - LKey64 := TBinaryPrimitives.ReadUInt64LittleEndian(LPSecret, I * 8); - LAcc64 := PUInt64(PByte(LPAcc) + I * 8)^; - LAcc64 := LAcc64 xor (LAcc64 shr 47); - LAcc64 := LAcc64 xor LKey64; - LAcc64 := LAcc64 * XXH_PRIME32_1; - PUInt64(PByte(LPAcc) + I * 8)^ := LAcc64; - end; -end; - -procedure XXH3_InitSecret_Scalar(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); -var - I: Int32; - LPSrc, LPDst: PByte; -begin - LPSrc := PByte(ADefaultSecret); - LPDst := PByte(ACustomSecret); - for I := 0 to (192 div 16) - 1 do - begin - PUInt64(LPDst + 16 * I)^ := - TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I) + ASeed; - PUInt64(LPDst + 16 * I + 8)^ := - TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I + 8) - ASeed; - end; -end; - -procedure XXH3_Accumulate_Scalar(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer; ANbStripes: Int32); -var - N: Int32; -begin - for N := 0 to ANbStripes - 1 do - XXH3_Accumulate512_Scalar(AAcc, PByte(AInput) + N * XXH_STRIPE_LEN, - PByte(ASecret) + N * XXH_SECRET_CONSUME_RATE); -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: AVX2, SSE2 -// aarch64: NEON -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure XXH3_Accumulate512_Sse2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} - {$I ..\Include\Simd\XXH3\XXH3Acc512Sse2_i386.inc} -end; - -procedure XXH3_ScrambleAcc_Sse2(AAcc: Pointer; ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\Include\Simd\XXH3\XXH3ScrambleSse2_i386.inc} -end; - -procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} - {$I ..\Include\Simd\XXH3\XXH3InitSecretSse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure XXH3_Accumulate512_Sse2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\Include\Simd\XXH3\XXH3Acc512Sse2_x86_64.inc} -end; - -procedure XXH3_ScrambleAcc_Sse2(AAcc: Pointer; ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\Include\Simd\XXH3\XXH3ScrambleSse2_x86_64.inc} -end; - -procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\Include\Simd\XXH3\XXH3InitSecretSse2_x86_64.inc} -end; - -procedure XXH3_Accumulate512_Avx2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\Include\Simd\XXH3\XXH3Acc512Avx2_x86_64.inc} -end; - -procedure XXH3_ScrambleAcc_Avx2(AAcc: Pointer; ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\Include\Simd\XXH3\XXH3ScrambleAvx2_x86_64.inc} -end; - -procedure XXH3_InitSecret_Avx2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\Include\Simd\XXH3\XXH3InitSecretAvx2_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IF DEFINED(HASHLIB_X86_SIMD) OR DEFINED(HASHLIB_ARM_SIMD)} - -type - TXXH3_Accumulate512Proc = procedure(AAcc, AInput, ASecret: Pointer); - -procedure XXH3_Accumulate_Loop(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer; ANbStripes: Int32; AAcc512: TXXH3_Accumulate512Proc); -var - N: Int32; -begin - for N := 0 to ANbStripes - 1 do - AAcc512(AAcc, PByte(AInput) + N * XXH_STRIPE_LEN, - PByte(ASecret) + N * XXH_SECRET_CONSUME_RATE); -end; - -{$IFEND} - -{$IFDEF HASHLIB_X86_SIMD} - -procedure XXH3_Accumulate_Sse2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer; ANbStripes: Int32); -begin - XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Sse2); -end; - -{$ENDIF HASHLIB_X86_SIMD} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure XXH3_Accumulate_Avx2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer; ANbStripes: Int32); -begin - XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Avx2); -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure XXH3_Accumulate512_Neon(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_aarch64.inc} - {$I ..\Include\Simd\XXH3\XXH3Acc512Neon_aarch64.inc} -end; - -procedure XXH3_ScrambleAcc_Neon(AAcc: Pointer; ASecret: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} - {$I ..\Include\Simd\XXH3\XXH3ScrambleNeon_aarch64.inc} -end; - -procedure XXH3_InitSecret_Neon(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\Include\Simd\Common\HlpSimdProc3Begin_aarch64.inc} - {$I ..\Include\Simd\XXH3\XXH3InitSecretNeon_aarch64.inc} -end; - -{$IFDEF HASHLIB_ARM_SIMD} - -procedure XXH3_Accumulate_Neon(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer; ANbStripes: Int32); -begin - XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Neon); -end; - -{$ENDIF HASHLIB_ARM_SIMD} - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - XXH3_Accumulate512 := @XXH3_Accumulate512_Scalar; - XXH3_Accumulate := @XXH3_Accumulate_Scalar; - XXH3_ScrambleAcc := @XXH3_ScrambleAcc_Scalar; - XXH3_InitSecret := @XXH3_InitSecret_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - XXH3_Accumulate512 := @XXH3_Accumulate512_Sse2; - XXH3_Accumulate := @XXH3_Accumulate_Sse2; - XXH3_ScrambleAcc := @XXH3_ScrambleAcc_Sse2; - XXH3_InitSecret := @XXH3_InitSecret_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - XXH3_Accumulate512 := @XXH3_Accumulate512_Avx2; - XXH3_Accumulate := @XXH3_Accumulate_Avx2; - XXH3_ScrambleAcc := @XXH3_ScrambleAcc_Avx2; - XXH3_InitSecret := @XXH3_InitSecret_Avx2; - end; - TX86SimdLevel.SSE2: - begin - XXH3_Accumulate512 := @XXH3_Accumulate512_Sse2; - XXH3_Accumulate := @XXH3_Accumulate_Sse2; - XXH3_ScrambleAcc := @XXH3_ScrambleAcc_Sse2; - XXH3_InitSecret := @XXH3_InitSecret_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - TArmSimdLevel.NEON: - begin - XXH3_Accumulate512 := @XXH3_Accumulate512_Neon; - XXH3_Accumulate := @XXH3_Accumulate_Neon; - XXH3_ScrambleAcc := @XXH3_ScrambleAcc_Neon; - XXH3_InitSecret := @XXH3_InitSecret_Neon; - end; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc index 6260520..a65ed9a 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc @@ -10,7 +10,7 @@ // weight bytes via pmaddwd (SSE2), producing the same 4 x i32 weighted // sums per 16-byte half that pmaddubsw + pmaddwd would yield. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // Zero constant pxor xmm3, xmm3 @@ -98,4 +98,4 @@ mov dword [r8], eax mov dword [r8 + 4], r10d - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc index a277aff..a9e486a 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc @@ -5,7 +5,7 @@ // Processes num_blocks x 32-byte blocks. Does NOT apply mod 65521 (caller does it). // Uses xmm0-xmm8; xmm6-xmm8 are MS x64 non-volatile (saved/restored). - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // Load constants movdqu xmm4, oword [r9] @@ -76,4 +76,4 @@ mov dword [r8], eax mov dword [r8 + 4], r10d - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc index 4bff0fe..9d82dd1 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc @@ -15,7 +15,7 @@ // Diagonalize/Undiagonalize via vpermq (cross-lane 64-bit permute). // vzeroupper required before return. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 2056 @@ -326,4 +326,4 @@ add rsp, 2056 db $C5, $F8, $77 // vzeroupper - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc index 4d696be..b529766 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc @@ -16,7 +16,7 @@ // register pairs. Right-rotates require a 3-movdqa swap since shufpd // naturally places results in the opposite register for that direction. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 2056 @@ -555,4 +555,4 @@ @epilogue: add rsp, 2056 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc index c72e55d..1eb793d 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc @@ -15,7 +15,7 @@ // v21-v23 = rotate / diagonalize temps (b1 gather uses v23) // u64 ror-by-32 uses rev64.4s (vrev64q_u32), not rev64.16b. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} .long 0xad400400 // ldp q0, q1, [x0] .long 0xad410c02 // ldp q2, q3, [x0, #32] @@ -1395,5 +1395,5 @@ .long 0xad000400 // stp q0, q1, [x0] .long 0xad010c02 // stp q2, q3, [x0, #32] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} ret diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc index 861c04f..b001d1d 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc @@ -5,7 +5,7 @@ // xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15), xmm8-9 = temps. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // Initialize working vector movdqu xmm0, oword [rcx] @@ -1989,4 +1989,4 @@ movdqu oword [rcx + $20], xmm2 movdqu oword [rcx + $30], xmm3 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc index 55b78f7..7729069 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc @@ -7,7 +7,7 @@ // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // Initialize working vector db $C5, $FA, $6F, $01 // vmovdqu xmm0, oword [rcx] @@ -993,4 +993,4 @@ db $C5, $F8, $77 // vzeroupper - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc index 6fdfaf6..3888211 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc @@ -8,7 +8,7 @@ // Message loads via movd + punpcklqdq + shufps. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // Initialize working vector movdqu xmm0, oword [rcx] @@ -1072,4 +1072,4 @@ movdqu oword [rcx], xmm0 movdqu oword [rcx + $10], xmm1 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc index c2c1023..18dee8b 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc @@ -16,7 +16,7 @@ // [rsp + 96..111]: IV staging area (loaded into xmm2) // [rsp +112..119]: padding - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 24 @@ -584,4 +584,4 @@ add rsp, 24 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc index 396ecb5..539b444 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc @@ -16,7 +16,7 @@ // [rsp + 96..111]: IV staging area (loaded into xmm2) // [rsp +112..119]: padding - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 24 @@ -637,4 +637,4 @@ add rsp, 24 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc index 7907c57..2aec258 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc @@ -18,7 +18,7 @@ // [sp, #320..568] saved CV, counter vectors, IV, block len, AOut ptr, flags // Message transpose uses trn1/trn2 + zip1/zip2 (equivalent to SSE punpck / neon transpose_vecs_128). - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} stp x19, x20, [sp, #-16]! sub sp, sp, #720 @@ -1711,5 +1711,5 @@ add sp, sp, #720 ldp x19, x20, [sp], #16 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} ret diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc index f17b54f..6cc80f3 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc @@ -18,7 +18,7 @@ push rbx push rbp - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 584 @@ -1828,7 +1828,7 @@ add rsp, 584 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} pop rbp pop rbx diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc index 5f7060d..c0df074 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc @@ -18,7 +18,7 @@ // // MS x64 non-volatile saves: xmm6-xmm13. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} push rbx push rbp @@ -1678,4 +1678,4 @@ pop rbp pop rbx - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc index c68debc..273cfef 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc @@ -29,7 +29,7 @@ // pshufb xmm_dst, xmm_src (SSSE3): // 66 0F 38 00 ModRM - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // BswapMask is always needed (kept in xmm6 throughout) movdqu xmm6, dqword ptr [r9 + 64] // BswapMask @@ -195,4 +195,4 @@ // movq rax, xmm0: 66 48 0F 7E C0 db $66, $48, $0F, $7E, $C0 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc index a00c355..a9b97f4 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc @@ -26,7 +26,7 @@ // 2-byte: C5 [R.vvvv.L.pp] // 3-byte: C4 [R.X.B.mmmmm] [W.vvvv.L.pp] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} cmp edx, 128 jb @xmm_path @@ -240,4 +240,4 @@ // movq rax, xmm0: 66 48 0F 7E C0 db $66, $48, $0F, $7E, $C0 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc index 49a9521..0db7df3 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc @@ -26,7 +26,7 @@ // xmm0=000 xmm1=001 xmm2=010 xmm3=011 xmm4=100 // xmm5=101 xmm6=110 xmm7=111 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // fold_1x128 is always needed (fold-by-1 loop and Barrett step 1) movdqu xmm7, dqword ptr [r9 + 16] // fold_1x128 @@ -194,4 +194,4 @@ // pextrq rax, xmm0, 1: 66 48 0F 3A 16 C0 01 db $66, $48, $0F, $3A, $16, $C0, $01 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc index ea35440..4eb74ca 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc @@ -25,7 +25,7 @@ // 2-byte: C5 [R.vvvv.L.pp] // 3-byte: C4 [R.X.B.mmmmm] [W.vvvv.L.pp] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} cmp edx, 128 jb @xmm_path @@ -216,4 +216,4 @@ db $C5, $F8, $77 // vzeroupper db $C4, $E3, $F9, $16, $C0, $01 // vpextrq rax, xmm0, 1 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc index fbb5b20..c334e8f 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc @@ -13,7 +13,7 @@ // include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 // holds the caller rsp across the kernel for the unwind. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} mov r11, rsp push r9 @@ -1679,4 +1679,4 @@ mov rbx, qword [r11 - $10] lea rsp, [r11] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc index 3f8fa1b..35e72da 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc @@ -34,7 +34,7 @@ // MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore // include (no-op on SysV); the kernel itself uses only volatile GPRs (rcx/rdx/r8-r11). - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} test r8d, r8d jz @sha1ni_done @@ -203,4 +203,4 @@ @sha1ni_done: - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc index 7562a95..7b9e57c 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc @@ -13,7 +13,7 @@ // include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 // holds the caller rsp across the kernel for the unwind. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} mov r11, rsp push r9 @@ -1228,4 +1228,4 @@ mov rbx, qword [r11 - $10] lea rsp, [r11] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc index 0eb5c27..af245c1 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc @@ -14,7 +14,7 @@ // MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore // include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} mov rax, rsp push r9 @@ -1252,4 +1252,4 @@ lea rsp, [rsi] mov rsi, rax - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc index 640ed16..0b1f0f3 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc @@ -30,7 +30,7 @@ // MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore // include (no-op on SysV); the kernel itself uses only volatile GPRs (rcx/rdx/r8-r10). - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} test r8d, r8d jz @shani_done @@ -255,4 +255,4 @@ @shani_done: - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc index 11fcdc1..7829cb9 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc @@ -13,7 +13,7 @@ // MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore // include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} mov rax, rsp push r9 @@ -1150,4 +1150,4 @@ lea rsp, [rsi] mov rsi, rax - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc index 9174094..2729c93 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc @@ -52,7 +52,7 @@ push rdi push rsi - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 264 @@ -393,7 +393,7 @@ add rsp, 264 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} pop rsi pop rdi diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc index e40f309..9f97422 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc @@ -24,7 +24,7 @@ // [rsp+ 32..191]: xmm6-xmm15 save area // [rsp+192..223]: padding - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} sub rsp, 64 @@ -274,4 +274,4 @@ add rsp, 64 - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc index fc514f0..a827b35 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc @@ -9,7 +9,7 @@ // v25-v30 = permutation scratch // v31 = loaded input lane - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} .long 0x6d400400 // ldp d0, d1, [x0] .long 0x6d410c02 // ldp d2, d3, [x0, #16] .long 0x6d421404 // ldp d4, d5, [x0, #32] @@ -200,5 +200,5 @@ .long 0x6d0a5414 // stp d20, d21, [x0, #160] .long 0x6d0b5c16 // stp d22, d23, [x0, #176] .long 0xfd006018 // str d24, [x0, #192] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} ret diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc index 7728a65..a6fef56 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc @@ -11,7 +11,7 @@ // v26 = iota round constant (ld1r) // v30-v31 = Rho/Pi scratch - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} .long 0x6d400400 // ldp d0, d1, [x0] .long 0x6d410c02 // ldp d2, d3, [x0, #16] .long 0x6d421404 // ldp d4, d5, [x0, #32] @@ -109,5 +109,5 @@ .long 0x6d0a5414 // stp d20, d21, [x0, #160] .long 0x6d0b5c16 // stp d22, d23, [x0, #176] .long 0xfd006018 // str d24, [x0, #192] - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_aarch64.inc} ret diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc index 7195dee..9bfd15a 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc @@ -13,7 +13,7 @@ // MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore // include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} mov rax, rsp push r9 @@ -1344,4 +1344,4 @@ lea rsp, [rsi] mov rsi, rax - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc index c16de39..56852e8 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc @@ -12,7 +12,7 @@ // MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore // include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. - {$I ..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} push rbx push rbp @@ -1295,4 +1295,4 @@ pop rbp pop rbx - {$I ..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/KDF/HlpArgon2Dispatch.pas b/HashLib/src/KDF/HlpArgon2Dispatch.pas deleted file mode 100644 index 260a6ff..0000000 --- a/HashLib/src/KDF/HlpArgon2Dispatch.pas +++ /dev/null @@ -1,185 +0,0 @@ -unit HlpArgon2Dispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TArgon2FillBlockProc = procedure(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - -var - Argon2_FillBlock: TArgon2FillBlockProc; - -implementation - -uses - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Scalar fallback implementation -// ============================================================================= - -procedure Argon2_FillBlock_Scalar(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); -var - LR, LZ: array [0 .. 127] of UInt64; - LPLeft, LPRight, LPCurrent: PUInt64; - LIdx, LRoundIdx, LColBase, LRowBase: Int32; - - procedure G(AA, AB, AC, AD: Int32); - var - LProd: UInt64; - begin - LProd := UInt64(UInt32(LZ[AA])) * UInt64(UInt32(LZ[AB])); - LZ[AA] := LZ[AA] + LZ[AB] + (2 * LProd); - LZ[AD] := TBitOperations.RotateRight64(LZ[AD] xor LZ[AA], 32); - - LProd := UInt64(UInt32(LZ[AC])) * UInt64(UInt32(LZ[AD])); - LZ[AC] := LZ[AC] + LZ[AD] + (2 * LProd); - LZ[AB] := TBitOperations.RotateRight64(LZ[AB] xor LZ[AC], 24); - - LProd := UInt64(UInt32(LZ[AA])) * UInt64(UInt32(LZ[AB])); - LZ[AA] := LZ[AA] + LZ[AB] + (2 * LProd); - LZ[AD] := TBitOperations.RotateRight64(LZ[AD] xor LZ[AA], 16); - - LProd := UInt64(UInt32(LZ[AC])) * UInt64(UInt32(LZ[AD])); - LZ[AC] := LZ[AC] + LZ[AD] + (2 * LProd); - LZ[AB] := TBitOperations.RotateRight64(LZ[AB] xor LZ[AC], 63); - end; - - procedure RoundFunction(AV0, AV1, AV2, AV3, AV4, AV5, AV6, AV7, - AV8, AV9, AV10, AV11, AV12, AV13, AV14, AV15: Int32); - begin - G(AV0, AV4, AV8, AV12); - G(AV1, AV5, AV9, AV13); - G(AV2, AV6, AV10, AV14); - G(AV3, AV7, AV11, AV15); - - G(AV0, AV5, AV10, AV15); - G(AV1, AV6, AV11, AV12); - G(AV2, AV7, AV8, AV13); - G(AV3, AV4, AV9, AV14); - end; - -begin - LPLeft := PUInt64(ALeft); - LPRight := PUInt64(ARight); - LPCurrent := PUInt64(ACurrent); - - for LIdx := 0 to 127 do - LR[LIdx] := LPLeft[LIdx] xor LPRight[LIdx]; - - System.Move(LR, LZ, SizeOf(LR)); - - for LRoundIdx := 0 to 7 do - begin - LColBase := 16 * LRoundIdx; - RoundFunction(LColBase, LColBase + 1, LColBase + 2, LColBase + 3, - LColBase + 4, LColBase + 5, LColBase + 6, LColBase + 7, - LColBase + 8, LColBase + 9, LColBase + 10, LColBase + 11, - LColBase + 12, LColBase + 13, LColBase + 14, LColBase + 15); - end; - - for LRoundIdx := 0 to 7 do - begin - LRowBase := 2 * LRoundIdx; - RoundFunction(LRowBase, LRowBase + 1, LRowBase + 16, LRowBase + 17, - LRowBase + 32, LRowBase + 33, LRowBase + 48, LRowBase + 49, - LRowBase + 64, LRowBase + 65, LRowBase + 80, LRowBase + 81, - LRowBase + 96, LRowBase + 97, LRowBase + 112, LRowBase + 113); - end; - - if AWithXor <> 0 then - begin - for LIdx := 0 to 127 do - LPCurrent[LIdx] := LR[LIdx] xor LZ[LIdx] xor LPCurrent[LIdx]; - end - else - begin - for LIdx := 0 to 127 do - LPCurrent[LIdx] := LR[LIdx] xor LZ[LIdx]; - end; -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: AVX2, SSE2 -// aarch64: NEON -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\Argon2\Argon2FillBlockSse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Argon2\Argon2FillBlockSse2_x86_64.inc} -end; - -procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\Argon2\Argon2FillBlockAvx2_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure Argon2_FillBlock_Neon(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\Argon2\Argon2FillBlockNeon_aarch64.inc} -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - Argon2_FillBlock := @Argon2_FillBlock_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - Argon2_FillBlock := @Argon2_FillBlock_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - Argon2_FillBlock := @Argon2_FillBlock_Avx2; - end; - TX86SimdLevel.SSE2: - begin - Argon2_FillBlock := @Argon2_FillBlock_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - TArmSimdLevel.NEON: - begin - Argon2_FillBlock := @Argon2_FillBlock_Neon; - end; - end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/KDF/HlpPBKDF_Argon2NotBuildInAdapter.pas b/HashLib/src/KDF/HlpPBKDF_Argon2NotBuildInAdapter.pas index 284bfea..016f891 100644 --- a/HashLib/src/KDF/HlpPBKDF_Argon2NotBuildInAdapter.pas +++ b/HashLib/src/KDF/HlpPBKDF_Argon2NotBuildInAdapter.pas @@ -18,10 +18,15 @@ interface HlpConverters, HlpBinaryPrimitives, HlpArgon2TypeAndVersion, - HlpArgon2Dispatch, HlpArrayUtils, HlpHashLibTypes; +type + TArgon2FillBlockProc = procedure(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); + +var + Argon2_FillBlock: TArgon2FillBlockProc; + resourcestring SInvalidOutputByteCount = '"(AByteCount)" Argument Less Than "%d".'; SBlockInstanceNotInitialized = 'Block Instance not Initialized'; @@ -355,6 +360,95 @@ TFillBlock = record implementation +uses + HlpBitOperations, + HlpArgon2Simd; + +// ============================================================================= +// Scalar reference implementation +// ============================================================================= + +procedure Argon2_FillBlock_Scalar(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); +var + LR, LZ: array [0 .. 127] of UInt64; + LPLeft, LPRight, LPCurrent: PUInt64; + LIdx, LRoundIdx, LColBase, LRowBase: Int32; + + procedure G(AA, AB, AC, AD: Int32); + var + LProd: UInt64; + begin + LProd := UInt64(UInt32(LZ[AA])) * UInt64(UInt32(LZ[AB])); + LZ[AA] := LZ[AA] + LZ[AB] + (2 * LProd); + LZ[AD] := TBitOperations.RotateRight64(LZ[AD] xor LZ[AA], 32); + + LProd := UInt64(UInt32(LZ[AC])) * UInt64(UInt32(LZ[AD])); + LZ[AC] := LZ[AC] + LZ[AD] + (2 * LProd); + LZ[AB] := TBitOperations.RotateRight64(LZ[AB] xor LZ[AC], 24); + + LProd := UInt64(UInt32(LZ[AA])) * UInt64(UInt32(LZ[AB])); + LZ[AA] := LZ[AA] + LZ[AB] + (2 * LProd); + LZ[AD] := TBitOperations.RotateRight64(LZ[AD] xor LZ[AA], 16); + + LProd := UInt64(UInt32(LZ[AC])) * UInt64(UInt32(LZ[AD])); + LZ[AC] := LZ[AC] + LZ[AD] + (2 * LProd); + LZ[AB] := TBitOperations.RotateRight64(LZ[AB] xor LZ[AC], 63); + end; + + procedure RoundFunction(AV0, AV1, AV2, AV3, AV4, AV5, AV6, AV7, + AV8, AV9, AV10, AV11, AV12, AV13, AV14, AV15: Int32); + begin + G(AV0, AV4, AV8, AV12); + G(AV1, AV5, AV9, AV13); + G(AV2, AV6, AV10, AV14); + G(AV3, AV7, AV11, AV15); + + G(AV0, AV5, AV10, AV15); + G(AV1, AV6, AV11, AV12); + G(AV2, AV7, AV8, AV13); + G(AV3, AV4, AV9, AV14); + end; + +begin + LPLeft := PUInt64(ALeft); + LPRight := PUInt64(ARight); + LPCurrent := PUInt64(ACurrent); + + for LIdx := 0 to 127 do + LR[LIdx] := LPLeft[LIdx] xor LPRight[LIdx]; + + System.Move(LR, LZ, SizeOf(LR)); + + for LRoundIdx := 0 to 7 do + begin + LColBase := 16 * LRoundIdx; + RoundFunction(LColBase, LColBase + 1, LColBase + 2, LColBase + 3, + LColBase + 4, LColBase + 5, LColBase + 6, LColBase + 7, + LColBase + 8, LColBase + 9, LColBase + 10, LColBase + 11, + LColBase + 12, LColBase + 13, LColBase + 14, LColBase + 15); + end; + + for LRoundIdx := 0 to 7 do + begin + LRowBase := 2 * LRoundIdx; + RoundFunction(LRowBase, LRowBase + 1, LRowBase + 16, LRowBase + 17, + LRowBase + 32, LRowBase + 33, LRowBase + 48, LRowBase + 49, + LRowBase + 64, LRowBase + 65, LRowBase + 80, LRowBase + 81, + LRowBase + 96, LRowBase + 97, LRowBase + 112, LRowBase + 113); + end; + + if AWithXor <> 0 then + begin + for LIdx := 0 to 127 do + LPCurrent[LIdx] := LR[LIdx] xor LZ[LIdx] xor LPCurrent[LIdx]; + end + else + begin + for LIdx := 0 to 127 do + LPCurrent[LIdx] := LR[LIdx] xor LZ[LIdx]; + end; +end; + { TPBKDF_Argon2NotBuildInAdapter.TBlock } class function TPBKDF_Argon2NotBuildInAdapter.TBlock.CreateBlock: TBlock; @@ -1315,5 +1409,8 @@ destructor TPBKDF_Argon2NotBuildInAdapter.Destroy; inherited Destroy; end; +initialization + Argon2_FillBlock := TArgon2Simd.Select(@Argon2_FillBlock_Scalar); + end. diff --git a/HashLib/src/KDF/HlpPBKDF_ScryptNotBuildInAdapter.pas b/HashLib/src/KDF/HlpPBKDF_ScryptNotBuildInAdapter.pas index 45d6979..997cda3 100644 --- a/HashLib/src/KDF/HlpPBKDF_ScryptNotBuildInAdapter.pas +++ b/HashLib/src/KDF/HlpPBKDF_ScryptNotBuildInAdapter.pas @@ -15,10 +15,18 @@ interface HlpIHashInfo, HlpBinaryPrimitives, HlpPBKDF2_HMACNotBuildInAdapter, - HlpScryptDispatch, HlpArrayUtils, HlpHashLibTypes; +type + TScryptSalsaXorProc = procedure(AState, AInput: Pointer); + +var + Scrypt_SalsaXor: TScryptSalsaXorProc; + +procedure Scrypt_Permute(ABlock: PCardinal; AChunkCount: Int32); +procedure Scrypt_Unpermute(ABlock: PCardinal; AChunkCount: Int32); + resourcestring SInvalidByteCount = '"(AByteCount)" Argument must be a value greater than zero.'; @@ -115,6 +123,157 @@ TPBKDF_ScryptNotBuildInAdapter = class sealed(TKDF, IPBKDF_Scrypt, implementation +uses + HlpBitOperations, + HlpScryptSimd; + +// ============================================================================= +// Percival's (i*5 mod 16) permutation rearranges each 16-word Salsa20 state +// from natural order into role-based diagonal order so that column and row +// quarter-rounds map to lane-parallel SIMD operations. Applied once at +// SMixLane entry/exit; all intermediate data stays in permuted order. +// Reference: Colin Percival, crypto_scrypt-sse.c (Tarsnap). +// ============================================================================= + +procedure Scrypt_Permute(ABlock: PCardinal; AChunkCount: Int32); +var + LTemp: array[0..15] of UInt32; + LIdx: Int32; +begin + while AChunkCount > 0 do + begin + for LIdx := 0 to 15 do + LTemp[LIdx] := ABlock[(LIdx * 5) and 15]; + System.Move(LTemp, ABlock^, 64); + Inc(ABlock, 16); + Dec(AChunkCount); + end; +end; + +procedure Scrypt_Unpermute(ABlock: PCardinal; AChunkCount: Int32); +var + LTemp: array[0..15] of UInt32; + LIdx: Int32; +begin + while AChunkCount > 0 do + begin + for LIdx := 0 to 15 do + LTemp[LIdx] := ABlock[(LIdx * 13) and 15]; + System.Move(LTemp, ABlock^, 64); + Inc(ABlock, 16); + Dec(AChunkCount); + end; +end; + +// ============================================================================= +// Scalar fallback: fused XOR + Salsa20/8 on Percival-permuted data. +// Loads from permuted positions into natural-named locals, performs standard +// Salsa20/8 column+row rounds, stores back to permuted positions. +// ============================================================================= + +procedure Scrypt_SalsaXor_Scalar(AState, AInput: Pointer); +var + LW0, LW1, LW2, LW3, LW4, LW5, LW6, LW7, + LW8, LW9, LW10, LW11, LW12, LW13, LW14, LW15: UInt32; + LPS, LPI: PCardinal; + LIdx: Int32; +begin + LPS := PCardinal(AState); + LPI := PCardinal(AInput); + + // Permuted layout: {w0,w5,w10,w15, w4,w9,w14,w3, w8,w13,w2,w7, w12,w1,w6,w11} + LW0 := LPS[0] xor LPI[0]; + LW5 := LPS[1] xor LPI[1]; + LW10 := LPS[2] xor LPI[2]; + LW15 := LPS[3] xor LPI[3]; + LW4 := LPS[4] xor LPI[4]; + LW9 := LPS[5] xor LPI[5]; + LW14 := LPS[6] xor LPI[6]; + LW3 := LPS[7] xor LPI[7]; + LW8 := LPS[8] xor LPI[8]; + LW13 := LPS[9] xor LPI[9]; + LW2 := LPS[10] xor LPI[10]; + LW7 := LPS[11] xor LPI[11]; + LW12 := LPS[12] xor LPI[12]; + LW1 := LPS[13] xor LPI[13]; + LW6 := LPS[14] xor LPI[14]; + LW11 := LPS[15] xor LPI[15]; + + LPS[0] := LW0; + LPS[1] := LW5; + LPS[2] := LW10; + LPS[3] := LW15; + LPS[4] := LW4; + LPS[5] := LW9; + LPS[6] := LW14; + LPS[7] := LW3; + LPS[8] := LW8; + LPS[9] := LW13; + LPS[10] := LW2; + LPS[11] := LW7; + LPS[12] := LW12; + LPS[13] := LW1; + LPS[14] := LW6; + LPS[15] := LW11; + + LIdx := 4; + while LIdx > 0 do + begin + LW4 := LW4 xor TBitOperations.RotateLeft32(LW0 + LW12, 7); + LW8 := LW8 xor TBitOperations.RotateLeft32(LW4 + LW0, 9); + LW12 := LW12 xor TBitOperations.RotateLeft32(LW8 + LW4, 13); + LW0 := LW0 xor TBitOperations.RotateLeft32(LW12 + LW8, 18); + LW9 := LW9 xor TBitOperations.RotateLeft32(LW5 + LW1, 7); + LW13 := LW13 xor TBitOperations.RotateLeft32(LW9 + LW5, 9); + LW1 := LW1 xor TBitOperations.RotateLeft32(LW13 + LW9, 13); + LW5 := LW5 xor TBitOperations.RotateLeft32(LW1 + LW13, 18); + LW14 := LW14 xor TBitOperations.RotateLeft32(LW10 + LW6, 7); + LW2 := LW2 xor TBitOperations.RotateLeft32(LW14 + LW10, 9); + LW6 := LW6 xor TBitOperations.RotateLeft32(LW2 + LW14, 13); + LW10 := LW10 xor TBitOperations.RotateLeft32(LW6 + LW2, 18); + LW3 := LW3 xor TBitOperations.RotateLeft32(LW15 + LW11, 7); + LW7 := LW7 xor TBitOperations.RotateLeft32(LW3 + LW15, 9); + LW11 := LW11 xor TBitOperations.RotateLeft32(LW7 + LW3, 13); + LW15 := LW15 xor TBitOperations.RotateLeft32(LW11 + LW7, 18); + + LW1 := LW1 xor TBitOperations.RotateLeft32(LW0 + LW3, 7); + LW2 := LW2 xor TBitOperations.RotateLeft32(LW1 + LW0, 9); + LW3 := LW3 xor TBitOperations.RotateLeft32(LW2 + LW1, 13); + LW0 := LW0 xor TBitOperations.RotateLeft32(LW3 + LW2, 18); + LW6 := LW6 xor TBitOperations.RotateLeft32(LW5 + LW4, 7); + LW7 := LW7 xor TBitOperations.RotateLeft32(LW6 + LW5, 9); + LW4 := LW4 xor TBitOperations.RotateLeft32(LW7 + LW6, 13); + LW5 := LW5 xor TBitOperations.RotateLeft32(LW4 + LW7, 18); + LW11 := LW11 xor TBitOperations.RotateLeft32(LW10 + LW9, 7); + LW8 := LW8 xor TBitOperations.RotateLeft32(LW11 + LW10, 9); + LW9 := LW9 xor TBitOperations.RotateLeft32(LW8 + LW11, 13); + LW10 := LW10 xor TBitOperations.RotateLeft32(LW9 + LW8, 18); + LW12 := LW12 xor TBitOperations.RotateLeft32(LW15 + LW14, 7); + LW13 := LW13 xor TBitOperations.RotateLeft32(LW12 + LW15, 9); + LW14 := LW14 xor TBitOperations.RotateLeft32(LW13 + LW12, 13); + LW15 := LW15 xor TBitOperations.RotateLeft32(LW14 + LW13, 18); + + System.Dec(LIdx); + end; + + LPS[0] := LPS[0] + LW0; + LPS[1] := LPS[1] + LW5; + LPS[2] := LPS[2] + LW10; + LPS[3] := LPS[3] + LW15; + LPS[4] := LPS[4] + LW4; + LPS[5] := LPS[5] + LW9; + LPS[6] := LPS[6] + LW14; + LPS[7] := LPS[7] + LW3; + LPS[8] := LPS[8] + LW8; + LPS[9] := LPS[9] + LW13; + LPS[10] := LPS[10] + LW2; + LPS[11] := LPS[11] + LW7; + LPS[12] := LPS[12] + LW12; + LPS[13] := LPS[13] + LW1; + LPS[14] := LPS[14] + LW6; + LPS[15] := LPS[15] + LW11; +end; + { TPBKDF_ScryptNotBuildInAdapter } class function TPBKDF_ScryptNotBuildInAdapter.IsPowerOf2(AValue: Int32): Boolean; @@ -346,4 +505,7 @@ function TPBKDF_ScryptNotBuildInAdapter.GetBytes(AByteCount: Int32) AByteCount); end; +initialization + Scrypt_SalsaXor := TScryptSimd.Select(@Scrypt_SalsaXor_Scalar); + end. diff --git a/HashLib/src/KDF/HlpScryptDispatch.pas b/HashLib/src/KDF/HlpScryptDispatch.pas deleted file mode 100644 index 8d0450c..0000000 --- a/HashLib/src/KDF/HlpScryptDispatch.pas +++ /dev/null @@ -1,264 +0,0 @@ -unit HlpScryptDispatch; - -{$I ..\Include\HashLib.inc} - -interface - -type - TScryptSalsaXorProc = procedure(AState, AInput: Pointer); - -var - Scrypt_SalsaXor: TScryptSalsaXorProc; - -procedure Scrypt_Permute(ABlock: PCardinal; AChunkCount: Int32); -procedure Scrypt_Unpermute(ABlock: PCardinal; AChunkCount: Int32); - -implementation - -uses - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Percival's (i*5 mod 16) permutation rearranges each 16-word Salsa20 state -// from natural order into role-based diagonal order so that column and row -// quarter-rounds map to lane-parallel SIMD operations. Applied once at -// SMixLane entry/exit; all intermediate data stays in permuted order. -// Reference: Colin Percival, crypto_scrypt-sse.c (Tarsnap). -// ============================================================================= - -procedure Scrypt_Permute(ABlock: PCardinal; AChunkCount: Int32); -var - LTemp: array[0..15] of UInt32; - LIdx: Int32; -begin - while AChunkCount > 0 do - begin - for LIdx := 0 to 15 do - LTemp[LIdx] := ABlock[(LIdx * 5) and 15]; - System.Move(LTemp, ABlock^, 64); - Inc(ABlock, 16); - Dec(AChunkCount); - end; -end; - -procedure Scrypt_Unpermute(ABlock: PCardinal; AChunkCount: Int32); -var - LTemp: array[0..15] of UInt32; - LIdx: Int32; -begin - while AChunkCount > 0 do - begin - for LIdx := 0 to 15 do - LTemp[LIdx] := ABlock[(LIdx * 13) and 15]; - System.Move(LTemp, ABlock^, 64); - Inc(ABlock, 16); - Dec(AChunkCount); - end; -end; - -// ============================================================================= -// Scalar fallback: fused XOR + Salsa20/8 on Percival-permuted data. -// Loads from permuted positions into natural-named locals, performs standard -// Salsa20/8 column+row rounds, stores back to permuted positions. -// ============================================================================= - -procedure Scrypt_SalsaXor_Scalar(AState, AInput: Pointer); -var - LW0, LW1, LW2, LW3, LW4, LW5, LW6, LW7, - LW8, LW9, LW10, LW11, LW12, LW13, LW14, LW15: UInt32; - LPS, LPI: PCardinal; - LIdx: Int32; -begin - LPS := PCardinal(AState); - LPI := PCardinal(AInput); - - // Permuted layout: {w0,w5,w10,w15, w4,w9,w14,w3, w8,w13,w2,w7, w12,w1,w6,w11} - LW0 := LPS[0] xor LPI[0]; - LW5 := LPS[1] xor LPI[1]; - LW10 := LPS[2] xor LPI[2]; - LW15 := LPS[3] xor LPI[3]; - LW4 := LPS[4] xor LPI[4]; - LW9 := LPS[5] xor LPI[5]; - LW14 := LPS[6] xor LPI[6]; - LW3 := LPS[7] xor LPI[7]; - LW8 := LPS[8] xor LPI[8]; - LW13 := LPS[9] xor LPI[9]; - LW2 := LPS[10] xor LPI[10]; - LW7 := LPS[11] xor LPI[11]; - LW12 := LPS[12] xor LPI[12]; - LW1 := LPS[13] xor LPI[13]; - LW6 := LPS[14] xor LPI[14]; - LW11 := LPS[15] xor LPI[15]; - - LPS[0] := LW0; - LPS[1] := LW5; - LPS[2] := LW10; - LPS[3] := LW15; - LPS[4] := LW4; - LPS[5] := LW9; - LPS[6] := LW14; - LPS[7] := LW3; - LPS[8] := LW8; - LPS[9] := LW13; - LPS[10] := LW2; - LPS[11] := LW7; - LPS[12] := LW12; - LPS[13] := LW1; - LPS[14] := LW6; - LPS[15] := LW11; - - LIdx := 4; - while LIdx > 0 do - begin - LW4 := LW4 xor TBitOperations.RotateLeft32(LW0 + LW12, 7); - LW8 := LW8 xor TBitOperations.RotateLeft32(LW4 + LW0, 9); - LW12 := LW12 xor TBitOperations.RotateLeft32(LW8 + LW4, 13); - LW0 := LW0 xor TBitOperations.RotateLeft32(LW12 + LW8, 18); - LW9 := LW9 xor TBitOperations.RotateLeft32(LW5 + LW1, 7); - LW13 := LW13 xor TBitOperations.RotateLeft32(LW9 + LW5, 9); - LW1 := LW1 xor TBitOperations.RotateLeft32(LW13 + LW9, 13); - LW5 := LW5 xor TBitOperations.RotateLeft32(LW1 + LW13, 18); - LW14 := LW14 xor TBitOperations.RotateLeft32(LW10 + LW6, 7); - LW2 := LW2 xor TBitOperations.RotateLeft32(LW14 + LW10, 9); - LW6 := LW6 xor TBitOperations.RotateLeft32(LW2 + LW14, 13); - LW10 := LW10 xor TBitOperations.RotateLeft32(LW6 + LW2, 18); - LW3 := LW3 xor TBitOperations.RotateLeft32(LW15 + LW11, 7); - LW7 := LW7 xor TBitOperations.RotateLeft32(LW3 + LW15, 9); - LW11 := LW11 xor TBitOperations.RotateLeft32(LW7 + LW3, 13); - LW15 := LW15 xor TBitOperations.RotateLeft32(LW11 + LW7, 18); - - LW1 := LW1 xor TBitOperations.RotateLeft32(LW0 + LW3, 7); - LW2 := LW2 xor TBitOperations.RotateLeft32(LW1 + LW0, 9); - LW3 := LW3 xor TBitOperations.RotateLeft32(LW2 + LW1, 13); - LW0 := LW0 xor TBitOperations.RotateLeft32(LW3 + LW2, 18); - LW6 := LW6 xor TBitOperations.RotateLeft32(LW5 + LW4, 7); - LW7 := LW7 xor TBitOperations.RotateLeft32(LW6 + LW5, 9); - LW4 := LW4 xor TBitOperations.RotateLeft32(LW7 + LW6, 13); - LW5 := LW5 xor TBitOperations.RotateLeft32(LW4 + LW7, 18); - LW11 := LW11 xor TBitOperations.RotateLeft32(LW10 + LW9, 7); - LW8 := LW8 xor TBitOperations.RotateLeft32(LW11 + LW10, 9); - LW9 := LW9 xor TBitOperations.RotateLeft32(LW8 + LW11, 13); - LW10 := LW10 xor TBitOperations.RotateLeft32(LW9 + LW8, 18); - LW12 := LW12 xor TBitOperations.RotateLeft32(LW15 + LW14, 7); - LW13 := LW13 xor TBitOperations.RotateLeft32(LW12 + LW15, 9); - LW14 := LW14 xor TBitOperations.RotateLeft32(LW13 + LW12, 13); - LW15 := LW15 xor TBitOperations.RotateLeft32(LW14 + LW13, 18); - - System.Dec(LIdx); - end; - - LPS[0] := LPS[0] + LW0; - LPS[1] := LPS[1] + LW5; - LPS[2] := LPS[2] + LW10; - LPS[3] := LPS[3] + LW15; - LPS[4] := LPS[4] + LW4; - LPS[5] := LPS[5] + LW9; - LPS[6] := LPS[6] + LW14; - LPS[7] := LPS[7] + LW3; - LPS[8] := LPS[8] + LW8; - LPS[9] := LPS[9] + LW13; - LPS[10] := LPS[10] + LW2; - LPS[11] := LPS[11] + LW7; - LPS[12] := LPS[12] + LW12; - LPS[13] := LPS[13] + LW1; - LPS[14] := LPS[14] + LW6; - LPS[15] := LPS[15] + LW11; -end; - -// ============================================================================= -// SIMD implementations -// -// i386: SSE2 -// x86_64: AVX2, SSE2 -// aarch64: NEON (not registered) -// ============================================================================= - -{$IFDEF HASHLIB_I386_ASM} - -procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\Include\Simd\Scrypt\ScryptSalsa8Sse2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -{$IFDEF HASHLIB_X86_64_ASM} - -procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\Include\Simd\Scrypt\ScryptSalsa8Sse2_x86_64.inc} -end; - -procedure Scrypt_SalsaXor_Avx2(AState, AInput: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\Include\Simd\Scrypt\ScryptSalsa8Avx2_x86_64.inc} -end; - -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure Scrypt_SalsaXor_Neon(AState, AInput: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} - {$I ..\Include\Simd\Scrypt\ScryptSalsa8Neon_aarch64.inc} -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - Scrypt_SalsaXor := @Scrypt_SalsaXor_Scalar; -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - begin - Scrypt_SalsaXor := @Scrypt_SalsaXor_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: - begin - Scrypt_SalsaXor := @Scrypt_SalsaXor_Avx2; - end; - TX86SimdLevel.SSE2: - begin - Scrypt_SalsaXor := @Scrypt_SalsaXor_Sse2; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - // NEON intentionally NOT registered for scrypt: the scalar path is faster on - // AArch64. scrypt's Salsa20/8 is a single 64-byte block with a strictly serial - // dependency chain (BlockMix feeds each Salsa call from the previous one, and - // SMix is sequential by design), so there is no block-level parallelism for - // SIMD lanes to exploit at p=1. Meanwhile AArch64's 31 general-purpose - // registers let the scalar kernel hold the whole 16-word state with no spills - // and rotate via a single-cycle 'ror', whereas NEON adds a lane-shuffle (ext) - // tax and a 2-instruction (shl+sri) rotate. Benchmarks (Apple Silicon, FPC - // 3.2.2) confirm scalar wins at every N (e.g. N=16384: ~39 ms scalar vs - // ~56 ms NEON). This mirrors OpenSSL/libsodium/Tarsnap, which ship an x86 SSE2 - // scrypt (to relieve x86's 16-register pressure) but no NEON variant. The - // Scrypt_SalsaXor_Neon kernel is kept (verified, correct) for reference and in - // case a future p>1 / multi-block batched path makes SIMD worthwhile. - // - // case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of - // TArmSimdLevel.NEON: - // begin - // Scrypt_SalsaXor := @Scrypt_SalsaXor_Neon; - // end; - // end; -{$ENDIF} -end; - -initialization - InitDispatch(); - -end. diff --git a/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk b/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk index 535d6c4..8e8ced0 100644 --- a/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk +++ b/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk @@ -46,9 +46,14 @@ contains HlpHMACNotBuildInAdapter in '..\..\Base\HlpHMACNotBuildInAdapter.pas', HlpMultipleTransformNonBlock in '..\..\Base\HlpMultipleTransformNonBlock.pas', HlpAdler32 in '..\..\Checksum\HlpAdler32.pas', - HlpAdler32Dispatch in '..\..\Checksum\HlpAdler32Dispatch.pas', + HlpAdler32Simd in '..\..\Simd\Facade\HlpAdler32Simd.pas', + HlpAdler32X86Backend in '..\..\Simd\Backend\HlpAdler32X86Backend.pas', + HlpAdler32ArmBackend in '..\..\Simd\Backend\HlpAdler32ArmBackend.pas', HlpCRC in '..\..\Checksum\HlpCRC.pas', - HlpCRCDispatch in '..\..\Checksum\HlpCRCDispatch.pas', + HlpCRCCore in '..\..\Checksum\HlpCRCCore.pas', + HlpCRCSimd in '..\..\Simd\Facade\HlpCRCSimd.pas', + HlpCRCX86Backend in '..\..\Simd\Backend\HlpCRCX86Backend.pas', + HlpCRCArmBackend in '..\..\Simd\Backend\HlpCRCArmBackend.pas', HlpCRCFoldConstants in '..\..\Checksum\HlpCRCFoldConstants.pas', HlpCRCStandard in '..\..\Checksum\HlpCRCStandard.pas', HlpCRC32Fast in '..\..\Checksum\HlpCRC32Fast.pas', @@ -71,27 +76,39 @@ contains HlpRIPEMD320 in '..\..\Crypto\HlpRIPEMD320.pas', HlpSHA0 in '..\..\Crypto\HlpSHA0.pas', HlpSHA1 in '..\..\Crypto\HlpSHA1.pas', - HlpSHA1Dispatch in '..\..\Crypto\HlpSHA1Dispatch.pas', + HlpSHA1Simd in '..\..\Simd\Facade\HlpSHA1Simd.pas', + HlpSHA1X86Backend in '..\..\Simd\Backend\HlpSHA1X86Backend.pas', + HlpSHA1ArmBackend in '..\..\Simd\Backend\HlpSHA1ArmBackend.pas', HlpSHA2_224 in '..\..\Crypto\HlpSHA2_224.pas', HlpSHA2_256 in '..\..\Crypto\HlpSHA2_256.pas', - HlpSHA2_256Dispatch in '..\..\Crypto\HlpSHA2_256Dispatch.pas', - HlpSHA2_512Dispatch in '..\..\Crypto\HlpSHA2_512Dispatch.pas', + HlpSHA2_256Simd in '..\..\Simd\Facade\HlpSHA2_256Simd.pas', + HlpSHA2_256X86Backend in '..\..\Simd\Backend\HlpSHA2_256X86Backend.pas', + HlpSHA2_256ArmBackend in '..\..\Simd\Backend\HlpSHA2_256ArmBackend.pas', + HlpSHA2_512Simd in '..\..\Simd\Facade\HlpSHA2_512Simd.pas', + HlpSHA2_512X86Backend in '..\..\Simd\Backend\HlpSHA2_512X86Backend.pas', + HlpSHA2_512ArmBackend in '..\..\Simd\Backend\HlpSHA2_512ArmBackend.pas', HlpSHA2_256Base in '..\..\Crypto\HlpSHA2_256Base.pas', HlpSHA2_384 in '..\..\Crypto\HlpSHA2_384.pas', HlpSHA2_512 in '..\..\Crypto\HlpSHA2_512.pas', HlpSHA2_512_224 in '..\..\Crypto\HlpSHA2_512_224.pas', HlpSHA2_512_256 in '..\..\Crypto\HlpSHA2_512_256.pas', HlpSHA2_512Base in '..\..\Crypto\HlpSHA2_512Base.pas', - HlpSHA3Dispatch in '..\..\Crypto\HlpSHA3Dispatch.pas', + HlpSHA3Simd in '..\..\Simd\Facade\HlpSHA3Simd.pas', + HlpSHA3X86Backend in '..\..\Simd\Backend\HlpSHA3X86Backend.pas', + HlpSHA3ArmBackend in '..\..\Simd\Backend\HlpSHA3ArmBackend.pas', HlpSHA3 in '..\..\Crypto\HlpSHA3.pas', HlpSnefru in '..\..\Crypto\HlpSnefru.pas', HlpTiger in '..\..\Crypto\HlpTiger.pas', HlpTiger2 in '..\..\Crypto\HlpTiger2.pas', HlpWhirlPool in '..\..\Crypto\HlpWhirlPool.pas', HlpGOST3411_2012 in '..\..\Crypto\HlpGOST3411_2012.pas', - HlpBlake2BDispatch in '..\..\Crypto\HlpBlake2BDispatch.pas', + HlpBlake2BSimd in '..\..\Simd\Facade\HlpBlake2BSimd.pas', + HlpBlake2BX86Backend in '..\..\Simd\Backend\HlpBlake2BX86Backend.pas', + HlpBlake2BArmBackend in '..\..\Simd\Backend\HlpBlake2BArmBackend.pas', HlpBlake2B in '..\..\Crypto\HlpBlake2B.pas', - HlpBlake2SDispatch in '..\..\Crypto\HlpBlake2SDispatch.pas', + HlpBlake2SSimd in '..\..\Simd\Facade\HlpBlake2SSimd.pas', + HlpBlake2SX86Backend in '..\..\Simd\Backend\HlpBlake2SX86Backend.pas', + HlpBlake2SArmBackend in '..\..\Simd\Backend\HlpBlake2SArmBackend.pas', HlpBlake2S in '..\..\Crypto\HlpBlake2S.pas', HlpBlake2BParams in '..\..\Crypto\Blake2BParams\HlpBlake2BParams.pas', HlpBlake2SParams in '..\..\Crypto\Blake2SParams\HlpBlake2SParams.pas', @@ -122,7 +139,9 @@ contains HlpMurmur2_64 in '..\..\Hash64\HlpMurmur2_64.pas', HlpSipHash in '..\..\Hash64\HlpSipHash.pas', HlpXXHash64 in '..\..\Hash64\HlpXXHash64.pas', - HlpXXHash3Dispatch in '..\..\Hash64\HlpXXHash3Dispatch.pas', + HlpXXHash3Simd in '..\..\Simd\Facade\HlpXXHash3Simd.pas', + HlpXXHash3X86Backend in '..\..\Simd\Backend\HlpXXHash3X86Backend.pas', + HlpXXHash3ArmBackend in '..\..\Simd\Backend\HlpXXHash3ArmBackend.pas', HlpXXHash3 in '..\..\Hash64\HlpXXHash3.pas', HlpMurmurHash3_x86_128 in '..\..\Hash128\HlpMurmurHash3_x86_128.pas', HlpMurmurHash3_x64_128 in '..\..\Hash128\HlpMurmurHash3_x64_128.pas', @@ -137,14 +156,20 @@ contains HlpIBlake2SParams in '..\..\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas', HlpBlake2BP in '..\..\Crypto\HlpBlake2BP.pas', HlpBlake2SP in '..\..\Crypto\HlpBlake2SP.pas', - HlpBlake3Dispatch in '..\..\Crypto\HlpBlake3Dispatch.pas', + HlpBlake3Simd in '..\..\Simd\Facade\HlpBlake3Simd.pas', + HlpBlake3X86Backend in '..\..\Simd\Backend\HlpBlake3X86Backend.pas', + HlpBlake3ArmBackend in '..\..\Simd\Backend\HlpBlake3ArmBackend.pas', HlpBlake3 in '..\..\Crypto\HlpBlake3.pas', HlpPBKDF2_HMACNotBuildInAdapter in '..\..\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas', HlpPBKDF_Argon2NotBuildInAdapter in '..\..\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas', - HlpArgon2Dispatch in '..\..\KDF\HlpArgon2Dispatch.pas', + HlpArgon2Simd in '..\..\Simd\Facade\HlpArgon2Simd.pas', + HlpArgon2X86Backend in '..\..\Simd\Backend\HlpArgon2X86Backend.pas', + HlpArgon2ArmBackend in '..\..\Simd\Backend\HlpArgon2ArmBackend.pas', HlpArgon2TypeAndVersion in '..\..\KDF\HlpArgon2TypeAndVersion.pas', HlpPBKDF_ScryptNotBuildInAdapter in '..\..\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas', - HlpScryptDispatch in '..\..\KDF\HlpScryptDispatch.pas', + HlpScryptSimd in '..\..\Simd\Facade\HlpScryptSimd.pas', + HlpScryptX86Backend in '..\..\Simd\Backend\HlpScryptX86Backend.pas', + HlpScryptArmBackend in '..\..\Simd\Backend\HlpScryptArmBackend.pas', HlpConverters in '..\..\Utils\HlpConverters.pas', HlpBitOperations in '..\..\Utils\HlpBitOperations.pas', HlpBinaryPrimitives in '..\..\Utils\HlpBinaryPrimitives.pas', diff --git a/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk b/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk index d3300a5..8196cf8 100644 --- a/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk +++ b/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk @@ -10,7 +10,7 @@ - + @@ -29,7 +29,7 @@ "/> - + @@ -451,56 +451,56 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -522,6 +522,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas b/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas index 08e2ee3..a54137f 100644 --- a/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas +++ b/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas @@ -10,31 +10,38 @@ interface uses HlpHash, HlpHashBuffer, HlpHashCryptoNotBuildIn, HlpHashFactory, HlpHashResult, HlpHashRounds, HlpHashSize, HlpHMACNotBuildInAdapter, - HlpMultipleTransformNonBlock, HlpAdler32, HlpCRC, HlpCRCStandard, - HlpGost, HlpGrindahl256, HlpGrindahl512, HlpHAS160, HlpHaval, - HlpMD2, HlpMD4, HlpMD5, HlpMDBase, HlpPanama, HlpRadioGatun32, - HlpRadioGatun64, HlpRIPEMD, HlpRIPEMD128, HlpRIPEMD160, HlpRIPEMD256, - HlpRIPEMD320, HlpSHA0, HlpSHA1, HlpSHA2_224, HlpSHA2_256, HlpSHA2_256Base, - HlpSHA2_384, HlpSHA2_512, HlpSHA2_512Base, HlpSHA2_512_224, HlpSHA2_512_256, - HlpSHA3, HlpSnefru, HlpTiger, HlpTiger2, HlpWhirlPool, - HlpMurmurHash3_x64_128, HlpNullDigest, HlpAP, HlpBernstein, HlpBernstein1, - HlpBKDR, HlpDEK, HlpDJB, HlpELF, HlpFNV, HlpFNV1a, HlpJenkins3, HlpJS, - HlpMurmur2, HlpMurmurHash3_x86_32, HlpOneAtTime, HlpPJW, HlpRotating, HlpRS, - HlpSDBM, HlpShiftAndXor, HlpSuperFast, HlpXXHash32, HlpFNV1a64, HlpFNV64, - HlpMurmur2_64, HlpSipHash, HlpXXHash64, HlpIHash, HlpIHashInfo, - HlpIHashResult, HlpConverters, HlpBitOperations, HlpBinaryPrimitives, HlpHashLibTypes, + HlpMultipleTransformNonBlock, HlpAdler32, HlpCRC, HlpCRCStandard, HlpGost, + HlpGrindahl256, HlpGrindahl512, HlpHAS160, HlpHaval, HlpMD2, HlpMD4, HlpMD5, + HlpMDBase, HlpPanama, HlpRadioGatun32, HlpRadioGatun64, HlpRIPEMD, + HlpRIPEMD128, HlpRIPEMD160, HlpRIPEMD256, HlpRIPEMD320, HlpSHA0, HlpSHA1, + HlpSHA2_224, HlpSHA2_256, HlpSHA2_256Base, HlpSHA2_384, HlpSHA2_512, + HlpSHA2_512Base, HlpSHA2_512_224, HlpSHA2_512_256, HlpSHA3, HlpSnefru, + HlpTiger, HlpTiger2, HlpWhirlPool, HlpMurmurHash3_x64_128, HlpNullDigest, + HlpAP, HlpBernstein, HlpBernstein1, HlpBKDR, HlpDEK, HlpDJB, HlpELF, HlpFNV, + HlpFNV1a, HlpJenkins3, HlpJS, HlpMurmur2, HlpMurmurHash3_x86_32, + HlpOneAtTime, HlpPJW, HlpRotating, HlpRS, HlpSDBM, HlpShiftAndXor, + HlpSuperFast, HlpXXHash32, HlpFNV1a64, HlpFNV64, HlpMurmur2_64, HlpSipHash, + HlpXXHash64, HlpIHash, HlpIHashInfo, HlpIHashResult, HlpConverters, + HlpBitOperations, HlpBinaryPrimitives, HlpHashLibTypes, HlpMurmurHash3_x86_128, HlpPBKDF2_HMACNotBuildInAdapter, HlpIKDF, HlpKDF, HlpICRC, HlpBlake2B, HlpBlake2S, HlpGOST3411_2012, HlpCRC32Fast, HlpArgon2TypeAndVersion, HlpPBKDF_Argon2NotBuildInAdapter, HlpPBKDF_ScryptNotBuildInAdapter, HlpArrayUtils, HlpBlake2BP, HlpBlake2SP, HlpSipHash128, HlpBlake2SParams, HlpBlake2BParams, HlpIBlake2SParams, HlpIBlake2BParams, HlpBlake3, HlpXXHash3, HlpXXHash128, HlpCpuFeatures, - HlpXXHash3Dispatch, HlpBlake2BDispatch, HlpBlake2SDispatch, - HlpArgon2Dispatch, HlpScryptDispatch, HlpBlake3Dispatch, - HlpSHA2_256Dispatch, HlpSHA2_512Dispatch, HlpSHA1Dispatch, - HlpAdler32Dispatch, HlpCRCFoldConstants, HlpCRCDispatch, HlpSHA3Dispatch, + HlpXXHash3Simd, HlpBlake2BSimd, HlpBlake2SSimd, HlpArgon2Simd, + HlpScryptSimd, HlpBlake3Simd, HlpSHA2_256Simd, HlpSHA2_512Simd, HlpSHA1Simd, + HlpAdler32Simd, HlpCRCFoldConstants, HlpCRCCore, HlpSHA3Simd, HlpArmSimdFeatures, HlpSimdLevels, HlpX86SimdFeatures, HlpArmHwCapProvider, - HlpDarwinSysCtl; + HlpDarwinSysCtl, HlpSHA2_256X86Backend, HlpSHA2_256ArmBackend, + HlpSHA1X86Backend, HlpSHA1ArmBackend, HlpSHA2_512X86Backend, + HlpSHA2_512ArmBackend, HlpSHA3X86Backend, HlpSHA3ArmBackend, + HlpBlake2BX86Backend, HlpBlake2BArmBackend, HlpBlake2SX86Backend, + HlpBlake2SArmBackend, HlpBlake3X86Backend, HlpBlake3ArmBackend, + HlpXXHash3X86Backend, HlpXXHash3ArmBackend, HlpAdler32X86Backend, + HlpAdler32ArmBackend, HlpArgon2X86Backend, HlpArgon2ArmBackend, + HlpScryptX86Backend, HlpScryptArmBackend, HlpCRCSimd, HlpCRCX86Backend, + HlpCRCArmBackend; implementation diff --git a/HashLib/src/Simd/Backend/HlpAdler32ArmBackend.pas b/HashLib/src/Simd/Backend/HlpAdler32ArmBackend.pas new file mode 100644 index 0000000..67f8012 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpAdler32ArmBackend.pas @@ -0,0 +1,60 @@ +unit HlpAdler32ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpAdler32; + +type + /// + /// Arm SIMD backend for Adler-32: owns the AArch64 NEON block-processing kernel + /// (body in Include\Simd\Adler32\) and the runtime tier selection via + /// TCpuFeatures.Arm. Compiles on every target - without Arm SIMD, + /// Select just returns the scalar routine. + /// + TAdler32ArmBackend = class sealed + public + class function Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// aarch64: NEON +// ============================================================================= + +procedure Adler32_ProcessBlocks_Neon(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksNeon_aarch64.inc} +end; + +procedure Adler32_Update_Neon(AData: PByte; ALength: UInt32; ASums: Pointer); +begin + Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Neon); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TAdler32ArmBackend } + +class function TAdler32ArmBackend.Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: Exit(@Adler32_Update_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas b/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas new file mode 100644 index 0000000..0c7e967 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas @@ -0,0 +1,116 @@ +unit HlpAdler32X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpAdler32; + +type + /// + /// x86 SIMD backend for Adler-32: owns the SSE2 / SSSE3 / AVX2 block-processing + /// kernels (bodies in Include\Simd\Adler32\) and the runtime tier + /// selection via TCpuFeatures.X86. The SSSE3 tier is kept (its + /// pmaddubsw is materially faster than the SSE2 emulation). Compiles on every + /// target - without x86 SIMD, Select just returns the scalar routine. + /// + TAdler32X86Backend = class sealed + public + class function Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2, SSSE3 +// x86_64: AVX2, SSSE3, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure Adler32_ProcessBlocks_Sse2(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksSse2_i386.inc} +end; + +procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Adler32_ProcessBlocks_Sse2(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksSse2_x86_64.inc} +end; + +procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_x86_64.inc} +end; + +procedure Adler32_ProcessBlocks_Avx2(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksAvx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +procedure Adler32_Update_Sse2(AData: PByte; ALength: UInt32; ASums: Pointer); +begin + Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Sse2); +end; + +procedure Adler32_Update_Ssse3(AData: PByte; ALength: UInt32; ASums: Pointer); +begin + Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Ssse3); +end; + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Adler32_Update_Avx2(AData: PByte; ALength: UInt32; ASums: Pointer); +begin + Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Avx2); +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TAdler32X86Backend } + +class function TAdler32X86Backend.Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSSE3: Exit(@Adler32_Update_Ssse3); + TX86SimdLevel.SSE2: Exit(@Adler32_Update_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@Adler32_Update_Avx2); + TX86SimdLevel.SSSE3: Exit(@Adler32_Update_Ssse3); + TX86SimdLevel.SSE2: Exit(@Adler32_Update_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpArgon2ArmBackend.pas b/HashLib/src/Simd/Backend/HlpArgon2ArmBackend.pas new file mode 100644 index 0000000..3b89e7f --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpArgon2ArmBackend.pas @@ -0,0 +1,54 @@ +unit HlpArgon2ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpPBKDF_Argon2NotBuildInAdapter; + +type + /// + /// Arm SIMD backend for Argon2's fill-block: owns the AArch64 NEON kernel (body + /// in Include\Simd\Argon2\) and the runtime tier selection via + /// TCpuFeatures.Arm. Compiles on every target - built without Arm SIMD, + /// Select just returns the scalar routine. + /// + TArgon2ArmBackend = class sealed + public + class function Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// aarch64: NEON +// ============================================================================= + +procedure Argon2_FillBlock_Neon(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\Argon2\Argon2FillBlockNeon_aarch64.inc} +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TArgon2ArmBackend } + +class function TArgon2ArmBackend.Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: Exit(@Argon2_FillBlock_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas new file mode 100644 index 0000000..53f3aa5 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas @@ -0,0 +1,79 @@ +unit HlpArgon2X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpPBKDF_Argon2NotBuildInAdapter; + +type + /// + /// x86 SIMD backend for Argon2's fill-block: owns the SSE2 / AVX2 kernels + /// (bodies in Include\Simd\Argon2\) and the runtime tier selection via + /// TCpuFeatures.X86. Compiles on every target - built without x86 SIMD, + /// Select just returns the scalar routine. + /// + TArgon2X86Backend = class sealed + public + class function Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_x86_64.inc} +end; + +procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TArgon2X86Backend } + +class function TArgon2X86Backend.Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: Exit(@Argon2_FillBlock_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@Argon2_FillBlock_Avx2); + TX86SimdLevel.SSE2: Exit(@Argon2_FillBlock_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpBlake2BArmBackend.pas b/HashLib/src/Simd/Backend/HlpBlake2BArmBackend.pas new file mode 100644 index 0000000..9b66759 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpBlake2BArmBackend.pas @@ -0,0 +1,55 @@ +unit HlpBlake2BArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake2B; + +type + /// + /// Arm SIMD backend for Blake2B: owns the AArch64 NEON compression kernel + /// (body in Include\Simd\Blake2B\) and the runtime tier selection via + /// TCpuFeatures.Arm. Compiles on every target - built without Arm SIMD, + /// Select just returns the scalar routine. + /// + TBlake2BArmBackend = class sealed + public + class function Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// aarch64: NEON +// ============================================================================= + +procedure Blake2B_Compress_Neon(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressNeon_aarch64.inc} +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TBlake2BArmBackend } + +class function TBlake2BArmBackend.Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@Blake2B_Compress_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas new file mode 100644 index 0000000..3356856 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas @@ -0,0 +1,82 @@ +unit HlpBlake2BX86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake2B; + +type + /// + /// x86 SIMD backend for Blake2B: owns the SSE2 / AVX2 compression kernels + /// (bodies in Include\Simd\Blake2B\) and the runtime tier selection via + /// TCpuFeatures.X86. Compiles on every target - built without x86 SIMD, + /// Select just returns the scalar routine. + /// + TBlake2BX86Backend = class sealed + public + class function Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_x86_64.inc} +end; + +procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TBlake2BX86Backend } + +class function TBlake2BX86Backend.Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@Blake2B_Compress_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Blake2B_Compress_Avx2); + TX86SimdLevel.SSE2: + Exit(@Blake2B_Compress_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpBlake2SArmBackend.pas b/HashLib/src/Simd/Backend/HlpBlake2SArmBackend.pas new file mode 100644 index 0000000..706cc77 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpBlake2SArmBackend.pas @@ -0,0 +1,55 @@ +unit HlpBlake2SArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake2S; + +type + /// + /// Arm SIMD backend for Blake2S: owns the AArch64 NEON compression kernel + /// (body in Include\Simd\Blake2S\) and the runtime tier selection via + /// TCpuFeatures.Arm. Compiles on every target - built without Arm SIMD, + /// Select just returns the scalar routine. + /// + TBlake2SArmBackend = class sealed + public + class function Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// aarch64: NEON +// ============================================================================= + +procedure Blake2S_Compress_Neon(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressNeon_aarch64.inc} +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TBlake2SArmBackend } + +class function TBlake2SArmBackend.Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@Blake2S_Compress_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas new file mode 100644 index 0000000..0abf8c9 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas @@ -0,0 +1,82 @@ +unit HlpBlake2SX86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake2S; + +type + /// + /// x86 SIMD backend for Blake2S: owns the SSE2 / AVX2 compression kernels + /// (bodies in Include\Simd\Blake2S\) and the runtime tier selection via + /// TCpuFeatures.X86. Compiles on every target - built without x86 SIMD, + /// Select just returns the scalar routine. + /// + TBlake2SX86Backend = class sealed + public + class function Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_x86_64.inc} +end; + +procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TBlake2SX86Backend } + +class function TBlake2SX86Backend.Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@Blake2S_Compress_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Blake2S_Compress_Avx2); + TX86SimdLevel.SSE2: + Exit(@Blake2S_Compress_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpBlake3ArmBackend.pas b/HashLib/src/Simd/Backend/HlpBlake3ArmBackend.pas new file mode 100644 index 0000000..bf91bd5 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpBlake3ArmBackend.pas @@ -0,0 +1,107 @@ +unit HlpBlake3ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake3; + +type + /// + /// Arm SIMD backend for Blake3: owns the AArch64 NEON compression and 4-way + /// hash-many kernels (bodies in Include\Simd\Blake3\) and the runtime + /// tier selection via TCpuFeatures.Arm. The hash-many wrapper processes + /// full 4-way groups in asm and delegates the remainder to the scalar + /// hash-many. Compiles on every target - without Arm SIMD the selectors return + /// the scalar routines / degree 1. + /// + TBlake3ArmBackend = class sealed + public + class function SelectCompress(AScalar: TBlake3CompressProc): TBlake3CompressProc; static; + class function SelectHashMany(AScalar: TBlake3HashManyProc): TBlake3HashManyProc; static; + class function SelectParallelDegree(ADefault: Int32): Int32; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// aarch64: NEON +// ============================================================================= + +procedure Blake3_Compress_Neon(AState, AMsg, ACV, ACounterFlags: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3CompressNeon_aarch64.inc} +end; + +procedure Blake3_Hash4_Neon(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); + {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_aarch64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3Hash4Neon_aarch64.inc} +end; + +// NEON hash_many: hash4 -> delegate remainder to scalar hash_many +procedure Blake3_HashMany_Neon(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); +var + LPInput, LPOut: PByte; +begin + LPInput := PByte(AInput); + LPOut := PByte(AOut); + while ANumChunks >= 4 do + begin + Blake3_Hash4_Neon(LPInput, AKey, LPOut, 4, ACounter, AFlags); + System.Inc(LPInput, 4 * 1024); + System.Inc(LPOut, 4 * 32); + System.Inc(ACounter, 4); + System.Dec(ANumChunks, 4); + end; + if ANumChunks > 0 then + Blake3_HashMany_Scalar(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TBlake3ArmBackend } + +class function TBlake3ArmBackend.SelectCompress(AScalar: TBlake3CompressProc): TBlake3CompressProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@Blake3_Compress_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TBlake3ArmBackend.SelectHashMany(AScalar: TBlake3HashManyProc): TBlake3HashManyProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@Blake3_HashMany_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TBlake3ArmBackend.SelectParallelDegree(ADefault: Int32): Int32; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(4); + end; +{$ENDIF} + Result := ADefault; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas new file mode 100644 index 0000000..575b368 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas @@ -0,0 +1,186 @@ +unit HlpBlake3X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake3; + +type + /// + /// x86 SIMD backend for Blake3: owns the SSE2 / AVX2 compression and 4-/8-way + /// hash-many kernels (bodies in Include\Simd\Blake3\) and the runtime + /// tier selection via TCpuFeatures.X86. The hash-many wrappers process + /// full parallel groups in asm and delegate the remainder to the scalar + /// hash-many. Compiles on every target - without x86 SIMD the selectors return + /// the scalar routines / degree 1. + /// + TBlake3X86Backend = class sealed + public + class function SelectCompress(AScalar: TBlake3CompressProc): TBlake3CompressProc; static; + class function SelectHashMany(AScalar: TBlake3HashManyProc): TBlake3HashManyProc; static; + class function SelectParallelDegree(ADefault: Int32): Int32; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_i386.inc} +end; + +procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); + {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_i386.inc} + {$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_x86_64.inc} +end; + +procedure Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3CompressAvx2_x86_64.inc} +end; + +procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); + {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_x86_64.inc} +end; + +procedure Blake3_Hash8_Avx2(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); + {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3Hash8Avx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +// SSE2 hash_many: hash4 -> delegate remainder to scalar hash_many +procedure Blake3_HashMany_Sse2(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); +var + LPInput, LPOut: PByte; +begin + LPInput := PByte(AInput); + LPOut := PByte(AOut); + while ANumChunks >= 4 do + begin + Blake3_Hash4_Sse2(LPInput, AKey, LPOut, 4, ACounter, AFlags); + System.Inc(LPInput, 4 * 1024); + System.Inc(LPOut, 4 * 32); + System.Inc(ACounter, 4); + System.Dec(ANumChunks, 4); + end; + if ANumChunks > 0 then + Blake3_HashMany_Scalar(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); +end; + +{$IFDEF HASHLIB_X86_64_ASM} + +// AVX2 hash_many: hash8 -> delegate remainder to SSE2 hash_many +procedure Blake3_HashMany_Avx2(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); +var + LPInput, LPOut: PByte; +begin + LPInput := PByte(AInput); + LPOut := PByte(AOut); + while ANumChunks >= 8 do + begin + Blake3_Hash8_Avx2(LPInput, AKey, LPOut, 8, ACounter, AFlags); + System.Inc(LPInput, 8 * 1024); + System.Inc(LPOut, 8 * 32); + System.Inc(ACounter, 8); + System.Dec(ANumChunks, 8); + end; + if ANumChunks > 0 then + Blake3_HashMany_Sse2(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TBlake3X86Backend } + +class function TBlake3X86Backend.SelectCompress(AScalar: TBlake3CompressProc): TBlake3CompressProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@Blake3_Compress_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Blake3_Compress_Avx2); + TX86SimdLevel.SSE2: + Exit(@Blake3_Compress_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TBlake3X86Backend.SelectHashMany(AScalar: TBlake3HashManyProc): TBlake3HashManyProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@Blake3_HashMany_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Blake3_HashMany_Avx2); + TX86SimdLevel.SSE2: + Exit(@Blake3_HashMany_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TBlake3X86Backend.SelectParallelDegree(ADefault: Int32): Int32; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(4); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(8); + TX86SimdLevel.SSE2: + Exit(4); + end; +{$ENDIF} + Result := ADefault; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas b/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas new file mode 100644 index 0000000..a7814d8 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas @@ -0,0 +1,70 @@ +unit HlpCRCArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpCRCCore; + +type + /// + /// Arm SIMD backend for CRC's fold: owns the PMULL kernels (bodies in + /// Include\Simd\CRC\) and the runtime tier selection via + /// TCpuFeatures.Arm. Compiles on every target - built without Arm SIMD, + /// Select just returns the scalar routines. + /// + TCRCArmBackend = class sealed + public + class function Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures; + +// ============================================================================= +// SIMD kernels +// aarch64: PMULL +// ============================================================================= + +function CRC_Fold_Reflected_Pmull(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedPmull_aarch64.inc} +end; + +function CRC_Fold_Forward_Pmull(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardPmull_aarch64.inc} +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TCRCArmBackend } + +class function TCRCArmBackend.Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; +begin + Result.Reflected := AReflectedScalar; + Result.Fwd := AForwardScalar; + Result.Reflected32 := AReflected32Scalar; + Result.UsesCarrylessMul := False; + +{$IFDEF HASHLIB_AARCH64_ASM} + if TCpuFeatures.Arm.HasPMULL() then + begin + Result.Reflected := @CRC_Fold_Reflected_Pmull; + Result.Fwd := @CRC_Fold_Forward_Pmull; + Result.Reflected32 := @CRC_Fold_Reflected_Pmull; + Result.UsesCarrylessMul := True; + end; +{$ENDIF HASHLIB_AARCH64_ASM} +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas new file mode 100644 index 0000000..92057dd --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas @@ -0,0 +1,148 @@ +unit HlpCRCX86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpCRCCore; + +type + /// + /// x86 SIMD backend for CRC's fold: owns the SSE2 / PCLMULQDQ / VPCLMULQDQ + /// kernels (bodies in Include\Simd\CRC\) and the runtime tier selection + /// via TCpuFeatures.X86. Compiles on every target - built without x86 + /// SIMD, Select just returns the scalar routines. + /// + TCRCX86Backend = class sealed + public + class function Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: VPCLMULQDQ, PCLMULQDQ, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedSse2_i386.inc} +end; + +function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_i386.inc} +end; + +function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflected32Sse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedSse2_x86_64.inc} +end; + +function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_x86_64.inc} +end; + +function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflected32Sse2_x86_64.inc} +end; + +function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedPclmul_x86_64.inc} +end; + +function CRC_Fold_Reflected_Vpclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedVpclmul_x86_64.inc} +end; + +function CRC_Fold_Forward_Pclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardPclmul_x86_64.inc} +end; + +function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardVpclmul_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TCRCX86Backend } + +class function TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; +begin + Result.Reflected := AReflectedScalar; + Result.Fwd := AForwardScalar; + Result.Reflected32 := AReflected32Scalar; + Result.UsesCarrylessMul := False; + +{$IFDEF HASHLIB_X86_64_ASM} + if TCpuFeatures.X86.HasVPCLMULQDQ() then + begin + Result.Reflected := @CRC_Fold_Reflected_Vpclmul; + Result.Fwd := @CRC_Fold_Forward_Vpclmul; + Result.Reflected32 := @CRC_Fold_Reflected_Vpclmul; + Result.UsesCarrylessMul := True; + Exit; + end; + if TCpuFeatures.X86.HasPCLMULQDQ() then + begin + Result.Reflected := @CRC_Fold_Reflected_Pclmul; + Result.Fwd := @CRC_Fold_Forward_Pclmul; + Result.Reflected32 := @CRC_Fold_Reflected_Pclmul; + Result.UsesCarrylessMul := True; + Exit; + end; +{$ENDIF HASHLIB_X86_64_ASM} + +{$IFDEF HASHLIB_X86_SIMD} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + begin + Result.Reflected := @CRC_Fold_Reflected_Sse2; + Result.Fwd := @CRC_Fold_Forward_Sse2; + Result.Reflected32 := @CRC_Fold_Reflected32_Sse2; + end; + end; +{$ENDIF HASHLIB_X86_SIMD} +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas new file mode 100644 index 0000000..62e5c2b --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas @@ -0,0 +1,58 @@ +unit HlpSHA1ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA1; + +type + /// + /// Arm SIMD backend for SHA-1: owns the AArch64 FEAT_SHA1 crypto-extension + /// kernel (body in Include\Simd\SHA1\) and the runtime feature check via + /// TCpuFeatures.Arm. Compiles on every target - built without Arm SIMD, + /// Select just returns the scalar routine. + /// + TSHA1ArmBackend = class sealed + public + class function Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures; + +// ============================================================================= +// SIMD kernels +// aarch64: SHA1 Crypto Extensions +// ============================================================================= + +procedure SHA1_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressCryptoExt_aarch64.inc} +end; + +procedure SHA1_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_CryptoExt(AState, AData, ANumBlocks, @K_SHA1); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TSHA1ArmBackend } + +class function TSHA1ArmBackend.Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + if TCpuFeatures.Arm.HasSHA1() then + Exit(@SHA1_Compress_CryptoExt_Wrap); +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas new file mode 100644 index 0000000..b2819ed --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas @@ -0,0 +1,137 @@ +unit HlpSHA1X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA1; + +type + /// + /// x86 SIMD backend for SHA-1: owns the SSE2 / AVX2 / SHA-NI keystream kernels + /// (bodies in Include\Simd\SHA1\) and the runtime tier selection via + /// TCpuFeatures.X86. Compiles on every target - built without x86 SIMD, + /// Select just returns the scalar routine. + /// + TSHA1X86Backend = class sealed + public + class function Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +const + // BSWAP32 shuffle mask for pshufb (x86 SIMD only): byte-swaps and reverses + // dword order in one shuffle (sha1rnds4 reads its four words in reverse). Not a + // SHA-1 constant; used only by the SHA-NI kernel. + BSWAP32_MASK: array [0 .. 3] of UInt32 = ( + $0C0D0E0F, $08090A0B, $04050607, $00010203 + ); + + // Doubled SHA-1 round constants plus the AVX2 byte-swap masks, shared by the + // AVX2 and SSE2 SIMD-schedule SHA-1 kernels. Each round constant fills a 128-bit + // lane (its four dwords) and is stored twice so one table feeds both the 256-bit + // AVX2 read and the 128-bit SSE2 reads (both read at a 32-byte stride, skipping + // the duplicate halves). Only the AVX2 kernel uses the appended masks: the + // byte-swap mask (BSWAP32 pattern, twice) then a whole-vector reverse mask; the + // SSE2 kernel computes its byte-swap and needs no mask. + K_SHA1_Doubled: array [0 .. 43] of UInt32 = ( + $5A827999, $5A827999, $5A827999, $5A827999, + $5A827999, $5A827999, $5A827999, $5A827999, + $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, + $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, $6ED9EBA1, + $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, + $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, $8F1BBCDC, + $CA62C1D6, $CA62C1D6, $CA62C1D6, $CA62C1D6, + $CA62C1D6, $CA62C1D6, $CA62C1D6, $CA62C1D6, + $00010203, $04050607, $08090A0B, $0C0D0E0F, + $00010203, $04050607, $08090A0B, $0C0D0E0F, + $0C0D0E0F, $08090A0B, $04050607, $00010203 + ); + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: ShaNi, AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure SHA1_Compress_ShaNi(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants, AMask: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressShaNi_x86_64.inc} +end; + +procedure SHA1_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_ShaNi(AState, AData, ANumBlocks, @K_SHA1, @BSWAP32_MASK); +end; + +procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_x86_64.inc} +end; + +procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx2_x86_64.inc} +end; + +procedure SHA1_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_Avx2(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +procedure SHA1_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_Sse2(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + +{$ENDIF HASHLIB_X86_SIMD} + +{ TSHA1X86Backend } + +class function TSHA1X86Backend.Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@SHA1_Compress_Sse2_Wrap); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + if TCpuFeatures.X86.HasSHANI() then + Exit(@SHA1_Compress_ShaNi_Wrap); + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@SHA1_Compress_Avx2_Wrap); + TX86SimdLevel.SSE2: + Exit(@SHA1_Compress_Sse2_Wrap); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas new file mode 100644 index 0000000..6e56321 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas @@ -0,0 +1,58 @@ +unit HlpSHA2_256ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA2_256Base; + +type + /// + /// Arm SIMD backend for SHA-256: owns the AArch64 FEAT_SHA256 crypto-extension + /// kernel (body in Include\Simd\SHA256\) and the runtime feature check + /// via TCpuFeatures.Arm. Compiles on every target - built without Arm + /// SIMD, Select just returns the scalar routine. + /// + TSHA2_256ArmBackend = class sealed + public + class function Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures; + +// ============================================================================= +// SIMD kernels +// aarch64: SHA256 Crypto Extensions +// ============================================================================= + +procedure SHA256_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressCryptoExt_aarch64.inc} +end; + +procedure SHA256_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_CryptoExt(AState, AData, ANumBlocks, @K256); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TSHA2_256ArmBackend } + +class function TSHA2_256ArmBackend.Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + if TCpuFeatures.Arm.HasSHA256() then + Exit(@SHA256_Compress_CryptoExt_Wrap); +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas new file mode 100644 index 0000000..474cbe9 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas @@ -0,0 +1,164 @@ +unit HlpSHA2_256X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA2_256Base; + +type + /// + /// x86 SIMD backend for SHA-256: owns the SSE2 / AVX2 / SHA-NI keystream + /// kernels (bodies in Include\Simd\SHA256\) and the runtime tier + /// selection via TCpuFeatures.X86. Compiles on every target - built + /// without x86 SIMD, Select just returns the scalar routine. + /// + TSHA2_256X86Backend = class sealed + public + class function Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +const + // BSWAP32 shuffle mask for pshufb (x86 SIMD only): reverses bytes within each + // dword. Not a SHA-256 constant; used only by the SHA-NI kernel. + BSWAP32_MASK: array [0 .. 3] of UInt32 = ( + $00010203, $04050607, $08090A0B, $0C0D0E0F + ); + + // Doubled K256 round constants plus the three AVX2 message-schedule masks, + // shared by the AVX2 and SSE2 SIMD-schedule SHA-256 kernels. Each 128-bit K256 + // quadruple is stored twice so one table feeds both the 256-bit AVX2 lanes and + // the 128-bit SSE2 reads (both read at a 32-byte stride, skipping the duplicate + // halves). Only the AVX2 kernel uses the appended masks: the byte-swap mask + // (BSWAP32 pattern, twice) occupies [128..135] and the two schedule shuffle + // masks follow at [136..143] and [144..151]; the SSE2 kernel computes its + // byte-swap and needs no mask. Derived from K256. + K256_Doubled: array [0 .. 151] of UInt32 = ( + $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, + $D807AA98, $12835B01, $243185BE, $550C7DC3, + $D807AA98, $12835B01, $243185BE, $550C7DC3, + $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, + $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, + $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, + $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, + $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, + $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, + $983E5152, $A831C66D, $B00327C8, $BF597FC7, + $983E5152, $A831C66D, $B00327C8, $BF597FC7, + $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, + $650A7354, $766A0ABB, $81C2C92E, $92722C85, + $650A7354, $766A0ABB, $81C2C92E, $92722C85, + $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, + $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, + $D192E819, $D6990624, $F40E3585, $106AA070, + $D192E819, $D6990624, $F40E3585, $106AA070, + $19A4C116, $1E376C08, $2748774C, $34B0BCB5, + $19A4C116, $1E376C08, $2748774C, $34B0BCB5, + $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, + $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, + $748F82EE, $78A5636F, $84C87814, $8CC70208, + $748F82EE, $78A5636F, $84C87814, $8CC70208, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2, + $00010203, $04050607, $08090A0B, $0C0D0E0F, + $00010203, $04050607, $08090A0B, $0C0D0E0F, + $03020100, $0B0A0908, $FFFFFFFF, $FFFFFFFF, + $03020100, $0B0A0908, $FFFFFFFF, $FFFFFFFF, + $FFFFFFFF, $FFFFFFFF, $03020100, $0B0A0908, + $FFFFFFFF, $FFFFFFFF, $03020100, $0B0A0908 + ); + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: ShaNi, AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure SHA256_Compress_ShaNi(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants, AMask: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressShaNi_x86_64.inc} +end; + +procedure SHA256_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_ShaNi(AState, AData, ANumBlocks, @K256, @BSWAP32_MASK); +end; + +procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_x86_64.inc} +end; + +procedure SHA256_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressAvx2_x86_64.inc} +end; + +procedure SHA256_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_Avx2(AState, AData, ANumBlocks, @K256_Doubled); +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +procedure SHA256_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_Sse2(AState, AData, ANumBlocks, @K256_Doubled); +end; + +{$ENDIF HASHLIB_X86_SIMD} + +{ TSHA2_256X86Backend } + +class function TSHA2_256X86Backend.Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@SHA256_Compress_Sse2_Wrap); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + if TCpuFeatures.X86.HasSHANI() then + Exit(@SHA256_Compress_ShaNi_Wrap); + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@SHA256_Compress_Avx2_Wrap); + TX86SimdLevel.SSE2: + Exit(@SHA256_Compress_Sse2_Wrap); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas new file mode 100644 index 0000000..0800d22 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas @@ -0,0 +1,58 @@ +unit HlpSHA2_512ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA2_512Base; + +type + /// + /// Arm SIMD backend for SHA-512: owns the AArch64 FEAT_SHA512 crypto-extension + /// kernel (body in Include\Simd\SHA512\) and the runtime feature check + /// via TCpuFeatures.Arm. Compiles on every target - built without Arm + /// SIMD, Select just returns the scalar routine. + /// + TSHA2_512ArmBackend = class sealed + public + class function Select(AScalar: TSHA512CompressProc): TSHA512CompressProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures; + +// ============================================================================= +// SIMD kernels +// aarch64: SHA512 Crypto Extensions +// ============================================================================= + +procedure SHA512_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA512\SHA512CompressCryptoExt_aarch64.inc} +end; + +procedure SHA512_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA512_Compress_CryptoExt(AState, AData, ANumBlocks, @K512); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TSHA2_512ArmBackend } + +class function TSHA2_512ArmBackend.Select(AScalar: TSHA512CompressProc): TSHA512CompressProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + if TCpuFeatures.Arm.HasSHA512() then + Exit(@SHA512_Compress_CryptoExt_Wrap); +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Crypto/HlpSHA2_512Dispatch.pas b/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas similarity index 51% rename from HashLib/src/Crypto/HlpSHA2_512Dispatch.pas rename to HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas index dfec4e6..8ac1a46 100644 --- a/HashLib/src/Crypto/HlpSHA2_512Dispatch.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas @@ -1,67 +1,39 @@ -unit HlpSHA2_512Dispatch; +unit HlpSHA2_512X86Backend; -{$I ..\Include\HashLib.inc} +{$I ..\..\Include\HashLib.inc} interface -type - TSHA512CompressProc = procedure(AState, AData: Pointer; ANumBlocks: UInt32); +uses + HlpSHA2_512Base; -var - SHA512_Compress: TSHA512CompressProc; +type + /// + /// x86 SIMD backend for SHA-512: owns the SSE2 / AVX2 keystream kernels (bodies + /// in Include\Simd\SHA512\) and the runtime tier selection via + /// TCpuFeatures.X86. Compiles on every target - built without x86 SIMD, + /// Select just returns the scalar routine. + /// + TSHA2_512X86Backend = class sealed + public + class function Select(AScalar: TSHA512CompressProc): TSHA512CompressProc; static; + end; -const - // K512 round constants (80 UInt64 = 640 bytes) - K512: array [0 .. 79] of UInt64 = ( - UInt64($428A2F98D728AE22), UInt64($7137449123EF65CD), - UInt64($B5C0FBCFEC4D3B2F), UInt64($E9B5DBA58189DBBC), - UInt64($3956C25BF348B538), UInt64($59F111F1B605D019), - UInt64($923F82A4AF194F9B), UInt64($AB1C5ED5DA6D8118), - UInt64($D807AA98A3030242), UInt64($12835B0145706FBE), - UInt64($243185BE4EE4B28C), UInt64($550C7DC3D5FFB4E2), - UInt64($72BE5D74F27B896F), UInt64($80DEB1FE3B1696B1), - UInt64($9BDC06A725C71235), UInt64($C19BF174CF692694), - UInt64($E49B69C19EF14AD2), UInt64($EFBE4786384F25E3), - UInt64($0FC19DC68B8CD5B5), UInt64($240CA1CC77AC9C65), - UInt64($2DE92C6F592B0275), UInt64($4A7484AA6EA6E483), - UInt64($5CB0A9DCBD41FBD4), UInt64($76F988DA831153B5), - UInt64($983E5152EE66DFAB), UInt64($A831C66D2DB43210), - UInt64($B00327C898FB213F), UInt64($BF597FC7BEEF0EE4), - UInt64($C6E00BF33DA88FC2), UInt64($D5A79147930AA725), - UInt64($06CA6351E003826F), UInt64($142929670A0E6E70), - UInt64($27B70A8546D22FFC), UInt64($2E1B21385C26C926), - UInt64($4D2C6DFC5AC42AED), UInt64($53380D139D95B3DF), - UInt64($650A73548BAF63DE), UInt64($766A0ABB3C77B2A8), - UInt64($81C2C92E47EDAEE6), UInt64($92722C851482353B), - UInt64($A2BFE8A14CF10364), UInt64($A81A664BBC423001), - UInt64($C24B8B70D0F89791), UInt64($C76C51A30654BE30), - UInt64($D192E819D6EF5218), UInt64($D69906245565A910), - UInt64($F40E35855771202A), UInt64($106AA07032BBD1B8), - UInt64($19A4C116B8D2D0C8), UInt64($1E376C085141AB53), - UInt64($2748774CDF8EEB99), UInt64($34B0BCB5E19B48A8), - UInt64($391C0CB3C5C95A63), UInt64($4ED8AA4AE3418ACB), - UInt64($5B9CCA4F7763E373), UInt64($682E6FF3D6B2B8A3), - UInt64($748F82EE5DEFB2FC), UInt64($78A5636F43172F60), - UInt64($84C87814A1F0AB72), UInt64($8CC702081A6439EC), - UInt64($90BEFFFA23631E28), UInt64($A4506CEBDE82BDE9), - UInt64($BEF9A3F7B2C67915), UInt64($C67178F2E372532B), - UInt64($CA273ECEEA26619C), UInt64($D186B8C721C0C207), - UInt64($EADA7DD6CDE0EB1E), UInt64($F57D4F7FEE6ED178), - UInt64($06F067AA72176FBA), UInt64($0A637DC5A2C898A6), - UInt64($113F9804BEF90DAE), UInt64($1B710B35131C471B), - UInt64($28DB77F523047D84), UInt64($32CAAB7B40C72493), - UInt64($3C9EBE0A15C9BEBC), UInt64($431D67C49C100D4C), - UInt64($4CC5D4BECB3E42B6), UInt64($597F299CFC657E2A), - UInt64($5FCB6FAB3AD6FAEC), UInt64($6C44198C4A475817) - ); +implementation {$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +const // Doubled K512 round constants plus the BSWAP64 mask, shared by the AVX2 and // SSE2 SIMD-schedule SHA-512 kernels. Each 128-bit K512 constant pair is stored // twice so one table feeds both the 256-bit AVX2 lanes and the 128-bit SSE2 // reads (both read at a 32-byte stride). Only the AVX2 kernel uses the appended // byte-swap mask (BSWAP64 pattern, twice) at [160..163]; the SSE2 kernel computes - // its byte-swap and needs no mask. Derived from K512. + // its byte-swap and needs no mask. K512_Doubled: array [0 .. 163] of UInt64 = ( UInt64($428A2F98D728AE22), UInt64($7137449123EF65CD), UInt64($428A2F98D728AE22), UInt64($7137449123EF65CD), @@ -146,85 +118,19 @@ interface UInt64($0001020304050607), UInt64($08090A0B0C0D0E0F), UInt64($0001020304050607), UInt64($08090A0B0C0D0E0F) ); -{$ENDIF HASHLIB_X86_SIMD} - -implementation -uses - HlpBinaryPrimitives, - HlpBitOperations, - HlpCpuFeatures, - HlpSimdLevels; - -// ============================================================================= -// Scalar fallback implementation // ============================================================================= - -procedure SHA512_Compress_Scalar(AState, AData: Pointer; ANumBlocks: UInt32); -var - LPState: PUInt64; - LPData: PByte; - LA, LB, LC, LD, LE, LF, LG, LH, LT1, LT2: UInt64; - LW: array [0 .. 79] of UInt64; - LRound: Int32; -begin - LPState := PUInt64(AState); - LPData := PByte(AData); - - while ANumBlocks > 0 do - begin - TBinaryPrimitives.CopyUInt64BigEndian(LPData, 0, @LW[0], 0, 128); - - for LRound := 16 to 79 do - begin - LT1 := LW[LRound - 2]; - LT2 := LW[LRound - 15]; - LW[LRound] := (TBitOperations.RotateRight64(LT1, 19) xor TBitOperations.RotateRight64(LT1, 61) - xor (LT1 shr 6)) + LW[LRound - 7] + - (TBitOperations.RotateRight64(LT2, 1) xor TBitOperations.RotateRight64(LT2, 8) - xor (LT2 shr 7)) + LW[LRound - 16]; - end; - - LA := LPState[0]; LB := LPState[1]; LC := LPState[2]; LD := LPState[3]; - LE := LPState[4]; LF := LPState[5]; LG := LPState[6]; LH := LPState[7]; - - for LRound := 0 to 79 do - begin - LT1 := LH + (TBitOperations.RotateRight64(LE, 14) xor TBitOperations.RotateRight64(LE, 18) - xor TBitOperations.RotateRight64(LE, 41)) + ((LE and LF) xor (not LE and LG)) - + K512[LRound] + LW[LRound]; - LT2 := (TBitOperations.RotateRight64(LA, 28) xor TBitOperations.RotateRight64(LA, 34) - xor TBitOperations.RotateRight64(LA, 39)) + - ((LA and LB) xor (LA and LC) xor (LB and LC)); - LH := LG; LG := LF; LF := LE; LE := LD + LT1; - LD := LC; LC := LB; LB := LA; LA := LT1 + LT2; - end; - - LPState[0] := LPState[0] + LA; LPState[1] := LPState[1] + LB; - LPState[2] := LPState[2] + LC; LPState[3] := LPState[3] + LD; - LPState[4] := LPState[4] + LE; LPState[5] := LPState[5] + LF; - LPState[6] := LPState[6] + LG; LPState[7] := LPState[7] + LH; - - System.FillChar(LW, System.SizeOf(LW), 0); - System.Inc(LPData, 128); - System.Dec(ANumBlocks); - end; -end; - -// ============================================================================= -// SIMD implementations -// +// SIMD kernels // i386: SSE2 // x86_64: AVX2, SSE2 -// aarch64: SHA512 Crypto Extensions // ============================================================================= {$IFDEF HASHLIB_I386_ASM} procedure SHA512_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\Include\Simd\SHA512\SHA512CompressSse2_i386.inc} + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_i386.inc} end; {$ENDIF HASHLIB_I386_ASM} @@ -233,14 +139,14 @@ procedure SHA512_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; procedure SHA512_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\SHA512\SHA512CompressSse2_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_x86_64.inc} end; procedure SHA512_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\Include\Simd\SHA512\SHA512CompressAvx2_x86_64.inc} + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA512\SHA512CompressAvx2_x86_64.inc} end; procedure SHA512_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); @@ -250,8 +156,6 @@ procedure SHA512_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); {$ENDIF HASHLIB_X86_64_ASM} -{$IFDEF HASHLIB_X86_SIMD} - procedure SHA512_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); begin {$IFDEF HASHLIB_X86_64_ASM} @@ -263,57 +167,25 @@ procedure SHA512_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); {$ENDIF HASHLIB_X86_SIMD} -{$IFDEF HASHLIB_AARCH64_ASM} - -procedure SHA512_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} - {$I ..\Include\Simd\SHA512\SHA512CompressCryptoExt_aarch64.inc} -end; +{ TSHA2_512X86Backend } -procedure SHA512_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +class function TSHA2_512X86Backend.Select(AScalar: TSHA512CompressProc): TSHA512CompressProc; begin - SHA512_Compress_CryptoExt(AState, AData, ANumBlocks, @K512); -end; - -{$ENDIF HASHLIB_AARCH64_ASM} - -// ============================================================================= -// Dispatch initialization -// ============================================================================= - -procedure InitDispatch(); -begin - SHA512_Compress := @SHA512_Compress_Scalar; {$IFDEF HASHLIB_I386_ASM} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of TX86SimdLevel.SSE2: - begin - SHA512_Compress := @SHA512_Compress_Sse2_Wrap; - end; + Exit(@SHA512_Compress_Sse2_Wrap); end; {$ENDIF} {$IFDEF HASHLIB_X86_64_ASM} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - begin - SHA512_Compress := @SHA512_Compress_Avx2_Wrap; - end; + Exit(@SHA512_Compress_Avx2_Wrap); TX86SimdLevel.SSE2: - begin - SHA512_Compress := @SHA512_Compress_Sse2_Wrap; - end; - end; -{$ENDIF} -{$IFDEF HASHLIB_AARCH64_ASM} - if TCpuFeatures.Arm.HasSHA512() then - begin - SHA512_Compress := @SHA512_Compress_CryptoExt_Wrap; + Exit(@SHA512_Compress_Sse2_Wrap); end; {$ENDIF} + Result := AScalar; end; -initialization - InitDispatch(); - end. diff --git a/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas new file mode 100644 index 0000000..22c3000 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas @@ -0,0 +1,83 @@ +unit HlpSHA3ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA3; + +type + /// + /// Arm SIMD backend for Keccak-F1600: owns the AArch64 FEAT_SHA3 crypto- + /// extension permute / absorb kernels (bodies in Include\Simd\SHA3\) and + /// the runtime feature check via TCpuFeatures.Arm. Compiles on every + /// target - without Arm SIMD the selectors return the scalar routines. + /// + TSHA3ArmBackend = class sealed + public + class function SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; static; + class function SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures; + +// ============================================================================= +// SIMD kernels +// aarch64: SHA3 Crypto Extensions +// +// The FEAT_SHA3 kernels reuse the plain RC round-constant table directly (the +// asm broadcasts each 64-bit iota with ld1r), so no packed constant block is +// needed. +// ============================================================================= + +procedure KeccakF1600_CryptoExt(AState: Pointer; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600CryptoExt_aarch64.inc} +end; + +procedure KeccakF1600_CryptoExt_Wrap(AState: Pointer); +begin + KeccakF1600_CryptoExt(AState, @RC); +end; + +procedure KeccakF1600_CryptoExt_Absorb(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600CryptoExtAbsorb_aarch64.inc} +end; + +procedure KeccakF1600_CryptoExt_Absorb_Wrap(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); +begin + KeccakF1600_CryptoExt_Absorb(AState, AData, ABlockCount, ABlockSize, @RC); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TSHA3ArmBackend } + +class function TSHA3ArmBackend.SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + if TCpuFeatures.Arm.HasSHA3() then + Exit(@KeccakF1600_CryptoExt_Wrap); +{$ENDIF} + Result := AScalar; +end; + +class function TSHA3ArmBackend.SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + if TCpuFeatures.Arm.HasSHA3() then + Exit(@KeccakF1600_CryptoExt_Absorb_Wrap); +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas new file mode 100644 index 0000000..846fc13 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas @@ -0,0 +1,136 @@ +unit HlpSHA3X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA3; + +type + /// + /// x86 SIMD backend for Keccak-F1600: owns the AVX2 permute / absorb kernels + /// (bodies in Include\Simd\SHA3\) and the runtime tier selection via + /// TCpuFeatures.X86 (AVX2 only; there is no i386 SIMD path). Compiles on + /// every target - without AVX2 the selectors return the scalar routines. + /// + TSHA3X86Backend = class sealed + public + class function SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; static; + class function SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +const + K_KECCAK: packed record + RhotatesLeft: array [0..23] of UInt64; + RhotatesRight: array [0..23] of UInt64; + Iotas: array [0..95] of UInt64; + Jagged: array [0..24] of Int32; + end = ( + RhotatesLeft: ( + 3, 18, 36, 41, // ymm2: [2][0] [4][0] [1][0] [3][0] + 1, 62, 28, 27, // ymm1: [0][1] [0][2] [0][3] [0][4] + 45, 6, 56, 39, // ymm3: [3][1] [1][2] [4][3] [2][4] + 10, 61, 55, 8, // ymm4: [2][1] [4][2] [1][3] [3][4] + 2, 15, 25, 20, // ymm5: [4][1] [3][2] [2][3] [1][4] + 44, 43, 21, 14); // ymm6: [1][1] [2][2] [3][3] [4][4] + RhotatesRight: ( + 61, 46, 28, 23, + 63, 2, 36, 37, + 19, 58, 8, 25, + 54, 3, 9, 56, + 62, 49, 39, 44, + 20, 21, 43, 50); + Iotas: ( + UInt64($0000000000000001), UInt64($0000000000000001), UInt64($0000000000000001), UInt64($0000000000000001), + UInt64($0000000000008082), UInt64($0000000000008082), UInt64($0000000000008082), UInt64($0000000000008082), + UInt64($800000000000808A), UInt64($800000000000808A), UInt64($800000000000808A), UInt64($800000000000808A), + UInt64($8000000080008000), UInt64($8000000080008000), UInt64($8000000080008000), UInt64($8000000080008000), + UInt64($000000000000808B), UInt64($000000000000808B), UInt64($000000000000808B), UInt64($000000000000808B), + UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), + UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), + UInt64($8000000000008009), UInt64($8000000000008009), UInt64($8000000000008009), UInt64($8000000000008009), + UInt64($000000000000008A), UInt64($000000000000008A), UInt64($000000000000008A), UInt64($000000000000008A), + UInt64($0000000000000088), UInt64($0000000000000088), UInt64($0000000000000088), UInt64($0000000000000088), + UInt64($0000000080008009), UInt64($0000000080008009), UInt64($0000000080008009), UInt64($0000000080008009), + UInt64($000000008000000A), UInt64($000000008000000A), UInt64($000000008000000A), UInt64($000000008000000A), + UInt64($000000008000808B), UInt64($000000008000808B), UInt64($000000008000808B), UInt64($000000008000808B), + UInt64($800000000000008B), UInt64($800000000000008B), UInt64($800000000000008B), UInt64($800000000000008B), + UInt64($8000000000008089), UInt64($8000000000008089), UInt64($8000000000008089), UInt64($8000000000008089), + UInt64($8000000000008003), UInt64($8000000000008003), UInt64($8000000000008003), UInt64($8000000000008003), + UInt64($8000000000008002), UInt64($8000000000008002), UInt64($8000000000008002), UInt64($8000000000008002), + UInt64($8000000000000080), UInt64($8000000000000080), UInt64($8000000000000080), UInt64($8000000000000080), + UInt64($000000000000800A), UInt64($000000000000800A), UInt64($000000000000800A), UInt64($000000000000800A), + UInt64($800000008000000A), UInt64($800000008000000A), UInt64($800000008000000A), UInt64($800000008000000A), + UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), UInt64($8000000080008081), + UInt64($8000000000008080), UInt64($8000000000008080), UInt64($8000000000008080), UInt64($8000000000008080), + UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), UInt64($0000000080000001), + UInt64($8000000080008008), UInt64($8000000080008008), UInt64($8000000080008008), UInt64($8000000080008008)); + Jagged: ( + 0, 32, 40, 48, 56, 80, 192, 104, 144, 184, + 64, 128, 200, 176, 120, 88, 96, 168, 208, 152, + 72, 160, 136, 112, 216) + ); + +// ============================================================================= +// SIMD kernels +// x86_64: AVX2 +// ============================================================================= + +procedure KeccakF1600_Avx2(AState: Pointer; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Avx2_x86_64.inc} +end; + +procedure KeccakF1600_Avx2_Wrap(AState: Pointer); +begin + KeccakF1600_Avx2(AState, @K_KECCAK); +end; + +procedure KeccakF1600_Avx2_Absorb(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Avx2Absorb_x86_64.inc} +end; + +procedure KeccakF1600_Avx2_Absorb_Wrap(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); +begin + KeccakF1600_Avx2_Absorb(AState, AData, ABlockCount, ABlockSize, @K_KECCAK); +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{ TSHA3X86Backend } + +class function TSHA3X86Backend.SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; +begin +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2]) of + TX86SimdLevel.AVX2: + Exit(@KeccakF1600_Avx2_Wrap); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TSHA3X86Backend.SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; +begin +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2]) of + TX86SimdLevel.AVX2: + Exit(@KeccakF1600_Avx2_Absorb_Wrap); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpScryptArmBackend.pas b/HashLib/src/Simd/Backend/HlpScryptArmBackend.pas new file mode 100644 index 0000000..51112ed --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpScryptArmBackend.pas @@ -0,0 +1,49 @@ +unit HlpScryptArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpPBKDF_ScryptNotBuildInAdapter; + +type + /// + /// Arm SIMD backend for scrypt's Salsa20/8 XOR core. The NEON kernel (body in + /// Include\Simd\Scrypt\) is compiled and verified but intentionally NOT + /// selected: at p=1 scrypt's Salsa20/8 is a single 64-byte block on a strictly + /// serial chain, and AArch64's 31 GP registers + single-cycle 'ror' let the + /// scalar kernel win at every N (this mirrors OpenSSL/libsodium/Tarsnap, which + /// ship x86 SSE2 scrypt but no NEON). Kept for reference / a future p>1 path. + /// So Select always returns the scalar routine. + /// + TScryptArmBackend = class sealed + public + class function Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +// ============================================================================= +// SIMD kernels +// aarch64: NEON (compiled/verified but not registered - see the class comment) +// ============================================================================= + +procedure Scrypt_SalsaXor_Neon(AState, AInput: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} + {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Neon_aarch64.inc} +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TScryptArmBackend } + +class function TScryptArmBackend.Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; +begin + // NEON not registered for scrypt on AArch64 (scalar is faster at p=1). + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas b/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas new file mode 100644 index 0000000..4659a94 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas @@ -0,0 +1,79 @@ +unit HlpScryptX86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpPBKDF_ScryptNotBuildInAdapter; + +type + /// + /// x86 SIMD backend for scrypt's Salsa20/8 XOR core: owns the SSE2 / AVX2 + /// kernels (bodies in Include\Simd\Scrypt\) and the runtime tier + /// selection via TCpuFeatures.X86. Compiles on every target - built + /// without x86 SIMD, Select just returns the scalar routine. + /// + TScryptX86Backend = class sealed + public + class function Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} + {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} + {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_x86_64.inc} +end; + +procedure Scrypt_SalsaXor_Avx2(AState, AInput: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} + {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Avx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TScryptX86Backend } + +class function TScryptX86Backend.Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: Exit(@Scrypt_SalsaXor_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@Scrypt_SalsaXor_Avx2); + TX86SimdLevel.SSE2: Exit(@Scrypt_SalsaXor_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas b/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas new file mode 100644 index 0000000..f252f92 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas @@ -0,0 +1,105 @@ +unit HlpXXHash3ArmBackend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpXXHash3; + +type + /// + /// Arm SIMD backend for XXH3: owns the AArch64 NEON accumulate / scramble / + /// init-secret kernels (bodies in Include\Simd\XXH3\) and the runtime + /// tier selection via TCpuFeatures.Arm. Compiles on every target - + /// without Arm SIMD the selectors return the scalar routines. + /// + TXXHash3ArmBackend = class sealed + public + class function SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; static; + class function SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; static; + class function SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; static; + class function SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; static; + end; + +implementation + +{$IFDEF HASHLIB_AARCH64_ASM} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// aarch64: NEON +// ============================================================================= + +procedure XXH3_Accumulate512_Neon(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_aarch64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3Acc512Neon_aarch64.inc} +end; + +procedure XXH3_ScrambleAcc_Neon(AAcc: Pointer; ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3ScrambleNeon_aarch64.inc} +end; + +procedure XXH3_InitSecret_Neon(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_aarch64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3InitSecretNeon_aarch64.inc} +end; + +procedure XXH3_Accumulate_Neon(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32); +begin + XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Neon); +end; + +{$ENDIF HASHLIB_AARCH64_ASM} + +{ TXXHash3ArmBackend } + +class function TXXHash3ArmBackend.SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: Exit(@XXH3_Accumulate512_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TXXHash3ArmBackend.SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: Exit(@XXH3_Accumulate_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TXXHash3ArmBackend.SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: Exit(@XXH3_ScrambleAcc_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TXXHash3ArmBackend.SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; +begin +{$IFDEF HASHLIB_AARCH64_ASM} + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: Exit(@XXH3_InitSecret_Neon); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas b/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas new file mode 100644 index 0000000..01a5040 --- /dev/null +++ b/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas @@ -0,0 +1,182 @@ +unit HlpXXHash3X86Backend; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpXXHash3; + +type + /// + /// x86 SIMD backend for XXH3: owns the SSE2 / AVX2 accumulate / scramble / + /// init-secret kernels (bodies in Include\Simd\XXH3\) and the runtime + /// tier selection via TCpuFeatures.X86. Compiles on every target - + /// without x86 SIMD the selectors return the scalar routines. + /// + TXXHash3X86Backend = class sealed + public + class function SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; static; + class function SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; static; + class function SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; static; + class function SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; static; + end; + +implementation + +{$IFDEF HASHLIB_X86_SIMD} + +uses + HlpCpuFeatures, + HlpSimdLevels; + +// ============================================================================= +// SIMD kernels +// i386: SSE2 +// x86_64: AVX2, SSE2 +// ============================================================================= + +{$IFDEF HASHLIB_I386_ASM} + +procedure XXH3_Accumulate512_Sse2(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} + {$I ..\..\Include\Simd\XXH3\XXH3Acc512Sse2_i386.inc} +end; + +procedure XXH3_ScrambleAcc_Sse2(AAcc: Pointer; ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} + {$I ..\..\Include\Simd\XXH3\XXH3ScrambleSse2_i386.inc} +end; + +procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} + {$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure XXH3_Accumulate512_Sse2(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3Acc512Sse2_x86_64.inc} +end; + +procedure XXH3_ScrambleAcc_Sse2(AAcc: Pointer; ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3ScrambleSse2_x86_64.inc} +end; + +procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_x86_64.inc} +end; + +procedure XXH3_Accumulate512_Avx2(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3Acc512Avx2_x86_64.inc} +end; + +procedure XXH3_ScrambleAcc_Avx2(AAcc: Pointer; ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3ScrambleAvx2_x86_64.inc} +end; + +procedure XXH3_InitSecret_Avx2(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} + {$I ..\..\Include\Simd\XXH3\XXH3InitSecretAvx2_x86_64.inc} +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +procedure XXH3_Accumulate_Sse2(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32); +begin + XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Sse2); +end; + +{$IFDEF HASHLIB_X86_64_ASM} + +procedure XXH3_Accumulate_Avx2(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer; ANbStripes: Int32); +begin + XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Avx2); +end; + +{$ENDIF HASHLIB_X86_64_ASM} + +{$ENDIF HASHLIB_X86_SIMD} + +{ TXXHash3X86Backend } + +class function TXXHash3X86Backend.SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate512_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@XXH3_Accumulate512_Avx2); + TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate512_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TXXHash3X86Backend.SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@XXH3_Accumulate_Avx2); + TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TXXHash3X86Backend.SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: Exit(@XXH3_ScrambleAcc_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@XXH3_ScrambleAcc_Avx2); + TX86SimdLevel.SSE2: Exit(@XXH3_ScrambleAcc_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +class function TXXHash3X86Backend.SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; +begin +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: Exit(@XXH3_InitSecret_Sse2); + end; +{$ENDIF} +{$IFDEF HASHLIB_X86_64_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: Exit(@XXH3_InitSecret_Avx2); + TX86SimdLevel.SSE2: Exit(@XXH3_InitSecret_Sse2); + end; +{$ENDIF} + Result := AScalar; +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpAdler32Simd.pas b/HashLib/src/Simd/Facade/HlpAdler32Simd.pas new file mode 100644 index 0000000..fead6de --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpAdler32Simd.pas @@ -0,0 +1,46 @@ +unit HlpAdler32Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpAdler32; + +type + /// + /// Arch-neutral SIMD facade for Adler-32. Picks the per-arch backend at compile + /// time and returns the best update routine the running CPU supports, or + /// AScalar when no SIMD backend is built/available. The hash unit calls + /// only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TAdler32Simd = class sealed + public + class function Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpAdler32X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpAdler32ArmBackend; +{$IFEND} + +{ TAdler32Simd } + +class function TAdler32Simd.Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TAdler32X86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TAdler32ArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpArgon2Simd.pas b/HashLib/src/Simd/Facade/HlpArgon2Simd.pas new file mode 100644 index 0000000..7ae267b --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpArgon2Simd.pas @@ -0,0 +1,46 @@ +unit HlpArgon2Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpPBKDF_Argon2NotBuildInAdapter; + +type + /// + /// Arch-neutral SIMD facade for Argon2's fill-block. Picks the per-arch backend + /// at compile time and returns the best routine the running CPU supports, or + /// AScalar when no SIMD backend is built/available. The KDF unit calls + /// only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TArgon2Simd = class sealed + public + class function Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpArgon2X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpArgon2ArmBackend; +{$IFEND} + +{ TArgon2Simd } + +class function TArgon2Simd.Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TArgon2X86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TArgon2ArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpBlake2BSimd.pas b/HashLib/src/Simd/Facade/HlpBlake2BSimd.pas new file mode 100644 index 0000000..3e7a00a --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpBlake2BSimd.pas @@ -0,0 +1,46 @@ +unit HlpBlake2BSimd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake2B; + +type + /// + /// Arch-neutral SIMD facade for Blake2B. Picks the per-arch backend at compile + /// time and returns the best compression routine the running CPU supports, or + /// AScalar when no SIMD backend is built/available. The hash unit calls + /// only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TBlake2BSimd = class sealed + public + class function Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpBlake2BX86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpBlake2BArmBackend; +{$IFEND} + +{ TBlake2BSimd } + +class function TBlake2BSimd.Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TBlake2BX86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TBlake2BArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpBlake2SSimd.pas b/HashLib/src/Simd/Facade/HlpBlake2SSimd.pas new file mode 100644 index 0000000..7dfc264 --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpBlake2SSimd.pas @@ -0,0 +1,46 @@ +unit HlpBlake2SSimd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake2S; + +type + /// + /// Arch-neutral SIMD facade for Blake2S. Picks the per-arch backend at compile + /// time and returns the best compression routine the running CPU supports, or + /// AScalar when no SIMD backend is built/available. The hash unit calls + /// only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TBlake2SSimd = class sealed + public + class function Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpBlake2SX86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpBlake2SArmBackend; +{$IFEND} + +{ TBlake2SSimd } + +class function TBlake2SSimd.Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TBlake2SX86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TBlake2SArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpBlake3Simd.pas b/HashLib/src/Simd/Facade/HlpBlake3Simd.pas new file mode 100644 index 0000000..20bcaf0 --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpBlake3Simd.pas @@ -0,0 +1,70 @@ +unit HlpBlake3Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpBlake3; + +type + /// + /// Arch-neutral SIMD facade for Blake3. Picks the per-arch backend at compile + /// time and returns the best compression / hash-many routines (and the parallel + /// degree) the running CPU supports, or the scalar reference when no SIMD + /// backend is built/available. The hash unit calls only this facade and stays + /// free of any TCpuFeatures / HASHLIB_*_ASM knowledge. + /// + TBlake3Simd = class sealed + public + class function SelectCompress(AScalar: TBlake3CompressProc): TBlake3CompressProc; static; + class function SelectHashMany(AScalar: TBlake3HashManyProc): TBlake3HashManyProc; static; + class function SelectParallelDegree(ADefault: Int32): Int32; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpBlake3X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpBlake3ArmBackend; +{$IFEND} + +{ TBlake3Simd } + +class function TBlake3Simd.SelectCompress(AScalar: TBlake3CompressProc): TBlake3CompressProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TBlake3X86Backend.SelectCompress(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TBlake3ArmBackend.SelectCompress(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +class function TBlake3Simd.SelectHashMany(AScalar: TBlake3HashManyProc): TBlake3HashManyProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TBlake3X86Backend.SelectHashMany(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TBlake3ArmBackend.SelectHashMany(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +class function TBlake3Simd.SelectParallelDegree(ADefault: Int32): Int32; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TBlake3X86Backend.SelectParallelDegree(ADefault); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TBlake3ArmBackend.SelectParallelDegree(ADefault); +{$ELSE} + Result := ADefault; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpCRCSimd.pas b/HashLib/src/Simd/Facade/HlpCRCSimd.pas new file mode 100644 index 0000000..2131334 --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpCRCSimd.pas @@ -0,0 +1,54 @@ +unit HlpCRCSimd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpCRCCore; + +type + /// + /// Arch-neutral SIMD facade for CRC's carry-less-multiply fold. Picks the + /// per-arch backend at compile time and returns the reflected / forward / + /// reflected-32 fold entry points the running CPU supports (plus whether they + /// use carry-less multiply), or the scalar routines when no SIMD backend is + /// built/available. The CRC core calls only this facade and stays free of any + /// TCpuFeatures / HASHLIB_*_ASM knowledge. + /// + TCRCSimd = class sealed + public + class function Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpCRCX86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpCRCArmBackend; +{$IFEND} + +{ TCRCSimd } + +class function TCRCSimd.Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TCRCArmBackend.Select(AReflectedScalar, AForwardScalar, + AReflected32Scalar); +{$ELSE} + Result.Reflected := AReflectedScalar; + Result.Fwd := AForwardScalar; + Result.Reflected32 := AReflected32Scalar; + Result.UsesCarrylessMul := False; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpSHA1Simd.pas b/HashLib/src/Simd/Facade/HlpSHA1Simd.pas new file mode 100644 index 0000000..ea18497 --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpSHA1Simd.pas @@ -0,0 +1,48 @@ +unit HlpSHA1Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA1; + +type + /// + /// Arch-neutral SIMD facade for SHA-1. Picks the per-arch backend at compile + /// time and returns the best block-compression routine the running CPU + /// supports, or AScalar when no SIMD backend is built/available. The + /// hash unit calls only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TSHA1Simd = class sealed + public + /// Return the fastest available SHA-1 compression routine for the + /// running CPU, falling back to AScalar. Call once at init. + class function Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpSHA1X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpSHA1ArmBackend; +{$IFEND} + +{ TSHA1Simd } + +class function TSHA1Simd.Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TSHA1X86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TSHA1ArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpSHA2_256Simd.pas b/HashLib/src/Simd/Facade/HlpSHA2_256Simd.pas new file mode 100644 index 0000000..da7f5ec --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpSHA2_256Simd.pas @@ -0,0 +1,48 @@ +unit HlpSHA2_256Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA2_256Base; + +type + /// + /// Arch-neutral SIMD facade for SHA-256. Picks the per-arch backend at compile + /// time and returns the best block-compression routine the running CPU + /// supports, or AScalar when no SIMD backend is built/available. The + /// hash unit calls only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TSHA2_256Simd = class sealed + public + /// Return the fastest available SHA-256 compression routine for the + /// running CPU, falling back to AScalar. Call once at init. + class function Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpSHA2_256X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpSHA2_256ArmBackend; +{$IFEND} + +{ TSHA2_256Simd } + +class function TSHA2_256Simd.Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TSHA2_256X86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TSHA2_256ArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpSHA2_512Simd.pas b/HashLib/src/Simd/Facade/HlpSHA2_512Simd.pas new file mode 100644 index 0000000..d9a6f9f --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpSHA2_512Simd.pas @@ -0,0 +1,48 @@ +unit HlpSHA2_512Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA2_512Base; + +type + /// + /// Arch-neutral SIMD facade for SHA-512. Picks the per-arch backend at compile + /// time and returns the best block-compression routine the running CPU + /// supports, or AScalar when no SIMD backend is built/available. The + /// hash unit calls only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TSHA2_512Simd = class sealed + public + /// Return the fastest available SHA-512 compression routine for the + /// running CPU, falling back to AScalar. Call once at init. + class function Select(AScalar: TSHA512CompressProc): TSHA512CompressProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpSHA2_512X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpSHA2_512ArmBackend; +{$IFEND} + +{ TSHA2_512Simd } + +class function TSHA2_512Simd.Select(AScalar: TSHA512CompressProc): TSHA512CompressProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TSHA2_512X86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TSHA2_512ArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpSHA3Simd.pas b/HashLib/src/Simd/Facade/HlpSHA3Simd.pas new file mode 100644 index 0000000..63a7c7d --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpSHA3Simd.pas @@ -0,0 +1,58 @@ +unit HlpSHA3Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpSHA3; + +type + /// + /// Arch-neutral SIMD facade for Keccak-F1600 (SHA-3 / SHAKE). Picks the + /// per-arch backend at compile time and returns the best permute / absorb + /// routines the running CPU supports, or the scalar reference when no SIMD + /// backend is built/available. The hash unit calls only this facade and stays + /// free of any TCpuFeatures / HASHLIB_*_ASM knowledge. + /// + TSHA3Simd = class sealed + public + class function SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; static; + class function SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpSHA3X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpSHA3ArmBackend; +{$IFEND} + +{ TSHA3Simd } + +class function TSHA3Simd.SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TSHA3X86Backend.SelectPermute(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TSHA3ArmBackend.SelectPermute(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +class function TSHA3Simd.SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TSHA3X86Backend.SelectAbsorb(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TSHA3ArmBackend.SelectAbsorb(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpScryptSimd.pas b/HashLib/src/Simd/Facade/HlpScryptSimd.pas new file mode 100644 index 0000000..704ed60 --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpScryptSimd.pas @@ -0,0 +1,46 @@ +unit HlpScryptSimd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpPBKDF_ScryptNotBuildInAdapter; + +type + /// + /// Arch-neutral SIMD facade for scrypt's Salsa20/8 XOR core. Picks the per-arch + /// backend at compile time and returns the best routine the running CPU + /// supports, or AScalar when no SIMD backend is built/available. The KDF + /// unit calls only this facade and stays free of any TCpuFeatures / + /// HASHLIB_*_ASM knowledge. + /// + TScryptSimd = class sealed + public + class function Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpScryptX86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpScryptArmBackend; +{$IFEND} + +{ TScryptSimd } + +class function TScryptSimd.Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TScryptX86Backend.Select(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TScryptArmBackend.Select(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. diff --git a/HashLib/src/Simd/Facade/HlpXXHash3Simd.pas b/HashLib/src/Simd/Facade/HlpXXHash3Simd.pas new file mode 100644 index 0000000..75ab030 --- /dev/null +++ b/HashLib/src/Simd/Facade/HlpXXHash3Simd.pas @@ -0,0 +1,82 @@ +unit HlpXXHash3Simd; + +{$I ..\..\Include\HashLib.inc} + +interface + +uses + HlpXXHash3; + +type + /// + /// Arch-neutral SIMD facade for XXH3. Picks the per-arch backend at compile + /// time and returns the best accumulate / scramble / init-secret routines the + /// running CPU supports, or the scalar references when no SIMD backend is + /// built/available. The hash unit calls only this facade and stays free of any + /// TCpuFeatures / HASHLIB_*_ASM knowledge. + /// + TXXHash3Simd = class sealed + public + class function SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; static; + class function SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; static; + class function SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; static; + class function SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; static; + end; + +implementation + +{$IF DEFINED(HASHLIB_X86_SIMD)} +uses + HlpXXHash3X86Backend; +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} +uses + HlpXXHash3ArmBackend; +{$IFEND} + +{ TXXHash3Simd } + +class function TXXHash3Simd.SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TXXHash3X86Backend.SelectAccumulate512(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TXXHash3ArmBackend.SelectAccumulate512(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +class function TXXHash3Simd.SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TXXHash3X86Backend.SelectAccumulate(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TXXHash3ArmBackend.SelectAccumulate(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +class function TXXHash3Simd.SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TXXHash3X86Backend.SelectScrambleAcc(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TXXHash3ArmBackend.SelectScrambleAcc(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +class function TXXHash3Simd.SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; +begin +{$IF DEFINED(HASHLIB_X86_SIMD)} + Result := TXXHash3X86Backend.SelectInitSecret(AScalar); +{$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} + Result := TXXHash3ArmBackend.SelectInitSecret(AScalar); +{$ELSE} + Result := AScalar; +{$IFEND} +end; + +end. From 1eefec878dc5c98e3ff18860a4196c3a99bec9fe Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sun, 12 Jul 2026 02:00:29 +0100 Subject: [PATCH 02/10] Consolidate CRC into one generic engine + fold-by-8 SIMD kernels Engine consolidation (6 units -> 3, ~1,800 lines removed): - Delete HlpCRCStandard (wrapper TCRC16/32/64 + dead duplicate PKZIP/ Castagnoli classes), HlpCRC32Fast (whole UInt32 fast-path ecosystem incl. both Reflected32 SSE2 kernels), and HlpCRCFoldConstants (GF(2) math merged into HlpCRCCore). Factory named methods now route through the generic engine; on carry-less-multiply CPUs they already used the same kernel. - All 108 standards live in a single const table (params + aliases); replaces the 460-line case and per-class parameter duplicates. - Unified width 3..64 path: bit-serial engine deleted; MSB-first CRCs narrower than 8 bits run left-aligned at width 8 and un-shift at finalization; reflected CRCs are width-agnostic as-is. Fixes: - TransformFinal truncated widths 17-23 to 16 bits (live for CRC-17/CAN-FD); output is now sized by the constructor's HashSize ranges and the width-21 special case is gone. - Table cache was a class-level TDictionary mutated without a lock; now guarded by a critical section. - Fold state handoff uses TBinaryPrimitives.LoadUInt64/StoreUInt64 and a single UInt64 (kernels never touched the second qword). - Forward SSE2 kernels (x86_64 + i386) hoist width/mask/byte-count out of the per-16-byte-block loop. fold-by-8 kernels (128 bytes/iter for inputs >= 128B): - PCLMUL x86_64 reflected + forward gain an 8-accumulator upper path (xmm0-3 + xmm8-11) using the runtime-generated Fold_8x128 stride-1024 constants, reducing 8->4->1 into the untouched Barrett tail. New REX-prefixed pclmulqdq/pshufb encodings verified against GNU as. - PMULL aarch64 kernels regenerated with the same structure (v19-v22); all 32 new opcodes cross-checked against aarch64-linux-gnu-as. Tests: ChunkedData lengthened to 299 bytes so chunked tests cross- validate table/fold4/fold8; new fold-boundary sweep (22 lengths x 108 standards) against the byte-table reference. --- .../Delphi/HashLib.BenchmarkConsole.dpr | 3 - .../Delphi/HashLib.BenchmarkFMX.dpr | 3 - .../Delphi.Tests/HashLib.Tests.Mobile.dpr | 3 - .../Delphi.Tests/HashLib.Tests.Mobile.dproj | 3 - HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr | 3 - HashLib/src/Base/HlpHashFactory.pas | 22 +- HashLib/src/Checksum/HlpCRC.pas | 1873 +++++------------ HashLib/src/Checksum/HlpCRC32Fast.pas | 170 -- HashLib/src/Checksum/HlpCRCCore.pas | 567 +++-- HashLib/src/Checksum/HlpCRCFoldConstants.pas | 333 --- HashLib/src/Checksum/HlpCRCStandard.pas | 273 --- .../Simd/CRC/CRCFoldForwardPclmul_x86_64.inc | 158 +- .../Simd/CRC/CRCFoldForwardPmull_aarch64.inc | 119 +- .../Simd/CRC/CRCFoldForwardSse2_i386.inc | 18 +- .../Simd/CRC/CRCFoldForwardSse2_x86_64.inc | 15 +- .../Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc | 2 +- .../Simd/CRC/CRCFoldReflected32Sse2_i386.inc | 134 -- .../CRC/CRCFoldReflected32Sse2_x86_64.inc | 134 -- .../CRC/CRCFoldReflectedPclmul_x86_64.inc | 139 +- .../CRC/CRCFoldReflectedPmull_aarch64.inc | 101 +- .../CRC/CRCFoldReflectedVpclmul_x86_64.inc | 2 +- .../Packages/Delphi/HashLib4PascalPackage.dpk | 3 - .../Packages/FPC/HashLib4PascalPackage.lpk | 546 +++-- .../Packages/FPC/HashLib4PascalPackage.pas | 6 +- HashLib/src/Simd/Backend/HlpCRCArmBackend.pas | 10 +- HashLib/src/Simd/Backend/HlpCRCX86Backend.pas | 24 +- HashLib/src/Simd/Facade/HlpCRCSimd.pas | 23 +- 27 files changed, 1676 insertions(+), 3011 deletions(-) delete mode 100644 HashLib/src/Checksum/HlpCRC32Fast.pas delete mode 100644 HashLib/src/Checksum/HlpCRCFoldConstants.pas delete mode 100644 HashLib/src/Checksum/HlpCRCStandard.pas delete mode 100644 HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_i386.inc delete mode 100644 HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_x86_64.inc diff --git a/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr b/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr index 87d331a..d9151d4 100644 --- a/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr +++ b/HashLib.Benchmark/Delphi/HashLib.BenchmarkConsole.dpr @@ -28,9 +28,6 @@ uses HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', - HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', - HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', - HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', HlpGost in '..\..\HashLib\src\Crypto\HlpGost.pas', HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas', HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas', diff --git a/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr b/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr index 9417f11..3b4c486 100644 --- a/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr +++ b/HashLib.Benchmark/Delphi/HashLib.BenchmarkFMX.dpr @@ -27,9 +27,6 @@ uses HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', - HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', - HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', - HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', HlpGost in '..\..\HashLib\src\Crypto\HlpGost.pas', HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas', HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas', diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr index a78eb47..122693c 100644 --- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr +++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dpr @@ -29,9 +29,6 @@ uses HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', - HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', - HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', - HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', HlpGost in '..\..\HashLib\src\Crypto\HlpGost.pas', HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas', HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas', diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj index 5ea340f..302935a 100644 --- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj +++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.Mobile.dproj @@ -369,9 +369,6 @@ - - - diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr b/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr index 6b9016c..f6f545b 100644 --- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr +++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr @@ -46,9 +46,6 @@ uses HlpCRCSimd in '..\..\HashLib\src\Simd\Facade\HlpCRCSimd.pas', HlpCRCX86Backend in '..\..\HashLib\src\Simd\Backend\HlpCRCX86Backend.pas', HlpCRCArmBackend in '..\..\HashLib\src\Simd\Backend\HlpCRCArmBackend.pas', - HlpCRCFoldConstants in '..\..\HashLib\src\Checksum\HlpCRCFoldConstants.pas', - HlpCRCStandard in '..\..\HashLib\src\Checksum\HlpCRCStandard.pas', - HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas', HlpGost in '..\..\HashLib\src\Crypto\HlpGost.pas', HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas', HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas', diff --git a/HashLib/src/Base/HlpHashFactory.pas b/HashLib/src/Base/HlpHashFactory.pas index 9a1e7e1..3cacc5c 100644 --- a/HashLib/src/Base/HlpHashFactory.pas +++ b/HashLib/src/Base/HlpHashFactory.pas @@ -16,8 +16,6 @@ interface HlpAdler32, // CRC Units // HlpCRC, - HlpCRCStandard, - HlpCRC32Fast, // Hash32 Units // HlpAP, HlpBernstein, @@ -696,44 +694,44 @@ class function THashFactory.TChecksum.TCRC.CreateCRC16(APolynomial, AInitialValue: UInt64; AReflectIn, AReflectOut: Boolean; AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray): IHash; begin - Result := TCRC16.Create(APolynomial, AInitialValue, AReflectIn, AReflectOut, - AOutputXor, ACheckValue, ANames); + Result := HlpCRC.TCRC.Create(16, APolynomial, AInitialValue, AReflectIn, + AReflectOut, AOutputXor, ACheckValue, ANames); end; class function THashFactory.TChecksum.TCRC.CreateCRC16_BUYPASS: IHash; begin - Result := TCRC16_BUYPASS.Create(); + Result := HlpCRC.TCRC.CreateCRCObject(TCRCStandard.CRC16_BUYPASS); end; class function THashFactory.TChecksum.TCRC.CreateCRC32(APolynomial, AInitialValue: UInt64; AReflectIn, AReflectOut: Boolean; AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray): IHash; begin - Result := TCRC32.Create(APolynomial, AInitialValue, AReflectIn, AReflectOut, - AOutputXor, ACheckValue, ANames); + Result := HlpCRC.TCRC.Create(32, APolynomial, AInitialValue, AReflectIn, + AReflectOut, AOutputXor, ACheckValue, ANames); end; class function THashFactory.TChecksum.TCRC.CreateCRC32_CASTAGNOLI: IHash; begin - Result := HlpCRC32Fast.TCRC32_CASTAGNOLI.Create(); + Result := HlpCRC.TCRC.CreateCRCObject(TCRCStandard.CRC32C); end; class function THashFactory.TChecksum.TCRC.CreateCRC32_PKZIP: IHash; begin - Result := HlpCRC32Fast.TCRC32_PKZIP.Create(); + Result := HlpCRC.TCRC.CreateCRCObject(TCRCStandard.CRC32); end; class function THashFactory.TChecksum.TCRC.CreateCRC64(APolynomial, AInitialValue: UInt64; AReflectIn, AReflectOut: Boolean; AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray): IHash; begin - Result := TCRC64.Create(APolynomial, AInitialValue, AReflectIn, AReflectOut, - AOutputXor, ACheckValue, ANames); + Result := HlpCRC.TCRC.Create(64, APolynomial, AInitialValue, AReflectIn, + AReflectOut, AOutputXor, ACheckValue, ANames); end; class function THashFactory.TChecksum.TCRC.CreateCRC64_ECMA_182: IHash; begin - Result := TCRC64_ECMA_182.Create(); + Result := HlpCRC.TCRC.CreateCRCObject(TCRCStandard.CRC64); end; { THashFactory.TChecksum } diff --git a/HashLib/src/Checksum/HlpCRC.pas b/HashLib/src/Checksum/HlpCRC.pas index cb12017..9149fef 100644 --- a/HashLib/src/Checksum/HlpCRC.pas +++ b/HashLib/src/Checksum/HlpCRC.pas @@ -1,7 +1,15 @@ unit HlpCRC; -// A vast majority if not all of the parameters for these CRC standards -// were gotten from http://reveng.sourceforge.net/crc-catalogue/. +{ + Generic CRC engine for any width 3..64 and any polynomial, plus the catalogue + of named standards (parameters from http://reveng.sourceforge.net/crc-catalogue/). + + One engine path serves every width: a slicing-by-16 table plus the SIMD / + scalar fold selected in HlpCRCCore. Widths below 8 with MSB-first input are + computed in a left-aligned domain (polynomial and state shifted up by + 8 - Width, un-shifted at finalization); LSB-first (reflected) CRCs are + width-agnostic and run as-is. +} {$I ..\Include\HashLib.inc} @@ -9,7 +17,7 @@ interface uses SysUtils, - TypInfo, + SyncObjs, Generics.Collections, HlpHashLibTypes, HlpHash, @@ -21,625 +29,68 @@ interface HlpCRCCore; resourcestring - SUnSupportedCRCType = 'UnSupported CRC Type: "%s"'; SWidthOutOfRange = 'Width Must be Between 3 and 64. "%d"'; type /// - /// Enum of all defined and implemented CRC standards. + /// All defined and implemented CRC standards. /// - TCRCStandard = ( - - /// - /// CRC standard named "CRC3_GSM". - /// - CRC3_GSM, - - /// - /// CRC standard named "CRC3_ROHC". - /// - CRC3_ROHC, - - /// - /// CRC standard named "CRC4_INTERLAKEN". - /// - CRC4_INTERLAKEN, - - /// - /// CRC standard named "CRC4_ITU". - /// - CRC4_ITU, - - /// - /// CRC standard named "CRC5_EPC". - /// - CRC5_EPC, - - /// - /// CRC standard named "CRC5_ITU". - /// - CRC5_ITU, - - /// - /// CRC standard named "CRC5_USB". - /// - CRC5_USB, - - /// - /// CRC standard named "CRC6_CDMA2000A". - /// - CRC6_CDMA2000A, - - /// - /// CRC standard named "CRC6_CDMA2000B". - /// - CRC6_CDMA2000B, - - /// - /// CRC standard named "CRC6_DARC". - /// - CRC6_DARC, - - /// - /// CRC standard named "CRC6_GSM". - /// - CRC6_GSM, - - /// - /// CRC standard named "CRC6_ITU". - /// - CRC6_ITU, - - /// - /// CRC standard named "CRC7". - /// - CRC7, - - /// - /// CRC standard named "CRC7_ROHC". - /// - CRC7_ROHC, - - /// - /// CRC standard named "CRC7_UMTS". - /// - CRC7_UMTS, - - /// - /// CRC standard named "CRC8". - /// - CRC8, - - /// - /// CRC standard named "CRC8_AUTOSAR". - /// - CRC8_AUTOSAR, - - /// - /// CRC standard named "CRC8_BLUETOOTH". - /// - CRC8_BLUETOOTH, - - /// - /// CRC standard named "CRC8_CDMA2000". - /// - CRC8_CDMA2000, - - /// - /// CRC standard named "CRC8_DARC". - /// - CRC8_DARC, - - /// - /// CRC standard named "CRC8_DVBS2". - /// - CRC8_DVBS2, - - /// - /// CRC standard named "CRC8_EBU". - /// - CRC8_EBU, - - /// - /// CRC standard named "CRC8_GSMA". - /// - CRC8_GSMA, - - /// - /// CRC standard named "CRC8_GSMB". - /// - CRC8_GSMB, - - /// - /// CRC standard named "CRC8_ICODE". - /// - CRC8_ICODE, - - /// - /// CRC standard named "CRC8_ITU". - /// - CRC8_ITU, - - /// - /// CRC standard named "CRC8_LTE". - /// - CRC8_LTE, - - /// - /// CRC standard named "CRC8_MAXIM". - /// - CRC8_MAXIM, - - /// - /// CRC standard named "CRC8_OPENSAFETY". - /// - CRC8_OPENSAFETY, - - /// - /// CRC standard named "CRC8_ROHC". - /// - CRC8_ROHC, - - /// - /// CRC standard named "CRC8_SAEJ1850". - /// - CRC8_SAEJ1850, - - /// - /// CRC standard named "CRC8_WCDMA". - /// - CRC8_WCDMA, - - /// - /// CRC standard named "CRC8_MIFAREMAD". - /// - CRC8_MIFAREMAD, - - /// - /// CRC standard named "CRC8_NRSC5". - /// - CRC8_NRSC5, - - /// - /// CRC standard named "CRC10". - /// - CRC10, - - /// - /// CRC standard named "CRC10_CDMA2000". - /// - CRC10_CDMA2000, - - /// - /// CRC standard named "CRC10_GSM". - /// - CRC10_GSM, - - /// - /// CRC standard named "CRC11". - /// - CRC11, - - /// - /// CRC standard named "CRC11_UMTS". - /// - CRC11_UMTS, - - /// - /// CRC standard named "CRC12_CDMA2000". - /// - CRC12_CDMA2000, - - /// - /// CRC standard named "CRC12_DECT". - /// - CRC12_DECT, - - /// - /// CRC standard named "CRC12_GSM". - /// - CRC12_GSM, - - /// - /// CRC standard named "CRC12_UMTS". - /// - CRC12_UMTS, - - /// - /// CRC standard named "CRC13_BBC". - /// - CRC13_BBC, - - /// - /// CRC standard named "CRC14_DARC". - /// - CRC14_DARC, - - /// - /// CRC standard named "CRC14_GSM". - /// - CRC14_GSM, - - /// - /// CRC standard named "CRC15". - /// - CRC15, - - /// - /// CRC standard named "CRC15_MPT1327". - /// - CRC15_MPT1327, - - /// - /// CRC standard named "ARC". - /// - ARC, - - /// - /// CRC standard named "CRC16_AUGCCITT". - /// - CRC16_AUGCCITT, - - /// - /// CRC standard named "CRC16_BUYPASS". - /// - CRC16_BUYPASS, - - /// - /// CRC standard named "CRC16_CCITTFALSE". - /// - CRC16_CCITTFALSE, - - /// - /// CRC standard named "CRC16_CDMA2000". - /// - CRC16_CDMA2000, - - /// - /// CRC standard named "CRC16_CMS". - /// - CRC16_CMS, - - /// - /// CRC standard named "CRC16_DDS110". - /// - CRC16_DDS110, - - /// - /// CRC standard named "CRC16_DECTR". - /// - CRC16_DECTR, - - /// - /// CRC standard named "CRC16_DECTX". - /// - CRC16_DECTX, - - /// - /// CRC standard named "CRC16_DNP". - /// - CRC16_DNP, - - /// - /// CRC standard named "CRC16_EN13757". - /// - CRC16_EN13757, - - /// - /// CRC standard named "CRC16_GENIBUS". - /// - CRC16_GENIBUS, - - /// - /// CRC standard named "CRC16_GSM". - /// - CRC16_GSM, - - /// - /// CRC standard named "CRC16_LJ1200". - /// - CRC16_LJ1200, - - /// - /// CRC standard named "CRC16_MAXIM". - /// - CRC16_MAXIM, - - /// - /// CRC standard named "CRC16_MCRF4XX". - /// - CRC16_MCRF4XX, - - /// - /// CRC standard named "CRC16_OPENSAFETYA". - /// - CRC16_OPENSAFETYA, - - /// - /// CRC standard named "CRC16_OPENSAFETYB". - /// - CRC16_OPENSAFETYB, - - /// - /// CRC standard named "CRC16_PROFIBUS". - /// - CRC16_PROFIBUS, - - /// - /// CRC standard named "CRC16_RIELLO". - /// - CRC16_RIELLO, - - /// - /// CRC standard named "CRC16_T10DIF". - /// - CRC16_T10DIF, - - /// - /// CRC standard named "CRC16_TELEDISK". - /// - CRC16_TELEDISK, - - /// - /// CRC standard named "CRC16_TMS37157". - /// - CRC16_TMS37157, - - /// - /// CRC standard named "CRC16_USB". - /// - CRC16_USB, - - /// - /// CRC standard named "CRCA". - /// - CRCA, - - /// - /// CRC standard named "KERMIT". - /// - KERMIT, - - /// - /// CRC standard named "MODBUS". - /// - MODBUS, - - /// - /// CRC standard named "X25". - /// - X25, - - /// - /// CRC standard named "XMODEM". - /// - XMODEM, - - /// - /// CRC standard named "CRC16_NRSC5". - /// - CRC16_NRSC5, - - /// - /// CRC standard named "CRC17_CANFD". - /// - CRC17_CANFD, - - /// - /// CRC standard named "CRC21_CANFD". - /// - CRC21_CANFD, - - /// - /// CRC standard named "CRC24". - /// - CRC24, - - /// - /// CRC standard named "CRC24_BLE". - /// - CRC24_BLE, - - /// - /// CRC standard named "CRC24_FLEXRAYA". - /// - CRC24_FLEXRAYA, - - /// - /// CRC standard named "CRC24_FLEXRAYB". - /// - CRC24_FLEXRAYB, - - /// - /// CRC standard named "CRC24_INTERLAKEN". - /// - CRC24_INTERLAKEN, - - /// - /// CRC standard named "CRC24_LTEA". - /// - CRC24_LTEA, - - /// - /// CRC standard named "CRC24_LTEB". - /// - CRC24_LTEB, - - /// - /// CRC standard named "CRC24_OS9". - /// - CRC24_OS9, - - /// - /// CRC standard named "CRC30_CDMA". - /// - CRC30_CDMA, - - /// - /// CRC standard named "CRC31_PHILIPS". - /// - CRC31_PHILIPS, - - /// - /// CRC standard named "CRC32". - /// - CRC32, - - /// - /// CRC standard named "CRC32_AUTOSAR". - /// - CRC32_AUTOSAR, - - /// - /// CRC standard named "CRC32_BZIP2". - /// - CRC32_BZIP2, - - /// - /// CRC standard named "CRC32C". - /// - CRC32C, - - /// - /// CRC standard named "CRC32D". - /// - CRC32D, - - /// - /// CRC standard named "CRC32_MPEG2". - /// - CRC32_MPEG2, - - /// - /// CRC standard named "CRC32_POSIX". - /// - CRC32_POSIX, - - /// - /// CRC standard named "CRC32Q". - /// - CRC32Q, - - /// - /// CRC standard named "JAMCRC". - /// - JAMCRC, - - /// - /// CRC standard named "XFER". - /// - XFER, - - /// - /// CRC standard named "CRC32_CDROMEDC". - /// - CRC32_CDROMEDC, - - /// - /// CRC standard named "CRC40_GSM". - /// - CRC40_GSM, - - /// - /// CRC standard named "CRC64". - /// - CRC64, - - /// - /// CRC standard named "CRC64_GOISO". - /// - CRC64_GOISO, - - /// - /// CRC standard named "CRC64_WE". - /// - CRC64_WE, - - /// - /// CRC standard named "CRC64_XZ". - /// - CRC64_XZ, - - /// - /// CRC standard named "CRC64_1B". - /// - CRC64_1B, - - /// - /// CRC standard named "CRC64_Jones". - /// - CRC64_Jones); + TCRCStandard = (CRC3_GSM, CRC3_ROHC, CRC4_INTERLAKEN, CRC4_ITU, CRC5_EPC, + CRC5_ITU, CRC5_USB, CRC6_CDMA2000A, CRC6_CDMA2000B, CRC6_DARC, CRC6_GSM, + CRC6_ITU, CRC7, CRC7_ROHC, CRC7_UMTS, CRC8, CRC8_AUTOSAR, CRC8_BLUETOOTH, + CRC8_CDMA2000, CRC8_DARC, CRC8_DVBS2, CRC8_EBU, CRC8_GSMA, CRC8_GSMB, + CRC8_ICODE, CRC8_ITU, CRC8_LTE, CRC8_MAXIM, CRC8_OPENSAFETY, CRC8_ROHC, + CRC8_SAEJ1850, CRC8_WCDMA, CRC8_MIFAREMAD, CRC8_NRSC5, CRC10, + CRC10_CDMA2000, CRC10_GSM, CRC11, CRC11_UMTS, CRC12_CDMA2000, CRC12_DECT, + CRC12_GSM, CRC12_UMTS, CRC13_BBC, CRC14_DARC, CRC14_GSM, CRC15, + CRC15_MPT1327, ARC, CRC16_AUGCCITT, CRC16_BUYPASS, CRC16_CCITTFALSE, + CRC16_CDMA2000, CRC16_CMS, CRC16_DDS110, CRC16_DECTR, CRC16_DECTX, + CRC16_DNP, CRC16_EN13757, CRC16_GENIBUS, CRC16_GSM, CRC16_LJ1200, + CRC16_MAXIM, CRC16_MCRF4XX, CRC16_OPENSAFETYA, CRC16_OPENSAFETYB, + CRC16_PROFIBUS, CRC16_RIELLO, CRC16_T10DIF, CRC16_TELEDISK, CRC16_TMS37157, + CRC16_USB, CRCA, KERMIT, MODBUS, X25, XMODEM, CRC16_NRSC5, CRC17_CANFD, + CRC21_CANFD, CRC24, CRC24_BLE, CRC24_FLEXRAYA, CRC24_FLEXRAYB, + CRC24_INTERLAKEN, CRC24_LTEA, CRC24_LTEB, CRC24_OS9, CRC30_CDMA, + CRC31_PHILIPS, CRC32, CRC32_AUTOSAR, CRC32_BZIP2, CRC32C, CRC32D, + CRC32_MPEG2, CRC32_POSIX, CRC32Q, JAMCRC, XFER, CRC32_CDROMEDC, CRC40_GSM, + CRC64, CRC64_GOISO, CRC64_WE, CRC64_XZ, CRC64_1B, CRC64_Jones); type TCRC = class sealed(THash, IChecksum, ICRC, ITransformBlock) strict private - type - TCRCCacheValue = record - Table: THashLibMatrixUInt64Array; - FoldRuntime: TCRCFoldRuntimeCtx; - end; - class var FCache: TDictionary; + FCacheLock: TCriticalSection; var FNames: THashLibStringArray; - FWidth: Int32; + FWidth, FEngineWidth, FEngineShift: Int32; FPolynomial, FInitialValue, FOutputXor, FCheckValue, FCRCMask, - FCRCHighBitMask, FHash: UInt64; + FHash: UInt64; FIsInputReflected, FIsOutputReflected: Boolean; FCacheEntry: TCRCCacheValue; - const - MinTableWidth = Int32(7); - class constructor CreateCRCCache; class destructor DestroyCRCCache; - class function MakeCacheKey(APoly: UInt64; AWidth: Int32; - AReflected: Boolean): String; static; - class function GetOrCreateCacheEntry(APoly: UInt64; AWidth: Int32; - AReflected: Boolean): TCRCCacheValue; static; class function GenerateCRCTable(APoly: UInt64; AWidth: Int32; AReflected: Boolean): THashLibMatrixUInt64Array; static; + class function GetOrCreateCacheEntry(APoly: UInt64; AWidth: Int32; + AReflected: Boolean): TCRCCacheValue; static; - function GetNames: THashLibStringArray; inline; - procedure SetNames(const AValue: THashLibStringArray); inline; - function GetWidth: Int32; inline; - procedure SetWidth(AValue: Int32); inline; - function GetPolynomial: UInt64; inline; - procedure SetPolynomial(AValue: UInt64); inline; - function GetInitialValue: UInt64; inline; - procedure SetInitialValue(AValue: UInt64); inline; - function GetIsInputReflected: Boolean; inline; - procedure SetIsInputReflected(AValue: Boolean); inline; - function GetIsOutputReflected: Boolean; inline; - procedure SetIsOutputReflected(AValue: Boolean); inline; - function GetOutputXor: UInt64; inline; - procedure SetOutputXor(AValue: UInt64); inline; - function GetCheckValue: UInt64; inline; - procedure SetCheckValue(AValue: UInt64); inline; + function GetNames: THashLibStringArray; + function GetWidth: Int32; + function GetPolynomial: UInt64; + function GetInitialValue: UInt64; + function GetIsInputReflected: Boolean; + function GetIsOutputReflected: Boolean; + function GetOutputXor: UInt64; + function GetCheckValue: UInt64; - // Table-driven byte path: length < MinSimdBytes or tail after fold (no 16-byte block). + // Table-driven byte path: length < MinSimdBytes or tail after fold. procedure UpdateCRCViaByteTable(AData: PByte; ADataLength, AIndex: Int32); - // Bit-serial update without table (width <= MinTableWidth). - procedure UpdateCRCViaBitSerial(AData: PByte; ADataLength, AIndex: Int32); - - // reflects the lower 'width' LBits of 'value' - class function Reflect(AValue: UInt64; AWidth: Int32): UInt64; static; - - property Names: THashLibStringArray read GetNames write SetNames; - property Width: Int32 read GetWidth write SetWidth; - property Polynomial: UInt64 read GetPolynomial write SetPolynomial; - property InitialValue: UInt64 read GetInitialValue write SetInitialValue; - property IsInputReflected: Boolean read GetIsInputReflected - write SetIsInputReflected; - property IsOutputReflected: Boolean read GetIsOutputReflected - write SetIsOutputReflected; - property OutputXor: UInt64 read GetOutputXor write SetOutputXor; - property CheckValue: UInt64 read GetCheckValue write SetCheckValue; strict protected function GetName: String; override; @@ -663,91 +114,465 @@ TCRCCacheValue = record implementation -{ TCRC } +type + TCRCStandardDef = record + Width: Int32; + Poly, Init: UInt64; + RefIn, RefOut: Boolean; + XorOut, Check: UInt64; + Names: String; // comma-separated aliases; first one is the primary name + end; -function TCRC.GetCheckValue: UInt64; +const + CRCStandardDefs: array [TCRCStandard] of TCRCStandardDef = ( + (Width: 3; Poly: $3; Init: $0; RefIn: False; RefOut: False; XorOut: $7; + Check: $4; Names: 'CRC-3/GSM'), + (Width: 3; Poly: $3; Init: $7; RefIn: True; RefOut: True; XorOut: $0; + Check: $6; Names: 'CRC-3/ROHC'), + (Width: 4; Poly: $3; Init: $F; RefIn: False; RefOut: False; XorOut: $F; + Check: $B; Names: 'CRC-4/INTERLAKEN'), + (Width: 4; Poly: $3; Init: $0; RefIn: True; RefOut: True; XorOut: $0; + Check: $7; Names: 'CRC-4/ITU,CRC-4/G-704'), + (Width: 5; Poly: $9; Init: $9; RefIn: False; RefOut: False; XorOut: $00; + Check: $00; Names: 'CRC-5/EPC,CRC-5/EPC-C1G2'), + (Width: 5; Poly: $15; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $07; Names: 'CRC-5/ITU,CRC-5/G-704'), + (Width: 5; Poly: $05; Init: $1F; RefIn: True; RefOut: True; XorOut: $1F; + Check: $19; Names: 'CRC-5/USB'), + (Width: 6; Poly: $27; Init: $3F; RefIn: False; RefOut: False; XorOut: $00; + Check: $0D; Names: 'CRC-6/CDMA2000-A'), + (Width: 6; Poly: $07; Init: $3F; RefIn: False; RefOut: False; XorOut: $00; + Check: $3B; Names: 'CRC-6/CDMA2000-B'), + (Width: 6; Poly: $19; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $26; Names: 'CRC-6/DARC'), + (Width: 6; Poly: $2F; Init: $00; RefIn: False; RefOut: False; XorOut: $3F; + Check: $13; Names: 'CRC-6/GSM'), + (Width: 6; Poly: $03; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $06; Names: 'CRC-6/ITU,CRC-6/G-704'), + (Width: 7; Poly: $09; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $75; Names: 'CRC-7,CRC-7/MMC'), + (Width: 7; Poly: $4F; Init: $7F; RefIn: True; RefOut: True; XorOut: $00; + Check: $53; Names: 'CRC-7/ROHC'), + (Width: 7; Poly: $45; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $61; Names: 'CRC-7/UMTS'), + (Width: 8; Poly: $07; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $F4; Names: 'CRC-8,CRC-8/SMBUS'), + (Width: 8; Poly: $2F; Init: $FF; RefIn: False; RefOut: False; XorOut: $FF; + Check: $DF; Names: 'CRC-8/AUTOSAR'), + (Width: 8; Poly: $A7; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $26; Names: 'CRC-8/BLUETOOTH'), + (Width: 8; Poly: $9B; Init: $FF; RefIn: False; RefOut: False; XorOut: $00; + Check: $DA; Names: 'CRC-8/CDMA2000'), + (Width: 8; Poly: $39; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $15; Names: 'CRC-8/DARC'), + (Width: 8; Poly: $D5; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $BC; Names: 'CRC-8/DVB-S2'), + (Width: 8; Poly: $1D; Init: $FF; RefIn: True; RefOut: True; XorOut: $00; + Check: $97; Names: 'CRC-8/EBU,CRC-8/AES,CRC-8/TECH-3250'), + (Width: 8; Poly: $1D; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $37; Names: 'CRC-8/GSM-A'), + (Width: 8; Poly: $49; Init: $00; RefIn: False; RefOut: False; XorOut: $FF; + Check: $94; Names: 'CRC-8/GSM-B'), + (Width: 8; Poly: $1D; Init: $FD; RefIn: False; RefOut: False; XorOut: $00; + Check: $7E; Names: 'CRC-8/I-CODE'), + (Width: 8; Poly: $07; Init: $00; RefIn: False; RefOut: False; XorOut: $55; + Check: $A1; Names: 'CRC-8/ITU,CRC-8/I-432-1'), + (Width: 8; Poly: $9B; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $EA; Names: 'CRC-8/LTE'), + (Width: 8; Poly: $31; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $A1; Names: 'CRC-8/MAXIM,DOW-CRC,CRC-8/MAXIM-DOW'), + (Width: 8; Poly: $2F; Init: $00; RefIn: False; RefOut: False; XorOut: $00; + Check: $3E; Names: 'CRC-8/OPENSAFETY'), + (Width: 8; Poly: $07; Init: $FF; RefIn: True; RefOut: True; XorOut: $00; + Check: $D0; Names: 'CRC-8/ROHC'), + (Width: 8; Poly: $1D; Init: $FF; RefIn: False; RefOut: False; XorOut: $FF; + Check: $4B; Names: 'CRC-8/SAE-J1850'), + (Width: 8; Poly: $9B; Init: $00; RefIn: True; RefOut: True; XorOut: $00; + Check: $25; Names: 'CRC-8/WCDMA'), + (Width: 8; Poly: $1D; Init: $C7; RefIn: False; RefOut: False; XorOut: $00; + Check: $99; Names: 'CRC-8/MIFARE-MAD'), + (Width: 8; Poly: $31; Init: $FF; RefIn: False; RefOut: False; XorOut: $00; + Check: $F7; Names: 'CRC-8/NRSC-5'), + (Width: 10; Poly: $233; Init: $000; RefIn: False; RefOut: False; + XorOut: $000; Check: $199; Names: 'CRC-10,CRC-10/ATM,CRC-10/I-610'), + (Width: 10; Poly: $3D9; Init: $3FF; RefIn: False; RefOut: False; + XorOut: $000; Check: $233; Names: 'CRC-10/CDMA2000'), + (Width: 10; Poly: $175; Init: $000; RefIn: False; RefOut: False; + XorOut: $3FF; Check: $12A; Names: 'CRC-10/GSM'), + (Width: 11; Poly: $385; Init: $01A; RefIn: False; RefOut: False; + XorOut: $000; Check: $5A3; Names: 'CRC-11,CRC-11/FLEXRAY'), + (Width: 11; Poly: $307; Init: $000; RefIn: False; RefOut: False; + XorOut: $000; Check: $061; Names: 'CRC-11/UMTS'), + (Width: 12; Poly: $F13; Init: $FFF; RefIn: False; RefOut: False; + XorOut: $000; Check: $D4D; Names: 'CRC-12/CDMA2000'), + (Width: 12; Poly: $80F; Init: $000; RefIn: False; RefOut: False; + XorOut: $000; Check: $F5B; Names: 'CRC-12/DECT,X-CRC-12'), + (Width: 12; Poly: $D31; Init: $000; RefIn: False; RefOut: False; + XorOut: $FFF; Check: $B34; Names: 'CRC-12/GSM'), + (Width: 12; Poly: $80F; Init: $000; RefIn: False; RefOut: True; + XorOut: $000; Check: $DAF; Names: 'CRC-12/UMTS,CRC-12/3GPP'), + (Width: 13; Poly: $1CF5; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $04FA; Names: 'CRC-13/BBC'), + (Width: 14; Poly: $0805; Init: $0000; RefIn: True; RefOut: True; + XorOut: $0000; Check: $082D; Names: 'CRC-14/DARC'), + (Width: 14; Poly: $202D; Init: $0000; RefIn: False; RefOut: False; + XorOut: $3FFF; Check: $30AE; Names: 'CRC-14/GSM'), + (Width: 15; Poly: $4599; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $059E; Names: 'CRC-15,CRC-15/CAN'), + (Width: 15; Poly: $6815; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0001; Check: $2566; Names: 'CRC-15/MPT1327'), + (Width: 16; Poly: $8005; Init: $0000; RefIn: True; RefOut: True; + XorOut: $0000; Check: $BB3D; + Names: 'CRC-16,ARC,CRC-IBM,CRC-16/ARC,CRC-16/LHA'), + (Width: 16; Poly: $1021; Init: $1D0F; RefIn: False; RefOut: False; + XorOut: $0000; Check: $E5CC; + Names: 'CRC-16/AUG-CCITT,CRC-16/SPI-FUJITSU'), + (Width: 16; Poly: $8005; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $FEE8; + Names: 'CRC-16/BUYPASS,CRC-16/VERIFONE,CRC-16/UMTS'), + (Width: 16; Poly: $1021; Init: $FFFF; RefIn: False; RefOut: False; + XorOut: $0000; Check: $29B1; + Names: 'CRC-16/CCITT-False,CRC-16/AUTOSAR,CRC-16/IBM-3740'), + (Width: 16; Poly: $C867; Init: $FFFF; RefIn: False; RefOut: False; + XorOut: $0000; Check: $4C06; Names: 'CRC-16/CDMA2000'), + (Width: 16; Poly: $8005; Init: $FFFF; RefIn: False; RefOut: False; + XorOut: $0000; Check: $AEE7; Names: 'CRC-16/CMS'), + (Width: 16; Poly: $8005; Init: $800D; RefIn: False; RefOut: False; + XorOut: $0000; Check: $9ECF; Names: 'CRC-16/DDS-110'), + (Width: 16; Poly: $0589; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0001; Check: $007E; Names: 'CRC-16/DECT-R,R-CRC-16'), + (Width: 16; Poly: $0589; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $007F; Names: 'CRC-16/DECT-X,X-CRC-16'), + (Width: 16; Poly: $3D65; Init: $0000; RefIn: True; RefOut: True; + XorOut: $FFFF; Check: $EA82; Names: 'CRC-16/DNP'), + (Width: 16; Poly: $3D65; Init: $0000; RefIn: False; RefOut: False; + XorOut: $FFFF; Check: $C2B7; Names: 'CRC-16/EN13757'), + (Width: 16; Poly: $1021; Init: $FFFF; RefIn: False; RefOut: False; + XorOut: $FFFF; Check: $D64E; + Names: 'CRC-16/GENIBUS,CRC-16/EPC,CRC-16/I-CODE,CRC-16/DARC,CRC-16/EPC-C1G2'), + (Width: 16; Poly: $1021; Init: $0000; RefIn: False; RefOut: False; + XorOut: $FFFF; Check: $CE3C; Names: 'CRC-16/GSM'), + (Width: 16; Poly: $6F63; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $BDF4; Names: 'CRC-16/LJ1200'), + (Width: 16; Poly: $8005; Init: $0000; RefIn: True; RefOut: True; + XorOut: $FFFF; Check: $44C2; Names: 'CRC-16/MAXIM,CRC-16/MAXIM-DOW'), + (Width: 16; Poly: $1021; Init: $FFFF; RefIn: True; RefOut: True; + XorOut: $0000; Check: $6F91; Names: 'CRC-16/MCRF4XX'), + (Width: 16; Poly: $5935; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $5D38; Names: 'CRC-16/OPENSAFETY-A'), + (Width: 16; Poly: $755B; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $20FE; Names: 'CRC-16/OPENSAFETY-B'), + (Width: 16; Poly: $1DCF; Init: $FFFF; RefIn: False; RefOut: False; + XorOut: $FFFF; Check: $A819; Names: 'CRC-16/PROFIBUS,CRC-16/IEC-61158-2'), + (Width: 16; Poly: $1021; Init: $B2AA; RefIn: True; RefOut: True; + XorOut: $0000; Check: $63D0; Names: 'CRC-16/RIELLO'), + (Width: 16; Poly: $8BB7; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $D0DB; Names: 'CRC-16/T10-DIF'), + (Width: 16; Poly: $A097; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $0FB3; Names: 'CRC-16/TELEDISK'), + (Width: 16; Poly: $1021; Init: $89EC; RefIn: True; RefOut: True; + XorOut: $0000; Check: $26B1; Names: 'CRC-16/TMS37157'), + (Width: 16; Poly: $8005; Init: $FFFF; RefIn: True; RefOut: True; + XorOut: $FFFF; Check: $B4C8; Names: 'CRC-16/USB'), + (Width: 16; Poly: $1021; Init: $C6C6; RefIn: True; RefOut: True; + XorOut: $0000; Check: $BF05; Names: 'CRC-A,CRC-16/ISO-IEC-14443-3-A'), + (Width: 16; Poly: $1021; Init: $0000; RefIn: True; RefOut: True; + XorOut: $0000; Check: $2189; + Names: 'KERMIT,CRC-16/CCITT,CRC-16/CCITT-True,CRC-CCITT,CRC-16/KERMIT,CRC-16/V-41-LSB'), + (Width: 16; Poly: $8005; Init: $FFFF; RefIn: True; RefOut: True; + XorOut: $0000; Check: $4B37; Names: 'MODBUS,CRC-16/MODBUS'), + (Width: 16; Poly: $1021; Init: $FFFF; RefIn: True; RefOut: True; + XorOut: $FFFF; Check: $906E; + Names: 'X-25,CRC-16/IBM-SDLC,CRC-16/ISO-HDLC,CRC-16/ISO-IEC-14443-3-B,CRC-B,CRC-16/X-25'), + (Width: 16; Poly: $1021; Init: $0000; RefIn: False; RefOut: False; + XorOut: $0000; Check: $31C3; + Names: 'XMODEM,ZMODEM,CRC-16/ACORN,CRC-16/XMODEM,CRC-16/V-41-MSB'), + (Width: 16; Poly: $080B; Init: $FFFF; RefIn: True; RefOut: True; + XorOut: $0000; Check: $A066; Names: 'CRC-16/NRSC-5'), + (Width: 17; Poly: $1685B; Init: $00000; RefIn: False; RefOut: False; + XorOut: $00000; Check: $04F03; Names: 'CRC-17/CAN-FD'), + (Width: 21; Poly: $102899; Init: $00000; RefIn: False; RefOut: False; + XorOut: $00000; Check: $0ED841; Names: 'CRC-21/CAN-FD'), + (Width: 24; Poly: $864CFB; Init: $B704CE; RefIn: False; RefOut: False; + XorOut: $000000; Check: $21CF02; Names: 'CRC-24,CRC-24/OPENPGP'), + (Width: 24; Poly: $00065B; Init: $555555; RefIn: True; RefOut: True; + XorOut: $000000; Check: $C25A56; Names: 'CRC-24/BLE'), + (Width: 24; Poly: $5D6DCB; Init: $FEDCBA; RefIn: False; RefOut: False; + XorOut: $000000; Check: $7979BD; Names: 'CRC-24/FLEXRAY-A'), + (Width: 24; Poly: $5D6DCB; Init: $ABCDEF; RefIn: False; RefOut: False; + XorOut: $000000; Check: $1F23B8; Names: 'CRC-24/FLEXRAY-B'), + (Width: 24; Poly: $328B63; Init: $FFFFFF; RefIn: False; RefOut: False; + XorOut: $FFFFFF; Check: $B4F3E6; Names: 'CRC-24/INTERLAKEN'), + (Width: 24; Poly: $864CFB; Init: $000000; RefIn: False; RefOut: False; + XorOut: $000000; Check: $CDE703; Names: 'CRC-24/LTE-A'), + (Width: 24; Poly: $800063; Init: $000000; RefIn: False; RefOut: False; + XorOut: $000000; Check: $23EF52; Names: 'CRC-24/LTE-B'), + (Width: 24; Poly: $800063; Init: $FFFFFF; RefIn: False; RefOut: False; + XorOut: $FFFFFF; Check: $200FA5; Names: 'CRC-24/OS-9'), + (Width: 30; Poly: $2030B9C7; Init: $3FFFFFFF; RefIn: False; RefOut: False; + XorOut: $3FFFFFFF; Check: $04C34ABF; Names: 'CRC-30/CDMA'), + (Width: 31; Poly: $04C11DB7; Init: $7FFFFFFF; RefIn: False; RefOut: False; + XorOut: $7FFFFFFF; Check: $0CE9E46C; Names: 'CRC-31/PHILLIPS'), + (Width: 32; Poly: $04C11DB7; Init: $FFFFFFFF; RefIn: True; RefOut: True; + XorOut: $FFFFFFFF; Check: $CBF43926; + Names: 'CRC-32,CRC-32/ADCCP,CRC-32/V-42,CRC-32/XZ,PKZIP,CRC-32/ISO-HDLC'), + (Width: 32; Poly: $F4ACFB13; Init: $FFFFFFFF; RefIn: True; RefOut: True; + XorOut: $FFFFFFFF; Check: $1697D06A; Names: 'CRC-32/AUTOSAR'), + (Width: 32; Poly: $04C11DB7; Init: $FFFFFFFF; RefIn: False; RefOut: False; + XorOut: $FFFFFFFF; Check: $FC891918; + Names: 'CRC-32/BZIP2,CRC-32/AAL5,CRC-32/DECT-B,B-CRC-32'), + (Width: 32; Poly: $1EDC6F41; Init: $FFFFFFFF; RefIn: True; RefOut: True; + XorOut: $FFFFFFFF; Check: $E3069283; + Names: 'CRC-32C,CRC-32/BASE91-C,CRC-32/CASTAGNOLI,CRC-32/INTERLAKEN,CRC-32/ISCSI'), + (Width: 32; Poly: $A833982B; Init: $FFFFFFFF; RefIn: True; RefOut: True; + XorOut: $FFFFFFFF; Check: $87315576; Names: 'CRC-32D,CRC-32/BASE91-D'), + (Width: 32; Poly: $04C11DB7; Init: $FFFFFFFF; RefIn: False; RefOut: False; + XorOut: $00000000; Check: $0376E6E7; Names: 'CRC-32/MPEG-2'), + (Width: 32; Poly: $04C11DB7; Init: $FFFFFFFF; RefIn: False; RefOut: False; + XorOut: $00000000; Check: $0376E6E7; Names: 'CRC-32/POSIX,CKSUM'), + (Width: 32; Poly: $814141AB; Init: $00000000; RefIn: False; RefOut: False; + XorOut: $00000000; Check: $3010BF7F; Names: 'CRC-32Q,CRC-32/AIXM'), + (Width: 32; Poly: $04C11DB7; Init: $FFFFFFFF; RefIn: True; RefOut: True; + XorOut: $00000000; Check: $340BC6D9; Names: 'JAMCRC,CRC-32/JAMCRC'), + (Width: 32; Poly: $000000AF; Init: $00000000; RefIn: False; RefOut: False; + XorOut: $00000000; Check: $BD0BE338; Names: 'XFER,CRC-32/XFER'), + (Width: 32; Poly: $8001801B; Init: $00000000; RefIn: True; RefOut: True; + XorOut: $00000000; Check: $6EC2EDC4; Names: 'CRC-32/CD-ROM-EDC'), + (Width: 40; Poly: $0004820009; Init: $0000000000; RefIn: False; + RefOut: False; XorOut: $FFFFFFFFFF; Check: $D4164FC646; + Names: 'CRC-40/GSM'), + (Width: 64; Poly: $42F0E1EBA9EA3693; Init: $0000000000000000; + RefIn: False; RefOut: False; XorOut: $0000000000000000; + Check: $6C40DF5F0B497347; Names: 'CRC-64,CRC-64/ECMA-182'), + (Width: 64; Poly: $000000000000001B; Init: UInt64($FFFFFFFFFFFFFFFF); + RefIn: True; RefOut: True; XorOut: UInt64($FFFFFFFFFFFFFFFF); + Check: UInt64($B90956C775A41001); Names: 'CRC-64/GO-ISO'), + (Width: 64; Poly: $42F0E1EBA9EA3693; Init: UInt64($FFFFFFFFFFFFFFFF); + RefIn: False; RefOut: False; XorOut: UInt64($FFFFFFFFFFFFFFFF); + Check: $62EC59E3F1A4F00A; Names: 'CRC-64/WE'), + (Width: 64; Poly: $42F0E1EBA9EA3693; Init: UInt64($FFFFFFFFFFFFFFFF); + RefIn: True; RefOut: True; XorOut: UInt64($FFFFFFFFFFFFFFFF); + Check: UInt64($995DC9BBDF1939FA); Names: 'CRC-64/XZ,CRC-64/GO-ECMA'), + (Width: 64; Poly: $000000000000001B; Init: $0000000000000000; + RefIn: True; RefOut: True; XorOut: $0000000000000000; + Check: $46A5A9388A5BEFFE; Names: 'CRC-64/1B'), + (Width: 64; Poly: UInt64($AD93D23594C935A9); + Init: UInt64($FFFFFFFFFFFFFFFF); RefIn: True; RefOut: True; + XorOut: $0000000000000000; Check: UInt64($CAA717168609F281); + Names: 'CRC-64/Jones')); + +function SplitNames(const ACsv: String): THashLibStringArray; +var + LCount, LPos, LStart, LIdx: Int32; begin - Result := FCheckValue; + LCount := 1; + for LPos := 1 to System.Length(ACsv) do + if ACsv[LPos] = ',' then + System.Inc(LCount); + System.SetLength(Result, LCount); + LIdx := 0; + LStart := 1; + for LPos := 1 to System.Length(ACsv) do + if ACsv[LPos] = ',' then + begin + Result[LIdx] := System.Copy(ACsv, LStart, LPos - LStart); + System.Inc(LIdx); + LStart := LPos + 1; + end; + Result[LIdx] := System.Copy(ACsv, LStart, + System.Length(ACsv) - LStart + 1); end; -function TCRC.GetInitialValue: UInt64; +{ TCRC } + +class constructor TCRC.CreateCRCCache; begin - Result := FInitialValue; + FCache := TDictionary.Create; + FCacheLock := TCriticalSection.Create; end; -function TCRC.GetNames: THashLibStringArray; +class destructor TCRC.DestroyCRCCache; begin - Result := FNames; + FCache.Free; + FCacheLock.Free; end; -function TCRC.GetPolynomial: UInt64; +class function TCRC.GenerateCRCTable(APoly: UInt64; AWidth: Int32; + AReflected: Boolean): THashLibMatrixUInt64Array; +var + LCRC: UInt64; + LIdx, LRow, LBit: Int32; + LReflectedPoly, LHighBitMask, LMask: UInt64; begin - Result := FPolynomial; + System.SetLength(Result, 16); + for LIdx := 0 to 15 do + System.SetLength(Result[LIdx], 256); + + if AReflected then + begin + LReflectedPoly := TGF2.BitReverse(APoly, AWidth); + for LIdx := 0 to 255 do + begin + LCRC := UInt64(LIdx); + for LRow := 0 to 15 do + begin + for LBit := 0 to 7 do + LCRC := (LCRC shr 1) xor (UInt64(-Int64(LCRC and 1)) and LReflectedPoly); + Result[LRow][LIdx] := LCRC; + end; + end; + end + else + begin + LHighBitMask := UInt64(1) shl (AWidth - 1); + LMask := ((LHighBitMask - 1) shl 1) or 1; + for LIdx := 0 to 255 do + begin + LCRC := UInt64(LIdx) shl (AWidth - 8); + for LRow := 0 to 15 do + begin + for LBit := 0 to 7 do + begin + if (LCRC and LHighBitMask) <> 0 then + LCRC := ((LCRC shl 1) xor APoly) and LMask + else + LCRC := (LCRC shl 1) and LMask; + end; + Result[LRow][LIdx] := LCRC; + end; + end; + end; end; -function TCRC.GetIsInputReflected: Boolean; +class function TCRC.GetOrCreateCacheEntry(APoly: UInt64; AWidth: Int32; + AReflected: Boolean): TCRCCacheValue; +var + LKey: String; begin - Result := FIsInputReflected; + LKey := Format('Poly-%x:Width-%d:Reflected-%s', + [APoly, AWidth, BoolToStr(AReflected, True)]); + FCacheLock.Acquire; + try + if not FCache.TryGetValue(LKey, Result) then + begin + Result.Table := GenerateCRCTable(APoly, AWidth, AReflected); + CRC_InitFoldRuntimeCtx(Result.Table, APoly, AWidth, AReflected, + Result.FoldRuntime); + FCache.Add(LKey, Result); + end; + finally + FCacheLock.Release; + end; end; -function TCRC.GetIsOutputReflected: Boolean; +constructor TCRC.Create(AWidth: Int32; APolynomial, AInitial: UInt64; + AIsInputReflected, AIsOutputReflected: Boolean; + AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); begin - Result := FIsOutputReflected; + if not(AWidth in [3 .. 64]) then + begin + raise EArgumentOutOfRangeHashLibException.CreateResFmt(@SWidthOutOfRange, + [AWidth]); + end; + + inherited Create(-1, -1); // Dummy State + + case AWidth of + 3 .. 7: + Self.HashSize := 1; + 8 .. 16: + Self.HashSize := 2; + 17 .. 39: + Self.HashSize := 4; + else + Self.HashSize := 8; + end; + Self.BlockSize := 1; + + FNames := ANames; + FWidth := AWidth; + FPolynomial := APolynomial; + FInitialValue := AInitial; + FIsInputReflected := AIsInputReflected; + FIsOutputReflected := AIsOutputReflected; + FOutputXor := AOutputXor; + FCheckValue := ACheckValue; + + // MSB-first CRCs narrower than a byte run left-aligned at width 8 + // (polynomial and state shifted up by FEngineShift, un-shifted at + // finalization). LSB-first CRCs are width-agnostic and run as-is. + if (AWidth < 8) and not AIsInputReflected then + FEngineShift := 8 - AWidth + else + FEngineShift := 0; + FEngineWidth := AWidth + FEngineShift; + + FCRCMask := (((UInt64(1) shl (FEngineWidth - 1)) - 1) shl 1) or 1; + + FCacheEntry := GetOrCreateCacheEntry(APolynomial shl FEngineShift, + FEngineWidth, AIsInputReflected); end; -function TCRC.GetWidth: Int32; +class function TCRC.CreateCRCObject(AValue: TCRCStandard): ICRC; +var + LDef: TCRCStandardDef; begin - Result := FWidth; + LDef := CRCStandardDefs[AValue]; + Result := TCRC.Create(LDef.Width, LDef.Poly, LDef.Init, LDef.RefIn, + LDef.RefOut, LDef.XorOut, LDef.Check, SplitNames(LDef.Names)); end; -function TCRC.GetOutputXor: UInt64; +function TCRC.GetNames: THashLibStringArray; begin - Result := FOutputXor; + Result := FNames; end; -procedure TCRC.SetCheckValue(AValue: UInt64); +function TCRC.GetWidth: Int32; begin - FCheckValue := AValue; + Result := FWidth; end; -procedure TCRC.SetInitialValue(AValue: UInt64); +function TCRC.GetPolynomial: UInt64; begin - FInitialValue := AValue; + Result := FPolynomial; end; -procedure TCRC.SetNames(const AValue: THashLibStringArray); +function TCRC.GetInitialValue: UInt64; begin - FNames := AValue; + Result := FInitialValue; end; -procedure TCRC.SetPolynomial(AValue: UInt64); +function TCRC.GetIsInputReflected: Boolean; begin - FPolynomial := AValue; + Result := FIsInputReflected; end; -procedure TCRC.SetIsInputReflected(AValue: Boolean); +function TCRC.GetIsOutputReflected: Boolean; begin - FIsInputReflected := AValue; + Result := FIsOutputReflected; end; -procedure TCRC.SetIsOutputReflected(AValue: Boolean); +function TCRC.GetOutputXor: UInt64; begin - FIsOutputReflected := AValue; + Result := FOutputXor; end; -procedure TCRC.SetWidth(AValue: Int32); +function TCRC.GetCheckValue: UInt64; begin - FWidth := AValue; + Result := FCheckValue; end; -procedure TCRC.SetOutputXor(AValue: UInt64); +function TCRC.GetName: String; begin - FOutputXor := AValue; + Result := Format('T%s', [FNames[0]]); end; -function TCRC.GetName: String; +procedure TCRC.Initialize; begin - Result := Format('T%s', [Names[0]]); + if FIsInputReflected then + FHash := TGF2.BitReverse(FInitialValue, FWidth) + else + FHash := FInitialValue shl FEngineShift; end; procedure TCRC.UpdateCRCViaByteTable(AData: PByte; ADataLength, AIndex: Int32); @@ -762,7 +587,7 @@ procedure TCRC.UpdateCRCViaByteTable(AData: PByte; ADataLength, AIndex: Int32); LTemp := FHash; LCRCTable := FCacheEntry.Table; - if IsInputReflected then + if FIsInputReflected then begin while LLength > 0 do begin @@ -776,7 +601,7 @@ procedure TCRC.UpdateCRCViaByteTable(AData: PByte; ADataLength, AIndex: Int32); while LLength > 0 do begin LTemp := (LTemp shl 8) xor LCRCTable[0] - [Byte((LTemp shr (Width - 8)) xor LPtrData^)]; + [Byte((LTemp shr (FEngineWidth - 8)) xor LPtrData^)]; System.Inc(LPtrData); System.Dec(LLength); end; @@ -785,652 +610,13 @@ procedure TCRC.UpdateCRCViaByteTable(AData: PByte; ADataLength, AIndex: Int32); FHash := LTemp; end; -procedure TCRC.UpdateCRCViaBitSerial(AData: PByte; ADataLength, AIndex: Int32); -begin - CRC_UpdateViaBitSerial(AData, ADataLength, AIndex, FHash, Polynomial, Width, - IsInputReflected, FCRCHighBitMask); -end; - -function TCRC.Clone(): IHash; +procedure TCRC.TransformBytes(const AData: THashLibByteArray; + AIndex, ALength: Int32); var - LHashInstance: TCRC; -begin - LHashInstance := TCRC.Create(Width, Polynomial, InitialValue, - IsInputReflected, IsOutputReflected, OutputXor, CheckValue, - System.Copy(Names)); - LHashInstance.FHash := FHash; - Result := LHashInstance; - Result.BufferSize := BufferSize; -end; - -constructor TCRC.Create(AWidth: Int32; APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); -begin - - if not(AWidth in [3 .. 64]) then - begin - raise EArgumentOutOfRangeHashLibException.CreateResFmt(@SWidthOutOfRange, - [AWidth]); - end; - - inherited Create(-1, -1); // Dummy State - - case AWidth of - 0 .. 7: - begin - Self.HashSize := 1; - Self.BlockSize := 1; - end; - - 8 .. 16: - begin - Self.HashSize := 2; - Self.BlockSize := 1; - end; - - 17 .. 39: - begin - Self.HashSize := 4; - Self.BlockSize := 1; - end; - - else - begin - Self.HashSize := 8; - Self.BlockSize := 1; - end; - - end; - - Names := ANames; - Width := AWidth; - Polynomial := APolynomial; - InitialValue := AInitial; - IsInputReflected := AIsInputReflected; - IsOutputReflected := AIsOutputReflected; - OutputXor := AOutputXor; - CheckValue := ACheckValue; - - FCRCHighBitMask := UInt64(1) shl (Width - 1); - FCRCMask := ((FCRCHighBitMask - 1) shl 1) or 1; - - if Width > MinTableWidth then - FCacheEntry := GetOrCreateCacheEntry(Polynomial, Width, IsInputReflected); -end; - -class function TCRC.CreateCRCObject(AValue: TCRCStandard): ICRC; -begin - case AValue of - - TCRCStandard.CRC3_GSM: - Result := TCRC.Create(3, $3, $0, False, False, $7, $4, - THashLibStringArray.Create('CRC-3/GSM')); - - TCRCStandard.CRC3_ROHC: - Result := TCRC.Create(3, $3, $7, True, True, $0, $6, - THashLibStringArray.Create('CRC-3/ROHC')); - - TCRCStandard.CRC4_INTERLAKEN: - Result := TCRC.Create(4, $3, $F, False, False, $F, $B, - THashLibStringArray.Create('CRC-4/INTERLAKEN')); - - TCRCStandard.CRC4_ITU: - Result := TCRC.Create(4, $3, $0, True, True, $0, $7, - THashLibStringArray.Create('CRC-4/ITU', 'CRC-4/G-704')); - - TCRCStandard.CRC5_EPC: - Result := TCRC.Create(5, $9, $9, False, False, $00, $00, - THashLibStringArray.Create('CRC-5/EPC', 'CRC-5/EPC-C1G2')); - - TCRCStandard.CRC5_ITU: - Result := TCRC.Create(5, $15, $00, True, True, $00, $07, - THashLibStringArray.Create('CRC-5/ITU', 'CRC-5/G-704')); - - TCRCStandard.CRC5_USB: - Result := TCRC.Create(5, $05, $1F, True, True, $1F, $19, - THashLibStringArray.Create('CRC-5/USB')); - - TCRCStandard.CRC6_CDMA2000A: - Result := TCRC.Create(6, $27, $3F, False, False, $00, $0D, - THashLibStringArray.Create('CRC-6/CDMA2000-A')); - - TCRCStandard.CRC6_CDMA2000B: - Result := TCRC.Create(6, $07, $3F, False, False, $00, $3B, - THashLibStringArray.Create('CRC-6/CDMA2000-B')); - - TCRCStandard.CRC6_DARC: - Result := TCRC.Create(6, $19, $00, True, True, $00, $26, - THashLibStringArray.Create('CRC-6/DARC')); - - TCRCStandard.CRC6_GSM: - Result := TCRC.Create(6, $2F, $00, False, False, $3F, $13, - THashLibStringArray.Create('CRC-6/GSM')); - - TCRCStandard.CRC6_ITU: - Result := TCRC.Create(6, $03, $00, True, True, $00, $06, - THashLibStringArray.Create('CRC-6/ITU', 'CRC-6/G-704')); - - TCRCStandard.CRC7: - Result := TCRC.Create(7, $09, $00, False, False, $00, $75, - THashLibStringArray.Create('CRC-7', 'CRC-7/MMC')); - - TCRCStandard.CRC7_ROHC: - Result := TCRC.Create(7, $4F, $7F, True, True, $00, $53, - THashLibStringArray.Create('CRC-7/ROHC')); - - TCRCStandard.CRC7_UMTS: - Result := TCRC.Create(7, $45, $00, False, False, $00, $61, - THashLibStringArray.Create('CRC-7/UMTS')); - - TCRCStandard.CRC8: - Result := TCRC.Create(8, $07, $00, False, False, $00, $F4, - THashLibStringArray.Create('CRC-8', 'CRC-8/SMBUS')); - - TCRCStandard.CRC8_AUTOSAR: - Result := TCRC.Create(8, $2F, $FF, False, False, $FF, $DF, - THashLibStringArray.Create('CRC-8/AUTOSAR')); - - TCRCStandard.CRC8_BLUETOOTH: - Result := TCRC.Create(8, $A7, $00, True, True, $00, $26, - THashLibStringArray.Create('CRC-8/BLUETOOTH')); - - TCRCStandard.CRC8_CDMA2000: - Result := TCRC.Create(8, $9B, $FF, False, False, $00, $DA, - THashLibStringArray.Create('CRC-8/CDMA2000')); - - TCRCStandard.CRC8_DARC: - Result := TCRC.Create(8, $39, $00, True, True, $00, $15, - THashLibStringArray.Create('CRC-8/DARC')); - - TCRCStandard.CRC8_DVBS2: - Result := TCRC.Create(8, $D5, $00, False, False, $00, $BC, - THashLibStringArray.Create('CRC-8/DVB-S2')); - - TCRCStandard.CRC8_EBU: - Result := TCRC.Create(8, $1D, $FF, True, True, $00, $97, - THashLibStringArray.Create('CRC-8/EBU', 'CRC-8/AES', - 'CRC-8/TECH-3250')); - - TCRCStandard.CRC8_GSMA: - Result := TCRC.Create(8, $1D, $00, False, False, $00, $37, - THashLibStringArray.Create('CRC-8/GSM-A')); - - TCRCStandard.CRC8_GSMB: - Result := TCRC.Create(8, $49, $00, False, False, $FF, $94, - THashLibStringArray.Create('CRC-8/GSM-B')); - - TCRCStandard.CRC8_ICODE: - Result := TCRC.Create(8, $1D, $FD, False, False, $00, $7E, - THashLibStringArray.Create('CRC-8/I-CODE')); - - TCRCStandard.CRC8_ITU: - Result := TCRC.Create(8, $07, $00, False, False, $55, $A1, - THashLibStringArray.Create('CRC-8/ITU', 'CRC-8/I-432-1')); - - TCRCStandard.CRC8_LTE: - Result := TCRC.Create(8, $9B, $00, False, False, $00, $EA, - THashLibStringArray.Create('CRC-8/LTE')); - - TCRCStandard.CRC8_MAXIM: - Result := TCRC.Create(8, $31, $00, True, True, $00, $A1, - THashLibStringArray.Create('CRC-8/MAXIM', 'DOW-CRC', - 'CRC-8/MAXIM-DOW')); - - TCRCStandard.CRC8_OPENSAFETY: - Result := TCRC.Create(8, $2F, $00, False, False, $00, $3E, - THashLibStringArray.Create('CRC-8/OPENSAFETY')); - - TCRCStandard.CRC8_ROHC: - Result := TCRC.Create(8, $07, $FF, True, True, $00, $D0, - THashLibStringArray.Create('CRC-8/ROHC')); - - TCRCStandard.CRC8_SAEJ1850: - Result := TCRC.Create(8, $1D, $FF, False, False, $FF, $4B, - THashLibStringArray.Create('CRC-8/SAE-J1850')); - - TCRCStandard.CRC8_WCDMA: - Result := TCRC.Create(8, $9B, $00, True, True, $00, $25, - THashLibStringArray.Create('CRC-8/WCDMA')); - - TCRCStandard.CRC8_MIFAREMAD: - Result := TCRC.Create(8, $1D, $C7, False, False, $00, $99, - THashLibStringArray.Create('CRC-8/MIFARE-MAD')); - - TCRCStandard.CRC8_NRSC5: - Result := TCRC.Create(8, $31, $FF, False, False, $00, $F7, - THashLibStringArray.Create('CRC-8/NRSC-5')); - - TCRCStandard.CRC10: - Result := TCRC.Create(10, $233, $000, False, False, $000, $199, - THashLibStringArray.Create('CRC-10', 'CRC-10/ATM', 'CRC-10/I-610')); - - TCRCStandard.CRC10_CDMA2000: - Result := TCRC.Create(10, $3D9, $3FF, False, False, $000, $233, - THashLibStringArray.Create('CRC-10/CDMA2000')); - - TCRCStandard.CRC10_GSM: - Result := TCRC.Create(10, $175, $000, False, False, $3FF, $12A, - THashLibStringArray.Create('CRC-10/GSM')); - - TCRCStandard.CRC11: - Result := TCRC.Create(11, $385, $01A, False, False, $000, $5A3, - THashLibStringArray.Create('CRC-11', 'CRC-11/FLEXRAY')); - - TCRCStandard.CRC11_UMTS: - Result := TCRC.Create(11, $307, $000, False, False, $000, $061, - THashLibStringArray.Create('CRC-11/UMTS')); - - TCRCStandard.CRC12_CDMA2000: - Result := TCRC.Create(12, $F13, $FFF, False, False, $000, $D4D, - THashLibStringArray.Create('CRC-12/CDMA2000')); - - TCRCStandard.CRC12_DECT: - Result := TCRC.Create(12, $80F, $000, False, False, $000, $F5B, - THashLibStringArray.Create('CRC-12/DECT', 'X-CRC-12')); - - TCRCStandard.CRC12_GSM: - Result := TCRC.Create(12, $D31, $000, False, False, $FFF, $B34, - THashLibStringArray.Create('CRC-12/GSM')); - - TCRCStandard.CRC12_UMTS: - Result := TCRC.Create(12, $80F, $000, False, True, $000, $DAF, - THashLibStringArray.Create('CRC-12/UMTS', 'CRC-12/3GPP')); - - TCRCStandard.CRC13_BBC: - Result := TCRC.Create(13, $1CF5, $0000, False, False, $0000, $04FA, - THashLibStringArray.Create('CRC-13/BBC')); - - TCRCStandard.CRC14_DARC: - Result := TCRC.Create(14, $0805, $0000, True, True, $0000, $082D, - THashLibStringArray.Create('CRC-14/DARC')); - - TCRCStandard.CRC14_GSM: - Result := TCRC.Create(14, $202D, $0000, False, False, $3FFF, $30AE, - THashLibStringArray.Create('CRC-14/GSM')); - - TCRCStandard.CRC15: - Result := TCRC.Create(15, $4599, $0000, False, False, $0000, $059E, - THashLibStringArray.Create('CRC-15', 'CRC-15/CAN')); - - TCRCStandard.CRC15_MPT1327: - Result := TCRC.Create(15, $6815, $0000, False, False, $0001, $2566, - THashLibStringArray.Create('CRC-15/MPT1327')); - - TCRCStandard.ARC: - Result := TCRC.Create(16, $8005, $0000, True, True, $0000, $BB3D, - THashLibStringArray.Create('CRC-16', 'ARC', 'CRC-IBM', 'CRC-16/ARC', - 'CRC-16/LHA')); - - TCRCStandard.CRC16_AUGCCITT: - Result := TCRC.Create(16, $1021, $1D0F, False, False, $0000, $E5CC, - THashLibStringArray.Create('CRC-16/AUG-CCITT', 'CRC-16/SPI-FUJITSU')); - - TCRCStandard.CRC16_BUYPASS: - Result := TCRC.Create(16, $8005, $0000, False, False, $0000, $FEE8, - THashLibStringArray.Create('CRC-16/BUYPASS', 'CRC-16/VERIFONE', - 'CRC-16/UMTS')); - - TCRCStandard.CRC16_CCITTFALSE: - Result := TCRC.Create(16, $1021, $FFFF, False, False, $0000, $29B1, - THashLibStringArray.Create('CRC-16/CCITT-False', 'CRC-16/AUTOSAR', - 'CRC-16/IBM-3740')); - - TCRCStandard.CRC16_CDMA2000: - Result := TCRC.Create(16, $C867, $FFFF, False, False, $0000, $4C06, - THashLibStringArray.Create('CRC-16/CDMA2000')); - - TCRCStandard.CRC16_CMS: - Result := TCRC.Create(16, $8005, $FFFF, False, False, $0000, $AEE7, - THashLibStringArray.Create('CRC-16/CMS')); - - TCRCStandard.CRC16_DDS110: - Result := TCRC.Create(16, $8005, $800D, False, False, $0000, $9ECF, - THashLibStringArray.Create('CRC-16/DDS-110')); - - TCRCStandard.CRC16_DECTR: - Result := TCRC.Create(16, $0589, $0000, False, False, $0001, $007E, - THashLibStringArray.Create('CRC-16/DECT-R', 'R-CRC-16')); - - TCRCStandard.CRC16_DECTX: - Result := TCRC.Create(16, $0589, $0000, False, False, $0000, $007F, - THashLibStringArray.Create('CRC-16/DECT-X', 'X-CRC-16')); - - TCRCStandard.CRC16_DNP: - Result := TCRC.Create(16, $3D65, $0000, True, True, $FFFF, $EA82, - THashLibStringArray.Create('CRC-16/DNP')); - - TCRCStandard.CRC16_EN13757: - Result := TCRC.Create(16, $3D65, $0000, False, False, $FFFF, $C2B7, - THashLibStringArray.Create('CRC-16/EN13757')); - - TCRCStandard.CRC16_GENIBUS: - Result := TCRC.Create(16, $1021, $FFFF, False, False, $FFFF, $D64E, - THashLibStringArray.Create('CRC-16/GENIBUS', 'CRC-16/EPC', - 'CRC-16/I-CODE', 'CRC-16/DARC', 'CRC-16/EPC-C1G2')); - - TCRCStandard.CRC16_GSM: - Result := TCRC.Create(16, $1021, $0000, False, False, $FFFF, $CE3C, - THashLibStringArray.Create('CRC-16/GSM')); - - TCRCStandard.CRC16_LJ1200: - Result := TCRC.Create(16, $6F63, $0000, False, False, $0000, $BDF4, - THashLibStringArray.Create('CRC-16/LJ1200')); - - TCRCStandard.CRC16_MAXIM: - Result := TCRC.Create(16, $8005, $0000, True, True, $FFFF, $44C2, - THashLibStringArray.Create('CRC-16/MAXIM', 'CRC-16/MAXIM-DOW')); - - TCRCStandard.CRC16_MCRF4XX: - Result := TCRC.Create(16, $1021, $FFFF, True, True, $0000, $6F91, - THashLibStringArray.Create('CRC-16/MCRF4XX')); - - TCRCStandard.CRC16_OPENSAFETYA: - Result := TCRC.Create(16, $5935, $0000, False, False, $0000, $5D38, - THashLibStringArray.Create('CRC-16/OPENSAFETY-A')); - - TCRCStandard.CRC16_OPENSAFETYB: - Result := TCRC.Create(16, $755B, $0000, False, False, $0000, $20FE, - THashLibStringArray.Create('CRC-16/OPENSAFETY-B')); - - TCRCStandard.CRC16_PROFIBUS: - Result := TCRC.Create(16, $1DCF, $FFFF, False, False, $FFFF, $A819, - THashLibStringArray.Create('CRC-16/PROFIBUS', 'CRC-16/IEC-61158-2')); - - TCRCStandard.CRC16_RIELLO: - Result := TCRC.Create(16, $1021, $B2AA, True, True, $0000, $63D0, - THashLibStringArray.Create('CRC-16/RIELLO')); - - TCRCStandard.CRC16_T10DIF: - Result := TCRC.Create(16, $8BB7, $0000, False, False, $0000, $D0DB, - THashLibStringArray.Create('CRC-16/T10-DIF')); - - TCRCStandard.CRC16_TELEDISK: - Result := TCRC.Create(16, $A097, $0000, False, False, $0000, $0FB3, - THashLibStringArray.Create('CRC-16/TELEDISK')); - - TCRCStandard.CRC16_TMS37157: - Result := TCRC.Create(16, $1021, $89EC, True, True, $0000, $26B1, - THashLibStringArray.Create('CRC-16/TMS37157')); - - TCRCStandard.CRC16_USB: - Result := TCRC.Create(16, $8005, $FFFF, True, True, $FFFF, $B4C8, - THashLibStringArray.Create('CRC-16/USB')); - - TCRCStandard.CRCA: - Result := TCRC.Create(16, $1021, $C6C6, True, True, $0000, $BF05, - THashLibStringArray.Create('CRC-A', 'CRC-16/ISO-IEC-14443-3-A')); - - TCRCStandard.KERMIT: - Result := TCRC.Create(16, $1021, $0000, True, True, $0000, $2189, - THashLibStringArray.Create('KERMIT', 'CRC-16/CCITT', - 'CRC-16/CCITT-True', 'CRC-CCITT', 'CRC-16/KERMIT', 'CRC-16/V-41-LSB')); - - TCRCStandard.MODBUS: - Result := TCRC.Create(16, $8005, $FFFF, True, True, $0000, $4B37, - THashLibStringArray.Create('MODBUS', 'CRC-16/MODBUS')); - - TCRCStandard.X25: - Result := TCRC.Create(16, $1021, $FFFF, True, True, $FFFF, $906E, - THashLibStringArray.Create('X-25', 'CRC-16/IBM-SDLC', 'CRC-16/ISO-HDLC', - 'CRC-16/ISO-IEC-14443-3-B', 'CRC-B', 'CRC-16/X-25')); - - TCRCStandard.XMODEM: - Result := TCRC.Create(16, $1021, $0000, False, False, $0000, $31C3, - THashLibStringArray.Create('XMODEM', 'ZMODEM', 'CRC-16/ACORN', - 'CRC-16/XMODEM', 'CRC-16/V-41-MSB')); - - TCRCStandard.CRC16_NRSC5: - Result := TCRC.Create(16, $080B, $FFFF, True, True, $0000, $A066, - THashLibStringArray.Create('CRC-16/NRSC-5')); - - TCRCStandard.CRC17_CANFD: - Result := TCRC.Create(17, $1685B, $00000, False, False, $00000, $04F03, - THashLibStringArray.Create('CRC-17/CAN-FD')); - - TCRCStandard.CRC21_CANFD: - Result := TCRC.Create(21, $102899, $00000, False, False, $00000, $0ED841, - THashLibStringArray.Create('CRC-21/CAN-FD')); - - TCRCStandard.CRC24: - Result := TCRC.Create(24, $864CFB, $B704CE, False, False, $000000, - $21CF02, THashLibStringArray.Create('CRC-24', 'CRC-24/OPENPGP')); - - TCRCStandard.CRC24_BLE: - Result := TCRC.Create(24, $00065B, $555555, True, True, $000000, $C25A56, - THashLibStringArray.Create('CRC-24/BLE')); - - TCRCStandard.CRC24_FLEXRAYA: - Result := TCRC.Create(24, $5D6DCB, $FEDCBA, False, False, $000000, - $7979BD, THashLibStringArray.Create('CRC-24/FLEXRAY-A')); - - TCRCStandard.CRC24_FLEXRAYB: - Result := TCRC.Create(24, $5D6DCB, $ABCDEF, False, False, $000000, - $1F23B8, THashLibStringArray.Create('CRC-24/FLEXRAY-B')); - - TCRCStandard.CRC24_INTERLAKEN: - Result := TCRC.Create(24, $328B63, $FFFFFF, False, False, $FFFFFF, - $B4F3E6, THashLibStringArray.Create('CRC-24/INTERLAKEN')); - - TCRCStandard.CRC24_LTEA: - Result := TCRC.Create(24, $864CFB, $000000, False, False, $000000, - $CDE703, THashLibStringArray.Create('CRC-24/LTE-A')); - - TCRCStandard.CRC24_LTEB: - Result := TCRC.Create(24, $800063, $000000, False, False, $000000, - $23EF52, THashLibStringArray.Create('CRC-24/LTE-B')); - - TCRCStandard.CRC24_OS9: - Result := TCRC.Create(24, $800063, $FFFFFF, False, False, $FFFFFF, - $200FA5, THashLibStringArray.Create('CRC-24/OS-9')); - - TCRCStandard.CRC30_CDMA: - Result := TCRC.Create(30, $2030B9C7, $3FFFFFFF, False, False, $3FFFFFFF, - $04C34ABF, THashLibStringArray.Create('CRC-30/CDMA')); - - TCRCStandard.CRC31_PHILIPS: - Result := TCRC.Create(31, $04C11DB7, $7FFFFFFF, False, False, $7FFFFFFF, - $0CE9E46C, THashLibStringArray.Create('CRC-31/PHILLIPS')); - - TCRCStandard.CRC32: - Result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, True, True, $FFFFFFFF, - $CBF43926, THashLibStringArray.Create('CRC-32', 'CRC-32/ADCCP', - 'CRC-32/V-42', 'CRC-32/XZ', 'PKZIP', 'CRC-32/ISO-HDLC')); - - TCRCStandard.CRC32_AUTOSAR: - Result := TCRC.Create(32, $F4ACFB13, $FFFFFFFF, True, True, $FFFFFFFF, - $1697D06A, THashLibStringArray.Create('CRC-32/AUTOSAR')); - - TCRCStandard.CRC32_BZIP2: - Result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, False, False, $FFFFFFFF, - $FC891918, THashLibStringArray.Create('CRC-32/BZIP2', 'CRC-32/AAL5', - 'CRC-32/DECT-B', 'B-CRC-32')); - - TCRCStandard.CRC32C: - Result := TCRC.Create(32, $1EDC6F41, $FFFFFFFF, True, True, $FFFFFFFF, - $E3069283, THashLibStringArray.Create('CRC-32C', 'CRC-32/BASE91-C', - 'CRC-32/CASTAGNOLI', 'CRC-32/INTERLAKEN', 'CRC-32/ISCSI')); - - TCRCStandard.CRC32D: - Result := TCRC.Create(32, $A833982B, $FFFFFFFF, True, True, $FFFFFFFF, - $87315576, THashLibStringArray.Create('CRC-32D', 'CRC-32/BASE91-D')); - - TCRCStandard.CRC32_MPEG2: - Result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, False, False, $00000000, - $0376E6E7, THashLibStringArray.Create('CRC-32/MPEG-2')); - - TCRCStandard.CRC32_POSIX: - Result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, False, False, $00000000, - $0376E6E7, THashLibStringArray.Create('CRC-32/POSIX', 'CKSUM')); - - TCRCStandard.CRC32Q: - Result := TCRC.Create(32, $814141AB, $00000000, False, False, $00000000, - $3010BF7F, THashLibStringArray.Create('CRC-32Q', 'CRC-32/AIXM')); - - TCRCStandard.JAMCRC: - Result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, True, True, $00000000, - $340BC6D9, THashLibStringArray.Create('JAMCRC', 'CRC-32/JAMCRC')); - - TCRCStandard.XFER: - Result := TCRC.Create(32, $000000AF, $00000000, False, False, $00000000, - $BD0BE338, THashLibStringArray.Create('XFER', 'CRC-32/XFER')); - - TCRCStandard.CRC32_CDROMEDC: - Result := TCRC.Create(32, $8001801B, $00000000, True, True, $00000000, - $6EC2EDC4, THashLibStringArray.Create('CRC-32/CD-ROM-EDC')); - - TCRCStandard.CRC40_GSM: - Result := TCRC.Create(40, $0004820009, $0000000000, False, False, - $FFFFFFFFFF, $D4164FC646, THashLibStringArray.Create('CRC-40/GSM')); - - TCRCStandard.CRC64: - Result := TCRC.Create(64, $42F0E1EBA9EA3693, $0000000000000000, False, - False, $0000000000000000, $6C40DF5F0B497347, - THashLibStringArray.Create('CRC-64', 'CRC-64/ECMA-182')); - - TCRCStandard.CRC64_GOISO: - Result := TCRC.Create(64, $000000000000001B, UInt64($FFFFFFFFFFFFFFFF), - True, True, UInt64($FFFFFFFFFFFFFFFF), UInt64($B90956C775A41001), - THashLibStringArray.Create('CRC-64/GO-ISO')); - - TCRCStandard.CRC64_WE: - Result := TCRC.Create(64, $42F0E1EBA9EA3693, UInt64($FFFFFFFFFFFFFFFF), - False, False, UInt64($FFFFFFFFFFFFFFFF), $62EC59E3F1A4F00A, - THashLibStringArray.Create('CRC-64/WE')); - - TCRCStandard.CRC64_XZ: - Result := TCRC.Create(64, $42F0E1EBA9EA3693, UInt64($FFFFFFFFFFFFFFFF), - True, True, UInt64($FFFFFFFFFFFFFFFF), UInt64($995DC9BBDF1939FA), - THashLibStringArray.Create('CRC-64/XZ', 'CRC-64/GO-ECMA')); - - TCRCStandard.CRC64_1B: - Result := TCRC.Create(64, $000000000000001B, UInt64($0000000000000000), - True, True, UInt64($0000000000000000), $46A5A9388A5BEFFE, - THashLibStringArray.Create('CRC-64/1B')); - - TCRCStandard.CRC64_Jones: - Result := TCRC.Create(64, UInt64($AD93D23594C935A9), - UInt64($FFFFFFFFFFFFFFFF), True, True, UInt64($0000000000000000), - UInt64($CAA717168609F281), THashLibStringArray.Create('CRC-64/Jones')) - - else - raise EArgumentInvalidHashLibException.CreateResFmt(@SUnSupportedCRCType, - [GetEnumName(TypeInfo(TCRCStandard), Ord(AValue))]); - - end; -end; - -class constructor TCRC.CreateCRCCache; -begin - FCache := TDictionary.Create; -end; - -class destructor TCRC.DestroyCRCCache; -begin - FCache.Free; -end; - -class function TCRC.MakeCacheKey(APoly: UInt64; AWidth: Int32; - AReflected: Boolean): String; -begin - Result := Format('Poly-%x:Width-%d:Reflected-%s', - [APoly, AWidth, BoolToStr(AReflected, True)]); -end; - -class function TCRC.GenerateCRCTable(APoly: UInt64; AWidth: Int32; - AReflected: Boolean): THashLibMatrixUInt64Array; -var - LCRC: UInt64; - LIdx, LRow, LBit: Int32; - LReflectedPoly, LHighBitMask, LMask: UInt64; -begin - System.SetLength(Result, 16); - for LIdx := 0 to 15 do - System.SetLength(Result[LIdx], 256); - - if AReflected then - begin - LReflectedPoly := Reflect(APoly, AWidth); - for LIdx := 0 to 255 do - begin - LCRC := UInt64(LIdx); - for LRow := 0 to 15 do - begin - for LBit := 0 to 7 do - LCRC := (LCRC shr 1) xor (UInt64(-Int64(LCRC and 1)) and LReflectedPoly); - Result[LRow][LIdx] := LCRC; - end; - end; - end - else - begin - LHighBitMask := UInt64(1) shl (AWidth - 1); - LMask := ((LHighBitMask - 1) shl 1) or 1; - for LIdx := 0 to 255 do - begin - LCRC := UInt64(LIdx) shl (AWidth - 8); - for LRow := 0 to 15 do - begin - for LBit := 0 to 7 do - begin - if (LCRC and LHighBitMask) <> 0 then - LCRC := ((LCRC shl 1) xor APoly) and LMask - else - LCRC := (LCRC shl 1) and LMask; - end; - Result[LRow][LIdx] := LCRC; - end; - end; - end; -end; - -class function TCRC.GetOrCreateCacheEntry(APoly: UInt64; AWidth: Int32; - AReflected: Boolean): TCRCCacheValue; -var - LKey: String; -begin - LKey := MakeCacheKey(APoly, AWidth, AReflected); - if not FCache.TryGetValue(LKey, Result) then - begin - Result.Table := GenerateCRCTable(APoly, AWidth, AReflected); - CRCDispatch_InitRuntimeCtx(Result.Table, APoly, AWidth, AReflected, - Result.FoldRuntime); - FCache.Add(LKey, Result); - end; -end; - -procedure TCRC.Initialize; -begin - FHash := InitialValue; - if (Width > MinTableWidth) and IsInputReflected then - FHash := Reflect(FHash, Width); -end; - -class function TCRC.Reflect(AValue: UInt64; AWidth: Int32): UInt64; -var - LIdx, LJdx: UInt64; -begin - LJdx := 1; - Result := 0; - LIdx := UInt64(1) shl (AWidth - 1); - while LIdx <> 0 do - begin - if ((AValue and LIdx) <> 0) then - begin - Result := Result or LJdx; - end; - LJdx := LJdx shl 1; - LIdx := LIdx shr 1; - end; -end; - -procedure TCRC.TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); -var - LPtrAData: PByte; - LFoldFunc: TCRCFoldFunc; - LState: array [0 .. 1] of UInt64; - LProcessed, LTail: Int32; + LPtrAData: PByte; + LFoldFunc: TCRCFoldFunc; + LState: UInt64; + LProcessed, LTail: Int32; begin {$IFDEF DEBUG} System.Assert(AIndex >= 0); @@ -1440,111 +626,64 @@ procedure TCRC.TransformBytes(const AData: THashLibByteArray; LPtrAData := PByte(AData); - if Width > MinTableWidth then + if ALength >= MinSimdBytes then begin - if ALength >= MinSimdBytes then + if FIsInputReflected then begin - if IsInputReflected then - begin - LFoldFunc := CRC_Fold_Reflected; - LState[0] := FHash; - end - else - begin - LFoldFunc := CRC_Fold_Forward; - if CRC_Fold_UsesCarrylessMul then - begin - if Width < 64 then - LState[0] := FHash shl (64 - Width) - else - LState[0] := FHash; - end - else - LState[0] := FHash; - end; - - LState[1] := 0; - LProcessed := ALength and (not Int32(15)); - FHash := LFoldFunc(LPtrAData + AIndex, UInt32(LProcessed), @LState[0], - @FCacheEntry.FoldRuntime) and FCRCMask; - LTail := ALength - LProcessed; - if LTail > 0 then - UpdateCRCViaByteTable(LPtrAData, LTail, AIndex + LProcessed); + LFoldFunc := CRC_Fold.Reflected; + LState := FHash; end else - UpdateCRCViaByteTable(LPtrAData, ALength, AIndex); + begin + LFoldFunc := CRC_Fold.Fwd; + if CRC_Fold.UsesCarrylessMul then + LState := FHash shl (64 - FEngineWidth) + else + LState := FHash; + end; + + LProcessed := ALength and (not Int32(15)); + FHash := LFoldFunc(LPtrAData + AIndex, UInt32(LProcessed), @LState, + @FCacheEntry.FoldRuntime) and FCRCMask; + LTail := ALength - LProcessed; + if LTail > 0 then + UpdateCRCViaByteTable(LPtrAData, LTail, AIndex + LProcessed); end else - UpdateCRCViaBitSerial(LPtrAData, ALength, AIndex); + UpdateCRCViaByteTable(LPtrAData, ALength, AIndex); end; function TCRC.TransformFinal: IHashResult; -var - LUInt64: UInt64; - LUInt32: UInt32; - LUInt16: UInt16; - LUInt8: UInt8; begin - - if Width > MinTableWidth then - begin - if (IsInputReflected xor IsOutputReflected) then - begin - FHash := Reflect(FHash, Width); - end; - end - else - begin - if (IsOutputReflected) then - begin - FHash := Reflect(FHash, Width); - end; - end; - - FHash := FHash xor OutputXor; - FHash := FHash and FCRCMask; - - if Width = 21 then // special case - begin - LUInt32 := UInt32(FHash); - - Result := THashResult.Create(LUInt32); - - Initialize(); - - Exit; - end; - - case Width shr 3 of - 0: - begin - LUInt8 := UInt8(FHash); - Result := THashResult.Create(LUInt8); - - end; - - 1 .. 2: - begin - LUInt16 := UInt16(FHash); - - Result := THashResult.Create(LUInt16); - end; - - 3 .. 4: - begin - LUInt32 := UInt32(FHash); - - Result := THashResult.Create(LUInt32); - end + FHash := FHash shr FEngineShift; + if FIsInputReflected xor FIsOutputReflected then + FHash := TGF2.BitReverse(FHash, FWidth); + FHash := (FHash xor FOutputXor) and (FCRCMask shr FEngineShift); + + case HashSize of + 1: + Result := THashResult.Create(UInt8(FHash)); + 2: + Result := THashResult.Create(UInt16(FHash)); + 4: + Result := THashResult.Create(UInt32(FHash)); else - begin - LUInt64 := (FHash); - - Result := THashResult.Create(LUInt64); - end; + Result := THashResult.Create(FHash); end; Initialize(); end; +function TCRC.Clone(): IHash; +var + LHashInstance: TCRC; +begin + LHashInstance := TCRC.Create(FWidth, FPolynomial, FInitialValue, + FIsInputReflected, FIsOutputReflected, FOutputXor, FCheckValue, + System.Copy(FNames)); + LHashInstance.FHash := FHash; + Result := LHashInstance; + Result.BufferSize := BufferSize; +end; + end. diff --git a/HashLib/src/Checksum/HlpCRC32Fast.pas b/HashLib/src/Checksum/HlpCRC32Fast.pas deleted file mode 100644 index b073dbb..0000000 --- a/HashLib/src/Checksum/HlpCRC32Fast.pas +++ /dev/null @@ -1,170 +0,0 @@ -unit HlpCRC32Fast; - -{$I ..\Include\HashLib.inc} - -interface - -uses - HlpBinaryPrimitives, - HlpHashLibTypes, - HlpHash, - HlpIHash, - HlpIHashInfo, - HlpHashResult, - HlpIHashResult, - HlpCRCCore; - -type - - TCRC32Fast = class(THash, IChecksum, IHash32, ITransformBlock) - - strict protected - var - FCurrentCRC: UInt32; - - public - - constructor Create(); - - procedure Initialize(); override; - function TransformFinal(): IHashResult; override; - - end; - - TCRC32_PKZIP = class sealed(TCRC32Fast) - - strict private - - const - Crc32PkzipPolynomial = UInt32($EDB88320); // Polynomial Reversed - Crc32PkzipMsbPoly = UInt32($04C11DB7); // MSB-first form - - class var - FCrc32PkzipTable: THashLibMatrixUInt32Array; - FCrc32PkzipFoldRuntime: TCRCFoldRuntimeCtx; - - class constructor Crc32Pkzip(); - - public - constructor Create(); - procedure TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); override; - function Clone(): IHash; override; - - end; - - TCRC32_CASTAGNOLI = class sealed(TCRC32Fast) - - strict private - - const - Crc32CastagnoliPolynomial = UInt32($82F63B78); // Polynomial Reversed - Crc32CastagnoliMsbPoly = UInt32($1EDC6F41); // MSB-first form - - class var - FCrc32CastagnoliTable: THashLibMatrixUInt32Array; - FCrc32CastagnoliFoldRuntime: TCRCFoldRuntimeCtx; - - class constructor Crc32Castagnoli(); - - public - constructor Create(); - procedure TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); override; - function Clone(): IHash; override; - - end; - -implementation - -procedure CRC32FastInitFoldTables(const AReflectedPoly, AMsbPoly: UInt32; - var ATable: THashLibMatrixUInt32Array; var ACtx: TCRCFoldRuntimeCtx); -begin - ATable := CRCDispatch_BuildSlicingTable32Reflect(AReflectedPoly); - CRCDispatch_InitRuntimeCtx(ATable, AMsbPoly, ACtx); -end; - -{ TCRC32Fast } - -constructor TCRC32Fast.Create(); -begin - inherited Create(4, 1); -end; - -procedure TCRC32Fast.Initialize; -begin - FCurrentCRC := 0; -end; - -function TCRC32Fast.TransformFinal: IHashResult; -var - LBufferBytes: THashLibByteArray; -begin - System.SetLength(LBufferBytes, HashSize); - TBinaryPrimitives.WriteUInt32BigEndian(LBufferBytes, 0, FCurrentCRC); - - Result := THashResult.Create(LBufferBytes); - Initialize(); -end; - -{ TCRC32_PKZIP } - -function TCRC32_PKZIP.Clone(): IHash; -var - LHashInstance: TCRC32_PKZIP; -begin - LHashInstance := TCRC32_PKZIP.Create(); - LHashInstance.FCurrentCRC := FCurrentCRC; - Result := LHashInstance; - Result.BufferSize := BufferSize; -end; - -constructor TCRC32_PKZIP.Create; -begin - inherited Create(); -end; - -procedure TCRC32_PKZIP.TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); -begin - CRCDispatch_UpdateReflectedCrc32(FCurrentCRC, PByte(AData) + AIndex, - UInt32(ALength), @FCrc32PkzipFoldRuntime); -end; - -class constructor TCRC32_PKZIP.Crc32Pkzip(); -begin - CRC32FastInitFoldTables(Crc32PkzipPolynomial, Crc32PkzipMsbPoly, - FCrc32PkzipTable, FCrc32PkzipFoldRuntime); -end; - -{ TCRC32_CASTAGNOLI } - -function TCRC32_CASTAGNOLI.Clone(): IHash; -var - LHashInstance: TCRC32_CASTAGNOLI; -begin - LHashInstance := TCRC32_CASTAGNOLI.Create(); - LHashInstance.FCurrentCRC := FCurrentCRC; - Result := LHashInstance; - Result.BufferSize := BufferSize; -end; - -constructor TCRC32_CASTAGNOLI.Create; -begin - inherited Create(); -end; - -procedure TCRC32_CASTAGNOLI.TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); -begin - CRCDispatch_UpdateReflectedCrc32(FCurrentCRC, PByte(AData) + AIndex, - UInt32(ALength), @FCrc32CastagnoliFoldRuntime); -end; - -class constructor TCRC32_CASTAGNOLI.Crc32Castagnoli(); -begin - CRC32FastInitFoldTables(Crc32CastagnoliPolynomial, Crc32CastagnoliMsbPoly, - FCrc32CastagnoliTable, FCrc32CastagnoliFoldRuntime); -end; - -end. diff --git a/HashLib/src/Checksum/HlpCRCCore.pas b/HashLib/src/Checksum/HlpCRCCore.pas index bcd99b2..9c596be 100644 --- a/HashLib/src/Checksum/HlpCRCCore.pas +++ b/HashLib/src/Checksum/HlpCRCCore.pas @@ -1,19 +1,22 @@ -unit HlpCRCCore; +unit HlpCRCCore; { - CRC fold dispatch (scalar + SIMD + PCLMUL) and fast reflected-CRC32 update. - - TCRC (HlpCRC.pas): generic widths, UInt64 table rows, FHash state — uses - CRC_Fold_Reflected/Forward + UpdateCRCViaByteTable; not the PKZIP wire inverted form. - - CRC32Fast (HlpCRC32Fast.pas): PKZIP/Castagnoli only; FCurrentCRC with not/xor - convention; uses CRCDispatch_UpdateReflectedCrc32 + TCRCFoldRuntimeCtx. - - TCRCFoldRuntimeCtx: FoldConstants + TableRow only. One record serves both the - UInt64 generic table and the UInt32 CRC32 table (TableRow stores untyped - pointers, cast at point of use). MSB fold reads CRC width from - FoldConstants.CrcBits (see TGF2.GenerateFoldConstants) and derives the state - mask the same way as TCRC.FCRCMask. + CRC engine internals, in three parts: + + 1. TGF2 - GF(2) polynomial math (carry-less multiply, division, PowerMod) + used to generate the PCLMUL/VPCLMUL/PMULL folding and Barrett reduction + constants at runtime for ANY generator polynomial (Linux kernel + gen-crc-consts.py algorithm). One generic carry-less-multiply kernel per + arch serves every CRC standard through these computed constants. + + 2. TCRCFoldRuntimeCtx - the runtime context handed to the fold kernels. + The carry-less-multiply paths read FoldConstants (offset 0) only; the + scalar/SSE2 slicing tiers read the 16 slicing-table row pointers at + offset 96 (= SizeOf(TCRCFoldConstants)), matching the fixed + +96+I*SizeOf(Pointer) offsets in the CRCFold*.inc kernels. + + 3. Scalar slicing-by-16 fold routines - the portable fallback selected by + TCRCSimd when no SIMD backend is built/available. } {$I ..\Include\HashLib.inc} @@ -21,81 +24,370 @@ interface uses - HlpHashLibTypes, - HlpCRCFoldConstants; + HlpHashLibTypes; const MinSimdBytes = Int32(16); type - // Unified fold runtime context. The PCLMUL/VPCLMUL (and future PMULL) paths - // read FoldConstants only (offset 0). The scalar/SSE2 slicing tiers read - // TableRow at offset 96 (= SizeOf(TCRCFoldConstants)); rows point at UInt64 - // (generic CRC) or UInt32 (CRC32 fast path) tables and are cast at point of - // use. TableRow is declared as Pointer so one record serves both table cell - // widths with identical byte layout on i386 (4-byte rows) and x86_64 - // (8-byte rows) — matching the fixed +96+I*SizeOf(Pointer) asm offsets. + TUInt128 = record + Lo, Hi: UInt64; + end; + + // PCLMULQDQ / VPCLMULQDQ / PMULL CRC folding and Barrett reduction constants. + // Layout must match the assembly expectations in the CRCFold*.inc files. + TCRCFoldConstants = packed record + Fold_4x128: array [0 .. 1] of UInt64; // offset 0: fold-by-4 constants (stride 512) + Fold_1x128: array [0 .. 1] of UInt64; // offset 16: fold-by-1 constants (stride 128) + Barrett: array [0 .. 1] of UInt64; // offset 32: Barrett reduction constants + Fold_8x128: array [0 .. 1] of UInt64; // offset 48: fold-by-8 constants (stride 1024) + BswapMask: array [0 .. 15] of Byte; // offset 64: byte-reverse mask for MSB-first CRCs + CrcBits: UInt64; // offset 80: CRC width (8..64) + BarrettShift: UInt64; // offset 88: = 64 - CrcBits (MSB psrlq alignment) + end; + TCRCFoldRuntimeCtx = packed record FoldConstants: TCRCFoldConstants; - TableRow: array [0 .. 15] of Pointer; + TableRow: array [0 .. 15] of PUInt64; end; PCRCFoldRuntimeCtx = ^TCRCFoldRuntimeCtx; + // A slicing table plus its fold runtime context, cached by TCRC per + // (polynomial, width, reflection). + TCRCCacheValue = record + Table: THashLibMatrixUInt64Array; + FoldRuntime: TCRCFoldRuntimeCtx; + end; + // AData: data pointer, ALength: byte count (>= MinSimdBytes, multiple of 16). - // AState: pointer to 2 x UInt64 ([0]=CRC / state, [1]=0 for PCLMUL). + // AState: pointer to UInt64 (the running CRC / fold state). // AConstants: pointer to TCRCFoldRuntimeCtx (FoldConstants at offset 0). TCRCFoldFunc = function(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - // Tier-selection result: the three fold entry points plus whether they use + // Tier-selection result: the two fold entry points plus whether they use // carry-less multiply (PCLMUL/VPCLMUL/PMULL) rather than table slicing. TCRCFoldSelection = record Reflected: TCRCFoldFunc; Fwd: TCRCFoldFunc; - Reflected32: TCRCFoldFunc; UsesCarrylessMul: Boolean; end; -procedure CRCDispatch_InitRuntimeCtx(const Table: THashLibMatrixUInt64Array; + TGF2 = class sealed + strict private + class function BitLength64(A: UInt64): Int32; static; + class function BitLength128(const A: TUInt128): Int32; static; inline; + + // 64 x 64 -> 128 carry-less multiply (MSB-first polynomial arithmetic). + class function CLMul(A, B: UInt64): TUInt128; static; + + // 128-bit polynomial mod G, where G = x^ABits + APoly. + // Returns remainder (degree < ABits, fits in UInt64). + class function Reduce(const A: TUInt128; APoly: UInt64; + ABits: Int32): UInt64; static; + + // floor(A / G) where G = x^ABits + APoly. Returns quotient. + class function DivPoly(const A: TUInt128; APoly: UInt64; + ABits: Int32): UInt64; static; + + // XOR G << AShift into LVal (128-bit), G = x^ABits + APoly. + class procedure XorShiftedG(var AVal: TUInt128; APoly: UInt64; + ABits, AShift: Int32); static; + + // One (x^(AStride+64), x^AStride) fold constant pair, stored in the + // domain (bit-reflected or plain) the kernels expect. + class procedure FoldConstPair(AStride: Int32; APoly: UInt64; + ABits, AK: Int32; AReflected: Boolean; + var APair: array of UInt64); static; + + public + // Compute x^N mod G using repeated squaring. + // APoly: generator polynomial WITHOUT the leading x^ABits term. + // ABits: CRC width (degree of G). + class function PowerMod(N: Int32; APoly: UInt64; + ABits: Int32): UInt64; static; + + // Reverse the lowest ANumBits bits of AValue. + class function BitReverse(AValue: UInt64; ANumBits: Int32): UInt64; static; + + // Generate PCLMULQDQ fold and Barrett reduction constants for a CRC. + // APoly: generator polynomial (MSB-first, without leading bit). + // ABits: CRC width (8..64). + // AReflected: True for LSB-first (reflected input) CRCs. + class procedure GenerateFoldConstants(APoly: UInt64; ABits: Int32; + AReflected: Boolean; out AConstants: TCRCFoldConstants); static; + end; + +procedure CRC_InitFoldRuntimeCtx(const Table: THashLibMatrixUInt64Array; APoly: UInt64; AWidth: Int32; AReflected: Boolean; - out Ctx: TCRCFoldRuntimeCtx); overload; + out Ctx: TCRCFoldRuntimeCtx); + +var + CRC_Fold: TCRCFoldSelection; + +implementation -procedure CRCDispatch_InitRuntimeCtx(const Table: THashLibMatrixUInt32Array; - AMsbPoly: UInt32; out Ctx: TCRCFoldRuntimeCtx); overload; +uses + HlpBinaryPrimitives, + HlpCRCSimd; -// 16 x 256 slicing-by-16 table for reflected CRC32 (AReflectedPoly = e.g. $EDB88320). -function CRCDispatch_BuildSlicingTable32Reflect(AReflectedPoly: UInt32) - : THashLibMatrixUInt32Array; +{ TGF2 } -// PKZIP-style reflected CRC32: updates AWireCrc (e.g. FCurrentCRC) with ALength -// bytes at AData using fold dispatch + row-0 tail (same as former LocalCRCCompute). -procedure CRCDispatch_UpdateReflectedCrc32(var AWireCrc: UInt32; - AData: PByte; ALength: UInt32; ACtx: PCRCFoldRuntimeCtx); +class function TGF2.BitLength64(A: UInt64): Int32; +begin + Result := 0; + while A <> 0 do + begin + System.Inc(Result); + A := A shr 1; + end; +end; -procedure CRC_UpdateViaBitSerial(AData: PByte; ADataLength, AIndex: Int32; - var AHash: UInt64; APolynomial: UInt64; AWidth: Int32; - AInputReflected: Boolean; AHighBitMask: UInt64); +class function TGF2.BitLength128(const A: TUInt128): Int32; +begin + if A.Hi <> 0 then + Result := 64 + BitLength64(A.Hi) + else + Result := BitLength64(A.Lo); +end; +class function TGF2.CLMul(A, B: UInt64): TUInt128; var - CRC_Fold_Reflected: TCRCFoldFunc; - CRC_Fold_Forward: TCRCFoldFunc; - CRC_Fold_Reflected32: TCRCFoldFunc; - CRC_Fold_UsesCarrylessMul: Boolean; + I: Int32; +begin + Result.Lo := 0; + Result.Hi := 0; + for I := 0 to 63 do + begin + if (B and (UInt64(1) shl I)) <> 0 then + begin + if I = 0 then + begin + Result.Lo := Result.Lo xor A; + end + else + begin + Result.Lo := Result.Lo xor (A shl I); + Result.Hi := Result.Hi xor (A shr (64 - I)); + end; + end; + end; +end; -implementation +class procedure TGF2.XorShiftedG(var AVal: TUInt128; APoly: UInt64; + ABits, AShift: Int32); +var + LGLo, LGHi: UInt64; + LLeadPos: Int32; +begin + LGLo := 0; + LGHi := 0; + LLeadPos := ABits + AShift; -uses - HlpCRCSimd; + if AShift < 64 then + begin + LGLo := APoly shl AShift; + if AShift > 0 then + LGHi := APoly shr (64 - AShift); + end + else + begin + LGHi := APoly shl (AShift - 64); + end; + + if LLeadPos < 64 then + LGLo := LGLo xor (UInt64(1) shl LLeadPos) + else + LGHi := LGHi xor (UInt64(1) shl (LLeadPos - 64)); + + AVal.Lo := AVal.Lo xor LGLo; + AVal.Hi := AVal.Hi xor LGHi; +end; -function CrcTableU64(const Row: Pointer; B: Byte): UInt64; inline; +class function TGF2.Reduce(const A: TUInt128; APoly: UInt64; + ABits: Int32): UInt64; +var + LVal: TUInt128; + LDeg, LShift: Int32; begin - Result := PUInt64(NativeUInt(Row) + UInt64(B) * SizeOf(UInt64))^; + LVal := A; + while True do + begin + LDeg := BitLength128(LVal) - 1; + if LDeg < ABits then + Break; + LShift := LDeg - ABits; + XorShiftedG(LVal, APoly, ABits, LShift); + end; + Result := LVal.Lo; +end; + +class function TGF2.DivPoly(const A: TUInt128; APoly: UInt64; + ABits: Int32): UInt64; +var + LVal: TUInt128; + LDeg, LShift: Int32; + LQuotient: UInt64; +begin + LVal := A; + LQuotient := 0; + while True do + begin + LDeg := BitLength128(LVal) - 1; + if LDeg < ABits then + Break; + LShift := LDeg - ABits; + LQuotient := LQuotient xor (UInt64(1) shl LShift); + XorShiftedG(LVal, APoly, ABits, LShift); + end; + Result := LQuotient; +end; + +class function TGF2.PowerMod(N: Int32; APoly: UInt64; + ABits: Int32): UInt64; +var + LBase, LResult: UInt64; + LProduct: TUInt128; +begin + if N = 0 then + Exit(1); + LResult := 1; + LBase := 2; + while N > 0 do + begin + if (N and 1) <> 0 then + begin + LProduct := CLMul(LResult, LBase); + LResult := Reduce(LProduct, APoly, ABits); + end; + N := N shr 1; + if N > 0 then + begin + LProduct := CLMul(LBase, LBase); + LBase := Reduce(LProduct, APoly, ABits); + end; + end; + Result := LResult; +end; + +class function TGF2.BitReverse(AValue: UInt64; ANumBits: Int32): UInt64; +var + I: Int32; +begin + Result := 0; + for I := 0 to ANumBits - 1 do + begin + if (AValue and (UInt64(1) shl I)) <> 0 then + Result := Result or (UInt64(1) shl (ANumBits - 1 - I)); + end; end; -function CrcTableU32(const Row: Pointer; B: Byte): UInt32; inline; +class procedure TGF2.FoldConstPair(AStride: Int32; APoly: UInt64; + ABits, AK: Int32; AReflected: Boolean; var APair: array of UInt64); +var + LHiExp, LLoExp: UInt64; begin - Result := PUInt32(NativeUInt(Row) + UInt64(B) * SizeOf(UInt32))^; + LHiExp := PowerMod(AStride + 64 + AK, APoly, ABits); + LLoExp := PowerMod(AStride + AK, APoly, ABits); + if AReflected then + begin + APair[0] := BitReverse(LHiExp shl (64 - ABits), 64); + APair[1] := BitReverse(LLoExp shl (64 - ABits), 64); + end + else + begin + APair[0] := LLoExp; + APair[1] := LHiExp; + end; +end; + +class procedure TGF2.GenerateFoldConstants(APoly: UInt64; ABits: Int32; + AReflected: Boolean; out AConstants: TCRCFoldConstants); +var + LK, LPowOfX, I: Int32; + LBarrett0, LGMinusXn: UInt64; + LDiv128: TUInt128; +begin + // Following the Linux kernel gen-crc-consts.py algorithm. + // G(x) = x^ABits + APoly (MSB-first representation). + // For LSB-first (reflected): each constant is computed in MSB domain, + // then bit-reflected to 64 bits before storage. + + if AReflected then + LK := ABits - 65 + else + LK := 0; + + FoldConstPair(512, APoly, ABits, LK, AReflected, AConstants.Fold_4x128); + FoldConstPair(128, APoly, ABits, LK, AReflected, AConstants.Fold_1x128); + FoldConstPair(1024, APoly, ABits, LK, AReflected, AConstants.Fold_8x128); + + // --- Barrett reduction constants --- + LGMinusXn := APoly; + + if AReflected then + begin + // LSB-first: m = 63. + // Barrett[0] = bitreflect(floor(x^(63+n) / G), 64) + // Barrett[1] = bitreflect(G, n+1) (truncated: for n=64, x^0 removed) + LDiv128.Lo := 0; + LDiv128.Hi := 0; + if (63 + ABits) < 64 then + LDiv128.Lo := UInt64(1) shl (63 + ABits) + else if (63 + ABits) = 64 then + LDiv128.Hi := 1 + else + LDiv128.Hi := UInt64(1) shl ((63 + ABits) - 64); + LBarrett0 := DivPoly(LDiv128, APoly, ABits); + + AConstants.Barrett[0] := BitReverse(LBarrett0, 64); + if ABits < 64 then + begin + LPowOfX := 64 - ABits - 1; + AConstants.Barrett[1] := BitReverse(LGMinusXn shl LPowOfX, 64); + end + else + AConstants.Barrett[1] := BitReverse(LGMinusXn shr 1, 64); + end + else + begin + // MSB-first: m = 64. Two-round Barrett per Linux kernel. + // Barrett[0] = floor(x^(64+n) / G) - x^64 (mu, low 64 bits) + // Since floor(x^(64+n)/G) = x^64 + floor(APoly*x^64 / G), + // we compute Barrett[0] = DivPoly(APoly*x^64, G) to avoid the x^64 overflow. + // Barrett[1] = G (full generator polynomial; for n=64, x^64 term implicit) + LDiv128.Hi := APoly; + LDiv128.Lo := 0; + AConstants.Barrett[0] := DivPoly(LDiv128, APoly, ABits); + if ABits < 64 then + AConstants.Barrett[1] := (UInt64(1) shl ABits) or APoly + else + AConstants.Barrett[1] := APoly; + end; + + // --- Byte-swap mask for MSB-first CRCs --- + if AReflected then + FillChar(AConstants.BswapMask[0], 16, 0) + else + for I := 0 to 15 do + AConstants.BswapMask[I] := Byte(15 - I); + + // --- Metadata --- + AConstants.CrcBits := UInt64(ABits); + if ABits < 64 then + AConstants.BarrettShift := UInt64(64 - ABits) + else + AConstants.BarrettShift := 0; +end; + +// ============================================================================= +// Scalar slicing-by-16 fold routines +// ============================================================================= + +function CrcTableU64(const Row: PUInt64; B: Byte): UInt64; inline; +begin + Result := PUInt64(NativeUInt(Row) + UInt64(B) * SizeOf(UInt64))^; end; function CRCMaskFromWidth(AWidth: Int32): UInt64; inline; @@ -135,7 +427,7 @@ function CRC_Fold_Reflected_Scalar(AData: PByte; ALength: UInt32; Ctx := PCRCFoldRuntimeCtx(AConstants); LPtr := AData; LLen := ALength; - LTemp := PUInt64(AState)^; + LTemp := TBinaryPrimitives.LoadUInt64(PUInt64(AState)); while LLen >= 16 do begin @@ -144,7 +436,7 @@ function CRC_Fold_Reflected_Scalar(AData: PByte; ALength: UInt32; System.Dec(LLen, 16); end; - PUInt64(AState)^ := LTemp; + TBinaryPrimitives.StoreUInt64(PUInt64(AState), LTemp); Result := LTemp; end; @@ -163,7 +455,7 @@ function CRC_Fold_Forward_Scalar(AData: PByte; ALength: UInt32; Ctx := PCRCFoldRuntimeCtx(AConstants); LPtr := AData; LLen := ALength; - LTemp := PUInt64(AState)^; + LTemp := TBinaryPrimitives.LoadUInt64(PUInt64(AState)); LWidth := Int32(Ctx.FoldConstants.CrcBits); LCrcMask := CRCMaskFromWidth(LWidth); LCrcBytes := (LWidth + 7) shr 3; @@ -192,89 +484,11 @@ function CRC_Fold_Forward_Scalar(AData: PByte; ALength: UInt32; System.Dec(LLen, 16); end; - PUInt64(AState)^ := LTemp; + TBinaryPrimitives.StoreUInt64(PUInt64(AState), LTemp); Result := LTemp; end; -procedure CRC32_FoldReflected32_OneSlice(Ctx: PCRCFoldRuntimeCtx; - var LCRC: UInt32; LPtr: PByte); -var - LTempCrc: UInt32; -begin - LTempCrc := LCRC; - LCRC := CrcTableU32(Ctx.TableRow[0], LPtr[15]) - xor CrcTableU32(Ctx.TableRow[1], LPtr[14]) - xor CrcTableU32(Ctx.TableRow[2], LPtr[13]) - xor CrcTableU32(Ctx.TableRow[3], LPtr[12]) - xor CrcTableU32(Ctx.TableRow[4], LPtr[11]) - xor CrcTableU32(Ctx.TableRow[5], LPtr[10]) - xor CrcTableU32(Ctx.TableRow[6], LPtr[9]) - xor CrcTableU32(Ctx.TableRow[7], LPtr[8]) - xor CrcTableU32(Ctx.TableRow[8], LPtr[7]) - xor CrcTableU32(Ctx.TableRow[9], LPtr[6]) - xor CrcTableU32(Ctx.TableRow[10], LPtr[5]) - xor CrcTableU32(Ctx.TableRow[11], LPtr[4]) - xor CrcTableU32(Ctx.TableRow[12], LPtr[3] xor Byte(LTempCrc shr 24)) - xor CrcTableU32(Ctx.TableRow[13], LPtr[2] xor Byte(LTempCrc shr 16)) - xor CrcTableU32(Ctx.TableRow[14], LPtr[1] xor Byte(LTempCrc shr 8)) - xor CrcTableU32(Ctx.TableRow[15], LPtr[0] xor Byte(LTempCrc)); -end; - -function CRC_Fold_Reflected32_Scalar(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; -var - Ctx: PCRCFoldRuntimeCtx; - LCRC: UInt32; - LPtr: PByte; - LLen: UInt32; -begin - Ctx := PCRCFoldRuntimeCtx(AConstants); - LPtr := AData; - LLen := ALength; - LCRC := UInt32(PUInt64(AState)^); - - while LLen >= 16 do - begin - CRC32_FoldReflected32_OneSlice(Ctx, LCRC, LPtr); - System.Inc(LPtr, 16); - System.Dec(LLen, 16); - end; - - PUInt64(AState)^ := LCRC; - Result := LCRC; -end; - -procedure CRCDispatch_UpdateReflectedCrc32(var AWireCrc: UInt32; - AData: PByte; ALength: UInt32; ACtx: PCRCFoldRuntimeCtx); -var - LInternal: UInt32; - LPtr: PByte; - LLen, LProcessed: UInt32; - LState: array [0 .. 1] of UInt64; -begin - LInternal := not AWireCrc; - LPtr := AData; - LLen := ALength; - if LLen >= UInt32(MinSimdBytes) then - begin - LProcessed := LLen and (not UInt32(15)); - LState[0] := UInt64(LInternal); - LState[1] := 0; - LInternal := UInt32(CRC_Fold_Reflected32(LPtr, LProcessed, @LState[0], ACtx)); - System.Inc(LPtr, LProcessed); - System.Dec(LLen, LProcessed); - end; - while LLen > 0 do - begin - LInternal := (LInternal shr 8) xor CrcTableU32(ACtx.TableRow[0], - Byte(LInternal and $FF) xor LPtr^); - System.Inc(LPtr); - System.Dec(LLen); - end; - AWireCrc := not LInternal; -end; - -procedure CRCDispatch_InitRuntimeCtx(const Table: THashLibMatrixUInt64Array; +procedure CRC_InitFoldRuntimeCtx(const Table: THashLibMatrixUInt64Array; APoly: UInt64; AWidth: Int32; AReflected: Boolean; out Ctx: TCRCFoldRuntimeCtx); var @@ -285,91 +499,12 @@ procedure CRCDispatch_InitRuntimeCtx(const Table: THashLibMatrixUInt64Array; Ctx.TableRow[I] := @Table[I][0]; end; -procedure CRCDispatch_InitRuntimeCtx(const Table: THashLibMatrixUInt32Array; - AMsbPoly: UInt32; out Ctx: TCRCFoldRuntimeCtx); -var - I: Int32; -begin - TGF2.GenerateFoldConstants(UInt64(AMsbPoly), 32, True, Ctx.FoldConstants); - for I := 0 to 15 do - Ctx.TableRow[I] := @Table[I][0]; -end; - -function CRCDispatch_BuildSlicingTable32Reflect(AReflectedPoly: UInt32) - : THashLibMatrixUInt32Array; -var - LIdx, LJIdx, LKIdx: Int32; - LRes: UInt32; -begin - System.SetLength(Result, 16); - for LIdx := System.Low(Result) to System.High(Result) do - System.SetLength(Result[LIdx], 256); - for LIdx := 0 to System.Pred(256) do - begin - LRes := LIdx; - for LJIdx := 0 to System.Pred(16) do - begin - LKIdx := 0; - while LKIdx < System.Pred(9) do - begin - LRes := (LRes shr 1) xor (-Int32(LRes and 1) and AReflectedPoly); - Result[LJIdx][LIdx] := LRes; - System.Inc(LKIdx); - end; - end; - end; -end; - -procedure CRC_UpdateViaBitSerial(AData: PByte; ADataLength, AIndex: Int32; - var AHash: UInt64; APolynomial: UInt64; AWidth: Int32; - AInputReflected: Boolean; AHighBitMask: UInt64); -var - LLength, LIdx: Int32; - LTemp, LBit, LJdx, LHash: UInt64; -begin - LLength := ADataLength; - LIdx := AIndex; - while LLength > 0 do - begin - LTemp := UInt64(AData[LIdx]); - if AInputReflected then - LTemp := TGF2.BitReverse(LTemp, 8); - - LJdx := $80; - LHash := AHash; - while LJdx > 0 do - begin - LBit := LHash and AHighBitMask; - LHash := LHash shl 1; - if ((LTemp and LJdx) > 0) then - LBit := LBit xor AHighBitMask; - if (LBit > 0) then - LHash := LHash xor APolynomial; - LJdx := LJdx shr 1; - end; - AHash := LHash; - System.Inc(LIdx); - System.Dec(LLength); - end; -end; - // ============================================================================= // Fold routine selection (once, at init) // ============================================================================= -procedure InitCRCFold(); -var - LSel: TCRCFoldSelection; -begin - LSel := TCRCSimd.Select(@CRC_Fold_Reflected_Scalar, - @CRC_Fold_Forward_Scalar, @CRC_Fold_Reflected32_Scalar); - CRC_Fold_Reflected := LSel.Reflected; - CRC_Fold_Forward := LSel.Fwd; - CRC_Fold_Reflected32 := LSel.Reflected32; - CRC_Fold_UsesCarrylessMul := LSel.UsesCarrylessMul; -end; - initialization - InitCRCFold(); + CRC_Fold := TCRCSimd.Select(@CRC_Fold_Reflected_Scalar, + @CRC_Fold_Forward_Scalar); end. diff --git a/HashLib/src/Checksum/HlpCRCFoldConstants.pas b/HashLib/src/Checksum/HlpCRCFoldConstants.pas deleted file mode 100644 index 36e143f..0000000 --- a/HashLib/src/Checksum/HlpCRCFoldConstants.pas +++ /dev/null @@ -1,333 +0,0 @@ -unit HlpCRCFoldConstants; - -{$I ..\Include\HashLib.inc} - -interface - -type - TUInt128 = record - Lo, Hi: UInt64; - end; - - // PCLMULQDQ / VPCLMULQDQ CRC folding and Barrett reduction constants. - // Layout must match the assembly expectations in the CRCFold*.inc files. - TCRCFoldConstants = packed record - Fold_4x128: array [0 .. 1] of UInt64; // offset 0: fold-by-4 constants (stride 512) - Fold_1x128: array [0 .. 1] of UInt64; // offset 16: fold-by-1 constants (stride 128) - Barrett: array [0 .. 1] of UInt64; // offset 32: Barrett reduction constants - Fold_8x128: array [0 .. 1] of UInt64; // offset 48: fold-by-8 constants (stride 1024) - BswapMask: array [0 .. 15] of Byte; // offset 64: byte-reverse mask for MSB-first CRCs - CrcBits: UInt64; // offset 80: CRC width (8..64) - BarrettShift: UInt64; // offset 88: = 64 - CrcBits (MSB psrlq alignment) - end; - - TGF2 = class sealed - strict private - class function BitLength64(A: UInt64): Int32; static; - class function BitLength128(const A: TUInt128): Int32; static; - - // 64 x 64 -> 128 carry-less multiply (MSB-first polynomial arithmetic). - class function CLMul(A, B: UInt64): TUInt128; static; - - // 128-bit polynomial mod G, where G = x^ABits + APoly. - // Returns remainder (degree < ABits, fits in UInt64). - class function Reduce(const A: TUInt128; APoly: UInt64; - ABits: Int32): UInt64; static; - - // floor(A / G) where G = x^ABits + APoly. Returns quotient. - class function DivPoly(const A: TUInt128; APoly: UInt64; - ABits: Int32): UInt64; static; - - // XOR G << AShift into LVal (128-bit), G = x^ABits + APoly. - class procedure XorShiftedG(var AVal: TUInt128; APoly: UInt64; - ABits, AShift: Int32); static; - - public - // Compute x^N mod G using repeated squaring. - // APoly: generator polynomial WITHOUT the leading x^ABits term. - // ABits: CRC width (degree of G). - class function PowerMod(N: Int32; APoly: UInt64; - ABits: Int32): UInt64; static; - - // Reverse the lowest ANumBits bits of AValue. - class function BitReverse(AValue: UInt64; ANumBits: Int32): UInt64; static; - - // Generate PCLMULQDQ fold and Barrett reduction constants for a CRC. - // APoly: generator polynomial (MSB-first, without leading bit). - // ABits: CRC width (8..64). - // AReflected: True for LSB-first (reflected input) CRCs. - class procedure GenerateFoldConstants(APoly: UInt64; ABits: Int32; - AReflected: Boolean; out AConstants: TCRCFoldConstants); static; - end; - -implementation - -{ TGF2 } - -class function TGF2.BitLength64(A: UInt64): Int32; -begin - Result := 0; - while A <> 0 do - begin - System.Inc(Result); - A := A shr 1; - end; -end; - -class function TGF2.BitLength128(const A: TUInt128): Int32; -begin - if A.Hi <> 0 then - Result := 64 + BitLength64(A.Hi) - else - Result := BitLength64(A.Lo); -end; - -class function TGF2.CLMul(A, B: UInt64): TUInt128; -var - I: Int32; -begin - Result.Lo := 0; - Result.Hi := 0; - for I := 0 to 63 do - begin - if (B and (UInt64(1) shl I)) <> 0 then - begin - if I = 0 then - begin - Result.Lo := Result.Lo xor A; - end - else - begin - Result.Lo := Result.Lo xor (A shl I); - Result.Hi := Result.Hi xor (A shr (64 - I)); - end; - end; - end; -end; - -class procedure TGF2.XorShiftedG(var AVal: TUInt128; APoly: UInt64; - ABits, AShift: Int32); -var - LGLo, LGHi: UInt64; - LLeadPos: Int32; -begin - LGLo := 0; - LGHi := 0; - LLeadPos := ABits + AShift; - - if AShift < 64 then - begin - LGLo := APoly shl AShift; - if AShift > 0 then - LGHi := APoly shr (64 - AShift); - end - else - begin - LGHi := APoly shl (AShift - 64); - end; - - if LLeadPos < 64 then - LGLo := LGLo xor (UInt64(1) shl LLeadPos) - else - LGHi := LGHi xor (UInt64(1) shl (LLeadPos - 64)); - - AVal.Lo := AVal.Lo xor LGLo; - AVal.Hi := AVal.Hi xor LGHi; -end; - -class function TGF2.Reduce(const A: TUInt128; APoly: UInt64; - ABits: Int32): UInt64; -var - LVal: TUInt128; - LDeg, LShift: Int32; -begin - LVal := A; - while True do - begin - LDeg := BitLength128(LVal) - 1; - if LDeg < ABits then - Break; - LShift := LDeg - ABits; - XorShiftedG(LVal, APoly, ABits, LShift); - end; - Result := LVal.Lo; -end; - -class function TGF2.DivPoly(const A: TUInt128; APoly: UInt64; - ABits: Int32): UInt64; -var - LVal: TUInt128; - LDeg, LShift: Int32; - LQuotient: UInt64; -begin - LVal := A; - LQuotient := 0; - while True do - begin - LDeg := BitLength128(LVal) - 1; - if LDeg < ABits then - Break; - LShift := LDeg - ABits; - LQuotient := LQuotient xor (UInt64(1) shl LShift); - XorShiftedG(LVal, APoly, ABits, LShift); - end; - Result := LQuotient; -end; - -class function TGF2.PowerMod(N: Int32; APoly: UInt64; - ABits: Int32): UInt64; -var - LBase, LResult: UInt64; - LProduct: TUInt128; -begin - if N = 0 then - Exit(1); - LResult := 1; - LBase := 2; - while N > 0 do - begin - if (N and 1) <> 0 then - begin - LProduct := CLMul(LResult, LBase); - LResult := Reduce(LProduct, APoly, ABits); - end; - N := N shr 1; - if N > 0 then - begin - LProduct := CLMul(LBase, LBase); - LBase := Reduce(LProduct, APoly, ABits); - end; - end; - Result := LResult; -end; - -class function TGF2.BitReverse(AValue: UInt64; ANumBits: Int32): UInt64; -var - I: Int32; -begin - Result := 0; - for I := 0 to ANumBits - 1 do - begin - if (AValue and (UInt64(1) shl I)) <> 0 then - Result := Result or (UInt64(1) shl (ANumBits - 1 - I)); - end; -end; - -class procedure TGF2.GenerateFoldConstants(APoly: UInt64; ABits: Int32; - AReflected: Boolean; out AConstants: TCRCFoldConstants); -var - LK, LPowOfX, I: Int32; - LConst0, LConst1, LBarrett0, LGMinusXn: UInt64; - LDiv128: TUInt128; -begin - // Following the Linux kernel gen-crc-consts.py algorithm. - // G(x) = x^ABits + APoly (MSB-first representation). - // For LSB-first (reflected): each constant is computed in MSB domain, - // then bit-reflected to 64 bits before storage. - - if AReflected then - LK := ABits - 65 - else - LK := 0; - - // --- Fold-by-4 constants (stride = 512 bits) --- - LConst0 := PowerMod(512 + 64 + LK, APoly, ABits); - LConst1 := PowerMod(512 + LK, APoly, ABits); - if AReflected then - begin - AConstants.Fold_4x128[0] := BitReverse(LConst0 shl (64 - ABits), 64); - AConstants.Fold_4x128[1] := BitReverse(LConst1 shl (64 - ABits), 64); - end - else - begin - AConstants.Fold_4x128[0] := LConst1; - AConstants.Fold_4x128[1] := LConst0; - end; - - // --- Fold-by-1 constants (stride = 128 bits) --- - LConst0 := PowerMod(128 + 64 + LK, APoly, ABits); - LConst1 := PowerMod(128 + LK, APoly, ABits); - if AReflected then - begin - AConstants.Fold_1x128[0] := BitReverse(LConst0 shl (64 - ABits), 64); - AConstants.Fold_1x128[1] := BitReverse(LConst1 shl (64 - ABits), 64); - end - else - begin - AConstants.Fold_1x128[0] := LConst1; - AConstants.Fold_1x128[1] := LConst0; - end; - - // --- Fold-by-8 constants (stride = 1024 bits, for VPCLMULQDQ) --- - LConst0 := PowerMod(1024 + 64 + LK, APoly, ABits); - LConst1 := PowerMod(1024 + LK, APoly, ABits); - if AReflected then - begin - AConstants.Fold_8x128[0] := BitReverse(LConst0 shl (64 - ABits), 64); - AConstants.Fold_8x128[1] := BitReverse(LConst1 shl (64 - ABits), 64); - end - else - begin - AConstants.Fold_8x128[0] := LConst1; - AConstants.Fold_8x128[1] := LConst0; - end; - - // --- Barrett reduction constants --- - LGMinusXn := APoly; - - if AReflected then - begin - // LSB-first: m = 63. - // Barrett[0] = bitreflect(floor(x^(63+n) / G), 64) - // Barrett[1] = bitreflect(G, n+1) (truncated: for n=64, x^0 removed) - LDiv128.Lo := 0; - LDiv128.Hi := 0; - if (63 + ABits) < 64 then - LDiv128.Lo := UInt64(1) shl (63 + ABits) - else if (63 + ABits) = 64 then - LDiv128.Hi := 1 - else - LDiv128.Hi := UInt64(1) shl ((63 + ABits) - 64); - LBarrett0 := DivPoly(LDiv128, APoly, ABits); - - AConstants.Barrett[0] := BitReverse(LBarrett0, 64); - if ABits < 64 then - begin - LPowOfX := 64 - ABits - 1; - AConstants.Barrett[1] := BitReverse(LGMinusXn shl LPowOfX, 64); - end - else - AConstants.Barrett[1] := BitReverse(LGMinusXn shr 1, 64); - end - else - begin - // MSB-first: m = 64. Two-round Barrett per Linux kernel. - // Barrett[0] = floor(x^(64+n) / G) - x^64 (mu, low 64 bits) - // Since floor(x^(64+n)/G) = x^64 + floor(APoly*x^64 / G), - // we compute Barrett[0] = DivPoly(APoly*x^64, G) to avoid the x^64 overflow. - // Barrett[1] = G (full generator polynomial; for n=64, x^64 term implicit) - LDiv128.Hi := APoly; - LDiv128.Lo := 0; - AConstants.Barrett[0] := DivPoly(LDiv128, APoly, ABits); - if ABits < 64 then - AConstants.Barrett[1] := (UInt64(1) shl ABits) or APoly - else - AConstants.Barrett[1] := APoly; - end; - - // --- Byte-swap mask for MSB-first CRCs --- - if AReflected then - FillChar(AConstants.BswapMask[0], 16, 0) - else - for I := 0 to 15 do - AConstants.BswapMask[I] := Byte(15 - I); - - // --- Metadata --- - AConstants.CrcBits := UInt64(ABits); - if ABits < 64 then - AConstants.BarrettShift := UInt64(64 - ABits) - else - AConstants.BarrettShift := 0; -end; - -end. diff --git a/HashLib/src/Checksum/HlpCRCStandard.pas b/HashLib/src/Checksum/HlpCRCStandard.pas deleted file mode 100644 index 1a86a1d..0000000 --- a/HashLib/src/Checksum/HlpCRCStandard.pas +++ /dev/null @@ -1,273 +0,0 @@ -unit HlpCRCStandard; - -{$I ..\Include\HashLib.inc} - -{ - Width-specific CRC wrappers (TCRC16 / TCRC32 / TCRC64) that expose the - IHash16 / IHash32 / IHash64 interfaces while delegating all work to the - generic engine in HlpCRC (TCRC). The high-throughput PKZIP/Castagnoli - variants live separately in HlpCRC32Fast. -} - -interface - -uses - HlpHashLibTypes, - HlpHash, - HlpIHash, - HlpICRC, - HlpIHashResult, - HlpIHashInfo, - HlpCRC; - -type - - TCRC16Polynomials = class sealed(TObject) - - private - - const - - BUYPASS = UInt16($8005); - - end; - - TCRC16 = class(THash, IChecksum, IHash16, ITransformBlock) - - strict private - var - FCRCAlgorithm: ICRC; - - public - constructor Create(APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); - - procedure Initialize(); override; - procedure TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); override; - function TransformFinal(): IHashResult; override; - - end; - - TCRC16_BUYPASS = class sealed(TCRC16) - - public - constructor Create(); - - end; - - TCRC32Polynomials = class sealed(TObject) - - private - - const - - PKZIP = UInt32($04C11DB7); - Castagnoli = UInt32($1EDC6F41); - - end; - - TCRC32 = class(THash, IChecksum, IHash32, ITransformBlock) - - strict private - var - FCRCAlgorithm: ICRC; - - public - - constructor Create(APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); - - procedure Initialize(); override; - procedure TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); override; - function TransformFinal(): IHashResult; override; - function Clone(): IHash; override; - - end; - - TCRC32_PKZIP = class sealed(TCRC32) - - public - constructor Create(); - - end; - - TCRC32_CASTAGNOLI = class sealed(TCRC32) - - public - constructor Create(); - - end; - - TCRC64Polynomials = class sealed(TObject) - - private - - const - - ECMA_182 = UInt64($42F0E1EBA9EA3693); - - end; - - TCRC64 = class(THash, IChecksum, IHash64, ITransformBlock) - - strict private - var - FCRCAlgorithm: ICRC; - - public - constructor Create(APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); - - procedure Initialize(); override; - procedure TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); override; - function TransformFinal(): IHashResult; override; - function Clone(): IHash; override; - - end; - - TCRC64_ECMA_182 = class sealed(TCRC64) - - public - constructor Create(); - - end; - -implementation - -{ TCRC16 } - -constructor TCRC16.Create(APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); -begin - inherited Create(2, 1); - FCRCAlgorithm := TCRC.Create(16, APolynomial, AInitial, AIsInputReflected, - AIsOutputReflected, AOutputXor, ACheckValue, ANames); -end; - -procedure TCRC16.Initialize; -begin - FCRCAlgorithm.Initialize; -end; - -procedure TCRC16.TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); -begin - FCRCAlgorithm.TransformBytes(AData, AIndex, ALength); -end; - -function TCRC16.TransformFinal: IHashResult; -begin - Result := FCRCAlgorithm.TransformFinal(); -end; - -{ TCRC16_BUYPASS } - -constructor TCRC16_BUYPASS.Create; -begin - inherited Create(TCRC16Polynomials.BUYPASS, $0000, False, False, $0000, $FEE8, - THashLibStringArray.Create('CRC-16/BUYPASS', 'CRC-16/VERIFONE', - 'CRC-16/UMTS')); -end; - -{ TCRC32 } - -function TCRC32.Clone(): IHash; -begin - Result := FCRCAlgorithm.Clone(); -end; - -constructor TCRC32.Create(APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); -begin - inherited Create(4, 1); - FCRCAlgorithm := TCRC.Create(32, APolynomial, AInitial, AIsInputReflected, - AIsOutputReflected, AOutputXor, ACheckValue, ANames); -end; - -procedure TCRC32.Initialize; -begin - FCRCAlgorithm.Initialize; -end; - -procedure TCRC32.TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); -begin - FCRCAlgorithm.TransformBytes(AData, AIndex, ALength); -end; - -function TCRC32.TransformFinal: IHashResult; -begin - Result := FCRCAlgorithm.TransformFinal(); -end; - -{ TCRC32_PKZIP } - -constructor TCRC32_PKZIP.Create; -begin - inherited Create(TCRC32Polynomials.PKZIP, $FFFFFFFF, True, True, $FFFFFFFF, - $CBF43926, THashLibStringArray.Create('CRC-32', 'CRC-32/ADCCP', - 'CRC-32/V-42', 'CRC-32/XZ', 'PKZIP', 'CRC-32/ISO-HDLC')); - -end; - -{ TCRC32_CASTAGNOLI } - -constructor TCRC32_CASTAGNOLI.Create; -begin - inherited Create(TCRC32Polynomials.Castagnoli, $FFFFFFFF, True, True, - $FFFFFFFF, $E3069283, THashLibStringArray.Create('CRC-32C', - 'CRC-32/BASE91-C', 'CRC-32/CASTAGNOLI', 'CRC-32/INTERLAKEN', - 'CRC-32/ISCSI')); - -end; - -{ TCRC64 } - -function TCRC64.Clone(): IHash; -begin - Result := FCRCAlgorithm.Clone(); -end; - -constructor TCRC64.Create(APolynomial, AInitial: UInt64; - AIsInputReflected, AIsOutputReflected: Boolean; - AOutputXor, ACheckValue: UInt64; const ANames: THashLibStringArray); -begin - inherited Create(8, 1); - FCRCAlgorithm := TCRC.Create(64, APolynomial, AInitial, AIsInputReflected, - AIsOutputReflected, AOutputXor, ACheckValue, ANames); -end; - -procedure TCRC64.Initialize; -begin - FCRCAlgorithm.Initialize; -end; - -procedure TCRC64.TransformBytes(const AData: THashLibByteArray; - AIndex, ALength: Int32); -begin - FCRCAlgorithm.TransformBytes(AData, AIndex, ALength); -end; - -function TCRC64.TransformFinal: IHashResult; -begin - Result := FCRCAlgorithm.TransformFinal(); -end; - -{ TCRC64_ECMA_182 } - -constructor TCRC64_ECMA_182.Create; -begin - inherited Create(TCRC64Polynomials.ECMA_182, $0000000000000000, False, False, - $0000000000000000, $6C40DF5F0B497347, THashLibStringArray.Create('CRC-64', - 'CRC-64/ECMA-182')); -end; - -end. diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc index 273cfef..bcc87bf 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc @@ -8,12 +8,12 @@ // // Register mapping (MS x64 ABI after prologue): // rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: [0..7] = initial CRC pre-shifted left by (64 - Width), [8..15] = 0. +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as one UInt64. // AConstants layout (TCRCFoldConstants): // [0..15] = Fold_4x128 // [16..31] = Fold_1x128 // [32..47] = Barrett -// [48..63] = Fold_8x128 (unused by this path) +// [48..63] = Fold_8x128 // [64..79] = BswapMask // [80..87] = CrcBits // [88..95] = BarrettShift @@ -21,19 +21,165 @@ // // Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google). // -// pclmulqdq xmm_dst, xmm_src, imm8 (register-register, no REX for xmm0-7): -// 66 0F 3A 44 ModRM imm8 +// pclmulqdq xmm_dst, xmm_src, imm8 (register-register): +// 66 [REX] 0F 3A 44 ModRM imm8 (REX = $44 = REX.R for xmm8-15 dst) // ModRM for reg-reg: 11_dst_src // xmm0=000 xmm1=001 xmm2=010 xmm3=011 xmm4=100 -// xmm5=101 xmm6=110 xmm7=111 +// xmm5=101 xmm6=110 xmm7=111 xmm8-15=REX.R + 000..111 // pshufb xmm_dst, xmm_src (SSSE3): -// 66 0F 38 00 ModRM +// 66 [REX] 0F 38 00 ModRM {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // BswapMask is always needed (kept in xmm6 throughout) movdqu xmm6, dqword ptr [r9 + 64] // BswapMask + cmp edx, 128 + jb @check64 + + // ===== Very large input (>= 128 bytes): fold-by-8, 128 bytes/iter ===== + movdqu xmm7, dqword ptr [r9 + 48] // fold_8x128 (stride 1024) + + movdqu xmm0, dqword ptr [rcx] + db $66, $0F, $38, $00, $C6 // pshufb xmm0, xmm6 + movdqu xmm1, dqword ptr [rcx + 16] + db $66, $0F, $38, $00, $CE // pshufb xmm1, xmm6 + movdqu xmm2, dqword ptr [rcx + 32] + db $66, $0F, $38, $00, $D6 // pshufb xmm2, xmm6 + movdqu xmm3, dqword ptr [rcx + 48] + db $66, $0F, $38, $00, $DE // pshufb xmm3, xmm6 + movdqu xmm8, dqword ptr [rcx + 64] + db $66, $44, $0F, $38, $00, $C6 // pshufb xmm8, xmm6 + movdqu xmm9, dqword ptr [rcx + 80] + db $66, $44, $0F, $38, $00, $CE // pshufb xmm9, xmm6 + movdqu xmm10, dqword ptr [rcx + 96] + db $66, $44, $0F, $38, $00, $D6 // pshufb xmm10, xmm6 + movdqu xmm11, dqword ptr [rcx + 112] + db $66, $44, $0F, $38, $00, $DE // pshufb xmm11, xmm6 + + movq xmm4, qword ptr [r8] + pslldq xmm4, 8 + pxor xmm0, xmm4 + + add rcx, 128 + sub edx, 128 + + cmp edx, 128 + jb @fold8_reduce + +@fold8_loop: + // Fold xmm0 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + movdqu xmm5, dqword ptr [rcx] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm0, xmm5 + + // Fold xmm1 + movdqa xmm4, xmm1 + db $66, $0F, $3A, $44, $CF, $00 // pclmulqdq xmm1, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm1, xmm4 + movdqu xmm5, dqword ptr [rcx + 16] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm1, xmm5 + + // Fold xmm2 + movdqa xmm4, xmm2 + db $66, $0F, $3A, $44, $D7, $00 // pclmulqdq xmm2, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm2, xmm4 + movdqu xmm5, dqword ptr [rcx + 32] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm2, xmm5 + + // Fold xmm3 + movdqa xmm4, xmm3 + db $66, $0F, $3A, $44, $DF, $00 // pclmulqdq xmm3, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm3, xmm4 + movdqu xmm5, dqword ptr [rcx + 48] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm3, xmm5 + + // Fold xmm8 + movdqa xmm4, xmm8 + db $66, $44, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm8, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm8, xmm4 + movdqu xmm5, dqword ptr [rcx + 64] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm8, xmm5 + + // Fold xmm9 + movdqa xmm4, xmm9 + db $66, $44, $0F, $3A, $44, $CF, $00 // pclmulqdq xmm9, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm9, xmm4 + movdqu xmm5, dqword ptr [rcx + 80] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm9, xmm5 + + // Fold xmm10 + movdqa xmm4, xmm10 + db $66, $44, $0F, $3A, $44, $D7, $00 // pclmulqdq xmm10, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm10, xmm4 + movdqu xmm5, dqword ptr [rcx + 96] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm10, xmm5 + + // Fold xmm11 + movdqa xmm4, xmm11 + db $66, $44, $0F, $3A, $44, $DF, $00 // pclmulqdq xmm11, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm11, xmm4 + movdqu xmm5, dqword ptr [rcx + 112] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm11, xmm5 + + add rcx, 128 + sub edx, 128 + cmp edx, 128 + jae @fold8_loop + +@fold8_reduce: + // --- Reduce 8 accumulators to 4 using fold_4x128 (stride 512) --- + movdqu xmm7, dqword ptr [r9] // fold_4x128 + + // xmm0 = fold(xmm0) XOR xmm8 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm8 + + // xmm1 = fold(xmm1) XOR xmm9 + movdqa xmm4, xmm1 + db $66, $0F, $3A, $44, $CF, $00 // pclmulqdq xmm1, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm1, xmm4 + pxor xmm1, xmm9 + + // xmm2 = fold(xmm2) XOR xmm10 + movdqa xmm4, xmm2 + db $66, $0F, $3A, $44, $D7, $00 // pclmulqdq xmm2, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm2, xmm4 + pxor xmm2, xmm10 + + // xmm3 = fold(xmm3) XOR xmm11 + movdqa xmm4, xmm3 + db $66, $0F, $3A, $44, $DF, $00 // pclmulqdq xmm3, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm3, xmm4 + pxor xmm3, xmm11 + + jmp @fold4_done + +@check64: cmp edx, 64 jae @large_input diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc index 08cca4f..61ffc90 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc @@ -2,11 +2,11 @@ // non-reflected (MSB-first) CRCs with width 8..64. // Expects AAPCS64: x0 = AData, w1 = ALength (>= 16, multiple of 16), // x2 = AState, x3 = AConstants (PCRCFoldRuntimeCtx; FoldConstants at +0). -// AState: [0..7] = initial CRC pre-shifted left by (64 - Width), [8..15] = 0. +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as one UInt64. // AConstants: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, // [+64] BswapMask, [+80] CrcBits, [+88] BarrettShift. // Returns final CRC in x0. -// Leaf nostackframe; caller-saved GPR/vector only (v0-v7, v17). +// Leaf nostackframe; caller-saved GPR/vector only (v0-v7, v17, v19-v22). // Reference: Linux kernel crc-pclmul-template.S (Eric Biggers), // HashLib CRCFoldForwardPclmul_x86_64.inc. // AArch64 vector instructions are .long-encoded for broad assembler compatibility. @@ -15,9 +15,122 @@ // v4 = pmull-hi temp (xmm4) // v5 = loaded 16-byte block (xmm5) // v6 = BswapMask then Barrett consts [G : mu_lo] (xmm6) -// v7 = Fold_4x128 then Fold_1x128 (xmm7) +// v7 = Fold_8x128 / Fold_4x128 then Fold_1x128 (xmm7) // v17 = dup staging for clmul hi*lo ($01) Barrett mix +// v19-v22 = fold-by-8 upper accumulators (xmm8-11) .long 0x3dc01066 // ldr q6, [x3, #64] + .long 0x7102003f // cmp w1, #128 + b.lo .Lcrc_fwd_check64 + .long 0x3dc00c67 // ldr q7, [x3, #48] + .long 0x3dc00000 // ldr q0, [x0, #0] + .long 0x4e060000 // tbl v0.16b, {v0.16b}, v6.16b + .long 0x3dc00401 // ldr q1, [x0, #16] + .long 0x4e060021 // tbl v1.16b, {v1.16b}, v6.16b + .long 0x3dc00802 // ldr q2, [x0, #32] + .long 0x4e060042 // tbl v2.16b, {v2.16b}, v6.16b + .long 0x3dc00c03 // ldr q3, [x0, #48] + .long 0x4e060063 // tbl v3.16b, {v3.16b}, v6.16b + .long 0x3dc01013 // ldr q19, [x0, #64] + .long 0x4e060273 // tbl v19.16b, {v19.16b}, v6.16b + .long 0x3dc01414 // ldr q20, [x0, #80] + .long 0x4e060294 // tbl v20.16b, {v20.16b}, v6.16b + .long 0x3dc01815 // ldr q21, [x0, #96] + .long 0x4e0602b5 // tbl v21.16b, {v21.16b}, v6.16b + .long 0x3dc01c16 // ldr q22, [x0, #112] + .long 0x4e0602d6 // tbl v22.16b, {v22.16b}, v6.16b + .long 0xf9400044 // ldr x4, [x2] + .long 0x6e241c84 // eor v4.16b, v4.16b, v4.16b + .long 0x4e181c84 // ins v4.d[1], x4 + .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b + .long 0x91020000 // add x0, x0, #128 + .long 0x51020021 // sub w1, w1, #128 + .long 0x7102003f // cmp w1, #128 + b.lo .Lcrc_fwd_fold8_reduce +.Lcrc_fwd_fold8_loop: + .long 0x4ea01c04 // orr v4.16b, v0.16b, v0.16b + .long 0x0ee7e000 // pmull v0.1q, v0.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b + .long 0x3dc00005 // ldr q5, [x0, #0] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251c00 // eor v0.16b, v0.16b, v5.16b + .long 0x4ea11c24 // orr v4.16b, v1.16b, v1.16b + .long 0x0ee7e021 // pmull v1.1q, v1.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c21 // eor v1.16b, v1.16b, v4.16b + .long 0x3dc00405 // ldr q5, [x0, #16] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251c21 // eor v1.16b, v1.16b, v5.16b + .long 0x4ea21c44 // orr v4.16b, v2.16b, v2.16b + .long 0x0ee7e042 // pmull v2.1q, v2.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b + .long 0x3dc00805 // ldr q5, [x0, #32] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251c42 // eor v2.16b, v2.16b, v5.16b + .long 0x4ea31c64 // orr v4.16b, v3.16b, v3.16b + .long 0x0ee7e063 // pmull v3.1q, v3.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c63 // eor v3.16b, v3.16b, v4.16b + .long 0x3dc00c05 // ldr q5, [x0, #48] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b + .long 0x4eb31e64 // orr v4.16b, v19.16b, v19.16b + .long 0x0ee7e273 // pmull v19.1q, v19.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241e73 // eor v19.16b, v19.16b, v4.16b + .long 0x3dc01005 // ldr q5, [x0, #64] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251e73 // eor v19.16b, v19.16b, v5.16b + .long 0x4eb41e84 // orr v4.16b, v20.16b, v20.16b + .long 0x0ee7e294 // pmull v20.1q, v20.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241e94 // eor v20.16b, v20.16b, v4.16b + .long 0x3dc01405 // ldr q5, [x0, #80] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251e94 // eor v20.16b, v20.16b, v5.16b + .long 0x4eb51ea4 // orr v4.16b, v21.16b, v21.16b + .long 0x0ee7e2b5 // pmull v21.1q, v21.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x3dc01805 // ldr q5, [x0, #96] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251eb5 // eor v21.16b, v21.16b, v5.16b + .long 0x4eb61ec4 // orr v4.16b, v22.16b, v22.16b + .long 0x0ee7e2d6 // pmull v22.1q, v22.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241ed6 // eor v22.16b, v22.16b, v4.16b + .long 0x3dc01c05 // ldr q5, [x0, #112] + .long 0x4e0600a5 // tbl v5.16b, {v5.16b}, v6.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x91020000 // add x0, x0, #128 + .long 0x51020021 // sub w1, w1, #128 + .long 0x7102003f // cmp w1, #128 + b.hs .Lcrc_fwd_fold8_loop +.Lcrc_fwd_fold8_reduce: + .long 0x3dc00067 // ldr q7, [x3] + .long 0x4ea01c04 // orr v4.16b, v0.16b, v0.16b + .long 0x0ee7e000 // pmull v0.1q, v0.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b + .long 0x6e331c00 // eor v0.16b, v0.16b, v19.16b + .long 0x4ea11c24 // orr v4.16b, v1.16b, v1.16b + .long 0x0ee7e021 // pmull v1.1q, v1.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c21 // eor v1.16b, v1.16b, v4.16b + .long 0x6e341c21 // eor v1.16b, v1.16b, v20.16b + .long 0x4ea21c44 // orr v4.16b, v2.16b, v2.16b + .long 0x0ee7e042 // pmull v2.1q, v2.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b + .long 0x6e351c42 // eor v2.16b, v2.16b, v21.16b + .long 0x4ea31c64 // orr v4.16b, v3.16b, v3.16b + .long 0x0ee7e063 // pmull v3.1q, v3.1d, v7.1d + .long 0x4ee7e084 // pmull2 v4.1q, v4.2d, v7.2d + .long 0x6e241c63 // eor v3.16b, v3.16b, v4.16b + .long 0x6e361c63 // eor v3.16b, v3.16b, v22.16b + b .Lcrc_fwd_fold4_done +.Lcrc_fwd_check64: .long 0x7101003f // cmp w1, #64 b.hs .Lcrc_fwd_large .long 0x3dc00467 // ldr q7, [x3, #16] diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc index 0f96eff..5128fb1 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc @@ -16,13 +16,11 @@ // [esp+32] LBIdx // [esp+36] saved esi (remaining length) -@MsbSse2_outer: - cmp esi, 16 - jb @MsbSse2_done - + // Loop invariants: Width from CrcBits [ebp+80]; 64-bit mask into + // [esp+8],[esp+12]; LCrcBytes into [esp+16]; top-byte shift into [esp+20]. + // esi (length) is scratch during the mask build - park it in [esp+36]. mov dword ptr [esp + 36], esi - // Width from CrcBits [ebp+80]; build 64-bit mask into [esp+8],[esp+12] mov eax, dword ptr [ebp + 80] mov ecx, eax dec ecx @@ -50,8 +48,6 @@ mov dword ptr [esp + 8], eax mov dword ptr [esp + 12], edx - mov esi, dword ptr [esp + 36] - mov eax, dword ptr [ebp + 80] add eax, 7 shr eax, 3 @@ -61,6 +57,14 @@ sub eax, 8 mov dword ptr [esp + 20], eax + mov esi, dword ptr [esp + 36] + +@MsbSse2_outer: + cmp esi, 16 + jb @MsbSse2_done + + mov dword ptr [esp + 36], esi + mov eax, dword ptr [edi] mov edx, dword ptr [edi + 4] mov dword ptr [esp], eax diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc index 6bdbd6b..80aef2a 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc @@ -20,10 +20,7 @@ mov rbx, qword ptr [r8] // LTemp mov r15, rcx // data pointer (stable) -@MsbSse2_outer: - cmp edx, 16 - jb @MsbSse2_done - + // Loop invariants (width, mask, byte count, top-byte shift) mov r14d, dword ptr [r9 + 80] // Width from FoldConstants.CrcBits // r12 = CRCMaskFromWidth(r14d) @@ -41,13 +38,17 @@ shr eax, 3 // LCrcBytes mov r13d, eax + mov ecx, r14d + sub ecx, 8 // Width - 8, shift count for top byte + +@MsbSse2_outer: + cmp edx, 16 + jb @MsbSse2_done + xor rbp, rbp // LNewTemp mov rsi, rbx // LTempCopy xor edi, edi // LBIdx - mov ecx, r14d - sub ecx, 8 // Width - 8, shift count for top byte - @MsbSse2_m1: cmp edi, r13d jge @MsbSse2_m2 diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc index a9b97f4..203e4e0 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc @@ -9,7 +9,7 @@ // // Register mapping (MS x64 ABI after prologue): // rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: [0..7] = initial CRC pre-shifted left by (64 - Width), [8..15] = 0. +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as one UInt64. // AConstants layout (TCRCFoldConstants): // [0..15] = Fold_4x128 (stride 512) // [16..31] = Fold_1x128 (stride 128) diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_i386.inc deleted file mode 100644 index 186f190..0000000 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_i386.inc +++ /dev/null @@ -1,134 +0,0 @@ -// CRC32 reflected (PKZIP-style) 16-byte slice (IA-32 SSE2 + dword table XOR). -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength, edi = AState, eax = Ctx. -// Little-endian host only. PUInt32 rows at Ctx + 96. -// d0 xor CRC saved at [esp+12]; d1 in edx; d2/d3 on stack. Result eax, edx=0. - - push ebp - mov ebp, eax - - sub esp, 32 - // [esp+12] d0 after xor CRC, [esp+16] saved esi, [esp+20] d2, [esp+24] d3 - -@L32Sse2_outer: - cmp esi, 16 - jb @L32Sse2_done - - movdqu xmm0, oword ptr [ebx] - - movd eax, xmm0 - psrldq xmm0, 4 - movd edx, xmm0 - psrldq xmm0, 4 - movd dword ptr [esp + 20], xmm0 - psrldq xmm0, 4 - movd dword ptr [esp + 24], xmm0 - - mov dword ptr [esp + 16], esi - - xor eax, dword ptr [edi] - mov dword ptr [esp + 12], eax - - xor ecx, ecx - - mov esi, dword ptr [esp + 24] - shr esi, 24 - mov eax, dword ptr [ebp + 96 + 0 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 24] - shr esi, 16 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 1 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 24] - shr esi, 8 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 2 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 24] - and esi, $FF - mov eax, dword ptr [ebp + 96 + 3 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 20] - shr esi, 24 - mov eax, dword ptr [ebp + 96 + 4 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 20] - shr esi, 16 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 5 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 20] - shr esi, 8 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 6 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 20] - and esi, $FF - mov eax, dword ptr [ebp + 96 + 7 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, edx - shr esi, 24 - mov eax, dword ptr [ebp + 96 + 8 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, edx - shr esi, 16 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 9 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, edx - shr esi, 8 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 10 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, edx - and esi, $FF - mov eax, dword ptr [ebp + 96 + 11 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 12] - shr esi, 24 - mov eax, dword ptr [ebp + 96 + 12 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 12] - shr esi, 16 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 13 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 12] - shr esi, 8 - and esi, $FF - mov eax, dword ptr [ebp + 96 + 14 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov esi, dword ptr [esp + 12] - and esi, $FF - mov eax, dword ptr [ebp + 96 + 15 * 4] - xor ecx, dword ptr [eax + esi * 4] - - mov dword ptr [edi], ecx - mov esi, dword ptr [esp + 16] - add ebx, 16 - sub esi, 16 - jmp @L32Sse2_outer - -@L32Sse2_done: - mov eax, dword ptr [edi] - xor edx, edx - add esp, 32 - pop ebp - pop edi - pop esi - pop ebx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_x86_64.inc deleted file mode 100644 index 6a51c09..0000000 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflected32Sse2_x86_64.inc +++ /dev/null @@ -1,134 +0,0 @@ -// CRC32 reflected (PKZIP-style) 16-byte slice: SSE2 movdqu + dword table XOR. -// Little-endian host only (x86/x64 asm reads 32-bit words directly from memory). -// Signature (after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// State: low UInt32 of qword at AState is the running CRC. -// Ctx: PCRCFoldRuntimeCtx; TableRow offset = 96. - - push rbx - push r12 - push r13 - push r14 - push r15 - - mov ebx, dword ptr [r8] - -@L32Sse2_outer: - cmp edx, 16 - jb @L32Sse2_done - - movdqu xmm0, dqword ptr [rcx] - movd r10d, xmm0 - psrldq xmm0, 4 - movd r11d, xmm0 - psrldq xmm0, 4 - movd r12d, xmm0 - psrldq xmm0, 4 - movd r13d, xmm0 - - xor r10d, ebx - - xor ebx, ebx - - mov eax, r13d - shr eax, 24 - mov r14, qword ptr [r9 + 96 + 0 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r13d - shr eax, 16 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 1 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r13d - shr eax, 8 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 2 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r13d - and eax, $FF - mov r14, qword ptr [r9 + 96 + 3 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r12d - shr eax, 24 - mov r14, qword ptr [r9 + 96 + 4 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r12d - shr eax, 16 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 5 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r12d - shr eax, 8 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 6 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r12d - and eax, $FF - mov r14, qword ptr [r9 + 96 + 7 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r11d - shr eax, 24 - mov r14, qword ptr [r9 + 96 + 8 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r11d - shr eax, 16 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 9 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r11d - shr eax, 8 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 10 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r11d - and eax, $FF - mov r14, qword ptr [r9 + 96 + 11 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r10d - shr eax, 24 - mov r14, qword ptr [r9 + 96 + 12 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r10d - shr eax, 16 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 13 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r10d - shr eax, 8 - and eax, $FF - mov r14, qword ptr [r9 + 96 + 14 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - mov eax, r10d - and eax, $FF - mov r14, qword ptr [r9 + 96 + 15 * 8] - xor ebx, dword ptr [r14 + rax * 4] - - add rcx, 16 - sub edx, 16 - jmp @L32Sse2_outer - -@L32Sse2_done: - mov dword ptr [r8], ebx - mov eax, ebx - - pop r15 - pop r14 - pop r13 - pop r12 - pop rbx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc index 0db7df3..445c97c 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc @@ -8,29 +8,158 @@ // // Register mapping (MS x64 ABI after prologue): // rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: [0..7] = initial CRC (reflected), [8..15] = 0. +// AState: pointer to the initial CRC (reflected) as one UInt64. // AConstants layout (TCRCFoldConstants): // [0..15] = Fold_4x128 // [16..31] = Fold_1x128 // [32..47] = Barrett -// [48..63] = Fold_8x128 (unused by this path) +// [48..63] = Fold_8x128 // [64..79] = BswapMask (unused by this path) // [80..87] = CrcBits // Returns: final CRC in RAX. // // Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google). // -// pclmulqdq xmm_dst, xmm_src, imm8 (register-register, no REX for xmm0-7): -// 66 0F 3A 44 ModRM imm8 +// pclmulqdq xmm_dst, xmm_src, imm8 (register-register): +// 66 [REX] 0F 3A 44 ModRM imm8 (REX = $44 = REX.R for xmm8-15 dst) // ModRM for reg-reg: 11_dst_src // xmm0=000 xmm1=001 xmm2=010 xmm3=011 xmm4=100 -// xmm5=101 xmm6=110 xmm7=111 +// xmm5=101 xmm6=110 xmm7=111 xmm8-15=REX.R + 000..111 {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // fold_1x128 is always needed (fold-by-1 loop and Barrett step 1) movdqu xmm7, dqword ptr [r9 + 16] // fold_1x128 + cmp edx, 128 + jb @check64 + + // ===== Very large input (>= 128 bytes): fold-by-8, 128 bytes/iter ===== + movdqu xmm6, dqword ptr [r9 + 48] // fold_8x128 (stride 1024) + + movdqu xmm0, dqword ptr [rcx] + movdqu xmm1, dqword ptr [rcx + 16] + movdqu xmm2, dqword ptr [rcx + 32] + movdqu xmm3, dqword ptr [rcx + 48] + movdqu xmm8, dqword ptr [rcx + 64] + movdqu xmm9, dqword ptr [rcx + 80] + movdqu xmm10, dqword ptr [rcx + 96] + movdqu xmm11, dqword ptr [rcx + 112] + + movq xmm4, qword ptr [r8] + pxor xmm0, xmm4 + + add rcx, 128 + sub edx, 128 + + cmp edx, 128 + jb @fold8_reduce + +@fold8_loop: + // Fold xmm0 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C6, $00 // pclmulqdq xmm0, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm0, xmm4 + movdqu xmm5, dqword ptr [rcx] + pxor xmm0, xmm5 + + // Fold xmm1 + movdqa xmm4, xmm1 + db $66, $0F, $3A, $44, $CE, $00 // pclmulqdq xmm1, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm1, xmm4 + movdqu xmm5, dqword ptr [rcx + 16] + pxor xmm1, xmm5 + + // Fold xmm2 + movdqa xmm4, xmm2 + db $66, $0F, $3A, $44, $D6, $00 // pclmulqdq xmm2, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm2, xmm4 + movdqu xmm5, dqword ptr [rcx + 32] + pxor xmm2, xmm5 + + // Fold xmm3 + movdqa xmm4, xmm3 + db $66, $0F, $3A, $44, $DE, $00 // pclmulqdq xmm3, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm3, xmm4 + movdqu xmm5, dqword ptr [rcx + 48] + pxor xmm3, xmm5 + + // Fold xmm8 + movdqa xmm4, xmm8 + db $66, $44, $0F, $3A, $44, $C6, $00 // pclmulqdq xmm8, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm8, xmm4 + movdqu xmm5, dqword ptr [rcx + 64] + pxor xmm8, xmm5 + + // Fold xmm9 + movdqa xmm4, xmm9 + db $66, $44, $0F, $3A, $44, $CE, $00 // pclmulqdq xmm9, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm9, xmm4 + movdqu xmm5, dqword ptr [rcx + 80] + pxor xmm9, xmm5 + + // Fold xmm10 + movdqa xmm4, xmm10 + db $66, $44, $0F, $3A, $44, $D6, $00 // pclmulqdq xmm10, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm10, xmm4 + movdqu xmm5, dqword ptr [rcx + 96] + pxor xmm10, xmm5 + + // Fold xmm11 + movdqa xmm4, xmm11 + db $66, $44, $0F, $3A, $44, $DE, $00 // pclmulqdq xmm11, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm11, xmm4 + movdqu xmm5, dqword ptr [rcx + 112] + pxor xmm11, xmm5 + + add rcx, 128 + sub edx, 128 + cmp edx, 128 + jae @fold8_loop + +@fold8_reduce: + // --- Reduce 8 accumulators to 4 using fold_4x128 (stride 512) --- + movdqu xmm6, dqword ptr [r9] // fold_4x128 + + // xmm0 = fold(xmm0) XOR xmm8 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C6, $00 // pclmulqdq xmm0, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm8 + + // xmm1 = fold(xmm1) XOR xmm9 + movdqa xmm4, xmm1 + db $66, $0F, $3A, $44, $CE, $00 // pclmulqdq xmm1, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm1, xmm4 + pxor xmm1, xmm9 + + // xmm2 = fold(xmm2) XOR xmm10 + movdqa xmm4, xmm2 + db $66, $0F, $3A, $44, $D6, $00 // pclmulqdq xmm2, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm2, xmm4 + pxor xmm2, xmm10 + + // xmm3 = fold(xmm3) XOR xmm11 + movdqa xmm4, xmm3 + db $66, $0F, $3A, $44, $DE, $00 // pclmulqdq xmm3, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm3, xmm4 + pxor xmm3, xmm11 + + jmp @fold4_done + +@check64: cmp edx, 64 jae @large_input diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc index 06d9e96..a95dfed 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc @@ -2,10 +2,10 @@ // CRCs with width 8..64. CRC-64 uses a special Barrett path for the 65-bit G. // Expects AAPCS64: x0 = AData, w1 = ALength (>= 16, multiple of 16), // x2 = AState, x3 = AConstants (PCRCFoldRuntimeCtx; FoldConstants at +0). -// AState: [0..7] = initial CRC (reflected), [8..15] = 0. +// AState: pointer to the initial CRC (reflected) as one UInt64. // AConstants: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, // [+80] CrcBits. Returns final CRC in x0. -// Leaf nostackframe; caller-saved GPR/vector only (v0-v7, v16-v18). +// Leaf nostackframe; caller-saved GPR/vector only (v0-v7, v16-v22). // Reference: Linux kernel crc-pclmul-template.S (Eric Biggers), // HashLib CRCFoldReflectedPclmul_x86_64.inc. // AArch64 vector instructions are .long-encoded for broad assembler compatibility. @@ -13,12 +13,107 @@ // v0-v3 = fold accumulators (xmm0-3) // v4 = pmull-hi temp (xmm4) // v5 = loaded 16-byte block (xmm5) -// v6 = Fold_4x128 then Barrett consts (xmm6) +// v6 = Fold_8x128 / Fold_4x128 then Barrett consts (xmm6) // v7 = Fold_1x128 (xmm7) // v16 = zeroed scratch (psrldq emulation via ext) // v17 = dup staging for clmul lo*hi ($10) Barrett mixes // v18 = saved Barrett q (CRC-64 x^0 correction) +// v19-v22 = fold-by-8 upper accumulators (xmm8-11) .long 0x3dc00467 // ldr q7, [x3, #16] + .long 0x7102003f // cmp w1, #128 + b.lo .Lcrc_refl_check64 + .long 0x3dc00c66 // ldr q6, [x3, #48] + .long 0x3dc00000 // ldr q0, [x0, #0] + .long 0x3dc00401 // ldr q1, [x0, #16] + .long 0x3dc00802 // ldr q2, [x0, #32] + .long 0x3dc00c03 // ldr q3, [x0, #48] + .long 0x3dc01013 // ldr q19, [x0, #64] + .long 0x3dc01414 // ldr q20, [x0, #80] + .long 0x3dc01815 // ldr q21, [x0, #96] + .long 0x3dc01c16 // ldr q22, [x0, #112] + .long 0xfd400044 // ldr d4, [x2] + .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b + .long 0x91020000 // add x0, x0, #128 + .long 0x51020021 // sub w1, w1, #128 + .long 0x7102003f // cmp w1, #128 + b.lo .Lcrc_refl_fold8_reduce +.Lcrc_refl_fold8_loop: + .long 0x4ea01c04 // orr v4.16b, v0.16b, v0.16b + .long 0x0ee6e000 // pmull v0.1q, v0.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b + .long 0x3dc00005 // ldr q5, [x0, #0] + .long 0x6e251c00 // eor v0.16b, v0.16b, v5.16b + .long 0x4ea11c24 // orr v4.16b, v1.16b, v1.16b + .long 0x0ee6e021 // pmull v1.1q, v1.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c21 // eor v1.16b, v1.16b, v4.16b + .long 0x3dc00405 // ldr q5, [x0, #16] + .long 0x6e251c21 // eor v1.16b, v1.16b, v5.16b + .long 0x4ea21c44 // orr v4.16b, v2.16b, v2.16b + .long 0x0ee6e042 // pmull v2.1q, v2.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b + .long 0x3dc00805 // ldr q5, [x0, #32] + .long 0x6e251c42 // eor v2.16b, v2.16b, v5.16b + .long 0x4ea31c64 // orr v4.16b, v3.16b, v3.16b + .long 0x0ee6e063 // pmull v3.1q, v3.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c63 // eor v3.16b, v3.16b, v4.16b + .long 0x3dc00c05 // ldr q5, [x0, #48] + .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b + .long 0x4eb31e64 // orr v4.16b, v19.16b, v19.16b + .long 0x0ee6e273 // pmull v19.1q, v19.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241e73 // eor v19.16b, v19.16b, v4.16b + .long 0x3dc01005 // ldr q5, [x0, #64] + .long 0x6e251e73 // eor v19.16b, v19.16b, v5.16b + .long 0x4eb41e84 // orr v4.16b, v20.16b, v20.16b + .long 0x0ee6e294 // pmull v20.1q, v20.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241e94 // eor v20.16b, v20.16b, v4.16b + .long 0x3dc01405 // ldr q5, [x0, #80] + .long 0x6e251e94 // eor v20.16b, v20.16b, v5.16b + .long 0x4eb51ea4 // orr v4.16b, v21.16b, v21.16b + .long 0x0ee6e2b5 // pmull v21.1q, v21.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x3dc01805 // ldr q5, [x0, #96] + .long 0x6e251eb5 // eor v21.16b, v21.16b, v5.16b + .long 0x4eb61ec4 // orr v4.16b, v22.16b, v22.16b + .long 0x0ee6e2d6 // pmull v22.1q, v22.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241ed6 // eor v22.16b, v22.16b, v4.16b + .long 0x3dc01c05 // ldr q5, [x0, #112] + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x91020000 // add x0, x0, #128 + .long 0x51020021 // sub w1, w1, #128 + .long 0x7102003f // cmp w1, #128 + b.hs .Lcrc_refl_fold8_loop +.Lcrc_refl_fold8_reduce: + .long 0x3dc00066 // ldr q6, [x3] + .long 0x4ea01c04 // orr v4.16b, v0.16b, v0.16b + .long 0x0ee6e000 // pmull v0.1q, v0.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b + .long 0x6e331c00 // eor v0.16b, v0.16b, v19.16b + .long 0x4ea11c24 // orr v4.16b, v1.16b, v1.16b + .long 0x0ee6e021 // pmull v1.1q, v1.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c21 // eor v1.16b, v1.16b, v4.16b + .long 0x6e341c21 // eor v1.16b, v1.16b, v20.16b + .long 0x4ea21c44 // orr v4.16b, v2.16b, v2.16b + .long 0x0ee6e042 // pmull v2.1q, v2.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b + .long 0x6e351c42 // eor v2.16b, v2.16b, v21.16b + .long 0x4ea31c64 // orr v4.16b, v3.16b, v3.16b + .long 0x0ee6e063 // pmull v3.1q, v3.1d, v6.1d + .long 0x4ee6e084 // pmull2 v4.1q, v4.2d, v6.2d + .long 0x6e241c63 // eor v3.16b, v3.16b, v4.16b + .long 0x6e361c63 // eor v3.16b, v3.16b, v22.16b + b .Lcrc_refl_fold4_done +.Lcrc_refl_check64: .long 0x7101003f // cmp w1, #64 b.hs .Lcrc_refl_large .long 0x3dc00000 // ldr q0, [x0] diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc index 4eb74ca..469962d 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc @@ -8,7 +8,7 @@ // // Register mapping (MS x64 ABI after prologue): // rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: [0..7] = initial CRC (reflected), [8..15] = 0. +// AState: pointer to the initial CRC (reflected) as one UInt64. // AConstants layout (TCRCFoldConstants): // [0..15] = Fold_4x128 (stride 512) // [16..31] = Fold_1x128 (stride 128) diff --git a/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk b/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk index 8e8ced0..9612612 100644 --- a/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk +++ b/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk @@ -54,9 +54,6 @@ contains HlpCRCSimd in '..\..\Simd\Facade\HlpCRCSimd.pas', HlpCRCX86Backend in '..\..\Simd\Backend\HlpCRCX86Backend.pas', HlpCRCArmBackend in '..\..\Simd\Backend\HlpCRCArmBackend.pas', - HlpCRCFoldConstants in '..\..\Checksum\HlpCRCFoldConstants.pas', - HlpCRCStandard in '..\..\Checksum\HlpCRCStandard.pas', - HlpCRC32Fast in '..\..\Checksum\HlpCRC32Fast.pas', HlpGost in '..\..\Crypto\HlpGost.pas', HlpGrindahl256 in '..\..\Crypto\HlpGrindahl256.pas', HlpGrindahl512 in '..\..\Crypto\HlpGrindahl512.pas', diff --git a/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk b/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk index 8196cf8..4b6d6e7 100644 --- a/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk +++ b/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk @@ -29,7 +29,7 @@ "/> - + @@ -75,553 +75,541 @@ - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + - + - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + diff --git a/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas b/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas index a54137f..2660807 100644 --- a/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas +++ b/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas @@ -10,7 +10,7 @@ interface uses HlpHash, HlpHashBuffer, HlpHashCryptoNotBuildIn, HlpHashFactory, HlpHashResult, HlpHashRounds, HlpHashSize, HlpHMACNotBuildInAdapter, - HlpMultipleTransformNonBlock, HlpAdler32, HlpCRC, HlpCRCStandard, HlpGost, + HlpMultipleTransformNonBlock, HlpAdler32, HlpCRC, HlpGost, HlpGrindahl256, HlpGrindahl512, HlpHAS160, HlpHaval, HlpMD2, HlpMD4, HlpMD5, HlpMDBase, HlpPanama, HlpRadioGatun32, HlpRadioGatun64, HlpRIPEMD, HlpRIPEMD128, HlpRIPEMD160, HlpRIPEMD256, HlpRIPEMD320, HlpSHA0, HlpSHA1, @@ -24,14 +24,14 @@ interface HlpXXHash64, HlpIHash, HlpIHashInfo, HlpIHashResult, HlpConverters, HlpBitOperations, HlpBinaryPrimitives, HlpHashLibTypes, HlpMurmurHash3_x86_128, HlpPBKDF2_HMACNotBuildInAdapter, HlpIKDF, HlpKDF, - HlpICRC, HlpBlake2B, HlpBlake2S, HlpGOST3411_2012, HlpCRC32Fast, + HlpICRC, HlpBlake2B, HlpBlake2S, HlpGOST3411_2012, HlpArgon2TypeAndVersion, HlpPBKDF_Argon2NotBuildInAdapter, HlpPBKDF_ScryptNotBuildInAdapter, HlpArrayUtils, HlpBlake2BP, HlpBlake2SP, HlpSipHash128, HlpBlake2SParams, HlpBlake2BParams, HlpIBlake2SParams, HlpIBlake2BParams, HlpBlake3, HlpXXHash3, HlpXXHash128, HlpCpuFeatures, HlpXXHash3Simd, HlpBlake2BSimd, HlpBlake2SSimd, HlpArgon2Simd, HlpScryptSimd, HlpBlake3Simd, HlpSHA2_256Simd, HlpSHA2_512Simd, HlpSHA1Simd, - HlpAdler32Simd, HlpCRCFoldConstants, HlpCRCCore, HlpSHA3Simd, + HlpAdler32Simd, HlpCRCCore, HlpSHA3Simd, HlpArmSimdFeatures, HlpSimdLevels, HlpX86SimdFeatures, HlpArmHwCapProvider, HlpDarwinSysCtl, HlpSHA2_256X86Backend, HlpSHA2_256ArmBackend, HlpSHA1X86Backend, HlpSHA1ArmBackend, HlpSHA2_512X86Backend, diff --git a/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas b/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas index a7814d8..09815fe 100644 --- a/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas +++ b/HashLib/src/Simd/Backend/HlpCRCArmBackend.pas @@ -16,8 +16,8 @@ interface /// TCRCArmBackend = class sealed public - class function Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; static; + class function Select(AReflectedScalar, AForwardScalar: TCRCFoldFunc) + : TCRCFoldSelection; static; end; implementation @@ -48,12 +48,11 @@ function CRC_Fold_Forward_Pmull(AData: PByte; ALength: UInt32; { TCRCArmBackend } -class function TCRCArmBackend.Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; +class function TCRCArmBackend.Select(AReflectedScalar, + AForwardScalar: TCRCFoldFunc): TCRCFoldSelection; begin Result.Reflected := AReflectedScalar; Result.Fwd := AForwardScalar; - Result.Reflected32 := AReflected32Scalar; Result.UsesCarrylessMul := False; {$IFDEF HASHLIB_AARCH64_ASM} @@ -61,7 +60,6 @@ class function TCRCArmBackend.Select(AReflectedScalar, AForwardScalar, begin Result.Reflected := @CRC_Fold_Reflected_Pmull; Result.Fwd := @CRC_Fold_Forward_Pmull; - Result.Reflected32 := @CRC_Fold_Reflected_Pmull; Result.UsesCarrylessMul := True; end; {$ENDIF HASHLIB_AARCH64_ASM} diff --git a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas index 92057dd..95fbf43 100644 --- a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas @@ -16,8 +16,8 @@ interface /// TCRCX86Backend = class sealed public - class function Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; static; + class function Select(AReflectedScalar, AForwardScalar: TCRCFoldFunc) + : TCRCFoldSelection; static; end; implementation @@ -48,12 +48,6 @@ function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_i386.inc} end; -function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflected32Sse2_i386.inc} -end; - {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -70,12 +64,6 @@ function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_x86_64.inc} end; -function CRC_Fold_Reflected32_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflected32Sse2_x86_64.inc} -end; - function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} @@ -106,12 +94,11 @@ function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; { TCRCX86Backend } -class function TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; +class function TCRCX86Backend.Select(AReflectedScalar, + AForwardScalar: TCRCFoldFunc): TCRCFoldSelection; begin Result.Reflected := AReflectedScalar; Result.Fwd := AForwardScalar; - Result.Reflected32 := AReflected32Scalar; Result.UsesCarrylessMul := False; {$IFDEF HASHLIB_X86_64_ASM} @@ -119,7 +106,6 @@ class function TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, begin Result.Reflected := @CRC_Fold_Reflected_Vpclmul; Result.Fwd := @CRC_Fold_Forward_Vpclmul; - Result.Reflected32 := @CRC_Fold_Reflected_Vpclmul; Result.UsesCarrylessMul := True; Exit; end; @@ -127,7 +113,6 @@ class function TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, begin Result.Reflected := @CRC_Fold_Reflected_Pclmul; Result.Fwd := @CRC_Fold_Forward_Pclmul; - Result.Reflected32 := @CRC_Fold_Reflected_Pclmul; Result.UsesCarrylessMul := True; Exit; end; @@ -139,7 +124,6 @@ class function TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, begin Result.Reflected := @CRC_Fold_Reflected_Sse2; Result.Fwd := @CRC_Fold_Forward_Sse2; - Result.Reflected32 := @CRC_Fold_Reflected32_Sse2; end; end; {$ENDIF HASHLIB_X86_SIMD} diff --git a/HashLib/src/Simd/Facade/HlpCRCSimd.pas b/HashLib/src/Simd/Facade/HlpCRCSimd.pas index 2131334..40d0003 100644 --- a/HashLib/src/Simd/Facade/HlpCRCSimd.pas +++ b/HashLib/src/Simd/Facade/HlpCRCSimd.pas @@ -10,16 +10,16 @@ interface type /// /// Arch-neutral SIMD facade for CRC's carry-less-multiply fold. Picks the - /// per-arch backend at compile time and returns the reflected / forward / - /// reflected-32 fold entry points the running CPU supports (plus whether they - /// use carry-less multiply), or the scalar routines when no SIMD backend is - /// built/available. The CRC core calls only this facade and stays free of any + /// per-arch backend at compile time and returns the reflected / forward fold + /// entry points the running CPU supports (plus whether they use carry-less + /// multiply), or the scalar routines when no SIMD backend is built/available. + /// The CRC core calls only this facade and stays free of any /// TCpuFeatures / HASHLIB_*_ASM knowledge. /// TCRCSimd = class sealed public - class function Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; static; + class function Select(AReflectedScalar, AForwardScalar: TCRCFoldFunc) + : TCRCFoldSelection; static; end; implementation @@ -34,19 +34,16 @@ implementation { TCRCSimd } -class function TCRCSimd.Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar: TCRCFoldFunc): TCRCFoldSelection; +class function TCRCSimd.Select(AReflectedScalar, AForwardScalar: TCRCFoldFunc) + : TCRCFoldSelection; begin {$IF DEFINED(HASHLIB_X86_SIMD)} - Result := TCRCX86Backend.Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar); + Result := TCRCX86Backend.Select(AReflectedScalar, AForwardScalar); {$ELSEIF DEFINED(HASHLIB_AARCH64_ASM)} - Result := TCRCArmBackend.Select(AReflectedScalar, AForwardScalar, - AReflected32Scalar); + Result := TCRCArmBackend.Select(AReflectedScalar, AForwardScalar); {$ELSE} Result.Reflected := AReflectedScalar; Result.Fwd := AForwardScalar; - Result.Reflected32 := AReflected32Scalar; Result.UsesCarrylessMul := False; {$IFEND} end; From e2525be38ede345b1dd6cf824381293ecf79c63c Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sun, 12 Jul 2026 02:47:34 +0100 Subject: [PATCH 03/10] add i386 caryless multiply kernels for crc --- HashLib.Tests/src/CRCTests.pas | 49 +++++ HashLib.Tests/src/HashLibTestBase.pas | 7 +- .../Simd/CRC/CRCFoldForwardPclmul_i386.inc | 185 ++++++++++++++++++ .../Simd/CRC/CRCFoldForwardVpclmul_i386.inc | 170 ++++++++++++++++ .../Simd/CRC/CRCFoldReflectedPclmul_i386.inc | 180 +++++++++++++++++ .../Simd/CRC/CRCFoldReflectedVpclmul_i386.inc | 156 +++++++++++++++ HashLib/src/Simd/Backend/HlpCRCX86Backend.pas | 31 ++- 7 files changed, 773 insertions(+), 5 deletions(-) create mode 100644 HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc create mode 100644 HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc create mode 100644 HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc create mode 100644 HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc diff --git a/HashLib.Tests/src/CRCTests.pas b/HashLib.Tests/src/CRCTests.pas index ac82308..b445acf 100644 --- a/HashLib.Tests/src/CRCTests.pas +++ b/HashLib.Tests/src/CRCTests.pas @@ -30,6 +30,7 @@ TTestCRCModel = class(THashLibAlgorithmTestCase) procedure TestCheckValue; procedure TestCheckValueWithIncrementalHash; procedure TestAnotherChunkedDataIncrementalHash; + procedure TestFoldBoundariesMatchByteTable; procedure TestHashCloneIsCorrect; procedure TestHashCloneIsUnique; @@ -171,6 +172,54 @@ procedure TTestCRCModel.TestCheckValueWithIncrementalHash; end; +procedure TTestCRCModel.TestFoldBoundariesMatchByteTable; +const + // Lengths straddling the SIMD fold-path boundaries: fold-by-1 entry (16B), + // fold-by-4 entry (64B), fold-by-8 entry (128B), their loop repeats and + // reduce/tail edges. + Lengths: array [0 .. 21] of Int32 = (16, 17, 31, 32, 33, 63, 64, 65, 79, 95, + 96, 127, 128, 129, 143, 191, 192, 255, 256, 257, 512, 640); +var + LIdx: TCRCStandard; + LBuffer: TBytes; + LI, LJ, LLen, LPos, LChunk: Int32; + LOneShot, LChunked: IHash; +begin + System.SetLength(LBuffer, 640); + for LI := 0 to System.High(LBuffer) do + LBuffer[LI] := Byte((LI * 131) + 17); + + for LIdx := System.Low(TCRCStandard) to System.High(TCRCStandard) do + begin + for LJ := 0 to System.High(Lengths) do + begin + LLen := Lengths[LJ]; + + LOneShot := THashFactory.TChecksum.TCRC.CreateCRC(LIdx); + ActualString := LOneShot.ComputeBytes(System.Copy(LBuffer, 0, LLen)) + .ToString(); + + // Reference: sub-16-byte chunks keep everything on the byte-table path. + LChunked := THashFactory.TChecksum.TCRC.CreateCRC(LIdx); + LChunked.Initialize; + LPos := 0; + while LPos < LLen do + begin + LChunk := 15; + if LLen - LPos < LChunk then + LChunk := LLen - LPos; + LChunked.TransformBytes(LBuffer, LPos, LChunk); + System.Inc(LPos, LChunk); + end; + ExpectedString := LChunked.TransformFinal().ToString(); + + CheckEquals(ExpectedString, ActualString, + Format('Expected %s but got %s at length %d. %s', + [ExpectedString, ActualString, LLen, LOneShot.Name])); + end; + end; +end; + procedure TTestCRCModel.TestHashCloneIsCorrect; var LOriginal, LCopy: IHash; diff --git a/HashLib.Tests/src/HashLibTestBase.pas b/HashLib.Tests/src/HashLibTestBase.pas index cdd1792..d544364 100644 --- a/HashLib.Tests/src/HashLibTestBase.pas +++ b/HashLib.Tests/src/HashLibTestBase.pas @@ -164,8 +164,13 @@ THashLibAlgorithmTestCase = class abstract(THashLibTestCase) EmptyData: String = ''; DefaultData = 'HashLib4Pascal'; OneToNine = '123456789'; + // 299 bytes (13 x 23) so one-shot hashing crosses the SIMD wide-fold + // thresholds (>= 128 bytes) that the chunked passes then cross-validate. ChunkedData = - 'HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678'; + 'HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678' + + 'HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678' + + 'HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678HashLib4Pascal012345678' + + 'HashLib4Pascal012345678'; EEAABEEF = 'EEAABEEF'; ZeroToThreeInHex = '00010203'; ZeroToFifteenInHex = '000102030405060708090A0B0C0D0E0F'; diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc new file mode 100644 index 0000000..c522cf0 --- /dev/null +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc @@ -0,0 +1,185 @@ +// SSE2 + SSSE3 + PCLMULQDQ CRC folding + Barrett reduction for non-reflected +// (MSB-first) CRCs with width 8..64 (IA-32). Fold-by-4 only: the fold-by-8 +// upper path of the x86-64 kernel needs xmm8-11, which IA-32 does not have. +// PCLMULQDQ/PSHUFB instructions are db-encoded for broad assembler +// compatibility; all byte sequences are verbatim from +// CRCFoldForwardPclmul_x86_64.inc (xmm0-7 forms carry no REX prefix and +// encode identically on IA-32). +// +// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), +// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) +// as one UInt64. +// Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, [+64] BswapMask, +// [+80] CrcBits, [+88] BarrettShift. +// Result UInt64 in edx:eax (low qword of xmm0). +// +// pclmulqdq xmm_dst, xmm_src, imm8: 66 0F 3A 44 ModRM imm8 +// pshufb xmm_dst, xmm_src: 66 0F 38 00 ModRM +// ModRM = 11_dst_src. + + push ebp + mov ebp, eax // Ctx + + // BswapMask is always needed (kept in xmm6 throughout) + movdqu xmm6, oword ptr [ebp + 64] // BswapMask + + cmp esi, 64 + jae @large_input + + // --- Small input (16..63 bytes): load 1 block with byte-swap --- + movdqu xmm7, oword ptr [ebp + 16] // fold_1x128 + movdqu xmm0, oword ptr [ebx] + db $66, $0F, $38, $00, $C6 // pshufb xmm0, xmm6 + movq xmm4, qword ptr [edi] + pslldq xmm4, 8 + pxor xmm0, xmm4 + add ebx, 16 + sub esi, 16 + jmp @fold1_check + +@large_input: + // --- Large input (>= 64 bytes): load 4 blocks with byte-swap --- + movdqu xmm7, oword ptr [ebp] // fold_4x128 + + movdqu xmm0, oword ptr [ebx] + db $66, $0F, $38, $00, $C6 // pshufb xmm0, xmm6 + movdqu xmm1, oword ptr [ebx + 16] + db $66, $0F, $38, $00, $CE // pshufb xmm1, xmm6 + movdqu xmm2, oword ptr [ebx + 32] + db $66, $0F, $38, $00, $D6 // pshufb xmm2, xmm6 + movdqu xmm3, oword ptr [ebx + 48] + db $66, $0F, $38, $00, $DE // pshufb xmm3, xmm6 + + movq xmm4, qword ptr [edi] + pslldq xmm4, 8 + pxor xmm0, xmm4 + + add ebx, 64 + sub esi, 64 + + // --- Main fold-by-4 loop --- + cmp esi, 64 + jb @fold4_done + +@fold4_loop: + // Fold xmm0 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + movdqu xmm5, oword ptr [ebx] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm0, xmm5 + + // Fold xmm1 + movdqa xmm4, xmm1 + db $66, $0F, $3A, $44, $CF, $00 // pclmulqdq xmm1, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm1, xmm4 + movdqu xmm5, oword ptr [ebx + 16] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm1, xmm5 + + // Fold xmm2 + movdqa xmm4, xmm2 + db $66, $0F, $3A, $44, $D7, $00 // pclmulqdq xmm2, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm2, xmm4 + movdqu xmm5, oword ptr [ebx + 32] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm2, xmm5 + + // Fold xmm3 + movdqa xmm4, xmm3 + db $66, $0F, $3A, $44, $DF, $00 // pclmulqdq xmm3, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm3, xmm4 + movdqu xmm5, oword ptr [ebx + 48] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm3, xmm5 + + add ebx, 64 + sub esi, 64 + cmp esi, 64 + jae @fold4_loop + +@fold4_done: + // --- Fold 4 accumulators to 1 using fold_1x128 (reload into xmm7) --- + movdqu xmm7, oword ptr [ebp + 16] // fold_1x128 + + // xmm0 = fold(xmm0) XOR xmm1 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm1 + + // xmm0 = fold(xmm0) XOR xmm2 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm2 + + // xmm0 = fold(xmm0) XOR xmm3 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm3 + + // --- Fold remaining 16-byte blocks --- +@fold1_check: + cmp esi, 16 + jb @fold1_done + +@fold1_loop: + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + movdqu xmm5, oword ptr [ebx] + db $66, $0F, $38, $00, $EE // pshufb xmm5, xmm6 + pxor xmm0, xmm5 + add ebx, 16 + sub esi, 16 + cmp esi, 16 + jae @fold1_loop + +@fold1_done: + // ================================================================= + // MSB Barrett reduction: 128-bit xmm0 -> CRC in edx:eax + // Two Barrett rounds, each on one 64-bit half; per Linux kernel + // crc-pclmul-template.S (Eric Biggers). xmm6 = [G : mu_lo]. + // ================================================================= + + movdqu xmm6, oword ptr [ebp + 32] // xmm6 = [G : mu_lo] + + // --- Round 1: Barrett on A_H --- + movdqa xmm1, xmm0 + db $66, $0F, $3A, $44, $CE, $01 // pclmulqdq xmm1, xmm6, $01 + pxor xmm1, xmm0 // xmm1.hi = tmp + db $66, $0F, $3A, $44, $CE, $11 // pclmulqdq xmm1, xmm6, $11 + + // Merge: crc1 in xmm1.lo bits 0..n-1; shift left by (64-n) and XOR + movq xmm2, qword ptr [ebp + 88] + psllq xmm1, xmm2 + pxor xmm0, xmm1 + + // --- Round 2: Barrett on modified A_L --- + movdqa xmm1, xmm0 + db $66, $0F, $3A, $44, $CE, $00 // pclmulqdq xmm1, xmm6, $00 + pshufd xmm0, xmm0, $4E // swap hi/lo qwords + pxor xmm0, xmm1 // xmm0.hi = tmp2 + db $66, $0F, $3A, $44, $C6, $11 // pclmulqdq xmm0, xmm6, $11 + + // Low qword of xmm0 -> edx:eax + movd eax, xmm0 + psrldq xmm0, 4 + movd edx, xmm0 + + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc new file mode 100644 index 0000000..c20cd52 --- /dev/null +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc @@ -0,0 +1,170 @@ +// AVX2 + VPCLMULQDQ CRC folding + Barrett reduction for non-reflected +// (MSB-first) CRCs with width 8..64 (IA-32). +// Mirrors CRCFoldForwardVpclmul_x86_64.inc; ymm0-7/xmm0-7 only, so the +// structure carries over 1:1 (all vector registers are volatile on IA-32 - +// no save/restore needed, just vzeroupper before returning). +// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler +// compatibility; bytes machine-encoded via scripts/x86_s2db.py --i386 +// (binutils 2.28 lacks the 2018 VPCLMULQDQ-ymm form, so those are assembled +// as same-shape vpblendd and the opcode byte $02 -> $44 patched, each result +// asserted byte-identical to the verified x86_64 kernel's encoding). +// +// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), +// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) +// as one UInt64. +// Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, +// [+48] Fold_8x128, [+64] BswapMask, [+80] CrcBits, +// [+88] BarrettShift. +// Result UInt64 in edx:eax (low qword of xmm0). + + push ebp + mov ebp, eax + cmp esi, 128 + jb @xmm_path + db $C4, $E2, $7D, $5A, $6D, $40 // vbroadcasti128 ymm5, [ebp + 64] + db $C4, $E2, $7D, $5A, $75, $30 // vbroadcasti128 ymm6, [ebp + 48] + db $C5, $FE, $6F, $03 // vmovdqu ymm0, [ebx] + db $C4, $E2, $7D, $00, $C5 // vpshufb ymm0, ymm0, ymm5 + db $C5, $FE, $6F, $4B, $20 // vmovdqu ymm1, [ebx + 32] + db $C4, $E2, $75, $00, $CD // vpshufb ymm1, ymm1, ymm5 + db $C5, $FE, $6F, $53, $40 // vmovdqu ymm2, [ebx + 64] + db $C4, $E2, $6D, $00, $D5 // vpshufb ymm2, ymm2, ymm5 + db $C5, $FE, $6F, $5B, $60 // vmovdqu ymm3, [ebx + 96] + db $C4, $E2, $65, $00, $DD // vpshufb ymm3, ymm3, ymm5 + db $C5, $FA, $7E, $27 // vmovq xmm4, qword ptr [edi] + db $C5, $D9, $73, $FC, $08 // vpslldq xmm4, xmm4, 8 + db $C5, $FD, $EF, $C4 // vpxor ymm0, ymm0, ymm4 + add ebx, 128 + sub esi, 128 + cmp esi, 128 + jb @ymm_done + +@ymm_loop: + db $C4, $E3, $7D, $44, $E6, $11 // vpclmulqdq ymm4, ymm0, ymm6, $11 + db $C4, $E3, $7D, $44, $C6, $00 // vpclmulqdq ymm0, ymm0, ymm6, $00 + db $C5, $FD, $EF, $C4 // vpxor ymm0, ymm0, ymm4 + db $C5, $FE, $6F, $3B // vmovdqu ymm7, [ebx] + db $C4, $E2, $45, $00, $FD // vpshufb ymm7, ymm7, ymm5 + db $C5, $FD, $EF, $C7 // vpxor ymm0, ymm0, ymm7 + db $C4, $E3, $75, $44, $E6, $11 // vpclmulqdq ymm4, ymm1, ymm6, $11 + db $C4, $E3, $75, $44, $CE, $00 // vpclmulqdq ymm1, ymm1, ymm6, $00 + db $C5, $F5, $EF, $CC // vpxor ymm1, ymm1, ymm4 + db $C5, $FE, $6F, $7B, $20 // vmovdqu ymm7, [ebx + 32] + db $C4, $E2, $45, $00, $FD // vpshufb ymm7, ymm7, ymm5 + db $C5, $F5, $EF, $CF // vpxor ymm1, ymm1, ymm7 + db $C4, $E3, $6D, $44, $E6, $11 // vpclmulqdq ymm4, ymm2, ymm6, $11 + db $C4, $E3, $6D, $44, $D6, $00 // vpclmulqdq ymm2, ymm2, ymm6, $00 + db $C5, $ED, $EF, $D4 // vpxor ymm2, ymm2, ymm4 + db $C5, $FE, $6F, $7B, $40 // vmovdqu ymm7, [ebx + 64] + db $C4, $E2, $45, $00, $FD // vpshufb ymm7, ymm7, ymm5 + db $C5, $ED, $EF, $D7 // vpxor ymm2, ymm2, ymm7 + db $C4, $E3, $65, $44, $E6, $11 // vpclmulqdq ymm4, ymm3, ymm6, $11 + db $C4, $E3, $65, $44, $DE, $00 // vpclmulqdq ymm3, ymm3, ymm6, $00 + db $C5, $E5, $EF, $DC // vpxor ymm3, ymm3, ymm4 + db $C5, $FE, $6F, $7B, $60 // vmovdqu ymm7, [ebx + 96] + db $C4, $E2, $45, $00, $FD // vpshufb ymm7, ymm7, ymm5 + db $C5, $E5, $EF, $DF // vpxor ymm3, ymm3, ymm7 + add ebx, 128 + sub esi, 128 + cmp esi, 128 + jae @ymm_loop + +@ymm_done: + db $C4, $E2, $7D, $5A, $75, $00 // vbroadcasti128 ymm6, [ebp] + db $C4, $E3, $7D, $44, $E6, $11 // vpclmulqdq ymm4, ymm0, ymm6, $11 + db $C4, $E3, $7D, $44, $C6, $00 // vpclmulqdq ymm0, ymm0, ymm6, $00 + db $C5, $FD, $EF, $C4 // vpxor ymm0, ymm0, ymm4 + db $C5, $FD, $EF, $C2 // vpxor ymm0, ymm0, ymm2 + db $C4, $E3, $75, $44, $E6, $11 // vpclmulqdq ymm4, ymm1, ymm6, $11 + db $C4, $E3, $75, $44, $CE, $00 // vpclmulqdq ymm1, ymm1, ymm6, $00 + db $C5, $F5, $EF, $CC // vpxor ymm1, ymm1, ymm4 + db $C5, $F5, $EF, $CB // vpxor ymm1, ymm1, ymm3 + db $C5, $F9, $6F, $D1 // vmovdqa xmm2, xmm1 + db $C4, $E3, $7D, $39, $CB, $01 // vextracti128 xmm3, ymm1, 1 + db $C4, $E3, $7D, $39, $C1, $01 // vextracti128 xmm1, ymm0, 1 + db $C5, $F8, $77 // vzeroupper + jmp @fold4to1 + +@xmm_path: + db $C5, $FA, $6F, $6D, $40 // vmovdqu xmm5, [ebp + 64] + cmp esi, 64 + jae @xmm_large + db $C5, $FA, $6F, $03 // vmovdqu xmm0, [ebx] + db $C4, $E2, $79, $00, $C5 // vpshufb xmm0, xmm0, xmm5 + db $C5, $FA, $7E, $27 // vmovq xmm4, qword ptr [edi] + db $C5, $D9, $73, $FC, $08 // vpslldq xmm4, xmm4, 8 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + add ebx, 16 + sub esi, 16 + db $C5, $FA, $6F, $7D, $10 // vmovdqu xmm7, [ebp + 16] + jmp @tail_check + +@xmm_large: + db $C5, $FA, $6F, $03 // vmovdqu xmm0, [ebx] + db $C4, $E2, $79, $00, $C5 // vpshufb xmm0, xmm0, xmm5 + db $C5, $FA, $6F, $4B, $10 // vmovdqu xmm1, [ebx + 16] + db $C4, $E2, $71, $00, $CD // vpshufb xmm1, xmm1, xmm5 + db $C5, $FA, $6F, $53, $20 // vmovdqu xmm2, [ebx + 32] + db $C4, $E2, $69, $00, $D5 // vpshufb xmm2, xmm2, xmm5 + db $C5, $FA, $6F, $5B, $30 // vmovdqu xmm3, [ebx + 48] + db $C4, $E2, $61, $00, $DD // vpshufb xmm3, xmm3, xmm5 + db $C5, $FA, $7E, $27 // vmovq xmm4, qword ptr [edi] + db $C5, $D9, $73, $FC, $08 // vpslldq xmm4, xmm4, 8 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + add ebx, 64 + sub esi, 64 + +@fold4to1: + db $C5, $FA, $6F, $7D, $10 // vmovdqu xmm7, [ebp + 16] + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $F9, $EF, $C2 // vpxor xmm0, xmm0, xmm2 + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $F9, $EF, $C3 // vpxor xmm0, xmm0, xmm3 + +@tail_check: + cmp esi, 16 + jb @tail_done + +@tail_loop: + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $FA, $6F, $33 // vmovdqu xmm6, [ebx] + db $C4, $E2, $49, $00, $F5 // vpshufb xmm6, xmm6, xmm5 + db $C5, $F9, $EF, $C6 // vpxor xmm0, xmm0, xmm6 + add ebx, 16 + sub esi, 16 + cmp esi, 16 + jae @tail_loop + +@tail_done: + db $C5, $FA, $6F, $75, $20 // vmovdqu xmm6, [ebp + 32] + db $C5, $F9, $6F, $C8 // vmovdqa xmm1, xmm0 + db $C4, $E3, $71, $44, $CE, $01 // vpclmulqdq xmm1, xmm1, xmm6, $01 + db $C5, $F1, $EF, $C8 // vpxor xmm1, xmm1, xmm0 + db $C4, $E3, $71, $44, $CE, $11 // vpclmulqdq xmm1, xmm1, xmm6, $11 + db $C5, $FA, $7E, $55, $58 // vmovq xmm2, qword ptr [ebp + 88] + db $C5, $F1, $F3, $CA // vpsllq xmm1, xmm1, xmm2 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C5, $F9, $6F, $C8 // vmovdqa xmm1, xmm0 + db $C4, $E3, $71, $44, $CE, $00 // vpclmulqdq xmm1, xmm1, xmm6, $00 + db $C5, $F9, $70, $C0, $4E // vpshufd xmm0, xmm0, $4E + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C4, $E3, $79, $44, $C6, $11 // vpclmulqdq xmm0, xmm0, xmm6, $11 + db $C5, $F8, $77 // vzeroupper + movd eax, xmm0 + psrldq xmm0, 4 + movd edx, xmm0 + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc new file mode 100644 index 0000000..efb23c3 --- /dev/null +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc @@ -0,0 +1,180 @@ +// SSE2 + PCLMULQDQ CRC folding + Barrett reduction for reflected (LSB-first) +// CRCs with width 8..64 (IA-32). CRC-64 uses a special Barrett path for the +// 65-bit G. Fold-by-4 only: the fold-by-8 upper path of the x86-64 kernel +// needs xmm8-11, which IA-32 does not have. +// PCLMULQDQ instructions are db-encoded for broad assembler compatibility; +// all byte sequences are verbatim from CRCFoldReflectedPclmul_x86_64.inc +// (xmm0-7 forms carry no REX prefix and encode identically on IA-32). +// +// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), +// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). +// AState: pointer to the initial CRC (reflected) as one UInt64. +// Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, [+80] CrcBits. +// Result UInt64 in edx:eax (high qword of xmm0). +// +// pclmulqdq xmm_dst, xmm_src, imm8 (register-register): +// 66 0F 3A 44 ModRM imm8; ModRM = 11_dst_src. + + push ebp + mov ebp, eax // Ctx + + // fold_1x128 is always needed (fold-by-1 loop and Barrett step 1) + movdqu xmm7, oword ptr [ebp + 16] // fold_1x128 + + cmp esi, 64 + jae @large_input + + // --- Small input (16..63 bytes): load 1 block --- + movdqu xmm0, oword ptr [ebx] + movq xmm4, qword ptr [edi] + pxor xmm0, xmm4 + add ebx, 16 + sub esi, 16 + jmp @fold1_check + +@large_input: + // --- Large input (>= 64 bytes): load 4 blocks --- + movdqu xmm6, oword ptr [ebp] // fold_4x128 + + movdqu xmm0, oword ptr [ebx] + movdqu xmm1, oword ptr [ebx + 16] + movdqu xmm2, oword ptr [ebx + 32] + movdqu xmm3, oword ptr [ebx + 48] + + movq xmm4, qword ptr [edi] + pxor xmm0, xmm4 + + add ebx, 64 + sub esi, 64 + + // --- Main fold-by-4 loop --- + cmp esi, 64 + jb @fold4_done + +@fold4_loop: + // Fold xmm0 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C6, $00 // pclmulqdq xmm0, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm0, xmm4 + movdqu xmm5, oword ptr [ebx] + pxor xmm0, xmm5 + + // Fold xmm1 + movdqa xmm4, xmm1 + db $66, $0F, $3A, $44, $CE, $00 // pclmulqdq xmm1, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm1, xmm4 + movdqu xmm5, oword ptr [ebx + 16] + pxor xmm1, xmm5 + + // Fold xmm2 + movdqa xmm4, xmm2 + db $66, $0F, $3A, $44, $D6, $00 // pclmulqdq xmm2, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm2, xmm4 + movdqu xmm5, oword ptr [ebx + 32] + pxor xmm2, xmm5 + + // Fold xmm3 + movdqa xmm4, xmm3 + db $66, $0F, $3A, $44, $DE, $00 // pclmulqdq xmm3, xmm6, $00 + db $66, $0F, $3A, $44, $E6, $11 // pclmulqdq xmm4, xmm6, $11 + pxor xmm3, xmm4 + movdqu xmm5, oword ptr [ebx + 48] + pxor xmm3, xmm5 + + add ebx, 64 + sub esi, 64 + cmp esi, 64 + jae @fold4_loop + +@fold4_done: + // --- Fold 4 accumulators to 1 using fold_1x128 (xmm7) --- + + // xmm0 = fold(xmm0) XOR xmm1 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm1 + + // xmm0 = fold(xmm0) XOR xmm2 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm2 + + // xmm0 = fold(xmm0) XOR xmm3 + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + pxor xmm0, xmm3 + + // --- Fold remaining 16-byte blocks --- +@fold1_check: + cmp esi, 16 + jb @fold1_done + +@fold1_loop: + movdqa xmm4, xmm0 + db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, $00 + db $66, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm4, xmm7, $11 + pxor xmm0, xmm4 + movdqu xmm5, oword ptr [ebx] + pxor xmm0, xmm5 + add ebx, 16 + sub esi, 16 + cmp esi, 16 + jae @fold1_loop + +@fold1_done: + // ================================================================= + // Final reduction: 128-bit xmm0 -> CRC in edx:eax + // Following Linux kernel crc-pclmul-template.S Barrett reduction. + // ================================================================= + + // Step 1: Multiply by x^n and reduce 128 bits to 64+n bits. + movdqa xmm1, xmm0 + db $66, $0F, $3A, $44, $CF, $10 // pclmulqdq xmm1, xmm7, $10 + psrldq xmm0, 8 // xmm0 = {0, A_hi} + pxor xmm0, xmm1 // xmm0 = t0 (64+n bits) + + // Step 2: Barrett reduction. + movdqu xmm6, oword ptr [ebp + 32] + + // t1 = clmul(t0.lo, barrett[0]) => q = floor(t0 / G) + movdqa xmm1, xmm0 + db $66, $0F, $3A, $44, $CE, $00 // pclmulqdq xmm1, xmm6, $00 + + // Check if CRC-64: G is 65-bit, needs split multiplication + // (CrcBits <= 64, so the low dword suffices) + cmp dword ptr [ebp + 80], 64 + je @barrett_64 + + // Standard Barrett (width < 64): single pclmulqdq covers full G + db $66, $0F, $3A, $44, $CE, $10 // pclmulqdq xmm1, xmm6, $10 + pxor xmm0, xmm1 + jmp @extract_crc + +@barrett_64: + // CRC-64 Barrett: G is 65-bit, split into 64-bit pclmulqdq + x^0 correction. + movdqa xmm2, xmm1 // save q + db $66, $0F, $3A, $44, $CE, $10 // pclmulqdq xmm1, xmm6, $10 + db $66, $0F, $6C, $D2 // punpcklqdq xmm2, xmm2 {q.lo, q.lo} + pxor xmm0, xmm1 + pxor xmm0, xmm2 + +@extract_crc: + // High qword of xmm0 -> edx:eax + psrldq xmm0, 8 + movd eax, xmm0 + psrldq xmm0, 4 + movd edx, xmm0 + + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc new file mode 100644 index 0000000..dfa5897 --- /dev/null +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc @@ -0,0 +1,156 @@ +// AVX2 + VPCLMULQDQ CRC folding + Barrett reduction for reflected (LSB-first) +// CRCs with width 8..64 (IA-32). CRC-64 uses a special Barrett path for the +// 65-bit G. Mirrors CRCFoldReflectedVpclmul_x86_64.inc; ymm0-7/xmm0-7 only, +// so the structure carries over 1:1 (all vector registers are volatile on +// IA-32 - no save/restore needed, just vzeroupper before returning). +// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler +// compatibility; bytes machine-encoded via scripts/x86_s2db.py --i386 +// (binutils 2.28 lacks the 2018 VPCLMULQDQ-ymm form, so those are assembled +// as same-shape vpblendd and the opcode byte $02 -> $44 patched, each result +// asserted byte-identical to the verified x86_64 kernel's encoding). +// +// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), +// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). +// AState: pointer to the initial CRC (reflected) as one UInt64. +// Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, +// [+48] Fold_8x128, [+80] CrcBits. +// Result UInt64 in edx:eax (high qword of xmm0). + + push ebp + mov ebp, eax + cmp esi, 128 + jb @xmm_path + db $C4, $E2, $7D, $5A, $75, $30 // vbroadcasti128 ymm6, [ebp + 48] + db $C5, $FE, $6F, $03 // vmovdqu ymm0, [ebx] + db $C5, $FE, $6F, $4B, $20 // vmovdqu ymm1, [ebx + 32] + db $C5, $FE, $6F, $53, $40 // vmovdqu ymm2, [ebx + 64] + db $C5, $FE, $6F, $5B, $60 // vmovdqu ymm3, [ebx + 96] + db $C5, $FA, $7E, $27 // vmovq xmm4, qword ptr [edi] + db $C5, $FD, $EF, $C4 // vpxor ymm0, ymm0, ymm4 + add ebx, 128 + sub esi, 128 + cmp esi, 128 + jb @ymm_done + +@ymm_loop: + db $C4, $E3, $7D, $44, $E6, $11 // vpclmulqdq ymm4, ymm0, ymm6, $11 + db $C4, $E3, $7D, $44, $C6, $00 // vpclmulqdq ymm0, ymm0, ymm6, $00 + db $C5, $FD, $EF, $C4 // vpxor ymm0, ymm0, ymm4 + db $C5, $FE, $6F, $2B // vmovdqu ymm5, [ebx] + db $C5, $FD, $EF, $C5 // vpxor ymm0, ymm0, ymm5 + db $C4, $E3, $75, $44, $E6, $11 // vpclmulqdq ymm4, ymm1, ymm6, $11 + db $C4, $E3, $75, $44, $CE, $00 // vpclmulqdq ymm1, ymm1, ymm6, $00 + db $C5, $F5, $EF, $CC // vpxor ymm1, ymm1, ymm4 + db $C5, $FE, $6F, $6B, $20 // vmovdqu ymm5, [ebx + 32] + db $C5, $F5, $EF, $CD // vpxor ymm1, ymm1, ymm5 + db $C4, $E3, $6D, $44, $E6, $11 // vpclmulqdq ymm4, ymm2, ymm6, $11 + db $C4, $E3, $6D, $44, $D6, $00 // vpclmulqdq ymm2, ymm2, ymm6, $00 + db $C5, $ED, $EF, $D4 // vpxor ymm2, ymm2, ymm4 + db $C5, $FE, $6F, $6B, $40 // vmovdqu ymm5, [ebx + 64] + db $C5, $ED, $EF, $D5 // vpxor ymm2, ymm2, ymm5 + db $C4, $E3, $65, $44, $E6, $11 // vpclmulqdq ymm4, ymm3, ymm6, $11 + db $C4, $E3, $65, $44, $DE, $00 // vpclmulqdq ymm3, ymm3, ymm6, $00 + db $C5, $E5, $EF, $DC // vpxor ymm3, ymm3, ymm4 + db $C5, $FE, $6F, $6B, $60 // vmovdqu ymm5, [ebx + 96] + db $C5, $E5, $EF, $DD // vpxor ymm3, ymm3, ymm5 + add ebx, 128 + sub esi, 128 + cmp esi, 128 + jae @ymm_loop + +@ymm_done: + db $C4, $E2, $7D, $5A, $75, $00 // vbroadcasti128 ymm6, [ebp] + db $C4, $E3, $7D, $44, $E6, $11 // vpclmulqdq ymm4, ymm0, ymm6, $11 + db $C4, $E3, $7D, $44, $C6, $00 // vpclmulqdq ymm0, ymm0, ymm6, $00 + db $C5, $FD, $EF, $C4 // vpxor ymm0, ymm0, ymm4 + db $C5, $FD, $EF, $C2 // vpxor ymm0, ymm0, ymm2 + db $C4, $E3, $75, $44, $E6, $11 // vpclmulqdq ymm4, ymm1, ymm6, $11 + db $C4, $E3, $75, $44, $CE, $00 // vpclmulqdq ymm1, ymm1, ymm6, $00 + db $C5, $F5, $EF, $CC // vpxor ymm1, ymm1, ymm4 + db $C5, $F5, $EF, $CB // vpxor ymm1, ymm1, ymm3 + db $C5, $F9, $6F, $D1 // vmovdqa xmm2, xmm1 + db $C4, $E3, $7D, $39, $CB, $01 // vextracti128 xmm3, ymm1, 1 + db $C4, $E3, $7D, $39, $C1, $01 // vextracti128 xmm1, ymm0, 1 + db $C5, $F8, $77 // vzeroupper + jmp @fold4to1 + +@xmm_path: + cmp esi, 64 + jae @xmm_large + db $C5, $FA, $6F, $03 // vmovdqu xmm0, [ebx] + db $C5, $FA, $7E, $27 // vmovq xmm4, qword ptr [edi] + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + add ebx, 16 + sub esi, 16 + db $C5, $FA, $6F, $7D, $10 // vmovdqu xmm7, [ebp + 16] + jmp @tail_check + +@xmm_large: + db $C5, $FA, $6F, $03 // vmovdqu xmm0, [ebx] + db $C5, $FA, $6F, $4B, $10 // vmovdqu xmm1, [ebx + 16] + db $C5, $FA, $6F, $53, $20 // vmovdqu xmm2, [ebx + 32] + db $C5, $FA, $6F, $5B, $30 // vmovdqu xmm3, [ebx + 48] + db $C5, $FA, $7E, $27 // vmovq xmm4, qword ptr [edi] + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + add ebx, 64 + sub esi, 64 + +@fold4to1: + db $C5, $FA, $6F, $7D, $10 // vmovdqu xmm7, [ebp + 16] + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $F9, $EF, $C2 // vpxor xmm0, xmm0, xmm2 + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $F9, $EF, $C3 // vpxor xmm0, xmm0, xmm3 + +@tail_check: + cmp esi, 16 + jb @tail_done + +@tail_loop: + db $C4, $E3, $79, $44, $E7, $11 // vpclmulqdq xmm4, xmm0, xmm7, $11 + db $C4, $E3, $79, $44, $C7, $00 // vpclmulqdq xmm0, xmm0, xmm7, $00 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $FA, $6F, $2B // vmovdqu xmm5, [ebx] + db $C5, $F9, $EF, $C5 // vpxor xmm0, xmm0, xmm5 + add ebx, 16 + sub esi, 16 + cmp esi, 16 + jae @tail_loop + +@tail_done: + db $C4, $E3, $79, $44, $CF, $10 // vpclmulqdq xmm1, xmm0, xmm7, $10 + db $C5, $F9, $73, $D8, $08 // vpsrldq xmm0, xmm0, 8 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C5, $FA, $6F, $75, $20 // vmovdqu xmm6, [ebp + 32] + db $C4, $E3, $79, $44, $CE, $00 // vpclmulqdq xmm1, xmm0, xmm6, $00 + cmp dword ptr [ebp + 80], 64 + je @barrett_64 + db $C4, $E3, $71, $44, $CE, $10 // vpclmulqdq xmm1, xmm1, xmm6, $10 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + jmp @extract_crc + +@barrett_64: + db $C5, $F9, $6F, $D1 // vmovdqa xmm2, xmm1 + db $C4, $E3, $71, $44, $CE, $10 // vpclmulqdq xmm1, xmm1, xmm6, $10 + db $C5, $E9, $6C, $D2 // vpunpcklqdq xmm2, xmm2, xmm2 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C5, $F9, $EF, $C2 // vpxor xmm0, xmm0, xmm2 + +@extract_crc: + db $C5, $F8, $77 // vzeroupper + psrldq xmm0, 8 + movd eax, xmm0 + psrldq xmm0, 4 + movd edx, xmm0 + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas index 95fbf43..f83163f 100644 --- a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas @@ -30,7 +30,7 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2 +// i386: VPCLMULQDQ, PCLMULQDQ, SSE2 // x86_64: VPCLMULQDQ, PCLMULQDQ, SSE2 // ============================================================================= @@ -48,6 +48,30 @@ function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_i386.inc} end; +function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedPclmul_i386.inc} +end; + +function CRC_Fold_Forward_Pclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardPclmul_i386.inc} +end; + +function CRC_Fold_Reflected_Vpclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldReflectedVpclmul_i386.inc} +end; + +function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; + AState: Pointer; AConstants: Pointer): UInt64; + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\CRC\CRCFoldForwardVpclmul_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -101,7 +125,7 @@ class function TCRCX86Backend.Select(AReflectedScalar, Result.Fwd := AForwardScalar; Result.UsesCarrylessMul := False; -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} if TCpuFeatures.X86.HasVPCLMULQDQ() then begin Result.Reflected := @CRC_Fold_Reflected_Vpclmul; @@ -109,6 +133,7 @@ class function TCRCX86Backend.Select(AReflectedScalar, Result.UsesCarrylessMul := True; Exit; end; + if TCpuFeatures.X86.HasPCLMULQDQ() then begin Result.Reflected := @CRC_Fold_Reflected_Pclmul; @@ -116,9 +141,7 @@ class function TCRCX86Backend.Select(AReflectedScalar, Result.UsesCarrylessMul := True; Exit; end; -{$ENDIF HASHLIB_X86_64_ASM} -{$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of TX86SimdLevel.SSE2: begin From 930fba0df3308ad7459832864af8638b0d96810a Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sun, 12 Jul 2026 20:09:48 +0100 Subject: [PATCH 04/10] expand/improve x86 SIMD tiers kernels --- .../Simd/Adler32/Adler32BlocksAvx2_i386.inc | 57 + .../Argon2/Argon2FillBlockAvx2_x86_64.inc | 51 +- .../Argon2/Argon2FillBlockSsse3_x86_64.inc | 523 +++++ .../Simd/Blake2B/Blake2BCompressAvx2_i386.inc | 975 ++++++++ .../Blake2B/Blake2BCompressAvx2_x86_64.inc | 214 +- .../Blake2B/Blake2BCompressSsse3_i386.inc | 2071 +++++++++++++++++ .../Blake2B/Blake2BCompressSsse3_x86_64.inc | 1716 ++++++++++++++ .../Simd/Blake2S/Blake2SCompressAvx2_i386.inc | 941 ++++++++ .../Blake2S/Blake2SCompressAvx2_x86_64.inc | 176 +- .../Blake2S/Blake2SCompressSsse3_i386.inc | 992 ++++++++ .../Blake2S/Blake2SCompressSsse3_x86_64.inc | 965 ++++++++ .../Simd/Blake3/Blake3CompressAvx2_x86_64.inc | 115 +- .../Blake3/Blake3CompressSsse3_x86_64.inc | 590 +++++ .../Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc | 1622 +++++++++++++ .../Simd/Blake3/Blake3Hash8Avx2_x86_64.inc | 411 +--- .../Simd/CRC/CRCFoldForwardVpclmul_i386.inc | 7 +- .../Simd/CRC/CRCFoldReflectedVpclmul_i386.inc | 7 +- .../Simd/Common/HlpSimdProc7Begin_i386.inc | 39 + .../Simd/Common/HlpSimdProc7Begin_x86_64.inc | 32 + .../Simd/SHA1/SHA1CompressAvx2_i386.inc | 1175 ++++++++++ .../Simd/SHA1/SHA1CompressAvx2_x86_64.inc | 12 +- .../Simd/SHA1/SHA1CompressShaNi_i386.inc | 171 ++ .../Simd/SHA1/SHA1CompressShaNi_x86_64.inc | 4 +- .../Simd/SHA1/SHA1CompressSse2_i386.inc | 13 +- .../Simd/SHA1/SHA1CompressSse2_x86_64.inc | 8 +- .../Simd/SHA1/SHA1CompressSsse3_i386.inc | 1221 ++++++++++ .../Simd/SHA1/SHA1CompressSsse3_x86_64.inc | 1193 ++++++++++ .../Simd/SHA256/SHA256CompressAvx2_i386.inc | 1208 ++++++++++ .../Simd/SHA256/SHA256CompressAvx2_x86_64.inc | 15 +- .../Simd/SHA256/SHA256CompressShaNi_i386.inc | 222 ++ .../SHA256/SHA256CompressShaNi_x86_64.inc | 4 +- .../Simd/SHA256/SHA256CompressSse2_i386.inc | 12 +- .../Simd/SHA256/SHA256CompressSse2_x86_64.inc | 6 +- .../Simd/SHA256/SHA256CompressSsse3_i386.inc | 1235 ++++++++++ .../SHA256/SHA256CompressSsse3_x86_64.inc | 1110 +++++++++ .../SHA3/KeccakF1600Avx2Absorb_x86_64.inc | 2 +- .../Simd/SHA3/KeccakF1600Avx2_x86_64.inc | 2 +- .../Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc | 427 ++++ .../SHA3/KeccakF1600Sse2Absorb_x86_64.inc | 307 +++ .../Simd/SHA3/KeccakF1600Sse2_i386.inc | 397 ++++ .../Simd/SHA3/KeccakF1600Sse2_x86_64.inc | 275 +++ .../Simd/SHA512/SHA512CompressAvx2_x86_64.inc | 13 +- .../Simd/SHA512/SHA512CompressSse2_i386.inc | 9 +- .../Simd/SHA512/SHA512CompressSse2_x86_64.inc | 10 +- .../SHA512/SHA512CompressSsse3_x86_64.inc | 1259 ++++++++++ .../Simd/Scrypt/ScryptSalsa8Avx2_i386.inc | 130 ++ .../Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc | 37 + .../Simd/XXH3/XXH3InitSecretAvx2_i386.inc | 69 + .../Simd/XXH3/XXH3ScrambleAvx2_i386.inc | 44 + .../src/Simd/Backend/HlpAdler32X86Backend.pas | 32 +- .../src/Simd/Backend/HlpArgon2X86Backend.pas | 54 +- .../src/Simd/Backend/HlpBlake2BX86Backend.pas | 82 +- .../src/Simd/Backend/HlpBlake2SX86Backend.pas | 79 +- .../src/Simd/Backend/HlpBlake3X86Backend.pas | 95 +- .../src/Simd/Backend/HlpSHA1X86Backend.pas | 62 +- .../Simd/Backend/HlpSHA2_256X86Backend.pas | 56 +- .../Simd/Backend/HlpSHA2_512X86Backend.pas | 18 +- .../src/Simd/Backend/HlpSHA3X86Backend.pas | 103 +- .../src/Simd/Backend/HlpScryptX86Backend.pas | 20 +- .../src/Simd/Backend/HlpXXHash3X86Backend.pas | 75 +- 60 files changed, 21915 insertions(+), 855 deletions(-) create mode 100644 HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc create mode 100644 HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc create mode 100644 HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc create mode 100644 HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc create mode 100644 HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc create mode 100644 HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_i386.inc create mode 100644 HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_x86_64.inc create mode 100644 HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc create mode 100644 HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc create mode 100644 HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc create mode 100644 HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc create mode 100644 HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc create mode 100644 HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc create mode 100644 HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc create mode 100644 HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc new file mode 100644 index 0000000..fe5d598 --- /dev/null +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc @@ -0,0 +1,57 @@ +// AVX2 implementation of Adler-32 block processing (IA-32; 256-bit ymm +// integer ops work in 32-bit mode - only ymm0-7 exist, which this kernel +// fits). Same structure as Adler32BlocksAvx2_x86_64.inc. +// IA-32: after HlpSimdProc4Begin_i386 - ebx = data ptr, esi = num_blocks, +// edi = sums ptr, eax = constants ptr (moved to ecx at entry; eax then +// accumulates SumA). SumB rides xmm1 end-to-end via vmovd memory forms. +// ASums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout: [weights: 32B, ones_16: 32B] at offsets 0 and 32. +// Processes num_blocks x 32-byte blocks. Does NOT apply mod 65521 (caller does it). +// Uses ymm0-ymm5 only (all volatile on IA-32; no saves needed). +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: Chromium zlib adler32_simd.c, HashLib Adler32BlocksAvx2_x86_64.inc. + + mov ecx, eax + db $C5, $E5, $EF, $DB // vpxor ymm3, ymm3, ymm3 + mov eax, dword ptr [edi] + db $C5, $F9, $6E, $4F, $04 // vmovd xmm1, dword [edi + $4] + mov edx, esi + imul edx, eax + db $C5, $F9, $6E, $D2 // vmovd xmm2, edx + db $C5, $F9, $EF, $C0 // vpxor xmm0, xmm0, xmm0 + +@loop: + db $C5, $ED, $FE, $D0 // vpaddd ymm2, ymm2, ymm0 + db $C5, $FE, $6F, $23 // vmovdqu ymm4, yword [ebx] + db $C5, $DD, $F6, $EB // vpsadbw ymm5, ymm4, ymm3 + db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 + db $C5, $FE, $6F, $29 // vmovdqu ymm5, yword [ecx] + db $C4, $E2, $5D, $04, $E5 // vpmaddubsw ymm4, ymm4, ymm5 + db $C5, $FE, $6F, $69, $20 // vmovdqu ymm5, yword [ecx + $20] + db $C5, $DD, $F5, $E5 // vpmaddwd ymm4, ymm4, ymm5 + db $C5, $F5, $FE, $CC // vpaddd ymm1, ymm1, ymm4 + add ebx, $20 + dec esi + jnz @loop + db $C5, $ED, $72, $F2, $05 // vpslld ymm2, ymm2, $5 + db $C5, $F5, $FE, $CA // vpaddd ymm1, ymm1, ymm2 + db $C4, $E3, $7D, $39, $C5, $01 // vextracti128 xmm5, ymm0, $1 + db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 + db $C5, $F9, $70, $E8, $B1 // vpshufd xmm5, xmm0, $B1 + db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 + db $C5, $F9, $70, $E8, $4E // vpshufd xmm5, xmm0, $4E + db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 + db $C5, $F9, $7E, $C2 // vmovd edx, xmm0 + add eax, edx + db $C4, $E3, $7D, $39, $CD, $01 // vextracti128 xmm5, ymm1, $1 + db $C5, $F1, $FE, $CD // vpaddd xmm1, xmm1, xmm5 + db $C5, $F9, $70, $E9, $B1 // vpshufd xmm5, xmm1, $B1 + db $C5, $F1, $FE, $CD // vpaddd xmm1, xmm1, xmm5 + db $C5, $F9, $70, $E9, $4E // vpshufd xmm5, xmm1, $4E + db $C5, $F1, $FE, $CD // vpaddd xmm1, xmm1, xmm5 + mov dword ptr [edi], eax + db $C5, $F9, $7E, $4F, $04 // vmovd dword [edi + $4], xmm1 + db $C5, $F8, $77 // vzeroupper + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc index 9d82dd1..4968b07 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc @@ -1,10 +1,17 @@ // AVX2 implementation of Argon2 FillBlock. // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI: rcx = Left ptr, rdx = Right ptr, r8 = Current ptr, r9 = WithXor (0 or 1). +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = Left ptr, rdx = Right ptr, +// r8 = Current ptr, r9 = WithXor (0 or 1), r10 = byte-rotation masks ptr +// (see ARGON2_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment; consumed by the entry mask loads, +// r10 is scratch afterwards). // Each pointer addresses 128 QWords (1024 bytes). -// Uses ymm0-ymm9; ymm6-ymm9 are MS x64 non-volatile (saved/restored). +// Uses ymm0-ymm11; ymm6-ymm11 are MS x64 non-volatile (saved/restored). // Register map during G rounds: ymm0 = A(v0..v3), ymm1 = B(v4..v7), -// ymm2 = C(v8..v11), ymm3 = D(v12..v15), ymm4-ymm5 = temps. +// ymm2 = C(v8..v11), ymm3 = D(v12..v15), ymm4-ymm5 = temps, +// ymm10 = rot24 mask, ymm11 = rot16 mask. +// Rotations: rot32 via vpshufd, rot24/16 via vpshufb against the resident +// masks, rot63 via shift+or (not byte-aligned). // Stack layout (sub rsp, 2184): // [rsp+0..127] ymm6-9 save area (4 * 32 = 128 bytes) // [rsp+128..1151] R_buf (1024 bytes) @@ -17,6 +24,10 @@ {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + // Load byte-rotation masks (resident for the whole kernel) + db $C4, $41, $7E, $6F, $12 // vmovdqu ymm10, yword [r10] + db $C4, $41, $7E, $6F, $5A, $20 // vmovdqu ymm11, yword [r10 + $20] + sub rsp, 2056 // ========================================================================= @@ -77,9 +88,7 @@ // b = rotr64(b ^ c, 24) db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $DD, $73, $D1, $18 // vpsrlq ymm4, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + db $C4, $C2, $75, $00, $CA // vpshufb ymm1, ymm1, ymm10 // fBlaMka(a, b) db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 @@ -89,9 +98,7 @@ // d = rotr64(d ^ a, 16) db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $DD, $73, $D3, $10 // vpsrlq ymm4, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DC // vpor ymm3, ymm3, ymm4 + db $C4, $C2, $65, $00, $DB // vpshufb ymm3, ymm3, ymm11 // fBlaMka(c, d) db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 @@ -129,9 +136,7 @@ db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $DD, $73, $D1, $18 // vpsrlq ymm4, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + db $C4, $C2, $75, $00, $CA // vpshufb ymm1, ymm1, ymm10 db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, 1 @@ -139,9 +144,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $DD, $73, $D3, $10 // vpsrlq ymm4, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DC // vpor ymm3, ymm3, ymm4 + db $C4, $C2, $65, $00, $DB // vpshufb ymm3, ymm3, ymm11 db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, 1 @@ -207,9 +210,7 @@ db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $DD, $73, $D1, $18 // vpsrlq ymm4, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + db $C4, $C2, $75, $00, $CA // vpshufb ymm1, ymm1, ymm10 db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, 1 @@ -217,9 +218,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $DD, $73, $D3, $10 // vpsrlq ymm4, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DC // vpor ymm3, ymm3, ymm4 + db $C4, $C2, $65, $00, $DB // vpshufb ymm3, ymm3, ymm11 db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, 1 @@ -252,9 +251,7 @@ db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $DD, $73, $D1, $18 // vpsrlq ymm4, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + db $C4, $C2, $75, $00, $CA // vpshufb ymm1, ymm1, ymm10 db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, 1 @@ -262,9 +259,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $DD, $73, $D3, $10 // vpsrlq ymm4, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DC // vpor ymm3, ymm3, ymm4 + db $C4, $C2, $65, $00, $DB // vpshufb ymm3, ymm3, ymm11 db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, 1 @@ -296,7 +291,7 @@ jb @row_loop // ========================================================================= - // Step 5: Final XOR — Current = R_buf XOR Z_buf [XOR Current] + // Step 5: Final XOR - Current = R_buf XOR Z_buf [XOR Current] // ========================================================================= test r9, r9 jnz @final_with_xor diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc new file mode 100644 index 0000000..caa3b6b --- /dev/null +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc @@ -0,0 +1,523 @@ +// SSSE3 implementation of Argon2 FillBlock; SSE2 sibling: +// Argon2FillBlockSse2_x86_64.inc. Unlike the SSE2 sibling, the byte-aligned +// rotations (rot24/rot16) are single pshufb (db-encoded for broad assembler +// compatibility) against masks resident in xmm10/xmm11; rot32 stays pshufd and +// rot63 stays shift+or (not byte-aligned). +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = Left ptr, rdx = Right ptr, +// r8 = Current ptr, r9 = WithXor (0 or 1), r10 = byte-rotation masks ptr +// (see ARGON2_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment; consumed by the entry mask loads, +// r10 is scratch afterwards). +// Each pointer addresses 128 QWords (1024 bytes). +// Uses xmm0-xmm11; xmm6-xmm11 are MS x64 non-volatile (saved/restored). +// Register map during G rounds: xmm0-1 = A(0..3), xmm2-3 = B(4..7), +// xmm4-5 = C(8..11), xmm6-7 = D(12..15), xmm8-9 = temps, +// xmm10 = rot24 mask, xmm11 = rot16 mask. +// Stack layout (sub rsp, 2120): +// [rsp+0..63] xmm6-9 save area +// [rsp+64..1087] R_buf (1024 bytes) +// [rsp+1088..2111] Z_buf (1024 bytes) +// [rsp+2112..2119] alignment padding +// r8 (Current) and r9 (WithXor) survive all loops (not clobbered). +// ARight and ACurrent may alias; R_buf buffering handles this. +// +// Diagonalize/Undiagonalize use shufpd to rotate QWord positions within +// register pairs. Right-rotates require a 3-movdqa swap since shufpd +// naturally places results in the opposite register for that direction. + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + // Load byte-rotation masks (resident for the whole kernel) + db $F3, $45, $0F, $6F, $12 // movdqu xmm10, oword [r10] + db $F3, $45, $0F, $6F, $5A, $20 // movdqu xmm11, oword [r10 + $20] + + sub rsp, 2056 + + // ========================================================================= + // Step 1: Compute R_buf = Left XOR Right, store at [rsp+64] + // ========================================================================= + lea rax, [rsp] + xor r10, r10 +@xor_loop: + movdqu xmm0, oword [rcx + r10] + movdqu xmm1, oword [rdx + r10] + pxor xmm0, xmm1 + movdqu oword [rax + r10], xmm0 + add r10, 16 + cmp r10, 1024 + jb @xor_loop + + // ========================================================================= + // Step 2: Copy R_buf to Z_buf at [rsp+1088] + // ========================================================================= + lea r11, [rsp + 1024] + xor r10, r10 +@copy_loop: + movdqu xmm0, oword [rax + r10] + movdqu oword [r11 + r10], xmm0 + add r10, 16 + cmp r10, 1024 + jb @copy_loop + + // ========================================================================= + // Step 3: Column rounds on Z_buf (8 iterations, 16 QWords = 128 bytes each) + // ========================================================================= + xor r10, r10 + +@col_loop: + movdqu xmm0, oword [r11 + r10] + movdqu xmm1, oword [r11 + r10 + $10] + movdqu xmm2, oword [r11 + r10 + $20] + movdqu xmm3, oword [r11 + r10 + $30] + movdqu xmm4, oword [r11 + r10 + $40] + movdqu xmm5, oword [r11 + r10 + $50] + movdqu xmm6, oword [r11 + r10 + $60] + movdqu xmm7, oword [r11 + r10 + $70] + + // ----- Column G: G(A0,B0,C0,D0) || G(A1,B1,C1,D1) ----- + + // fBlaMka(a, b): a = a + b + 2*lo32(a)*lo32(b) + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + // d = rotr64(d ^ a, 32) + pxor xmm6, xmm0 + pshufd xmm6, xmm6, $B1 + pxor xmm7, xmm1 + pshufd xmm7, xmm7, $B1 + + // fBlaMka(c, d) + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + // b = rotr64(b ^ c, 24) + pxor xmm2, xmm4 + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + pxor xmm3, xmm5 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // fBlaMka(a, b) + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + // d = rotr64(d ^ a, 16) + pxor xmm6, xmm0 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + // fBlaMka(c, d) + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + // b = rotr64(b ^ c, 63) + pxor xmm2, xmm4 + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + pxor xmm3, xmm5 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // ----- Diagonalize ----- + // B: rotate QWord positions left by 1 + // B0=(v4,v5)->B0'=(v5,v6), B1=(v6,v7)->B1'=(v7,v4) + movdqa xmm8, xmm2 + shufpd xmm2, xmm3, 1 + shufpd xmm3, xmm8, 1 + + // C: swap register pair c0<->c1 + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + // D: rotate QWord positions right by 1 + // D0=(v12,v13)->D0'=(v15,v12), D1=(v14,v15)->D1'=(v13,v14) + // shufpd produces results in swapped registers, so we swap afterwards + movdqa xmm8, xmm7 + shufpd xmm7, xmm6, 1 + shufpd xmm6, xmm8, 1 + movdqa xmm8, xmm6 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + // ----- Diagonal G ----- + + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + pxor xmm6, xmm0 + pshufd xmm6, xmm6, $B1 + pxor xmm7, xmm1 + pshufd xmm7, xmm7, $B1 + + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + pxor xmm2, xmm4 + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + pxor xmm3, xmm5 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + pxor xmm6, xmm0 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + pxor xmm2, xmm4 + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + pxor xmm3, xmm5 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // ----- Undiagonalize ----- + // B: rotate QWord positions right by 1 (undo left-1) + // shufpd produces results in swapped registers, so we swap afterwards + movdqa xmm8, xmm3 + shufpd xmm3, xmm2, 1 + shufpd xmm2, xmm8, 1 + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + movdqa xmm3, xmm8 + + // C: swap register pair (self-inverse) + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + // D: rotate QWord positions left by 1 (undo right-1) + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, 1 + shufpd xmm7, xmm8, 1 + + // ----- Store back to Z_buf ----- + movdqu oword [r11 + r10], xmm0 + movdqu oword [r11 + r10 + $10], xmm1 + movdqu oword [r11 + r10 + $20], xmm2 + movdqu oword [r11 + r10 + $30], xmm3 + movdqu oword [r11 + r10 + $40], xmm4 + movdqu oword [r11 + r10 + $50], xmm5 + movdqu oword [r11 + r10 + $60], xmm6 + movdqu oword [r11 + r10 + $70], xmm7 + + add r10, 128 + cmp r10, 1024 + jb @col_loop + + // ========================================================================= + // Step 4: Row rounds on Z_buf (8 iterations, stride-16 QWord access) + // ========================================================================= + xor r10, r10 + +@row_loop: + movdqu xmm0, oword [r11 + r10] + movdqu xmm1, oword [r11 + r10 + 128] + movdqu xmm2, oword [r11 + r10 + 256] + movdqu xmm3, oword [r11 + r10 + 384] + movdqu xmm4, oword [r11 + r10 + 512] + movdqu xmm5, oword [r11 + r10 + 640] + movdqu xmm6, oword [r11 + r10 + 768] + movdqu xmm7, oword [r11 + r10 + 896] + + // ----- Column G ----- + + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + pxor xmm6, xmm0 + pshufd xmm6, xmm6, $B1 + pxor xmm7, xmm1 + pshufd xmm7, xmm7, $B1 + + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + pxor xmm2, xmm4 + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + pxor xmm3, xmm5 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + pxor xmm6, xmm0 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + pxor xmm2, xmm4 + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + pxor xmm3, xmm5 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // ----- Diagonalize ----- + movdqa xmm8, xmm2 + shufpd xmm2, xmm3, 1 + shufpd xmm3, xmm8, 1 + + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm7 + shufpd xmm7, xmm6, 1 + shufpd xmm6, xmm8, 1 + movdqa xmm8, xmm6 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + // ----- Diagonal G ----- + + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + pxor xmm6, xmm0 + pshufd xmm6, xmm6, $B1 + pxor xmm7, xmm1 + pshufd xmm7, xmm7, $B1 + + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + pxor xmm2, xmm4 + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + pxor xmm3, xmm5 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + movdqa xmm8, xmm0 + pmuludq xmm8, xmm2 + psllq xmm8, 1 + paddq xmm0, xmm2 + paddq xmm0, xmm8 + movdqa xmm9, xmm1 + pmuludq xmm9, xmm3 + psllq xmm9, 1 + paddq xmm1, xmm3 + paddq xmm1, xmm9 + + pxor xmm6, xmm0 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + movdqa xmm8, xmm4 + pmuludq xmm8, xmm6 + psllq xmm8, 1 + paddq xmm4, xmm6 + paddq xmm4, xmm8 + movdqa xmm9, xmm5 + pmuludq xmm9, xmm7 + psllq xmm9, 1 + paddq xmm5, xmm7 + paddq xmm5, xmm9 + + pxor xmm2, xmm4 + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + pxor xmm3, xmm5 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // ----- Undiagonalize ----- + movdqa xmm8, xmm3 + shufpd xmm3, xmm2, 1 + shufpd xmm2, xmm8, 1 + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + movdqa xmm3, xmm8 + + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, 1 + shufpd xmm7, xmm8, 1 + + // ----- Store back to Z_buf at stride offsets ----- + movdqu oword [r11 + r10], xmm0 + movdqu oword [r11 + r10 + 128], xmm1 + movdqu oword [r11 + r10 + 256], xmm2 + movdqu oword [r11 + r10 + 384], xmm3 + movdqu oword [r11 + r10 + 512], xmm4 + movdqu oword [r11 + r10 + 640], xmm5 + movdqu oword [r11 + r10 + 768], xmm6 + movdqu oword [r11 + r10 + 896], xmm7 + + add r10, 16 + cmp r10, 128 + jb @row_loop + + // ========================================================================= + // Step 5: Final XOR - Current = R_buf XOR Z_buf [XOR Current] + // ========================================================================= + test r9, r9 + jnz @final_with_xor + + xor r10, r10 +@final_noxor_loop: + movdqu xmm0, oword [rax + r10] + movdqu xmm1, oword [r11 + r10] + pxor xmm0, xmm1 + movdqu oword [r8 + r10], xmm0 + add r10, 16 + cmp r10, 1024 + jb @final_noxor_loop + jmp @epilogue + +@final_with_xor: + xor r10, r10 +@final_xor_loop: + movdqu xmm0, oword [rax + r10] + movdqu xmm1, oword [r11 + r10] + movdqu xmm2, oword [r8 + r10] + pxor xmm0, xmm1 + pxor xmm0, xmm2 + movdqu oword [r8 + r10], xmm0 + add r10, 16 + cmp r10, 1024 + jb @final_xor_loop + +@epilogue: + add rsp, 2056 + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc new file mode 100644 index 0000000..5f4df7d --- /dev/null +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc @@ -0,0 +1,975 @@ +// AVX2 implementation of BLAKE2b compress (IA-32; fully unrolled 12 rounds). +// 256-bit ymm integer ops work in 32-bit mode; the kernel fits IA-32's +// ymm0-7 exactly. Same structure as Blake2BCompressAvx2_x86_64.inc, with the +// x86_64 version's memory-source vpinsrq message loads (not encodable in +// 32-bit mode) replaced 1:1 by vmovhps (same load-high-qword semantics). +// IA-32: after HlpSimdProc5Begin_i386 - ebx = state ptr, esi = msg ptr, +// edi = counter+flags ptr, eax = IV ptr, ecx = byte-rotation masks ptr +// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment). +// Register map: ymm0 = a (v0-3), ymm1 = b (v4-7), ymm2 = c (v8-11), ymm3 = d (v12-15), +// ymm4 = message temp, ymm5 = computation temp, ymm6 = rot24 mask, ymm7 = rot16 mask. +// Rotations: ROT32 via vpshufd, ROT16/24 via vpshufb against the resident +// masks, ROT63 via shift+or (not byte-aligned; shifts are the known-best form). +// Diagonalize/Undiagonalize via vpermq. +// Uses ymm0-ymm7; xmm6/xmm7 saved/restored defensively (volatile on IA-32). +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: sneves/blake2-avx2 by Samuel Neves, HashLib +// Blake2BCompressAvx2_x86_64.inc. + + // Defensive save of xmm6/xmm7 (volatile on IA-32; saved like the + // SSE2 sibling to be safe under every RTL). Only the low 128 bits + // matter - the ymm uppers are dead after the trailing vzeroupper. + sub esp, $20 + db $C5, $FA, $7F, $34, $24 // vmovdqu oword [esp], xmm6 + db $C5, $FA, $7F, $7C, $24, $10 // vmovdqu oword [esp + $10], xmm7 + + + // Initialize working vector + db $C5, $FE, $6F, $03 // vmovdqu ymm0, yword [ebx] + db $C5, $FE, $6F, $4B, $20 // vmovdqu ymm1, yword [ebx + $20] + db $C5, $FE, $6F, $10 // vmovdqu ymm2, yword [eax] + db $C5, $FE, $6F, $58, $20 // vmovdqu ymm3, yword [eax + $20] + + // Load byte-rotation masks (resident for the whole kernel) + db $C5, $FE, $6F, $31 // vmovdqu ymm6, yword [ecx] + db $C5, $FE, $6F, $79, $20 // vmovdqu ymm7, yword [ecx + $20] + + // XOR d with counter and flags + db $C5, $FE, $6F, $27 // vmovdqu ymm4, yword [edi] + db $C5, $E5, $EF, $DC // vpxor ymm3, ymm3, ymm4 + + // ===== Round 0 ===== + + // G1 columns (msg: m0,m2,m4,m6) + db $C5, $FA, $7E, $26 // vmovq xmm4, qword [esi] + db $C5, $D8, $16, $66, $10 // vmovhps xmm4, xmm4, qword [esi + $10] + db $C5, $FA, $7E, $6E, $20 // vmovq xmm5, qword [esi + $20] + db $C5, $D0, $16, $6E, $30 // vmovhps xmm5, xmm5, qword [esi + $30] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m1,m3,m5,m7) + db $C5, $FA, $7E, $66, $08 // vmovq xmm4, qword [esi + $8] + db $C5, $D8, $16, $66, $18 // vmovhps xmm4, xmm4, qword [esi + $18] + db $C5, $FA, $7E, $6E, $28 // vmovq xmm5, qword [esi + $28] + db $C5, $D0, $16, $6E, $38 // vmovhps xmm5, xmm5, qword [esi + $38] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m14,m8,m10,m12) + db $C5, $FA, $7E, $66, $70 // vmovq xmm4, qword [esi + $70] + db $C5, $D8, $16, $66, $40 // vmovhps xmm4, xmm4, qword [esi + $40] + db $C5, $FA, $7E, $6E, $50 // vmovq xmm5, qword [esi + $50] + db $C5, $D0, $16, $6E, $60 // vmovhps xmm5, xmm5, qword [esi + $60] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m15,m9,m11,m13) + db $C5, $FA, $7E, $66, $78 // vmovq xmm4, qword [esi + $78] + db $C5, $D8, $16, $66, $48 // vmovhps xmm4, xmm4, qword [esi + $48] + db $C5, $FA, $7E, $6E, $58 // vmovq xmm5, qword [esi + $58] + db $C5, $D0, $16, $6E, $68 // vmovhps xmm5, xmm5, qword [esi + $68] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 1 ===== + + // G1 columns (msg: m14,m4,m9,m13) + db $C5, $FA, $7E, $66, $70 // vmovq xmm4, qword [esi + $70] + db $C5, $D8, $16, $66, $20 // vmovhps xmm4, xmm4, qword [esi + $20] + db $C5, $FA, $7E, $6E, $48 // vmovq xmm5, qword [esi + $48] + db $C5, $D0, $16, $6E, $68 // vmovhps xmm5, xmm5, qword [esi + $68] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m10,m8,m15,m6) + db $C5, $FA, $7E, $66, $50 // vmovq xmm4, qword [esi + $50] + db $C5, $D8, $16, $66, $40 // vmovhps xmm4, xmm4, qword [esi + $40] + db $C5, $FA, $7E, $6E, $78 // vmovq xmm5, qword [esi + $78] + db $C5, $D0, $16, $6E, $30 // vmovhps xmm5, xmm5, qword [esi + $30] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m5,m1,m0,m11) + db $C5, $FA, $7E, $66, $28 // vmovq xmm4, qword [esi + $28] + db $C5, $D8, $16, $66, $08 // vmovhps xmm4, xmm4, qword [esi + $8] + db $C5, $FA, $7E, $2E // vmovq xmm5, qword [esi] + db $C5, $D0, $16, $6E, $58 // vmovhps xmm5, xmm5, qword [esi + $58] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m3,m12,m2,m7) + db $C5, $FA, $7E, $66, $18 // vmovq xmm4, qword [esi + $18] + db $C5, $D8, $16, $66, $60 // vmovhps xmm4, xmm4, qword [esi + $60] + db $C5, $FA, $7E, $6E, $10 // vmovq xmm5, qword [esi + $10] + db $C5, $D0, $16, $6E, $38 // vmovhps xmm5, xmm5, qword [esi + $38] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 2 ===== + + // G1 columns (msg: m11,m12,m5,m15) + db $C5, $FA, $7E, $66, $58 // vmovq xmm4, qword [esi + $58] + db $C5, $D8, $16, $66, $60 // vmovhps xmm4, xmm4, qword [esi + $60] + db $C5, $FA, $7E, $6E, $28 // vmovq xmm5, qword [esi + $28] + db $C5, $D0, $16, $6E, $78 // vmovhps xmm5, xmm5, qword [esi + $78] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m8,m0,m2,m13) + db $C5, $FA, $7E, $66, $40 // vmovq xmm4, qword [esi + $40] + db $C5, $D8, $16, $26 // vmovhps xmm4, xmm4, qword [esi] + db $C5, $FA, $7E, $6E, $10 // vmovq xmm5, qword [esi + $10] + db $C5, $D0, $16, $6E, $68 // vmovhps xmm5, xmm5, qword [esi + $68] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m9,m10,m3,m7) + db $C5, $FA, $7E, $66, $48 // vmovq xmm4, qword [esi + $48] + db $C5, $D8, $16, $66, $50 // vmovhps xmm4, xmm4, qword [esi + $50] + db $C5, $FA, $7E, $6E, $18 // vmovq xmm5, qword [esi + $18] + db $C5, $D0, $16, $6E, $38 // vmovhps xmm5, xmm5, qword [esi + $38] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m4,m14,m6,m1) + db $C5, $FA, $7E, $66, $20 // vmovq xmm4, qword [esi + $20] + db $C5, $D8, $16, $66, $70 // vmovhps xmm4, xmm4, qword [esi + $70] + db $C5, $FA, $7E, $6E, $30 // vmovq xmm5, qword [esi + $30] + db $C5, $D0, $16, $6E, $08 // vmovhps xmm5, xmm5, qword [esi + $8] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 3 ===== + + // G1 columns (msg: m7,m3,m13,m11) + db $C5, $FA, $7E, $66, $38 // vmovq xmm4, qword [esi + $38] + db $C5, $D8, $16, $66, $18 // vmovhps xmm4, xmm4, qword [esi + $18] + db $C5, $FA, $7E, $6E, $68 // vmovq xmm5, qword [esi + $68] + db $C5, $D0, $16, $6E, $58 // vmovhps xmm5, xmm5, qword [esi + $58] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m9,m1,m12,m14) + db $C5, $FA, $7E, $66, $48 // vmovq xmm4, qword [esi + $48] + db $C5, $D8, $16, $66, $08 // vmovhps xmm4, xmm4, qword [esi + $8] + db $C5, $FA, $7E, $6E, $60 // vmovq xmm5, qword [esi + $60] + db $C5, $D0, $16, $6E, $70 // vmovhps xmm5, xmm5, qword [esi + $70] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m15,m2,m5,m4) + db $C5, $FA, $7E, $66, $78 // vmovq xmm4, qword [esi + $78] + db $C5, $D8, $16, $66, $10 // vmovhps xmm4, xmm4, qword [esi + $10] + db $C5, $FA, $7E, $6E, $28 // vmovq xmm5, qword [esi + $28] + db $C5, $D0, $16, $6E, $20 // vmovhps xmm5, xmm5, qword [esi + $20] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m8,m6,m10,m0) + db $C5, $FA, $7E, $66, $40 // vmovq xmm4, qword [esi + $40] + db $C5, $D8, $16, $66, $30 // vmovhps xmm4, xmm4, qword [esi + $30] + db $C5, $FA, $7E, $6E, $50 // vmovq xmm5, qword [esi + $50] + db $C5, $D0, $16, $2E // vmovhps xmm5, xmm5, qword [esi] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 4 ===== + + // G1 columns (msg: m9,m5,m2,m10) + db $C5, $FA, $7E, $66, $48 // vmovq xmm4, qword [esi + $48] + db $C5, $D8, $16, $66, $28 // vmovhps xmm4, xmm4, qword [esi + $28] + db $C5, $FA, $7E, $6E, $10 // vmovq xmm5, qword [esi + $10] + db $C5, $D0, $16, $6E, $50 // vmovhps xmm5, xmm5, qword [esi + $50] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m0,m7,m4,m15) + db $C5, $FA, $7E, $26 // vmovq xmm4, qword [esi] + db $C5, $D8, $16, $66, $38 // vmovhps xmm4, xmm4, qword [esi + $38] + db $C5, $FA, $7E, $6E, $20 // vmovq xmm5, qword [esi + $20] + db $C5, $D0, $16, $6E, $78 // vmovhps xmm5, xmm5, qword [esi + $78] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m3,m14,m11,m6) + db $C5, $FA, $7E, $66, $18 // vmovq xmm4, qword [esi + $18] + db $C5, $D8, $16, $66, $70 // vmovhps xmm4, xmm4, qword [esi + $70] + db $C5, $FA, $7E, $6E, $58 // vmovq xmm5, qword [esi + $58] + db $C5, $D0, $16, $6E, $30 // vmovhps xmm5, xmm5, qword [esi + $30] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m13,m1,m12,m8) + db $C5, $FA, $7E, $66, $68 // vmovq xmm4, qword [esi + $68] + db $C5, $D8, $16, $66, $08 // vmovhps xmm4, xmm4, qword [esi + $8] + db $C5, $FA, $7E, $6E, $60 // vmovq xmm5, qword [esi + $60] + db $C5, $D0, $16, $6E, $40 // vmovhps xmm5, xmm5, qword [esi + $40] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 5 ===== + + // G1 columns (msg: m2,m6,m0,m8) + db $C5, $FA, $7E, $66, $10 // vmovq xmm4, qword [esi + $10] + db $C5, $D8, $16, $66, $30 // vmovhps xmm4, xmm4, qword [esi + $30] + db $C5, $FA, $7E, $2E // vmovq xmm5, qword [esi] + db $C5, $D0, $16, $6E, $40 // vmovhps xmm5, xmm5, qword [esi + $40] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m12,m10,m11,m3) + db $C5, $FA, $7E, $66, $60 // vmovq xmm4, qword [esi + $60] + db $C5, $D8, $16, $66, $50 // vmovhps xmm4, xmm4, qword [esi + $50] + db $C5, $FA, $7E, $6E, $58 // vmovq xmm5, qword [esi + $58] + db $C5, $D0, $16, $6E, $18 // vmovhps xmm5, xmm5, qword [esi + $18] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m1,m4,m7,m15) + db $C5, $FA, $7E, $66, $08 // vmovq xmm4, qword [esi + $8] + db $C5, $D8, $16, $66, $20 // vmovhps xmm4, xmm4, qword [esi + $20] + db $C5, $FA, $7E, $6E, $38 // vmovq xmm5, qword [esi + $38] + db $C5, $D0, $16, $6E, $78 // vmovhps xmm5, xmm5, qword [esi + $78] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m9,m13,m5,m14) + db $C5, $FA, $7E, $66, $48 // vmovq xmm4, qword [esi + $48] + db $C5, $D8, $16, $66, $68 // vmovhps xmm4, xmm4, qword [esi + $68] + db $C5, $FA, $7E, $6E, $28 // vmovq xmm5, qword [esi + $28] + db $C5, $D0, $16, $6E, $70 // vmovhps xmm5, xmm5, qword [esi + $70] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 6 ===== + + // G1 columns (msg: m12,m1,m14,m4) + db $C5, $FA, $7E, $66, $60 // vmovq xmm4, qword [esi + $60] + db $C5, $D8, $16, $66, $08 // vmovhps xmm4, xmm4, qword [esi + $8] + db $C5, $FA, $7E, $6E, $70 // vmovq xmm5, qword [esi + $70] + db $C5, $D0, $16, $6E, $20 // vmovhps xmm5, xmm5, qword [esi + $20] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m5,m15,m13,m10) + db $C5, $FA, $7E, $66, $28 // vmovq xmm4, qword [esi + $28] + db $C5, $D8, $16, $66, $78 // vmovhps xmm4, xmm4, qword [esi + $78] + db $C5, $FA, $7E, $6E, $68 // vmovq xmm5, qword [esi + $68] + db $C5, $D0, $16, $6E, $50 // vmovhps xmm5, xmm5, qword [esi + $50] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m8,m0,m6,m9) + db $C5, $FA, $7E, $66, $40 // vmovq xmm4, qword [esi + $40] + db $C5, $D8, $16, $26 // vmovhps xmm4, xmm4, qword [esi] + db $C5, $FA, $7E, $6E, $30 // vmovq xmm5, qword [esi + $30] + db $C5, $D0, $16, $6E, $48 // vmovhps xmm5, xmm5, qword [esi + $48] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m11,m7,m3,m2) + db $C5, $FA, $7E, $66, $58 // vmovq xmm4, qword [esi + $58] + db $C5, $D8, $16, $66, $38 // vmovhps xmm4, xmm4, qword [esi + $38] + db $C5, $FA, $7E, $6E, $18 // vmovq xmm5, qword [esi + $18] + db $C5, $D0, $16, $6E, $10 // vmovhps xmm5, xmm5, qword [esi + $10] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 7 ===== + + // G1 columns (msg: m13,m7,m12,m3) + db $C5, $FA, $7E, $66, $68 // vmovq xmm4, qword [esi + $68] + db $C5, $D8, $16, $66, $38 // vmovhps xmm4, xmm4, qword [esi + $38] + db $C5, $FA, $7E, $6E, $60 // vmovq xmm5, qword [esi + $60] + db $C5, $D0, $16, $6E, $18 // vmovhps xmm5, xmm5, qword [esi + $18] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m11,m14,m1,m9) + db $C5, $FA, $7E, $66, $58 // vmovq xmm4, qword [esi + $58] + db $C5, $D8, $16, $66, $70 // vmovhps xmm4, xmm4, qword [esi + $70] + db $C5, $FA, $7E, $6E, $08 // vmovq xmm5, qword [esi + $8] + db $C5, $D0, $16, $6E, $48 // vmovhps xmm5, xmm5, qword [esi + $48] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m2,m5,m15,m8) + db $C5, $FA, $7E, $66, $10 // vmovq xmm4, qword [esi + $10] + db $C5, $D8, $16, $66, $28 // vmovhps xmm4, xmm4, qword [esi + $28] + db $C5, $FA, $7E, $6E, $78 // vmovq xmm5, qword [esi + $78] + db $C5, $D0, $16, $6E, $40 // vmovhps xmm5, xmm5, qword [esi + $40] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m10,m0,m4,m6) + db $C5, $FA, $7E, $66, $50 // vmovq xmm4, qword [esi + $50] + db $C5, $D8, $16, $26 // vmovhps xmm4, xmm4, qword [esi] + db $C5, $FA, $7E, $6E, $20 // vmovq xmm5, qword [esi + $20] + db $C5, $D0, $16, $6E, $30 // vmovhps xmm5, xmm5, qword [esi + $30] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 8 ===== + + // G1 columns (msg: m6,m14,m11,m0) + db $C5, $FA, $7E, $66, $30 // vmovq xmm4, qword [esi + $30] + db $C5, $D8, $16, $66, $70 // vmovhps xmm4, xmm4, qword [esi + $70] + db $C5, $FA, $7E, $6E, $58 // vmovq xmm5, qword [esi + $58] + db $C5, $D0, $16, $2E // vmovhps xmm5, xmm5, qword [esi] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m15,m9,m3,m8) + db $C5, $FA, $7E, $66, $78 // vmovq xmm4, qword [esi + $78] + db $C5, $D8, $16, $66, $48 // vmovhps xmm4, xmm4, qword [esi + $48] + db $C5, $FA, $7E, $6E, $18 // vmovq xmm5, qword [esi + $18] + db $C5, $D0, $16, $6E, $40 // vmovhps xmm5, xmm5, qword [esi + $40] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m10,m12,m13,m1) + db $C5, $FA, $7E, $66, $50 // vmovq xmm4, qword [esi + $50] + db $C5, $D8, $16, $66, $60 // vmovhps xmm4, xmm4, qword [esi + $60] + db $C5, $FA, $7E, $6E, $68 // vmovq xmm5, qword [esi + $68] + db $C5, $D0, $16, $6E, $08 // vmovhps xmm5, xmm5, qword [esi + $8] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m5,m2,m7,m4) + db $C5, $FA, $7E, $66, $28 // vmovq xmm4, qword [esi + $28] + db $C5, $D8, $16, $66, $10 // vmovhps xmm4, xmm4, qword [esi + $10] + db $C5, $FA, $7E, $6E, $38 // vmovq xmm5, qword [esi + $38] + db $C5, $D0, $16, $6E, $20 // vmovhps xmm5, xmm5, qword [esi + $20] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 9 ===== + + // G1 columns (msg: m10,m8,m7,m1) + db $C5, $FA, $7E, $66, $50 // vmovq xmm4, qword [esi + $50] + db $C5, $D8, $16, $66, $40 // vmovhps xmm4, xmm4, qword [esi + $40] + db $C5, $FA, $7E, $6E, $38 // vmovq xmm5, qword [esi + $38] + db $C5, $D0, $16, $6E, $08 // vmovhps xmm5, xmm5, qword [esi + $8] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m2,m4,m6,m5) + db $C5, $FA, $7E, $66, $10 // vmovq xmm4, qword [esi + $10] + db $C5, $D8, $16, $66, $20 // vmovhps xmm4, xmm4, qword [esi + $20] + db $C5, $FA, $7E, $6E, $30 // vmovq xmm5, qword [esi + $30] + db $C5, $D0, $16, $6E, $28 // vmovhps xmm5, xmm5, qword [esi + $28] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m13,m15,m9,m3) + db $C5, $FA, $7E, $66, $68 // vmovq xmm4, qword [esi + $68] + db $C5, $D8, $16, $66, $78 // vmovhps xmm4, xmm4, qword [esi + $78] + db $C5, $FA, $7E, $6E, $48 // vmovq xmm5, qword [esi + $48] + db $C5, $D0, $16, $6E, $18 // vmovhps xmm5, xmm5, qword [esi + $18] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m0,m11,m14,m12) + db $C5, $FA, $7E, $26 // vmovq xmm4, qword [esi] + db $C5, $D8, $16, $66, $58 // vmovhps xmm4, xmm4, qword [esi + $58] + db $C5, $FA, $7E, $6E, $70 // vmovq xmm5, qword [esi + $70] + db $C5, $D0, $16, $6E, $60 // vmovhps xmm5, xmm5, qword [esi + $60] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 10 ===== + + // G1 columns (msg: m0,m2,m4,m6) + db $C5, $FA, $7E, $26 // vmovq xmm4, qword [esi] + db $C5, $D8, $16, $66, $10 // vmovhps xmm4, xmm4, qword [esi + $10] + db $C5, $FA, $7E, $6E, $20 // vmovq xmm5, qword [esi + $20] + db $C5, $D0, $16, $6E, $30 // vmovhps xmm5, xmm5, qword [esi + $30] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m1,m3,m5,m7) + db $C5, $FA, $7E, $66, $08 // vmovq xmm4, qword [esi + $8] + db $C5, $D8, $16, $66, $18 // vmovhps xmm4, xmm4, qword [esi + $18] + db $C5, $FA, $7E, $6E, $28 // vmovq xmm5, qword [esi + $28] + db $C5, $D0, $16, $6E, $38 // vmovhps xmm5, xmm5, qword [esi + $38] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m14,m8,m10,m12) + db $C5, $FA, $7E, $66, $70 // vmovq xmm4, qword [esi + $70] + db $C5, $D8, $16, $66, $40 // vmovhps xmm4, xmm4, qword [esi + $40] + db $C5, $FA, $7E, $6E, $50 // vmovq xmm5, qword [esi + $50] + db $C5, $D0, $16, $6E, $60 // vmovhps xmm5, xmm5, qword [esi + $60] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m15,m9,m11,m13) + db $C5, $FA, $7E, $66, $78 // vmovq xmm4, qword [esi + $78] + db $C5, $D8, $16, $66, $48 // vmovhps xmm4, xmm4, qword [esi + $48] + db $C5, $FA, $7E, $6E, $58 // vmovq xmm5, qword [esi + $58] + db $C5, $D0, $16, $6E, $68 // vmovhps xmm5, xmm5, qword [esi + $68] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // ===== Round 11 ===== + + // G1 columns (msg: m14,m4,m9,m13) + db $C5, $FA, $7E, $66, $70 // vmovq xmm4, qword [esi + $70] + db $C5, $D8, $16, $66, $20 // vmovhps xmm4, xmm4, qword [esi + $20] + db $C5, $FA, $7E, $6E, $48 // vmovq xmm5, qword [esi + $48] + db $C5, $D0, $16, $6E, $68 // vmovhps xmm5, xmm5, qword [esi + $68] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 columns (msg: m10,m8,m15,m6) + db $C5, $FA, $7E, $66, $50 // vmovq xmm4, qword [esi + $50] + db $C5, $D8, $16, $66, $40 // vmovhps xmm4, xmm4, qword [esi + $40] + db $C5, $FA, $7E, $6E, $78 // vmovq xmm5, qword [esi + $78] + db $C5, $D0, $16, $6E, $30 // vmovhps xmm5, xmm5, qword [esi + $30] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Diagonalize + db $C4, $E3, $FD, $00, $C0, $93 // vpermq ymm0, ymm0, $93 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $39 // vpermq ymm2, ymm2, $39 + + // G1 diagonals (msg: m5,m1,m0,m11) + db $C5, $FA, $7E, $66, $28 // vmovq xmm4, qword [esi + $28] + db $C5, $D8, $16, $66, $08 // vmovhps xmm4, xmm4, qword [esi + $8] + db $C5, $FA, $7E, $2E // vmovq xmm5, qword [esi] + db $C5, $D0, $16, $6E, $58 // vmovhps xmm5, xmm5, qword [esi + $58] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 + + // G2 diagonals (msg: m3,m12,m2,m7) + db $C5, $FA, $7E, $66, $18 // vmovq xmm4, qword [esi + $18] + db $C5, $D8, $16, $66, $60 // vmovhps xmm4, xmm4, qword [esi + $60] + db $C5, $FA, $7E, $6E, $10 // vmovq xmm5, qword [esi + $10] + db $C5, $D0, $16, $6E, $38 // vmovhps xmm5, xmm5, qword [esi + $38] + db $C4, $E3, $5D, $38, $E5, $01 // vinserti128 ymm4, ymm4, xmm5, $1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 + + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $D5, $73, $D1, $3F // vpsrlq ymm5, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + + // Undiagonalize + db $C4, $E3, $FD, $00, $C0, $39 // vpermq ymm0, ymm0, $39 + db $C4, $E3, $FD, $00, $DB, $4E // vpermq ymm3, ymm3, $4E + db $C4, $E3, $FD, $00, $D2, $93 // vpermq ymm2, ymm2, $93 + + // Finalization + db $C5, $FD, $EF, $C2 // vpxor ymm0, ymm0, ymm2 + db $C5, $F5, $EF, $CB // vpxor ymm1, ymm1, ymm3 + + // XOR with original state (re-read from memory) + db $C5, $FD, $EF, $03 // vpxor ymm0, ymm0, yword [ebx] + db $C5, $F5, $EF, $4B, $20 // vpxor ymm1, ymm1, yword [ebx + $20] + + // Store result + db $C5, $FE, $7F, $03 // vmovdqu yword [ebx], ymm0 + db $C5, $FE, $7F, $4B, $20 // vmovdqu yword [ebx + $20], ymm1 + + db $C5, $F8, $77 // vzeroupper + + + + db $C5, $FA, $6F, $34, $24 // vmovdqu xmm6, oword [esp] + db $C5, $FA, $6F, $7C, $24, $10 // vmovdqu xmm7, oword [esp + $10] + add esp, $20 + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc index d507afc..94dfedb 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc @@ -1,12 +1,20 @@ // AVX2 implementation of BLAKE2b compress (fully unrolled 12 rounds). -// Expects MS x64 ABI: rcx = state ptr, rdx = msg ptr, r8 = counter+flags ptr, r9 = IV ptr. -// Uses ymm0-ymm5 only (volatile under both ABIs; no saves needed). +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr +// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment). // Register map: ymm0 = a (v0-3), ymm1 = b (v4-7), ymm2 = c (v8-11), ymm3 = d (v12-15), -// ymm4 = message temp, ymm5 = computation temp. -// Rotations: ROT32 via vpshufd, ROT16/24/63 via shift+or. +// ymm4 = message temp, ymm5 = computation temp, ymm6 = rot24 mask, ymm7 = rot16 mask. +// Rotations: ROT32 via vpshufd, ROT16/24 via vpshufb against the resident +// masks, ROT63 via shift+or (not byte-aligned; shifts are the known-best form). // Diagonalize/Undiagonalize via vpermq. // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: sneves/blake2-avx2 by Samuel Neves. +// +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV; only xmm6/xmm7 are clobbered here - by the mask loads). + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} // Initialize working vector db $C5, $FE, $6F, $01 // vmovdqu ymm0, yword [rcx] @@ -14,6 +22,10 @@ db $C4, $C1, $7E, $6F, $11 // vmovdqu ymm2, yword [r9] db $C4, $C1, $7E, $6F, $59, $20 // vmovdqu ymm3, yword [r9 + $20] + // Load byte-rotation masks (resident for the whole kernel) + db $C4, $C1, $7E, $6F, $32 // vmovdqu ymm6, yword [r10] + db $C4, $C1, $7E, $6F, $7A, $20 // vmovdqu ymm7, yword [r10 + $20] + // XOR d with counter and flags db $C4, $C1, $7E, $6F, $20 // vmovdqu ymm4, yword [r8] db $C5, $E5, $EF, $DC // vpxor ymm3, ymm3, ymm4 @@ -33,9 +45,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m1,m3,m5,m7) db $C4, $E1, $F9, $6E, $62, $08 // vmovq xmm4, qword [rdx + $08] @@ -46,9 +56,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -74,9 +82,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m15,m9,m11,m13) db $C4, $E1, $F9, $6E, $62, $78 // vmovq xmm4, qword [rdx + $78] @@ -87,9 +93,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -117,9 +121,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m10,m8,m15,m6) db $C4, $E1, $F9, $6E, $62, $50 // vmovq xmm4, qword [rdx + $50] @@ -130,9 +132,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -158,9 +158,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m3,m12,m2,m7) db $C4, $E1, $F9, $6E, $62, $18 // vmovq xmm4, qword [rdx + $18] @@ -171,9 +169,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -201,9 +197,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m8,m0,m2,m13) db $C4, $E1, $F9, $6E, $62, $40 // vmovq xmm4, qword [rdx + $40] @@ -214,9 +208,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -242,9 +234,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m4,m14,m6,m1) db $C4, $E1, $F9, $6E, $62, $20 // vmovq xmm4, qword [rdx + $20] @@ -255,9 +245,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -285,9 +273,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m9,m1,m12,m14) db $C4, $E1, $F9, $6E, $62, $48 // vmovq xmm4, qword [rdx + $48] @@ -298,9 +284,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -326,9 +310,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m8,m6,m10,m0) db $C4, $E1, $F9, $6E, $62, $40 // vmovq xmm4, qword [rdx + $40] @@ -339,9 +321,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -369,9 +349,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m0,m7,m4,m15) db $C4, $E1, $F9, $6E, $22 // vmovq xmm4, qword [rdx] @@ -382,9 +360,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -410,9 +386,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m13,m1,m12,m8) db $C4, $E1, $F9, $6E, $62, $68 // vmovq xmm4, qword [rdx + $68] @@ -423,9 +397,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -453,9 +425,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m12,m10,m11,m3) db $C4, $E1, $F9, $6E, $62, $60 // vmovq xmm4, qword [rdx + $60] @@ -466,9 +436,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -494,9 +462,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m9,m13,m5,m14) db $C4, $E1, $F9, $6E, $62, $48 // vmovq xmm4, qword [rdx + $48] @@ -507,9 +473,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -537,9 +501,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m5,m15,m13,m10) db $C4, $E1, $F9, $6E, $62, $28 // vmovq xmm4, qword [rdx + $28] @@ -550,9 +512,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -578,9 +538,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m11,m7,m3,m2) db $C4, $E1, $F9, $6E, $62, $58 // vmovq xmm4, qword [rdx + $58] @@ -591,9 +549,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -621,9 +577,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m11,m14,m1,m9) db $C4, $E1, $F9, $6E, $62, $58 // vmovq xmm4, qword [rdx + $58] @@ -634,9 +588,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -662,9 +614,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m10,m0,m4,m6) db $C4, $E1, $F9, $6E, $62, $50 // vmovq xmm4, qword [rdx + $50] @@ -675,9 +625,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -705,9 +653,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m15,m9,m3,m8) db $C4, $E1, $F9, $6E, $62, $78 // vmovq xmm4, qword [rdx + $78] @@ -718,9 +664,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -746,9 +690,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m5,m2,m7,m4) db $C4, $E1, $F9, $6E, $62, $28 // vmovq xmm4, qword [rdx + $28] @@ -759,9 +701,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -789,9 +729,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m2,m4,m6,m5) db $C4, $E1, $F9, $6E, $62, $10 // vmovq xmm4, qword [rdx + $10] @@ -802,9 +740,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -830,9 +766,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m0,m11,m14,m12) db $C4, $E1, $F9, $6E, $22 // vmovq xmm4, qword [rdx] @@ -843,9 +777,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -873,9 +805,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m1,m3,m5,m7) db $C4, $E1, $F9, $6E, $62, $08 // vmovq xmm4, qword [rdx + $08] @@ -886,9 +816,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -914,9 +842,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m15,m9,m11,m13) db $C4, $E1, $F9, $6E, $62, $78 // vmovq xmm4, qword [rdx + $78] @@ -927,9 +853,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -957,9 +881,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 columns (msg: m10,m8,m15,m6) db $C4, $E1, $F9, $6E, $62, $50 // vmovq xmm4, qword [rdx + $50] @@ -970,9 +892,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -998,9 +918,7 @@ db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 - db $C5, $D5, $73, $D1, $18 // vpsrlq ymm5, ymm1, 24 - db $C5, $F5, $73, $F1, $28 // vpsllq ymm1, ymm1, 40 - db $C5, $F5, $EB, $CD // vpor ymm1, ymm1, ymm5 + db $C4, $E2, $75, $00, $CE // vpshufb ymm1, ymm1, ymm6 // G2 diagonals (msg: m3,m12,m2,m7) db $C4, $E1, $F9, $6E, $62, $18 // vmovq xmm4, qword [rdx + $18] @@ -1011,9 +929,7 @@ db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 - db $C5, $D5, $73, $D3, $10 // vpsrlq ymm5, ymm3, 16 - db $C5, $E5, $73, $F3, $30 // vpsllq ymm3, ymm3, 48 - db $C5, $E5, $EB, $DD // vpor ymm3, ymm3, ymm5 + db $C4, $E2, $65, $00, $DF // vpshufb ymm3, ymm3, ymm7 db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 @@ -1039,3 +955,5 @@ db $C5, $FE, $7F, $49, $20 // vmovdqu yword [rcx + $20], ymm1 db $C5, $F8, $77 // vzeroupper + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc new file mode 100644 index 0000000..afd2fbb --- /dev/null +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc @@ -0,0 +1,2071 @@ +// SSSE3 implementation of BLAKE2b compress (fully unrolled 12 rounds); SSE2 +// sibling: Blake2BCompressSse2_i386.inc. Unlike the SSE2 sibling, each pair +// of byte-aligned rotations (rot24/rot16) is one mask load into the already +// stack-spilled xmm4 scratch plus two pshufb (db-encoded for broad assembler +// compatibility); rot63 stays shift+or (not byte-aligned). +// IA-32: after HlpSimdProc5Begin_i386 - ebx = state, esi = msg, +// edi = counter+flags, eax = IV, ecx = byte-rotation masks ptr +// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so +// the Pascal const needs no special alignment). +// XMM8+ from x64 eliminated: xmm4 scratch + stack, xmm0/1 for diagonal work; uses xmm0-xmm7. +// Non-volatile xmm6-xmm7 saved in stack frame (sub esp, 128). +// Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15) +// with temps folded per IA-32 constraints. +// Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. + + sub esp, 128 + movdqu oword ptr [esp], xmm6 + movdqu oword ptr [esp + $10], xmm7 + + // Initialize working vector + movdqu xmm0, oword ptr [ebx] + movdqu xmm1, oword ptr [ebx + $10] + movdqu xmm2, oword ptr [ebx + $20] + movdqu xmm3, oword ptr [ebx + $30] + movdqu xmm4, oword ptr [eax] + movdqu xmm5, oword ptr [eax + $10] + movdqu xmm6, oword ptr [eax + $20] + movdqu xmm7, oword ptr [eax + $30] + + // XOR row4 with counter and flags + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [edi] + pxor xmm6, xmm4 + movdqu xmm4, oword ptr [edi + $10] + pxor xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // ===== Round 0 ===== + + // G1 columns (msg: m0,m2 / m4,m6) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $10] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $20] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m1,m3 / m5,m7) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $28] + movhpd xmm4, qword ptr [esi + $38] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m8,m10 / m12,m14) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $40] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $70] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m9,m11 / m13,m15) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $58] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $68] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 1 ===== + + // G1 columns (msg: m14,m4 / m9,m13) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $70] + movhpd xmm4, qword ptr [esi + $20] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $68] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m10,m8 / m15,m6) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $50] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $78] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m1,m0 / m11,m5) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m12,m2 / m7,m3) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $10] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $38] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 2 ===== + + // G1 columns (msg: m11,m12 / m5,m15) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi + $60] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $28] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m8,m0 / m2,m13) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $40] + movhpd xmm4, qword ptr [esi] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $68] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m10,m3 / m7,m9) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $50] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $38] + movhpd xmm4, qword ptr [esi + $48] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m14,m6 / m1,m4) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $70] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi + $20] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 3 ===== + + // G1 columns (msg: m7,m3 / m13,m11) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $38] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $68] + movhpd xmm4, qword ptr [esi + $58] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m9,m1 / m12,m14) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $08] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $70] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m2,m5 / m4,m15) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $20] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m6,m10 / m0,m8) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $30] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 4 ===== + + // G1 columns (msg: m9,m5 / m2,m10) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m0,m7 / m4,m15) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $38] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $20] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m14,m11 / m6,m3) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $70] + movhpd xmm4, qword ptr [esi + $58] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $30] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m1,m12 / m8,m13) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi + $60] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $40] + movhpd xmm4, qword ptr [esi + $68] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 5 ===== + + // G1 columns (msg: m2,m6 / m0,m8) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m12,m10 / m11,m3) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m4,m7 / m15,m1) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $20] + movhpd xmm4, qword ptr [esi + $38] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $78] + movhpd xmm4, qword ptr [esi + $08] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m13,m5 / m14,m9) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $68] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $70] + movhpd xmm4, qword ptr [esi + $48] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 6 ===== + + // G1 columns (msg: m12,m1 / m14,m4) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $08] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $70] + movhpd xmm4, qword ptr [esi + $20] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m5,m15 / m13,m10) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $28] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $68] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m0,m6 / m9,m8) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m7,m3 / m2,m11) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $38] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $58] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 7 ===== + + // G1 columns (msg: m13,m7 / m12,m3) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $68] + movhpd xmm4, qword ptr [esi + $38] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m11,m14 / m1,m9) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi + $70] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi + $48] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m5,m15 / m8,m2) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $28] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $40] + movhpd xmm4, qword ptr [esi + $10] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m0,m4 / m6,m10) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $20] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $30] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 8 ===== + + // G1 columns (msg: m6,m14 / m11,m0) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $30] + movhpd xmm4, qword ptr [esi + $70] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m15,m9 / m3,m8) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $78] + movhpd xmm4, qword ptr [esi + $48] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $18] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m12,m13 / m1,m10) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $68] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m2,m7 / m4,m5) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $38] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $20] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 9 ===== + + // G1 columns (msg: m10,m8 / m7,m1) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $50] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $38] + movhpd xmm4, qword ptr [esi + $08] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m2,m4 / m6,m5) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $10] + movhpd xmm4, qword ptr [esi + $20] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $30] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m15,m9 / m3,m13) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $78] + movhpd xmm4, qword ptr [esi + $48] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $18] + movhpd xmm4, qword ptr [esi + $68] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m11,m14 / m12,m0) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi + $70] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 10 ===== + + // G1 columns (msg: m0,m2 / m4,m6) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi] + movhpd xmm4, qword ptr [esi + $10] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $20] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m1,m3 / m5,m7) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $28] + movhpd xmm4, qword ptr [esi + $38] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m8,m10 / m12,m14) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $40] + movhpd xmm4, qword ptr [esi + $50] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $70] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m9,m11 / m13,m15) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $58] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $68] + movhpd xmm4, qword ptr [esi + $78] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // ===== Round 11 ===== + + // G1 columns (msg: m14,m4 / m9,m13) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $70] + movhpd xmm4, qword ptr [esi + $20] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $48] + movhpd xmm4, qword ptr [esi + $68] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 columns (msg: m10,m8 / m15,m6) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $50] + movhpd xmm4, qword ptr [esi + $40] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $78] + movhpd xmm4, qword ptr [esi + $30] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Diagonalize (i386: xmm0/1 scratch; no XMM8+) + movdqu oword ptr [esp + $40], xmm0 + movdqu oword ptr [esp + $50], xmm1 + movdqa xmm0, xmm6 + movdqa xmm1, xmm2 + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + movdqa xmm6, xmm7 + shufpd xmm7, xmm0, $01 + shufpd xmm0, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm0 + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm1, $01 + movdqu xmm0, oword ptr [esp + $40] + movdqu xmm1, oword ptr [esp + $50] + + // G1 diagonals (msg: m1,m0 / m11,m5) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $08] + movhpd xmm4, qword ptr [esi] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $58] + movhpd xmm4, qword ptr [esi + $28] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx] + db $66, $0F, $38, $00, $D4 // pshufb xmm2, xmm4 + db $66, $0F, $38, $00, $DC // pshufb xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // G2 diagonals (msg: m12,m2 / m7,m3) + movdqu oword ptr [esp + $20], xmm4 + movq xmm4, qword ptr [esi + $60] + movhpd xmm4, qword ptr [esi + $10] + paddq xmm0, xmm4 + paddq xmm0, xmm2 + movq xmm4, qword ptr [esi + $38] + movhpd xmm4, qword ptr [esi + $18] + paddq xmm1, xmm4 + paddq xmm1, xmm3 + movdqu xmm4, oword ptr [esp + $20] + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ecx + $20] + db $66, $0F, $38, $00, $F4 // pshufb xmm6, xmm4 + db $66, $0F, $38, $00, $FC // pshufb xmm7, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqu oword ptr [esp + $20], xmm4 + movdqa xmm4, xmm2 + psrlq xmm4, 63 + paddq xmm2, xmm2 + por xmm2, xmm4 + movdqa xmm4, xmm3 + psrlq xmm4, 63 + paddq xmm3, xmm3 + por xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Undiagonalize (i386: memory swap + xmm0 scratch) + movdqu oword ptr [esp + $70], xmm4 + movdqa xmm4, xmm5 + movdqu xmm5, oword ptr [esp + $70] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm0, $01 + movdqu xmm0, oword ptr [esp + $40] + + movdqu oword ptr [esp + $40], xmm0 + movdqa xmm0, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm0, $01 + shufpd xmm0, xmm3, $01 + movdqa xmm3, xmm0 + movdqu xmm0, oword ptr [esp + $40] + + // Finalization + pxor xmm0, xmm4 + pxor xmm1, xmm5 + pxor xmm2, xmm6 + pxor xmm3, xmm7 + + // XOR with original state (re-read from memory via movdqu for safe unaligned access) + movdqu oword ptr [esp + $20], xmm4 + movdqu xmm4, oword ptr [ebx] + pxor xmm0, xmm4 + movdqu xmm4, oword ptr [ebx + $10] + pxor xmm1, xmm4 + movdqu xmm4, oword ptr [ebx + $20] + pxor xmm2, xmm4 + movdqu xmm4, oword ptr [ebx + $30] + pxor xmm3, xmm4 + movdqu xmm4, oword ptr [esp + $20] + + // Store result + movdqu oword ptr [ebx], xmm0 + movdqu oword ptr [ebx + $10], xmm1 + movdqu oword ptr [ebx + $20], xmm2 + movdqu oword ptr [ebx + $30], xmm3 + + movdqu xmm6, oword ptr [esp] + movdqu xmm7, oword ptr [esp + $10] + add esp, 128 + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc new file mode 100644 index 0000000..284ba07 --- /dev/null +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc @@ -0,0 +1,1716 @@ +// SSSE3 implementation of BLAKE2b compress (fully unrolled 12 rounds); SSE2 +// sibling: Blake2BCompressSse2_x86_64.inc. Unlike the SSE2 sibling, the +// byte-aligned rotations (rot24/rot16) are single pshufb (db-encoded for +// broad assembler compatibility) against masks resident in xmm10/xmm11; +// rot63 stays shift+or (not byte-aligned). +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr +// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment). +// Uses xmm0-xmm11; xmm6-xmm11 are MS x64 non-volatile (saved/restored). +// Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), +// xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15), xmm8-9 = temps, +// xmm10 = rot24 mask, xmm11 = rot16 mask. +// Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + // Load byte-rotation masks (resident for the whole kernel) + db $F3, $45, $0F, $6F, $12 // movdqu xmm10, oword [r10] + db $F3, $45, $0F, $6F, $5A, $20 // movdqu xmm11, oword [r10 + $20] + + // Initialize working vector + movdqu xmm0, oword [rcx] + movdqu xmm1, oword [rcx + $10] + movdqu xmm2, oword [rcx + $20] + movdqu xmm3, oword [rcx + $30] + movdqu xmm4, oword [r9] + movdqu xmm5, oword [r9 + $10] + movdqu xmm6, oword [r9 + $20] + movdqu xmm7, oword [r9 + $30] + + // XOR row4 with counter and flags + movdqu xmm8, oword [r8] + movdqu xmm9, oword [r8 + $10] + pxor xmm6, xmm8 + pxor xmm7, xmm9 + + // ===== Round 0 ===== + + // G1 columns (msg: m0,m2 / m4,m6) + movq xmm8, qword [rdx] + movhpd xmm8, qword [rdx + $10] + movq xmm9, qword [rdx + $20] + movhpd xmm9, qword [rdx + $30] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m1,m3 / m5,m7) + movq xmm8, qword [rdx + $08] + movhpd xmm8, qword [rdx + $18] + movq xmm9, qword [rdx + $28] + movhpd xmm9, qword [rdx + $38] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m8,m10 / m12,m14) + movq xmm8, qword [rdx + $40] + movhpd xmm8, qword [rdx + $50] + movq xmm9, qword [rdx + $60] + movhpd xmm9, qword [rdx + $70] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m9,m11 / m13,m15) + movq xmm8, qword [rdx + $48] + movhpd xmm8, qword [rdx + $58] + movq xmm9, qword [rdx + $68] + movhpd xmm9, qword [rdx + $78] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 1 ===== + + // G1 columns (msg: m14,m4 / m9,m13) + movq xmm8, qword [rdx + $70] + movhpd xmm8, qword [rdx + $20] + movq xmm9, qword [rdx + $48] + movhpd xmm9, qword [rdx + $68] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m10,m8 / m15,m6) + movq xmm8, qword [rdx + $50] + movhpd xmm8, qword [rdx + $40] + movq xmm9, qword [rdx + $78] + movhpd xmm9, qword [rdx + $30] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m1,m0 / m11,m5) + movq xmm8, qword [rdx + $08] + movhpd xmm8, qword [rdx] + movq xmm9, qword [rdx + $58] + movhpd xmm9, qword [rdx + $28] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m12,m2 / m7,m3) + movq xmm8, qword [rdx + $60] + movhpd xmm8, qword [rdx + $10] + movq xmm9, qword [rdx + $38] + movhpd xmm9, qword [rdx + $18] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 2 ===== + + // G1 columns (msg: m11,m12 / m5,m15) + movq xmm8, qword [rdx + $58] + movhpd xmm8, qword [rdx + $60] + movq xmm9, qword [rdx + $28] + movhpd xmm9, qword [rdx + $78] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m8,m0 / m2,m13) + movq xmm8, qword [rdx + $40] + movhpd xmm8, qword [rdx] + movq xmm9, qword [rdx + $10] + movhpd xmm9, qword [rdx + $68] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m10,m3 / m7,m9) + movq xmm8, qword [rdx + $50] + movhpd xmm8, qword [rdx + $18] + movq xmm9, qword [rdx + $38] + movhpd xmm9, qword [rdx + $48] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m14,m6 / m1,m4) + movq xmm8, qword [rdx + $70] + movhpd xmm8, qword [rdx + $30] + movq xmm9, qword [rdx + $08] + movhpd xmm9, qword [rdx + $20] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 3 ===== + + // G1 columns (msg: m7,m3 / m13,m11) + movq xmm8, qword [rdx + $38] + movhpd xmm8, qword [rdx + $18] + movq xmm9, qword [rdx + $68] + movhpd xmm9, qword [rdx + $58] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m9,m1 / m12,m14) + movq xmm8, qword [rdx + $48] + movhpd xmm8, qword [rdx + $08] + movq xmm9, qword [rdx + $60] + movhpd xmm9, qword [rdx + $70] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m2,m5 / m4,m15) + movq xmm8, qword [rdx + $10] + movhpd xmm8, qword [rdx + $28] + movq xmm9, qword [rdx + $20] + movhpd xmm9, qword [rdx + $78] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m6,m10 / m0,m8) + movq xmm8, qword [rdx + $30] + movhpd xmm8, qword [rdx + $50] + movq xmm9, qword [rdx] + movhpd xmm9, qword [rdx + $40] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 4 ===== + + // G1 columns (msg: m9,m5 / m2,m10) + movq xmm8, qword [rdx + $48] + movhpd xmm8, qword [rdx + $28] + movq xmm9, qword [rdx + $10] + movhpd xmm9, qword [rdx + $50] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m0,m7 / m4,m15) + movq xmm8, qword [rdx] + movhpd xmm8, qword [rdx + $38] + movq xmm9, qword [rdx + $20] + movhpd xmm9, qword [rdx + $78] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m14,m11 / m6,m3) + movq xmm8, qword [rdx + $70] + movhpd xmm8, qword [rdx + $58] + movq xmm9, qword [rdx + $30] + movhpd xmm9, qword [rdx + $18] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m1,m12 / m8,m13) + movq xmm8, qword [rdx + $08] + movhpd xmm8, qword [rdx + $60] + movq xmm9, qword [rdx + $40] + movhpd xmm9, qword [rdx + $68] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 5 ===== + + // G1 columns (msg: m2,m6 / m0,m8) + movq xmm8, qword [rdx + $10] + movhpd xmm8, qword [rdx + $30] + movq xmm9, qword [rdx] + movhpd xmm9, qword [rdx + $40] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m12,m10 / m11,m3) + movq xmm8, qword [rdx + $60] + movhpd xmm8, qword [rdx + $50] + movq xmm9, qword [rdx + $58] + movhpd xmm9, qword [rdx + $18] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m4,m7 / m15,m1) + movq xmm8, qword [rdx + $20] + movhpd xmm8, qword [rdx + $38] + movq xmm9, qword [rdx + $78] + movhpd xmm9, qword [rdx + $08] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m13,m5 / m14,m9) + movq xmm8, qword [rdx + $68] + movhpd xmm8, qword [rdx + $28] + movq xmm9, qword [rdx + $70] + movhpd xmm9, qword [rdx + $48] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 6 ===== + + // G1 columns (msg: m12,m1 / m14,m4) + movq xmm8, qword [rdx + $60] + movhpd xmm8, qword [rdx + $08] + movq xmm9, qword [rdx + $70] + movhpd xmm9, qword [rdx + $20] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m5,m15 / m13,m10) + movq xmm8, qword [rdx + $28] + movhpd xmm8, qword [rdx + $78] + movq xmm9, qword [rdx + $68] + movhpd xmm9, qword [rdx + $50] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m0,m6 / m9,m8) + movq xmm8, qword [rdx] + movhpd xmm8, qword [rdx + $30] + movq xmm9, qword [rdx + $48] + movhpd xmm9, qword [rdx + $40] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m7,m3 / m2,m11) + movq xmm8, qword [rdx + $38] + movhpd xmm8, qword [rdx + $18] + movq xmm9, qword [rdx + $10] + movhpd xmm9, qword [rdx + $58] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 7 ===== + + // G1 columns (msg: m13,m7 / m12,m3) + movq xmm8, qword [rdx + $68] + movhpd xmm8, qword [rdx + $38] + movq xmm9, qword [rdx + $60] + movhpd xmm9, qword [rdx + $18] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m11,m14 / m1,m9) + movq xmm8, qword [rdx + $58] + movhpd xmm8, qword [rdx + $70] + movq xmm9, qword [rdx + $08] + movhpd xmm9, qword [rdx + $48] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m5,m15 / m8,m2) + movq xmm8, qword [rdx + $28] + movhpd xmm8, qword [rdx + $78] + movq xmm9, qword [rdx + $40] + movhpd xmm9, qword [rdx + $10] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m0,m4 / m6,m10) + movq xmm8, qword [rdx] + movhpd xmm8, qword [rdx + $20] + movq xmm9, qword [rdx + $30] + movhpd xmm9, qword [rdx + $50] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 8 ===== + + // G1 columns (msg: m6,m14 / m11,m0) + movq xmm8, qword [rdx + $30] + movhpd xmm8, qword [rdx + $70] + movq xmm9, qword [rdx + $58] + movhpd xmm9, qword [rdx] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m15,m9 / m3,m8) + movq xmm8, qword [rdx + $78] + movhpd xmm8, qword [rdx + $48] + movq xmm9, qword [rdx + $18] + movhpd xmm9, qword [rdx + $40] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m12,m13 / m1,m10) + movq xmm8, qword [rdx + $60] + movhpd xmm8, qword [rdx + $68] + movq xmm9, qword [rdx + $08] + movhpd xmm9, qword [rdx + $50] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m2,m7 / m4,m5) + movq xmm8, qword [rdx + $10] + movhpd xmm8, qword [rdx + $38] + movq xmm9, qword [rdx + $20] + movhpd xmm9, qword [rdx + $28] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 9 ===== + + // G1 columns (msg: m10,m8 / m7,m1) + movq xmm8, qword [rdx + $50] + movhpd xmm8, qword [rdx + $40] + movq xmm9, qword [rdx + $38] + movhpd xmm9, qword [rdx + $08] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m2,m4 / m6,m5) + movq xmm8, qword [rdx + $10] + movhpd xmm8, qword [rdx + $20] + movq xmm9, qword [rdx + $30] + movhpd xmm9, qword [rdx + $28] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m15,m9 / m3,m13) + movq xmm8, qword [rdx + $78] + movhpd xmm8, qword [rdx + $48] + movq xmm9, qword [rdx + $18] + movhpd xmm9, qword [rdx + $68] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m11,m14 / m12,m0) + movq xmm8, qword [rdx + $58] + movhpd xmm8, qword [rdx + $70] + movq xmm9, qword [rdx + $60] + movhpd xmm9, qword [rdx] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 10 ===== + + // G1 columns (msg: m0,m2 / m4,m6) + movq xmm8, qword [rdx] + movhpd xmm8, qword [rdx + $10] + movq xmm9, qword [rdx + $20] + movhpd xmm9, qword [rdx + $30] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m1,m3 / m5,m7) + movq xmm8, qword [rdx + $08] + movhpd xmm8, qword [rdx + $18] + movq xmm9, qword [rdx + $28] + movhpd xmm9, qword [rdx + $38] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m8,m10 / m12,m14) + movq xmm8, qword [rdx + $40] + movhpd xmm8, qword [rdx + $50] + movq xmm9, qword [rdx + $60] + movhpd xmm9, qword [rdx + $70] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m9,m11 / m13,m15) + movq xmm8, qword [rdx + $48] + movhpd xmm8, qword [rdx + $58] + movq xmm9, qword [rdx + $68] + movhpd xmm9, qword [rdx + $78] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // ===== Round 11 ===== + + // G1 columns (msg: m14,m4 / m9,m13) + movq xmm8, qword [rdx + $70] + movhpd xmm8, qword [rdx + $20] + movq xmm9, qword [rdx + $48] + movhpd xmm9, qword [rdx + $68] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 columns (msg: m10,m8 / m15,m6) + movq xmm8, qword [rdx + $50] + movhpd xmm8, qword [rdx + $40] + movq xmm9, qword [rdx + $78] + movhpd xmm9, qword [rdx + $30] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Diagonalize + movdqa xmm8, xmm6 + movdqa xmm9, xmm2 + + movdqa xmm6, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm6 + + movdqa xmm6, xmm7 + shufpd xmm7, xmm8, $01 + shufpd xmm8, xmm6, $01 + movdqa xmm6, xmm7 + movdqa xmm7, xmm8 + + shufpd xmm2, xmm3, $01 + shufpd xmm3, xmm9, $01 + + // G1 diagonals (msg: m1,m0 / m11,m5) + movq xmm8, qword [rdx + $08] + movhpd xmm8, qword [rdx] + movq xmm9, qword [rdx + $58] + movhpd xmm9, qword [rdx + $28] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + pshufd xmm6, xmm6, $B1 + pshufd xmm7, xmm7, $B1 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + db $66, $41, $0F, $38, $00, $D2 // pshufb xmm2, xmm10 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + + // G2 diagonals (msg: m12,m2 / m7,m3) + movq xmm8, qword [rdx + $60] + movhpd xmm8, qword [rdx + $10] + movq xmm9, qword [rdx + $38] + movhpd xmm9, qword [rdx + $18] + paddq xmm0, xmm8 + paddq xmm0, xmm2 + paddq xmm1, xmm9 + paddq xmm1, xmm3 + + pxor xmm6, xmm0 + pxor xmm7, xmm1 + db $66, $41, $0F, $38, $00, $F3 // pshufb xmm6, xmm11 + db $66, $41, $0F, $38, $00, $FB // pshufb xmm7, xmm11 + + paddq xmm4, xmm6 + paddq xmm5, xmm7 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + movdqa xmm8, xmm2 + psrlq xmm8, 63 + paddq xmm2, xmm2 + por xmm2, xmm8 + movdqa xmm9, xmm3 + psrlq xmm9, 63 + paddq xmm3, xmm3 + por xmm3, xmm9 + + // Undiagonalize + movdqa xmm8, xmm4 + movdqa xmm4, xmm5 + movdqa xmm5, xmm8 + + movdqa xmm8, xmm6 + shufpd xmm6, xmm7, $01 + shufpd xmm7, xmm8, $01 + + movdqa xmm8, xmm2 + movdqa xmm2, xmm3 + shufpd xmm2, xmm8, $01 + shufpd xmm8, xmm3, $01 + movdqa xmm3, xmm8 + + // Finalization + pxor xmm0, xmm4 + pxor xmm1, xmm5 + pxor xmm2, xmm6 + pxor xmm3, xmm7 + + // XOR with original state (re-read from memory via movdqu for safe unaligned access) + movdqu xmm8, oword [rcx] + pxor xmm0, xmm8 + movdqu xmm9, oword [rcx + $10] + pxor xmm1, xmm9 + movdqu xmm8, oword [rcx + $20] + pxor xmm2, xmm8 + movdqu xmm9, oword [rcx + $30] + pxor xmm3, xmm9 + + // Store result + movdqu oword [rcx], xmm0 + movdqu oword [rcx + $10], xmm1 + movdqu oword [rcx + $20], xmm2 + movdqu oword [rcx + $30], xmm3 + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc new file mode 100644 index 0000000..09ea743 --- /dev/null +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc @@ -0,0 +1,941 @@ +// AVX2 implementation of BLAKE2s compress (IA-32; VEX-encoded 128-bit, fully +// unrolled 10 rounds). Same structure as Blake2SCompressAvx2_x86_64.inc, +// with the rot8 mask read as a VEX memory operand per site (IA-32 has only +// xmm0-7, so no register is free to keep it resident; VEX memory operands +// are read unaligned, so the Pascal const needs no special alignment). +// IA-32: after HlpSimdProc5Begin_i386 - ebx = state ptr, esi = msg ptr, +// edi = counter+flags ptr, eax = IV ptr, ecx = byte-rotation masks ptr +// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16). +// Uses xmm0-xmm7; xmm6/xmm7 saved/restored defensively (volatile on IA-32). +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), +// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), xmm7 = rot16 mask. +// Rotations: ROT16 via vpshufb against the resident xmm7 mask, ROT8 via +// vpshufb against the [ecx+$10] memory operand, ROT12/7 via shift+or +// (not byte-aligned; shifts are the known-best form). +// 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves, HashLib +// Blake2SCompressAvx2_x86_64.inc. + + // Defensive save of xmm6/xmm7 (volatile on IA-32; saved like the + // SSE2 sibling to be safe under every RTL) + sub esp, $20 + db $C5, $FA, $7F, $34, $24 // vmovdqu oword [esp], xmm6 + db $C5, $FA, $7F, $7C, $24, $10 // vmovdqu oword [esp + $10], xmm7 + + + // Load byte-rotation masks (resident for the whole kernel) + db $C5, $FA, $6F, $39 // vmovdqu xmm7, oword [ecx] + + // Initialize working vector + db $C5, $FA, $6F, $03 // vmovdqu xmm0, oword [ebx] + db $C5, $FA, $6F, $4B, $10 // vmovdqu xmm1, oword [ebx + $10] + db $C5, $FA, $6F, $10 // vmovdqu xmm2, oword [eax] + db $C5, $FA, $6F, $58, $10 // vmovdqu xmm3, oword [eax + $10] + + // XOR d with counter and flags + db $C5, $FA, $6F, $27 // vmovdqu xmm4, oword [edi] + db $C5, $E1, $EF, $DC // vpxor xmm3, xmm3, xmm4 + + // ===== Round 0 ===== + + // G1 columns (msg: m0,m2,m4,m6) + db $C5, $F9, $6E, $26 // vmovd xmm4, dword [esi] + db $C5, $F9, $6E, $6E, $08 // vmovd xmm5, dword [esi + $8] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $10 // vmovd xmm5, dword [esi + $10] + db $C5, $F9, $6E, $76, $18 // vmovd xmm6, dword [esi + $18] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m1,m3,m5,m7) + db $C5, $F9, $6E, $66, $04 // vmovd xmm4, dword [esi + $4] + db $C5, $F9, $6E, $6E, $0C // vmovd xmm5, dword [esi + $C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $14 // vmovd xmm5, dword [esi + $14] + db $C5, $F9, $6E, $76, $1C // vmovd xmm6, dword [esi + $1C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m14,m8,m10,m12) + db $C5, $F9, $6E, $66, $38 // vmovd xmm4, dword [esi + $38] + db $C5, $F9, $6E, $6E, $20 // vmovd xmm5, dword [esi + $20] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $28 // vmovd xmm5, dword [esi + $28] + db $C5, $F9, $6E, $76, $30 // vmovd xmm6, dword [esi + $30] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m15,m9,m11,m13) + db $C5, $F9, $6E, $66, $3C // vmovd xmm4, dword [esi + $3C] + db $C5, $F9, $6E, $6E, $24 // vmovd xmm5, dword [esi + $24] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $2C // vmovd xmm5, dword [esi + $2C] + db $C5, $F9, $6E, $76, $34 // vmovd xmm6, dword [esi + $34] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 1 ===== + + // G1 columns (msg: m14,m4,m9,m13) + db $C5, $F9, $6E, $66, $38 // vmovd xmm4, dword [esi + $38] + db $C5, $F9, $6E, $6E, $10 // vmovd xmm5, dword [esi + $10] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $24 // vmovd xmm5, dword [esi + $24] + db $C5, $F9, $6E, $76, $34 // vmovd xmm6, dword [esi + $34] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m10,m8,m15,m6) + db $C5, $F9, $6E, $66, $28 // vmovd xmm4, dword [esi + $28] + db $C5, $F9, $6E, $6E, $20 // vmovd xmm5, dword [esi + $20] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $3C // vmovd xmm5, dword [esi + $3C] + db $C5, $F9, $6E, $76, $18 // vmovd xmm6, dword [esi + $18] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m5,m1,m0,m11) + db $C5, $F9, $6E, $66, $14 // vmovd xmm4, dword [esi + $14] + db $C5, $F9, $6E, $6E, $04 // vmovd xmm5, dword [esi + $4] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $2E // vmovd xmm5, dword [esi] + db $C5, $F9, $6E, $76, $2C // vmovd xmm6, dword [esi + $2C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m3,m12,m2,m7) + db $C5, $F9, $6E, $66, $0C // vmovd xmm4, dword [esi + $C] + db $C5, $F9, $6E, $6E, $30 // vmovd xmm5, dword [esi + $30] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $08 // vmovd xmm5, dword [esi + $8] + db $C5, $F9, $6E, $76, $1C // vmovd xmm6, dword [esi + $1C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 2 ===== + + // G1 columns (msg: m11,m12,m5,m15) + db $C5, $F9, $6E, $66, $2C // vmovd xmm4, dword [esi + $2C] + db $C5, $F9, $6E, $6E, $30 // vmovd xmm5, dword [esi + $30] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $14 // vmovd xmm5, dword [esi + $14] + db $C5, $F9, $6E, $76, $3C // vmovd xmm6, dword [esi + $3C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m8,m0,m2,m13) + db $C5, $F9, $6E, $66, $20 // vmovd xmm4, dword [esi + $20] + db $C5, $F9, $6E, $2E // vmovd xmm5, dword [esi] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $08 // vmovd xmm5, dword [esi + $8] + db $C5, $F9, $6E, $76, $34 // vmovd xmm6, dword [esi + $34] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m9,m10,m3,m7) + db $C5, $F9, $6E, $66, $24 // vmovd xmm4, dword [esi + $24] + db $C5, $F9, $6E, $6E, $28 // vmovd xmm5, dword [esi + $28] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $0C // vmovd xmm5, dword [esi + $C] + db $C5, $F9, $6E, $76, $1C // vmovd xmm6, dword [esi + $1C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m4,m14,m6,m1) + db $C5, $F9, $6E, $66, $10 // vmovd xmm4, dword [esi + $10] + db $C5, $F9, $6E, $6E, $38 // vmovd xmm5, dword [esi + $38] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $18 // vmovd xmm5, dword [esi + $18] + db $C5, $F9, $6E, $76, $04 // vmovd xmm6, dword [esi + $4] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 3 ===== + + // G1 columns (msg: m7,m3,m13,m11) + db $C5, $F9, $6E, $66, $1C // vmovd xmm4, dword [esi + $1C] + db $C5, $F9, $6E, $6E, $0C // vmovd xmm5, dword [esi + $C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $34 // vmovd xmm5, dword [esi + $34] + db $C5, $F9, $6E, $76, $2C // vmovd xmm6, dword [esi + $2C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m9,m1,m12,m14) + db $C5, $F9, $6E, $66, $24 // vmovd xmm4, dword [esi + $24] + db $C5, $F9, $6E, $6E, $04 // vmovd xmm5, dword [esi + $4] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $30 // vmovd xmm5, dword [esi + $30] + db $C5, $F9, $6E, $76, $38 // vmovd xmm6, dword [esi + $38] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m15,m2,m5,m4) + db $C5, $F9, $6E, $66, $3C // vmovd xmm4, dword [esi + $3C] + db $C5, $F9, $6E, $6E, $08 // vmovd xmm5, dword [esi + $8] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $14 // vmovd xmm5, dword [esi + $14] + db $C5, $F9, $6E, $76, $10 // vmovd xmm6, dword [esi + $10] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m8,m6,m10,m0) + db $C5, $F9, $6E, $66, $20 // vmovd xmm4, dword [esi + $20] + db $C5, $F9, $6E, $6E, $18 // vmovd xmm5, dword [esi + $18] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $28 // vmovd xmm5, dword [esi + $28] + db $C5, $F9, $6E, $36 // vmovd xmm6, dword [esi] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 4 ===== + + // G1 columns (msg: m9,m5,m2,m10) + db $C5, $F9, $6E, $66, $24 // vmovd xmm4, dword [esi + $24] + db $C5, $F9, $6E, $6E, $14 // vmovd xmm5, dword [esi + $14] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $08 // vmovd xmm5, dword [esi + $8] + db $C5, $F9, $6E, $76, $28 // vmovd xmm6, dword [esi + $28] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m0,m7,m4,m15) + db $C5, $F9, $6E, $26 // vmovd xmm4, dword [esi] + db $C5, $F9, $6E, $6E, $1C // vmovd xmm5, dword [esi + $1C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $10 // vmovd xmm5, dword [esi + $10] + db $C5, $F9, $6E, $76, $3C // vmovd xmm6, dword [esi + $3C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m3,m14,m11,m6) + db $C5, $F9, $6E, $66, $0C // vmovd xmm4, dword [esi + $C] + db $C5, $F9, $6E, $6E, $38 // vmovd xmm5, dword [esi + $38] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $2C // vmovd xmm5, dword [esi + $2C] + db $C5, $F9, $6E, $76, $18 // vmovd xmm6, dword [esi + $18] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m13,m1,m12,m8) + db $C5, $F9, $6E, $66, $34 // vmovd xmm4, dword [esi + $34] + db $C5, $F9, $6E, $6E, $04 // vmovd xmm5, dword [esi + $4] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $30 // vmovd xmm5, dword [esi + $30] + db $C5, $F9, $6E, $76, $20 // vmovd xmm6, dword [esi + $20] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 5 ===== + + // G1 columns (msg: m2,m6,m0,m8) + db $C5, $F9, $6E, $66, $08 // vmovd xmm4, dword [esi + $8] + db $C5, $F9, $6E, $6E, $18 // vmovd xmm5, dword [esi + $18] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $2E // vmovd xmm5, dword [esi] + db $C5, $F9, $6E, $76, $20 // vmovd xmm6, dword [esi + $20] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m12,m10,m11,m3) + db $C5, $F9, $6E, $66, $30 // vmovd xmm4, dword [esi + $30] + db $C5, $F9, $6E, $6E, $28 // vmovd xmm5, dword [esi + $28] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $2C // vmovd xmm5, dword [esi + $2C] + db $C5, $F9, $6E, $76, $0C // vmovd xmm6, dword [esi + $C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m1,m4,m7,m15) + db $C5, $F9, $6E, $66, $04 // vmovd xmm4, dword [esi + $4] + db $C5, $F9, $6E, $6E, $10 // vmovd xmm5, dword [esi + $10] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $1C // vmovd xmm5, dword [esi + $1C] + db $C5, $F9, $6E, $76, $3C // vmovd xmm6, dword [esi + $3C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m9,m13,m5,m14) + db $C5, $F9, $6E, $66, $24 // vmovd xmm4, dword [esi + $24] + db $C5, $F9, $6E, $6E, $34 // vmovd xmm5, dword [esi + $34] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $14 // vmovd xmm5, dword [esi + $14] + db $C5, $F9, $6E, $76, $38 // vmovd xmm6, dword [esi + $38] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 6 ===== + + // G1 columns (msg: m12,m1,m14,m4) + db $C5, $F9, $6E, $66, $30 // vmovd xmm4, dword [esi + $30] + db $C5, $F9, $6E, $6E, $04 // vmovd xmm5, dword [esi + $4] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $38 // vmovd xmm5, dword [esi + $38] + db $C5, $F9, $6E, $76, $10 // vmovd xmm6, dword [esi + $10] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m5,m15,m13,m10) + db $C5, $F9, $6E, $66, $14 // vmovd xmm4, dword [esi + $14] + db $C5, $F9, $6E, $6E, $3C // vmovd xmm5, dword [esi + $3C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $34 // vmovd xmm5, dword [esi + $34] + db $C5, $F9, $6E, $76, $28 // vmovd xmm6, dword [esi + $28] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m8,m0,m6,m9) + db $C5, $F9, $6E, $66, $20 // vmovd xmm4, dword [esi + $20] + db $C5, $F9, $6E, $2E // vmovd xmm5, dword [esi] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $18 // vmovd xmm5, dword [esi + $18] + db $C5, $F9, $6E, $76, $24 // vmovd xmm6, dword [esi + $24] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m11,m7,m3,m2) + db $C5, $F9, $6E, $66, $2C // vmovd xmm4, dword [esi + $2C] + db $C5, $F9, $6E, $6E, $1C // vmovd xmm5, dword [esi + $1C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $0C // vmovd xmm5, dword [esi + $C] + db $C5, $F9, $6E, $76, $08 // vmovd xmm6, dword [esi + $8] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 7 ===== + + // G1 columns (msg: m13,m7,m12,m3) + db $C5, $F9, $6E, $66, $34 // vmovd xmm4, dword [esi + $34] + db $C5, $F9, $6E, $6E, $1C // vmovd xmm5, dword [esi + $1C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $30 // vmovd xmm5, dword [esi + $30] + db $C5, $F9, $6E, $76, $0C // vmovd xmm6, dword [esi + $C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m11,m14,m1,m9) + db $C5, $F9, $6E, $66, $2C // vmovd xmm4, dword [esi + $2C] + db $C5, $F9, $6E, $6E, $38 // vmovd xmm5, dword [esi + $38] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $04 // vmovd xmm5, dword [esi + $4] + db $C5, $F9, $6E, $76, $24 // vmovd xmm6, dword [esi + $24] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m2,m5,m15,m8) + db $C5, $F9, $6E, $66, $08 // vmovd xmm4, dword [esi + $8] + db $C5, $F9, $6E, $6E, $14 // vmovd xmm5, dword [esi + $14] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $3C // vmovd xmm5, dword [esi + $3C] + db $C5, $F9, $6E, $76, $20 // vmovd xmm6, dword [esi + $20] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m10,m0,m4,m6) + db $C5, $F9, $6E, $66, $28 // vmovd xmm4, dword [esi + $28] + db $C5, $F9, $6E, $2E // vmovd xmm5, dword [esi] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $10 // vmovd xmm5, dword [esi + $10] + db $C5, $F9, $6E, $76, $18 // vmovd xmm6, dword [esi + $18] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 8 ===== + + // G1 columns (msg: m6,m14,m11,m0) + db $C5, $F9, $6E, $66, $18 // vmovd xmm4, dword [esi + $18] + db $C5, $F9, $6E, $6E, $38 // vmovd xmm5, dword [esi + $38] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $2C // vmovd xmm5, dword [esi + $2C] + db $C5, $F9, $6E, $36 // vmovd xmm6, dword [esi] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m15,m9,m3,m8) + db $C5, $F9, $6E, $66, $3C // vmovd xmm4, dword [esi + $3C] + db $C5, $F9, $6E, $6E, $24 // vmovd xmm5, dword [esi + $24] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $0C // vmovd xmm5, dword [esi + $C] + db $C5, $F9, $6E, $76, $20 // vmovd xmm6, dword [esi + $20] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m10,m12,m13,m1) + db $C5, $F9, $6E, $66, $28 // vmovd xmm4, dword [esi + $28] + db $C5, $F9, $6E, $6E, $30 // vmovd xmm5, dword [esi + $30] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $34 // vmovd xmm5, dword [esi + $34] + db $C5, $F9, $6E, $76, $04 // vmovd xmm6, dword [esi + $4] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m5,m2,m7,m4) + db $C5, $F9, $6E, $66, $14 // vmovd xmm4, dword [esi + $14] + db $C5, $F9, $6E, $6E, $08 // vmovd xmm5, dword [esi + $8] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $1C // vmovd xmm5, dword [esi + $1C] + db $C5, $F9, $6E, $76, $10 // vmovd xmm6, dword [esi + $10] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // ===== Round 9 ===== + + // G1 columns (msg: m10,m8,m7,m1) + db $C5, $F9, $6E, $66, $28 // vmovd xmm4, dword [esi + $28] + db $C5, $F9, $6E, $6E, $20 // vmovd xmm5, dword [esi + $20] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $1C // vmovd xmm5, dword [esi + $1C] + db $C5, $F9, $6E, $76, $04 // vmovd xmm6, dword [esi + $4] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 columns (msg: m2,m4,m6,m5) + db $C5, $F9, $6E, $66, $08 // vmovd xmm4, dword [esi + $8] + db $C5, $F9, $6E, $6E, $10 // vmovd xmm5, dword [esi + $10] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $18 // vmovd xmm5, dword [esi + $18] + db $C5, $F9, $6E, $76, $14 // vmovd xmm6, dword [esi + $14] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Diagonalize + db $C5, $F9, $70, $C0, $93 // vpshufd xmm0, xmm0, $93 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $39 // vpshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m13,m15,m9,m3) + db $C5, $F9, $6E, $66, $34 // vmovd xmm4, dword [esi + $34] + db $C5, $F9, $6E, $6E, $3C // vmovd xmm5, dword [esi + $3C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $24 // vmovd xmm5, dword [esi + $24] + db $C5, $F9, $6E, $76, $0C // vmovd xmm6, dword [esi + $C] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $0C // vpsrld xmm5, xmm1, $C + db $C5, $F1, $72, $F1, $14 // vpslld xmm1, xmm1, $14 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // G2 diagonals (msg: m0,m11,m14,m12) + db $C5, $F9, $6E, $26 // vmovd xmm4, dword [esi] + db $C5, $F9, $6E, $6E, $2C // vmovd xmm5, dword [esi + $2C] + db $C5, $D9, $6C, $E5 // vpunpcklqdq xmm4, xmm4, xmm5 + db $C5, $F9, $6E, $6E, $38 // vmovd xmm5, dword [esi + $38] + db $C5, $F9, $6E, $76, $30 // vmovd xmm6, dword [esi + $30] + db $C5, $D1, $6C, $EE // vpunpcklqdq xmm5, xmm5, xmm6 + db $C5, $D8, $C6, $E5, $88 // vshufps xmm4, xmm4, xmm5, $88 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 + db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 + db $C4, $E2, $61, $00, $59, $10 // vpshufb xmm3, xmm3, oword [ecx + $10] + + db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $D1, $72, $D1, $07 // vpsrld xmm5, xmm1, $7 + db $C5, $F1, $72, $F1, $19 // vpslld xmm1, xmm1, $19 + db $C5, $F1, $EB, $CD // vpor xmm1, xmm1, xmm5 + + // Undiagonalize + db $C5, $F9, $70, $C0, $39 // vpshufd xmm0, xmm0, $39 + db $C5, $F9, $70, $DB, $4E // vpshufd xmm3, xmm3, $4E + db $C5, $F9, $70, $D2, $93 // vpshufd xmm2, xmm2, $93 + + // Finalization: state[i] ^= v[i] ^ v[i+8] + db $C5, $F9, $EF, $C2 // vpxor xmm0, xmm0, xmm2 + db $C5, $F1, $EF, $CB // vpxor xmm1, xmm1, xmm3 + db $C5, $FA, $6F, $23 // vmovdqu xmm4, oword [ebx] + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $FA, $6F, $63, $10 // vmovdqu xmm4, oword [ebx + $10] + db $C5, $F1, $EF, $CC // vpxor xmm1, xmm1, xmm4 + + // Store result + db $C5, $FA, $7F, $03 // vmovdqu oword [ebx], xmm0 + db $C5, $FA, $7F, $4B, $10 // vmovdqu oword [ebx + $10], xmm1 + + db $C5, $F8, $77 // vzeroupper + + + + db $C5, $FA, $6F, $34, $24 // vmovdqu xmm6, oword [esp] + db $C5, $FA, $6F, $7C, $24, $10 // vmovdqu xmm7, oword [esp + $10] + add esp, $20 + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc index 7729069..93381de 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc @@ -1,14 +1,24 @@ // AVX2 implementation of BLAKE2s compress (VEX-encoded 128-bit, fully unrolled 10 rounds). -// Expects MS x64 ABI: rcx = state ptr, rdx = msg ptr, r8 = counter+flags ptr, r9 = IV ptr. -// Uses xmm0-xmm6; xmm6 is MS x64 non-volatile (saved/restored). +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr +// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the +// Pascal const needs no special alignment). +// Uses xmm0-xmm8; xmm6-xmm8 are MS x64 non-volatile (saved/restored). // Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load). +// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), +// xmm7 = rot16 mask, xmm8 = rot8 mask. +// Rotations: ROT16/8 via vpshufb against the resident masks, ROT12/7 via +// shift+or (not byte-aligned; shifts are the known-best form). // 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + // Load byte-rotation masks (resident for the whole kernel) + db $C4, $C1, $7A, $6F, $3A // vmovdqu xmm7, oword [r10] + db $C4, $41, $7A, $6F, $42, $10 // vmovdqu xmm8, oword [r10 + $10] + // Initialize working vector db $C5, $FA, $6F, $01 // vmovdqu xmm0, oword [rcx] db $C5, $FA, $6F, $49, $10 // vmovdqu xmm1, oword [rcx + $10] @@ -32,9 +42,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -53,9 +61,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -79,9 +85,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -100,9 +104,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -128,9 +130,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -149,9 +149,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -175,9 +173,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -196,9 +192,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -224,9 +218,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -245,9 +237,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -271,9 +261,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -292,9 +280,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -320,9 +306,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -341,9 +325,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -367,9 +349,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -388,9 +368,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -416,9 +394,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -437,9 +413,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -463,9 +437,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -484,9 +456,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -512,9 +482,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -533,9 +501,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -559,9 +525,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -580,9 +544,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -608,9 +570,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -629,9 +589,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -655,9 +613,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -676,9 +632,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -704,9 +658,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -725,9 +677,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -751,9 +701,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -772,9 +720,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -800,9 +746,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -821,9 +765,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -847,9 +789,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -868,9 +808,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -896,9 +834,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -917,9 +853,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -943,9 +877,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $10 // vpsrld xmm5, xmm3, 16 - db $C5, $E1, $72, $F3, $10 // vpslld xmm3, xmm3, 16 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 @@ -964,9 +896,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $D1, $72, $D3, $08 // vpsrld xmm5, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + db $C4, $C2, $61, $00, $D8 // vpshufb xmm3, xmm3, xmm8 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc new file mode 100644 index 0000000..6f08ee9 --- /dev/null +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc @@ -0,0 +1,992 @@ +// SSSE3 implementation of BLAKE2s compress (fully unrolled 10 rounds); SSE2 +// sibling: Blake2SCompressSse2_i386.inc. +// IA-32: after HlpSimdProc5Begin_i386 - ebx = state, esi = msg, +// edi = counter+flags, eax = IV, ecx = byte-rotation masks ptr +// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the +// Pascal const needs no special alignment). +// Uses xmm0-xmm7; xmm6/xmm7 saved/restored defensively (volatile on i386). +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), +// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), xmm7 = rot16 mask. +// Rotations: ROT16 via pshufb (db-encoded for broad assembler compatibility) +// against the resident xmm7 mask; ROT8 via a per-site mask reload into the +// xmm5 temp + pshufb (only xmm7 is free); ROT12/7 via psrld/pslld/por +// (not byte-aligned). +// Diagonalize/Undiagonalize via pshufd. +// Message loads via movd + punpcklqdq + shufps. +// Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. + + sub esp, 32 + movdqu oword ptr [esp], xmm6 + movdqu oword ptr [esp + $10], xmm7 + + // Load the rot16 mask (resident; rot8 reloads the xmm5 temp per site) + movdqu xmm7, oword ptr [ecx] + + // Initialize working vector + movdqu xmm0, oword ptr [ebx] + movdqu xmm1, oword ptr [ebx + $10] + movdqu xmm2, oword ptr [eax] + movdqu xmm3, oword ptr [eax + $10] + + // XOR d with counter and flags + movdqu xmm4, oword ptr [edi] + pxor xmm3, xmm4 + + // ===== Round 0 ===== + + // G1 columns (msg: m0,m2,m4,m6) + movd xmm4, dword ptr [esi] + movd xmm5, dword ptr [esi + $08] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $10] + movd xmm6, dword ptr [esi + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m1,m3,m5,m7) + movd xmm4, dword ptr [esi + $04] + movd xmm5, dword ptr [esi + $0C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $14] + movd xmm6, dword ptr [esi + $1C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m14,m8,m10,m12) + movd xmm4, dword ptr [esi + $38] + movd xmm5, dword ptr [esi + $20] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $28] + movd xmm6, dword ptr [esi + $30] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m15,m9,m11,m13) + movd xmm4, dword ptr [esi + $3C] + movd xmm5, dword ptr [esi + $24] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $2C] + movd xmm6, dword ptr [esi + $34] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 1 ===== + + // G1 columns (msg: m14,m4,m9,m13) + movd xmm4, dword ptr [esi + $38] + movd xmm5, dword ptr [esi + $10] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $24] + movd xmm6, dword ptr [esi + $34] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m10,m8,m15,m6) + movd xmm4, dword ptr [esi + $28] + movd xmm5, dword ptr [esi + $20] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $3C] + movd xmm6, dword ptr [esi + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m5,m1,m0,m11) + movd xmm4, dword ptr [esi + $14] + movd xmm5, dword ptr [esi + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi] + movd xmm6, dword ptr [esi + $2C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m3,m12,m2,m7) + movd xmm4, dword ptr [esi + $0C] + movd xmm5, dword ptr [esi + $30] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $08] + movd xmm6, dword ptr [esi + $1C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 2 ===== + + // G1 columns (msg: m11,m12,m5,m15) + movd xmm4, dword ptr [esi + $2C] + movd xmm5, dword ptr [esi + $30] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $14] + movd xmm6, dword ptr [esi + $3C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m8,m0,m2,m13) + movd xmm4, dword ptr [esi + $20] + movd xmm5, dword ptr [esi] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $08] + movd xmm6, dword ptr [esi + $34] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m9,m10,m3,m7) + movd xmm4, dword ptr [esi + $24] + movd xmm5, dword ptr [esi + $28] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $0C] + movd xmm6, dword ptr [esi + $1C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m4,m14,m6,m1) + movd xmm4, dword ptr [esi + $10] + movd xmm5, dword ptr [esi + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $18] + movd xmm6, dword ptr [esi + $04] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 3 ===== + + // G1 columns (msg: m7,m3,m13,m11) + movd xmm4, dword ptr [esi + $1C] + movd xmm5, dword ptr [esi + $0C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $34] + movd xmm6, dword ptr [esi + $2C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m9,m1,m12,m14) + movd xmm4, dword ptr [esi + $24] + movd xmm5, dword ptr [esi + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $30] + movd xmm6, dword ptr [esi + $38] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m15,m2,m5,m4) + movd xmm4, dword ptr [esi + $3C] + movd xmm5, dword ptr [esi + $08] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $14] + movd xmm6, dword ptr [esi + $10] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m8,m6,m10,m0) + movd xmm4, dword ptr [esi + $20] + movd xmm5, dword ptr [esi + $18] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $28] + movd xmm6, dword ptr [esi] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 4 ===== + + // G1 columns (msg: m9,m5,m2,m10) + movd xmm4, dword ptr [esi + $24] + movd xmm5, dword ptr [esi + $14] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $08] + movd xmm6, dword ptr [esi + $28] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m0,m7,m4,m15) + movd xmm4, dword ptr [esi] + movd xmm5, dword ptr [esi + $1C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $10] + movd xmm6, dword ptr [esi + $3C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m3,m14,m11,m6) + movd xmm4, dword ptr [esi + $0C] + movd xmm5, dword ptr [esi + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $2C] + movd xmm6, dword ptr [esi + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m13,m1,m12,m8) + movd xmm4, dword ptr [esi + $34] + movd xmm5, dword ptr [esi + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $30] + movd xmm6, dword ptr [esi + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 5 ===== + + // G1 columns (msg: m2,m6,m0,m8) + movd xmm4, dword ptr [esi + $08] + movd xmm5, dword ptr [esi + $18] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi] + movd xmm6, dword ptr [esi + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m12,m10,m11,m3) + movd xmm4, dword ptr [esi + $30] + movd xmm5, dword ptr [esi + $28] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $2C] + movd xmm6, dword ptr [esi + $0C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m1,m4,m7,m15) + movd xmm4, dword ptr [esi + $04] + movd xmm5, dword ptr [esi + $10] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $1C] + movd xmm6, dword ptr [esi + $3C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m9,m13,m5,m14) + movd xmm4, dword ptr [esi + $24] + movd xmm5, dword ptr [esi + $34] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $14] + movd xmm6, dword ptr [esi + $38] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 6 ===== + + // G1 columns (msg: m12,m1,m14,m4) + movd xmm4, dword ptr [esi + $30] + movd xmm5, dword ptr [esi + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $38] + movd xmm6, dword ptr [esi + $10] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m5,m15,m13,m10) + movd xmm4, dword ptr [esi + $14] + movd xmm5, dword ptr [esi + $3C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $34] + movd xmm6, dword ptr [esi + $28] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m8,m0,m6,m9) + movd xmm4, dword ptr [esi + $20] + movd xmm5, dword ptr [esi] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $18] + movd xmm6, dword ptr [esi + $24] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m11,m7,m3,m2) + movd xmm4, dword ptr [esi + $2C] + movd xmm5, dword ptr [esi + $1C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $0C] + movd xmm6, dword ptr [esi + $08] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 7 ===== + + // G1 columns (msg: m13,m7,m12,m3) + movd xmm4, dword ptr [esi + $34] + movd xmm5, dword ptr [esi + $1C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $30] + movd xmm6, dword ptr [esi + $0C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m11,m14,m1,m9) + movd xmm4, dword ptr [esi + $2C] + movd xmm5, dword ptr [esi + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $04] + movd xmm6, dword ptr [esi + $24] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m2,m5,m15,m8) + movd xmm4, dword ptr [esi + $08] + movd xmm5, dword ptr [esi + $14] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $3C] + movd xmm6, dword ptr [esi + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m10,m0,m4,m6) + movd xmm4, dword ptr [esi + $28] + movd xmm5, dword ptr [esi] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $10] + movd xmm6, dword ptr [esi + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 8 ===== + + // G1 columns (msg: m6,m14,m11,m0) + movd xmm4, dword ptr [esi + $18] + movd xmm5, dword ptr [esi + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $2C] + movd xmm6, dword ptr [esi] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m15,m9,m3,m8) + movd xmm4, dword ptr [esi + $3C] + movd xmm5, dword ptr [esi + $24] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $0C] + movd xmm6, dword ptr [esi + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m10,m12,m13,m1) + movd xmm4, dword ptr [esi + $28] + movd xmm5, dword ptr [esi + $30] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $34] + movd xmm6, dword ptr [esi + $04] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m5,m2,m7,m4) + movd xmm4, dword ptr [esi + $14] + movd xmm5, dword ptr [esi + $08] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $1C] + movd xmm6, dword ptr [esi + $10] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 9 ===== + + // G1 columns (msg: m10,m8,m7,m1) + movd xmm4, dword ptr [esi + $28] + movd xmm5, dword ptr [esi + $20] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $1C] + movd xmm6, dword ptr [esi + $04] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m2,m4,m6,m5) + movd xmm4, dword ptr [esi + $08] + movd xmm5, dword ptr [esi + $10] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $18] + movd xmm6, dword ptr [esi + $14] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m13,m15,m9,m3) + movd xmm4, dword ptr [esi + $34] + movd xmm5, dword ptr [esi + $3C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $24] + movd xmm6, dword ptr [esi + $0C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m0,m11,m14,m12) + movd xmm4, dword ptr [esi] + movd xmm5, dword ptr [esi + $2C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword ptr [esi + $38] + movd xmm6, dword ptr [esi + $30] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + movdqu xmm5, oword ptr [ecx + $10] + db $66, $0F, $38, $00, $DD // pshufb xmm3, xmm5 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // Finalization: state[i] ^= v[i] ^ v[i+8] + pxor xmm0, xmm2 + pxor xmm1, xmm3 + movdqu xmm4, oword ptr [ebx] + pxor xmm0, xmm4 + movdqu xmm4, oword ptr [ebx + $10] + pxor xmm1, xmm4 + + // Store result + movdqu oword ptr [ebx], xmm0 + movdqu oword ptr [ebx + $10], xmm1 + + movdqu xmm6, oword ptr [esp] + movdqu xmm7, oword ptr [esp + $10] + add esp, 32 + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc new file mode 100644 index 0000000..84004ac --- /dev/null +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc @@ -0,0 +1,965 @@ +// SSSE3 implementation of BLAKE2s compress (fully unrolled 10 rounds); SSE2 +// sibling: Blake2SCompressSse2_x86_64.inc. +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr +// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the +// Pascal const needs no special alignment). +// Uses xmm0-xmm8; xmm6-xmm8 are MS x64 non-volatile (saved/restored). +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), +// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), +// xmm7 = rot16 mask, xmm8 = rot8 mask. +// Rotations: ROT16/8 via pshufb (db-encoded for broad assembler compatibility) +// against the resident masks; ROT12/7 via psrld/pslld/por (not byte-aligned). +// Diagonalize/Undiagonalize via pshufd. +// Message loads via movd + punpcklqdq + shufps. +// Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + // Load byte-rotation masks (resident for the whole kernel) + db $F3, $41, $0F, $6F, $3A // movdqu xmm7, oword [r10] + db $F3, $45, $0F, $6F, $42, $10 // movdqu xmm8, oword [r10 + $10] + + // Initialize working vector + movdqu xmm0, oword [rcx] + movdqu xmm1, oword [rcx + $10] + movdqu xmm2, oword [r9] + movdqu xmm3, oword [r9 + $10] + + // XOR d with counter and flags + movdqu xmm4, oword [r8] + pxor xmm3, xmm4 + + // ===== Round 0 ===== + + // G1 columns (msg: m0,m2,m4,m6) + movd xmm4, dword [rdx] + movd xmm5, dword [rdx + $08] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $10] + movd xmm6, dword [rdx + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m1,m3,m5,m7) + movd xmm4, dword [rdx + $04] + movd xmm5, dword [rdx + $0C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $14] + movd xmm6, dword [rdx + $1C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m14,m8,m10,m12) + movd xmm4, dword [rdx + $38] + movd xmm5, dword [rdx + $20] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $28] + movd xmm6, dword [rdx + $30] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m15,m9,m11,m13) + movd xmm4, dword [rdx + $3C] + movd xmm5, dword [rdx + $24] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $2C] + movd xmm6, dword [rdx + $34] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 1 ===== + + // G1 columns (msg: m14,m4,m9,m13) + movd xmm4, dword [rdx + $38] + movd xmm5, dword [rdx + $10] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $24] + movd xmm6, dword [rdx + $34] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m10,m8,m15,m6) + movd xmm4, dword [rdx + $28] + movd xmm5, dword [rdx + $20] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $3C] + movd xmm6, dword [rdx + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m5,m1,m0,m11) + movd xmm4, dword [rdx + $14] + movd xmm5, dword [rdx + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx] + movd xmm6, dword [rdx + $2C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m3,m12,m2,m7) + movd xmm4, dword [rdx + $0C] + movd xmm5, dword [rdx + $30] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $08] + movd xmm6, dword [rdx + $1C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 2 ===== + + // G1 columns (msg: m11,m12,m5,m15) + movd xmm4, dword [rdx + $2C] + movd xmm5, dword [rdx + $30] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $14] + movd xmm6, dword [rdx + $3C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m8,m0,m2,m13) + movd xmm4, dword [rdx + $20] + movd xmm5, dword [rdx] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $08] + movd xmm6, dword [rdx + $34] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m9,m10,m3,m7) + movd xmm4, dword [rdx + $24] + movd xmm5, dword [rdx + $28] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $0C] + movd xmm6, dword [rdx + $1C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m4,m14,m6,m1) + movd xmm4, dword [rdx + $10] + movd xmm5, dword [rdx + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $18] + movd xmm6, dword [rdx + $04] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 3 ===== + + // G1 columns (msg: m7,m3,m13,m11) + movd xmm4, dword [rdx + $1C] + movd xmm5, dword [rdx + $0C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $34] + movd xmm6, dword [rdx + $2C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m9,m1,m12,m14) + movd xmm4, dword [rdx + $24] + movd xmm5, dword [rdx + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $30] + movd xmm6, dword [rdx + $38] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m15,m2,m5,m4) + movd xmm4, dword [rdx + $3C] + movd xmm5, dword [rdx + $08] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $14] + movd xmm6, dword [rdx + $10] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m8,m6,m10,m0) + movd xmm4, dword [rdx + $20] + movd xmm5, dword [rdx + $18] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $28] + movd xmm6, dword [rdx] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 4 ===== + + // G1 columns (msg: m9,m5,m2,m10) + movd xmm4, dword [rdx + $24] + movd xmm5, dword [rdx + $14] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $08] + movd xmm6, dword [rdx + $28] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m0,m7,m4,m15) + movd xmm4, dword [rdx] + movd xmm5, dword [rdx + $1C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $10] + movd xmm6, dword [rdx + $3C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m3,m14,m11,m6) + movd xmm4, dword [rdx + $0C] + movd xmm5, dword [rdx + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $2C] + movd xmm6, dword [rdx + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m13,m1,m12,m8) + movd xmm4, dword [rdx + $34] + movd xmm5, dword [rdx + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $30] + movd xmm6, dword [rdx + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 5 ===== + + // G1 columns (msg: m2,m6,m0,m8) + movd xmm4, dword [rdx + $08] + movd xmm5, dword [rdx + $18] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx] + movd xmm6, dword [rdx + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m12,m10,m11,m3) + movd xmm4, dword [rdx + $30] + movd xmm5, dword [rdx + $28] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $2C] + movd xmm6, dword [rdx + $0C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m1,m4,m7,m15) + movd xmm4, dword [rdx + $04] + movd xmm5, dword [rdx + $10] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $1C] + movd xmm6, dword [rdx + $3C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m9,m13,m5,m14) + movd xmm4, dword [rdx + $24] + movd xmm5, dword [rdx + $34] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $14] + movd xmm6, dword [rdx + $38] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 6 ===== + + // G1 columns (msg: m12,m1,m14,m4) + movd xmm4, dword [rdx + $30] + movd xmm5, dword [rdx + $04] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $38] + movd xmm6, dword [rdx + $10] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m5,m15,m13,m10) + movd xmm4, dword [rdx + $14] + movd xmm5, dword [rdx + $3C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $34] + movd xmm6, dword [rdx + $28] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m8,m0,m6,m9) + movd xmm4, dword [rdx + $20] + movd xmm5, dword [rdx] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $18] + movd xmm6, dword [rdx + $24] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m11,m7,m3,m2) + movd xmm4, dword [rdx + $2C] + movd xmm5, dword [rdx + $1C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $0C] + movd xmm6, dword [rdx + $08] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 7 ===== + + // G1 columns (msg: m13,m7,m12,m3) + movd xmm4, dword [rdx + $34] + movd xmm5, dword [rdx + $1C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $30] + movd xmm6, dword [rdx + $0C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m11,m14,m1,m9) + movd xmm4, dword [rdx + $2C] + movd xmm5, dword [rdx + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $04] + movd xmm6, dword [rdx + $24] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m2,m5,m15,m8) + movd xmm4, dword [rdx + $08] + movd xmm5, dword [rdx + $14] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $3C] + movd xmm6, dword [rdx + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m10,m0,m4,m6) + movd xmm4, dword [rdx + $28] + movd xmm5, dword [rdx] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $10] + movd xmm6, dword [rdx + $18] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 8 ===== + + // G1 columns (msg: m6,m14,m11,m0) + movd xmm4, dword [rdx + $18] + movd xmm5, dword [rdx + $38] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $2C] + movd xmm6, dword [rdx] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m15,m9,m3,m8) + movd xmm4, dword [rdx + $3C] + movd xmm5, dword [rdx + $24] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $0C] + movd xmm6, dword [rdx + $20] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m10,m12,m13,m1) + movd xmm4, dword [rdx + $28] + movd xmm5, dword [rdx + $30] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $34] + movd xmm6, dword [rdx + $04] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m5,m2,m7,m4) + movd xmm4, dword [rdx + $14] + movd xmm5, dword [rdx + $08] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $1C] + movd xmm6, dword [rdx + $10] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Round 9 ===== + + // G1 columns (msg: m10,m8,m7,m1) + movd xmm4, dword [rdx + $28] + movd xmm5, dword [rdx + $20] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $1C] + movd xmm6, dword [rdx + $04] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 columns (msg: m2,m4,m6,m5) + movd xmm4, dword [rdx + $08] + movd xmm5, dword [rdx + $10] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $18] + movd xmm6, dword [rdx + $14] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // G1 diagonals (msg: m13,m15,m9,m3) + movd xmm4, dword [rdx + $34] + movd xmm5, dword [rdx + $3C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $24] + movd xmm6, dword [rdx + $0C] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 12 + pslld xmm5, 20 + por xmm1, xmm5 + + // G2 diagonals (msg: m0,m11,m14,m12) + movd xmm4, dword [rdx] + movd xmm5, dword [rdx + $2C] + punpcklqdq xmm4, xmm5 + movd xmm5, dword [rdx + $38] + movd xmm6, dword [rdx + $30] + punpcklqdq xmm5, xmm6 + shufps xmm4, xmm5, $88 + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm5, xmm1 + psrld xmm1, 7 + pslld xmm5, 25 + por xmm1, xmm5 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // Finalization: state[i] ^= v[i] ^ v[i+8] + pxor xmm0, xmm2 + pxor xmm1, xmm3 + movdqu xmm4, oword [rcx] + pxor xmm0, xmm4 + movdqu xmm4, oword [rcx + $10] + pxor xmm1, xmm4 + + // Store result + movdqu oword [rcx], xmm0 + movdqu oword [rcx + $10], xmm1 + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc index 18dee8b..b622420 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc @@ -2,14 +2,21 @@ // message scheduling). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE3-team/BLAKE3 official SSE2/AVX2 implementation. -// Expects MS x64 ABI: rcx = state ptr, rdx = msg ptr, r8 = CV ptr, r9 = counterflags ptr. +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// r8 = CV ptr, r9 = counterflags ptr, r10 = byte-rotation masks ptr +// (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +32; read unaligned, so the +// Pascal const needs no special alignment). // Register map: xmm0 = a, xmm1 = b, xmm2 = c, xmm3 = d, -// xmm4 = m0, xmm5 = m1, xmm6 = m2, xmm7 = m3, xmm8/xmm9 = temp, xmm11/xmm14 = temp. +// xmm4 = m0, xmm5 = m1, xmm6 = m2, xmm7 = m3, xmm8/xmm9 = temp, xmm11/xmm14 = temp, +// xmm10 = rot16 mask, xmm12 = rot8 mask. +// Rotations: ROT16/8 via vpshufb against the resident masks, ROT12/7 via +// shift+or (not byte-aligned; shifts are the known-best form). // 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. // Blend emulations use vshufps+vpshufd (blend_0xCC) and vpunpckhdq+vshufps (blend_0xC0), // avoiding the need for mask constants. // -// MS x64 non-volatile saves: xmm6, xmm7, xmm8, xmm9, xmm11, xmm14. +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV). // // Stack layout (sub rsp, 120): // [rsp + 0.. 95]: xmm6/xmm7/xmm8/xmm9/xmm11/xmm14 save area (6 * 16) @@ -18,6 +25,10 @@ {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + // Load byte-rotation masks (resident for the whole kernel) + db $C4, $41, $7A, $6F, $12 // vmovdqu xmm10, oword [r10] + db $C4, $41, $7A, $6F, $62, $20 // vmovdqu xmm12, oword [r10 + $20] + sub rsp, 24 mov eax, $6A09E667 @@ -56,8 +67,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -67,9 +77,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -83,8 +91,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -94,9 +101,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -133,8 +138,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -144,9 +148,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -160,8 +162,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -171,9 +172,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -210,8 +209,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -221,9 +219,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -237,8 +233,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -248,9 +243,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -287,8 +280,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -298,9 +290,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -314,8 +304,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -325,9 +314,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -364,8 +351,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -375,9 +361,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -391,8 +375,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -402,9 +385,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -441,8 +422,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -452,9 +432,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -468,8 +446,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -479,9 +456,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -518,8 +493,7 @@ db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -529,9 +503,7 @@ db $C5, $F9, $FE, $C5 // vpaddd xmm0, xmm0, xmm5 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 @@ -545,8 +517,7 @@ db $C5, $F9, $FE, $C6 // vpaddd xmm0, xmm0, xmm6 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $FB, $70, $DB, $B1 // vpshuflw xmm3, xmm3, $B1 - db $C5, $FA, $70, $DB, $B1 // vpshufhw xmm3, xmm3, $B1 + db $C4, $C2, $61, $00, $DA // vpshufb xmm3, xmm3, xmm10 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $14 // vpslld xmm11, xmm1, 20 @@ -556,9 +527,7 @@ db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 db $C5, $F9, $FE, $C1 // vpaddd xmm0, xmm0, xmm1 db $C5, $E1, $EF, $D8 // vpxor xmm3, xmm3, xmm0 - db $C5, $89, $72, $D3, $08 // vpsrld xmm14, xmm3, 8 - db $C5, $E1, $72, $F3, $18 // vpslld xmm3, xmm3, 24 - db $C4, $C1, $61, $EF, $DE // vpxor xmm3, xmm3, xmm14 + db $C4, $C2, $61, $00, $DC // vpshufb xmm3, xmm3, xmm12 db $C5, $E9, $FE, $D3 // vpaddd xmm2, xmm2, xmm3 db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 db $C5, $A1, $72, $F1, $19 // vpslld xmm11, xmm1, 25 diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc new file mode 100644 index 0000000..705d4c5 --- /dev/null +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc @@ -0,0 +1,590 @@ +// SSSE3 implementation of BLAKE3 compress (7 rounds with register-based message +// scheduling); SSE2 sibling: Blake3CompressSse2_x86_64.inc. +// Reference: BLAKE3-team/BLAKE3 official SSE2/SSE4.1 implementations. +// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// r8 = CV ptr, r9 = counterflags ptr, r10 = byte-rotation masks ptr +// (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +32; read unaligned, so the +// Pascal const needs no special alignment). +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), +// xmm4 = m0 (col G1 msg), xmm5 = m1 (col G2 msg), xmm6 = m2 (diag G1 msg), +// xmm7 = m3 (diag G2 msg), xmm8/xmm9 = temp (msg perm), xmm11/xmm14 = temp (rotations), +// xmm10 = rot16 mask, xmm12 = rot8 mask. +// Rotations: rot16/8 via pshufb (db-encoded for broad assembler compatibility) +// against the resident masks; rot12/7 via pslld/psrld/por (not byte-aligned). +// Message scheduling: all 16 words kept in xmm4-7, permuted between rounds using +// shufps/pshufd (blend_0xCC emulated via shufps+pshufd, blend_0xC0 via punpckhdq+shufps). +// Diagonalize/Undiagonalize via pshufd (row1 unrotated, per sneves optimization). +// +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV). + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + // Load byte-rotation masks (resident for the whole kernel) + db $F3, $45, $0F, $6F, $12 // movdqu xmm10, oword [r10] + db $F3, $45, $0F, $6F, $62, $20 // movdqu xmm12, oword [r10 + $20] + + sub rsp, 24 + + mov eax, $6A09E667 + mov dword ptr [rsp + $00], eax + mov eax, $BB67AE85 + mov dword ptr [rsp + $04], eax + mov eax, $3C6EF372 + mov dword ptr [rsp + $08], eax + mov eax, $A54FF53A + mov dword ptr [rsp + $0C], eax + movdqa xmm2, oword [rsp + $00] + + // Initialize state: a=CV[0..3], b=CV[4..7], c=IV[0..3], d=CounterFlags + movdqu xmm0, oword [r8] + movdqu xmm1, oword [r8 + $10] + // xmm2 = IV (loaded above) + movdqu xmm3, oword [r9] + + // Load and reorder message into 4 register pairs for round structure. + // After reorder: xmm4={m0,m2,m4,m6}, xmm5={m1,m3,m5,m7}, + // xmm6={m14,m8,m10,m12} (rotated), xmm7={m15,m9,m11,m13} (rotated). + movdqu xmm4, oword [rdx] + movdqu xmm5, oword [rdx + $10] + movdqa xmm8, xmm4 + shufps xmm4, xmm5, $88 + shufps xmm8, xmm5, $DD + movdqa xmm5, xmm8 + + movdqu xmm6, oword [rdx + $20] + movdqu xmm7, oword [rdx + $30] + movdqa xmm8, xmm6 + shufps xmm6, xmm7, $88 + pshufd xmm6, xmm6, $93 + shufps xmm8, xmm7, $DD + pshufd xmm7, xmm8, $93 + + // ===== Round 0 ===== + + // Column G1 (msg xmm4) + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + // Column G2 (msg xmm5) + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + // Diagonalize + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + // Diagonal G1 (msg xmm6) + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + // Diagonal G2 (msg xmm7) + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + // Undiagonalize + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Message Permutation 0->1 ===== + movdqa xmm8, xmm4 + shufps xmm8, xmm5, $D6 + pshufd xmm9, xmm4, $0F + pshufd xmm4, xmm8, $39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, $FA + shufps xmm9, xmm8, $D8 + pshufd xmm9, xmm9, $D8 + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + movdqa xmm14, xmm8 + punpckhdq xmm14, xmm6 + shufps xmm8, xmm14, $C4 + pshufd xmm8, xmm8, $78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, $1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + + // ===== Round 1 ===== + + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Message Permutation 1->2 ===== + movdqa xmm8, xmm4 + shufps xmm8, xmm5, $D6 + pshufd xmm9, xmm4, $0F + pshufd xmm4, xmm8, $39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, $FA + shufps xmm9, xmm8, $D8 + pshufd xmm9, xmm9, $D8 + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + movdqa xmm14, xmm8 + punpckhdq xmm14, xmm6 + shufps xmm8, xmm14, $C4 + pshufd xmm8, xmm8, $78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, $1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + + // ===== Round 2 ===== + + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Message Permutation 2->3 ===== + movdqa xmm8, xmm4 + shufps xmm8, xmm5, $D6 + pshufd xmm9, xmm4, $0F + pshufd xmm4, xmm8, $39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, $FA + shufps xmm9, xmm8, $D8 + pshufd xmm9, xmm9, $D8 + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + movdqa xmm14, xmm8 + punpckhdq xmm14, xmm6 + shufps xmm8, xmm14, $C4 + pshufd xmm8, xmm8, $78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, $1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + + // ===== Round 3 ===== + + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Message Permutation 3->4 ===== + movdqa xmm8, xmm4 + shufps xmm8, xmm5, $D6 + pshufd xmm9, xmm4, $0F + pshufd xmm4, xmm8, $39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, $FA + shufps xmm9, xmm8, $D8 + pshufd xmm9, xmm9, $D8 + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + movdqa xmm14, xmm8 + punpckhdq xmm14, xmm6 + shufps xmm8, xmm14, $C4 + pshufd xmm8, xmm8, $78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, $1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + + // ===== Round 4 ===== + + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Message Permutation 4->5 ===== + movdqa xmm8, xmm4 + shufps xmm8, xmm5, $D6 + pshufd xmm9, xmm4, $0F + pshufd xmm4, xmm8, $39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, $FA + shufps xmm9, xmm8, $D8 + pshufd xmm9, xmm9, $D8 + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + movdqa xmm14, xmm8 + punpckhdq xmm14, xmm6 + shufps xmm8, xmm14, $C4 + pshufd xmm8, xmm8, $78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, $1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + + // ===== Round 5 ===== + + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Message Permutation 5->6 ===== + movdqa xmm8, xmm4 + shufps xmm8, xmm5, $D6 + pshufd xmm9, xmm4, $0F + pshufd xmm4, xmm8, $39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, $FA + shufps xmm9, xmm8, $D8 + pshufd xmm9, xmm9, $D8 + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + movdqa xmm14, xmm8 + punpckhdq xmm14, xmm6 + shufps xmm8, xmm14, $C4 + pshufd xmm8, xmm8, $78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, $1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + + // ===== Round 6 ===== + + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $93 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $39 + + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DA // pshufb xmm3, xmm10 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + + pshufd xmm0, xmm0, $39 + pshufd xmm3, xmm3, $4E + pshufd xmm2, xmm2, $93 + + // ===== Finalization ===== + // BLAKE3: state[0..7] = a,b XOR c,d; state[8..15] = c,d XOR CV + pxor xmm0, xmm2 + pxor xmm1, xmm3 + movdqu xmm4, oword [r8] + movdqu xmm5, oword [r8 + $10] + pxor xmm2, xmm4 + pxor xmm3, xmm5 + + // Store all 16 words + movdqu oword [rcx], xmm0 + movdqu oword [rcx + $10], xmm1 + movdqu oword [rcx + $20], xmm2 + movdqu oword [rcx + $30], xmm3 + + add rsp, 24 + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc new file mode 100644 index 0000000..56fc93a --- /dev/null +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc @@ -0,0 +1,1622 @@ +// SSSE3 implementation of BLAKE3 hash4: processes 4 independent chunks +// simultaneously; SSE2 sibling: Blake3Hash4Sse2_x86_64.inc. +// Reference: BLAKE3-team/BLAKE3 official SSE2/SSE4.1 implementations +// (blake3_hash_many). +// Each XMM register holds the same 32-bit word from 4 different chunks (inter-chunk SIMD). +// 7 rounds per block fully unrolled; 16-block loop with branch for chunk start/end flags. +// +// After HlpSimdProc7Begin_x86_64.inc: +// rcx = AInput, rdx = AKey, r8 = AOut, +// r9 = ANumChunks, r10 = ACounter, r11 = AFlags, +// rax = byte-rotation masks ptr (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 +// at +32; read unaligned, so the Pascal const needs no special alignment; +// consumed by the entry mask loads, rax is scratch afterwards). +// +// Register map: xmm0-xmm7 = state v0-v7, xmm8-xmm11 = state v8-v11, +// xmm12-xmm13 = temp, xmm14 = rot16 mask, xmm15 = rot8 mask, +// v12-v15 spilled to stack. +// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block byte offset. +// Message transpose: 4x4 via punpckldq/punpckhdq + punpcklqdq/punpckhqdq (pure SSE2). +// Rotations: rot16/8 via pshufb (db-encoded for broad assembler compatibility) +// against the resident masks; rot12/7 via pslld/psrld/por (not byte-aligned). +// +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV). + + push rbx + push rbp + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + // Load byte-rotation masks (resident for the whole kernel) + db $F3, $44, $0F, $6F, $30 // movdqu xmm14, oword [rax] + db $F3, $44, $0F, $6F, $78, $20 // movdqu xmm15, oword [rax + $20] + + sub rsp, 584 + + mov qword ptr [rsp + 560], r8 + mov dword ptr [rsp + 568], r11d + + // Broadcast key words to CV registers + movd xmm0, dword ptr [rdx + 0] + pshufd xmm0, xmm0, 0 + movd xmm1, dword ptr [rdx + 4] + pshufd xmm1, xmm1, 0 + movd xmm2, dword ptr [rdx + 8] + pshufd xmm2, xmm2, 0 + movd xmm3, dword ptr [rdx + 12] + pshufd xmm3, xmm3, 0 + movd xmm4, dword ptr [rdx + 16] + pshufd xmm4, xmm4, 0 + movd xmm5, dword ptr [rdx + 20] + pshufd xmm5, xmm5, 0 + movd xmm6, dword ptr [rdx + 24] + pshufd xmm6, xmm6, 0 + movd xmm7, dword ptr [rdx + 28] + pshufd xmm7, xmm7, 0 + + // Save initial CV to stack + movdqa oword [rsp + 320], xmm0 + movdqa oword [rsp + 336], xmm1 + movdqa oword [rsp + 352], xmm2 + movdqa oword [rsp + 368], xmm3 + movdqa oword [rsp + 384], xmm4 + movdqa oword [rsp + 400], xmm5 + movdqa oword [rsp + 416], xmm6 + movdqa oword [rsp + 432], xmm7 + + // Build counter vectors (r10 = ACounter, 64-bit) + mov rax, r10 + mov dword ptr [rsp + 448], eax + shr rax, 32 + mov dword ptr [rsp + 464], eax + lea rax, [r10 + 1] + mov dword ptr [rsp + 452], eax + shr rax, 32 + mov dword ptr [rsp + 468], eax + lea rax, [r10 + 2] + mov dword ptr [rsp + 456], eax + shr rax, 32 + mov dword ptr [rsp + 472], eax + lea rax, [r10 + 3] + mov dword ptr [rsp + 460], eax + shr rax, 32 + mov dword ptr [rsp + 476], eax + + // Pre-compute IV broadcast vectors + mov eax, $6A09E667 + movd xmm12, eax + pshufd xmm12, xmm12, 0 + movdqa oword [rsp + 480], xmm12 + mov eax, $BB67AE85 + movd xmm12, eax + pshufd xmm12, xmm12, 0 + movdqa oword [rsp + 496], xmm12 + mov eax, $3C6EF372 + movd xmm12, eax + pshufd xmm12, xmm12, 0 + movdqa oword [rsp + 512], xmm12 + mov eax, $A54FF53A + movd xmm12, eax + pshufd xmm12, xmm12, 0 + movdqa oword [rsp + 528], xmm12 + + mov eax, 64 + movd xmm12, eax + pshufd xmm12, xmm12, 0 + movdqa oword [rsp + 544], xmm12 + + xor ebx, ebx + xor ebp, ebp + +@block_loop: + + // Transpose message for current block from 4 chunks + // Words 0..3 + movdqu xmm0, oword [rcx + rbp + 0] + movdqu xmm1, oword [rcx + rbp + 1024] + movdqu xmm2, oword [rcx + rbp + 2048] + movdqu xmm3, oword [rcx + rbp + 3072] + movdqa xmm4, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm4, xmm1 + movdqa xmm5, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm5, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm4 + punpcklqdq xmm4, xmm5 + punpckhqdq xmm3, xmm5 + movdqa oword [rsp + 0], xmm0 + movdqa oword [rsp + 16], xmm1 + movdqa oword [rsp + 32], xmm4 + movdqa oword [rsp + 48], xmm3 + + // Words 4..7 + movdqu xmm0, oword [rcx + rbp + 16] + movdqu xmm1, oword [rcx + rbp + 1040] + movdqu xmm2, oword [rcx + rbp + 2064] + movdqu xmm3, oword [rcx + rbp + 3088] + movdqa xmm4, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm4, xmm1 + movdqa xmm5, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm5, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm4 + punpcklqdq xmm4, xmm5 + punpckhqdq xmm3, xmm5 + movdqa oword [rsp + 64], xmm0 + movdqa oword [rsp + 80], xmm1 + movdqa oword [rsp + 96], xmm4 + movdqa oword [rsp + 112], xmm3 + + // Words 8..11 + movdqu xmm0, oword [rcx + rbp + 32] + movdqu xmm1, oword [rcx + rbp + 1056] + movdqu xmm2, oword [rcx + rbp + 2080] + movdqu xmm3, oword [rcx + rbp + 3104] + movdqa xmm4, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm4, xmm1 + movdqa xmm5, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm5, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm4 + punpcklqdq xmm4, xmm5 + punpckhqdq xmm3, xmm5 + movdqa oword [rsp + 128], xmm0 + movdqa oword [rsp + 144], xmm1 + movdqa oword [rsp + 160], xmm4 + movdqa oword [rsp + 176], xmm3 + + // Words 12..15 + movdqu xmm0, oword [rcx + rbp + 48] + movdqu xmm1, oword [rcx + rbp + 1072] + movdqu xmm2, oword [rcx + rbp + 2096] + movdqu xmm3, oword [rcx + rbp + 3120] + movdqa xmm4, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm4, xmm1 + movdqa xmm5, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm5, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm4 + punpcklqdq xmm4, xmm5 + punpckhqdq xmm3, xmm5 + movdqa oword [rsp + 192], xmm0 + movdqa oword [rsp + 208], xmm1 + movdqa oword [rsp + 224], xmm4 + movdqa oword [rsp + 240], xmm3 + + // Initialize state: v0-v7 from CV, v8-v11 from IV + movdqa xmm0, oword [rsp + 320] + movdqa xmm1, oword [rsp + 336] + movdqa xmm2, oword [rsp + 352] + movdqa xmm3, oword [rsp + 368] + movdqa xmm4, oword [rsp + 384] + movdqa xmm5, oword [rsp + 400] + movdqa xmm6, oword [rsp + 416] + movdqa xmm7, oword [rsp + 432] + movdqa xmm8, oword [rsp + 480] + movdqa xmm9, oword [rsp + 496] + movdqa xmm10, oword [rsp + 512] + movdqa xmm11, oword [rsp + 528] + + // v12-v15: counter, block length, flags + movdqa xmm12, oword [rsp + 448] + movdqa oword [rsp + 256], xmm12 + movdqa xmm12, oword [rsp + 464] + movdqa oword [rsp + 272], xmm12 + movdqa xmm12, oword [rsp + 544] + movdqa oword [rsp + 288], xmm12 + + // Compute per-block flags and broadcast + mov eax, dword ptr [rsp + 568] + cmp ebx, 0 + jne @h4_not_first + or eax, 1 +@h4_not_first: + cmp ebx, 15 + jne @h4_not_last + or eax, 2 +@h4_not_last: + movd xmm12, eax + pshufd xmm12, xmm12, 0 + movdqa oword [rsp + 304], xmm12 + + // === Round 0 === + // G col (0,4,8,12) m[0],m[1] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 0] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 16] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[2],m[3] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 32] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 48] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[4],m[5] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 64] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 80] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[6],m[7] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 96] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 112] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[8],m[9] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 128] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 144] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[10],m[11] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 160] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 176] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[12],m[13] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 192] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 208] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[14],m[15] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 224] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 240] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // === Round 1 === + // G col (0,4,8,12) m[2],m[6] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 32] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 96] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[3],m[10] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 48] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 160] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[7],m[0] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 112] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 0] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[4],m[13] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 64] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 208] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[1],m[11] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 16] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 176] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[12],m[5] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 192] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 80] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[9],m[14] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 144] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 224] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[15],m[8] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 240] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 128] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // === Round 2 === + // G col (0,4,8,12) m[3],m[4] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 48] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 64] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[10],m[12] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 160] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 192] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[13],m[2] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 208] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 32] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[7],m[14] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 112] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 224] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[6],m[5] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 96] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 80] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[9],m[0] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 144] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 0] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[11],m[15] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 176] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 240] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[8],m[1] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 128] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 16] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // === Round 3 === + // G col (0,4,8,12) m[10],m[7] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 160] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 112] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[12],m[9] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 192] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 144] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[14],m[3] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 224] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 48] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[13],m[15] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 208] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 240] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[4],m[0] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 64] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 0] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[11],m[2] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 176] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 32] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[5],m[8] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 80] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 128] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[1],m[6] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 16] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 96] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // === Round 4 === + // G col (0,4,8,12) m[12],m[13] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 192] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 208] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[9],m[11] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 144] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 176] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[15],m[10] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 240] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 160] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[14],m[8] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 224] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 128] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[7],m[2] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 112] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 32] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[5],m[3] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 80] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 48] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[0],m[1] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 0] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 16] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[6],m[4] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 96] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 64] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // === Round 5 === + // G col (0,4,8,12) m[9],m[14] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 144] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 224] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[11],m[5] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 176] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 80] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[8],m[12] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 128] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 192] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[15],m[1] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 240] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 16] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[13],m[3] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 208] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 48] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[0],m[10] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 0] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 160] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[2],m[6] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 32] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 96] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[4],m[7] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 64] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 112] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // === Round 6 === + // G col (0,4,8,12) m[11],m[15] + movdqa xmm12, oword [rsp + 256] + paddd xmm0, oword [rsp + 176] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm0, oword [rsp + 240] + paddd xmm0, xmm4 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm4, xmm8 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + // G col (1,5,9,13) m[5],m[0] + movdqa xmm12, oword [rsp + 272] + paddd xmm1, oword [rsp + 80] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm1, oword [rsp + 0] + paddd xmm1, xmm5 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm5, xmm9 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G col (2,6,10,14) m[1],m[9] + movdqa xmm12, oword [rsp + 288] + paddd xmm2, oword [rsp + 16] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm2, oword [rsp + 144] + paddd xmm2, xmm6 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm6, xmm10 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G col (3,7,11,15) m[8],m[6] + movdqa xmm12, oword [rsp + 304] + paddd xmm3, oword [rsp + 128] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm3, oword [rsp + 96] + paddd xmm3, xmm7 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm7, xmm11 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (0,5,10,15) m[14],m[10] + movdqa xmm12, oword [rsp + 304] + paddd xmm0, oword [rsp + 224] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm10, xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 20 + psrld xmm13, 12 + por xmm5, xmm13 + paddd xmm0, oword [rsp + 160] + paddd xmm0, xmm5 + pxor xmm12, xmm0 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm10, xmm12 + movdqa oword [rsp + 304], xmm12 + pxor xmm5, xmm10 + movdqa xmm13, xmm5 + pslld xmm5, 25 + psrld xmm13, 7 + por xmm5, xmm13 + // G diag (1,6,11,12) m[2],m[12] + movdqa xmm12, oword [rsp + 256] + paddd xmm1, oword [rsp + 32] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm11, xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 20 + psrld xmm13, 12 + por xmm6, xmm13 + paddd xmm1, oword [rsp + 192] + paddd xmm1, xmm6 + pxor xmm12, xmm1 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm11, xmm12 + movdqa oword [rsp + 256], xmm12 + pxor xmm6, xmm11 + movdqa xmm13, xmm6 + pslld xmm6, 25 + psrld xmm13, 7 + por xmm6, xmm13 + // G diag (2,7,8,13) m[3],m[4] + movdqa xmm12, oword [rsp + 272] + paddd xmm2, oword [rsp + 48] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm8, xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 20 + psrld xmm13, 12 + por xmm7, xmm13 + paddd xmm2, oword [rsp + 64] + paddd xmm2, xmm7 + pxor xmm12, xmm2 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm8, xmm12 + movdqa oword [rsp + 272], xmm12 + pxor xmm7, xmm8 + movdqa xmm13, xmm7 + pslld xmm7, 25 + psrld xmm13, 7 + por xmm7, xmm13 + // G diag (3,4,9,14) m[7],m[13] + movdqa xmm12, oword [rsp + 288] + paddd xmm3, oword [rsp + 112] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E6 // pshufb xmm12, xmm14 + paddd xmm9, xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 20 + psrld xmm13, 12 + por xmm4, xmm13 + paddd xmm3, oword [rsp + 208] + paddd xmm3, xmm4 + pxor xmm12, xmm3 + db $66, $45, $0F, $38, $00, $E7 // pshufb xmm12, xmm15 + paddd xmm9, xmm12 + movdqa oword [rsp + 288], xmm12 + pxor xmm4, xmm9 + movdqa xmm13, xmm4 + pslld xmm4, 25 + psrld xmm13, 7 + por xmm4, xmm13 + + // Finalize: new_cv[i] = v[i] XOR v[i+8] + pxor xmm0, xmm8 + pxor xmm1, xmm9 + pxor xmm2, xmm10 + pxor xmm3, xmm11 + movdqa xmm12, oword [rsp + 256] + pxor xmm4, xmm12 + movdqa xmm12, oword [rsp + 272] + pxor xmm5, xmm12 + movdqa xmm12, oword [rsp + 288] + pxor xmm6, xmm12 + movdqa xmm12, oword [rsp + 304] + pxor xmm7, xmm12 + + // Store new CV + movdqa oword [rsp + 320], xmm0 + movdqa oword [rsp + 336], xmm1 + movdqa oword [rsp + 352], xmm2 + movdqa oword [rsp + 368], xmm3 + movdqa oword [rsp + 384], xmm4 + movdqa oword [rsp + 400], xmm5 + movdqa oword [rsp + 416], xmm6 + movdqa oword [rsp + 432], xmm7 + + add ebp, 64 + inc ebx + cmp ebx, 16 + jb @block_loop + + // Output: transpose 4x8 CV back to per-chunk layout + mov rax, qword ptr [rsp + 560] + + // Transpose words 0-3 + movdqa xmm0, oword [rsp + 320] + movdqa xmm1, oword [rsp + 336] + movdqa xmm2, oword [rsp + 352] + movdqa xmm3, oword [rsp + 368] + movdqa xmm4, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm4, xmm1 + movdqa xmm5, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm5, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm4 + punpcklqdq xmm4, xmm5 + punpckhqdq xmm3, xmm5 + movdqu oword [rax], xmm0 + movdqu oword [rax + 32], xmm1 + movdqu oword [rax + 64], xmm4 + movdqu oword [rax + 96], xmm3 + + // Transpose words 4-7 + movdqa xmm0, oword [rsp + 384] + movdqa xmm1, oword [rsp + 400] + movdqa xmm2, oword [rsp + 416] + movdqa xmm3, oword [rsp + 432] + movdqa xmm4, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm4, xmm1 + movdqa xmm5, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm5, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm4 + punpcklqdq xmm4, xmm5 + punpckhqdq xmm3, xmm5 + movdqu oword [rax + 16], xmm0 + movdqu oword [rax + 48], xmm1 + movdqu oword [rax + 80], xmm4 + movdqu oword [rax + 112], xmm3 + + add rsp, 584 + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} + + pop rbp + pop rbx diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc index c0df074..50f1dca 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc @@ -4,22 +4,33 @@ // All VEX instructions are db-encoded for broad assembler compatibility. // 7 rounds per block fully unrolled; 16-block loop with branch for chunk start/end flags. // -// After HlpSimdProc6Begin_x86_64.inc: +// After HlpSimdProc7Begin_x86_64.inc: // rcx = AInput, rdx = AKey, r8 = AOut, -// r9 = ANumChunks, r10 = ACounter, r11 = AFlags +// r9 = ANumChunks, r10 = ACounter, r11 = AFlags, +// rax = byte-rotation masks ptr (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 +// at +32; read unaligned, so the Pascal const needs no special alignment; +// consumed by the entry mask loads, rax is scratch afterwards). // // Register map: ymm0-ymm7 = state v0-v7, ymm8-ymm11 = state v8-v11, -// ymm12-ymm13 = temp, v12-v15 spilled to stack. +// ymm12-ymm13 = temp, ymm14 = rot16 mask, ymm15 = rot8 mask, +// v12-v15 spilled to stack. +// Rotations: ROT16/8 via vpshufb against the resident masks, ROT12/7 via +// shift+or (not byte-aligned; shifts are the known-best form). // GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block byte offset. // Message transpose: chunks paired (0+4, 1+5, ...) via vinserti128, then per-lane 4x4. // Output transpose: full 8x8 via vperm2i128 + vpunpckl/hdq + vpunpcklq/hqdq. // 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. // Stack 32-byte aligned via "and rsp, -32" for YMM movdqu stores. // -// MS x64 non-volatile saves: xmm6-xmm13. +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + // Load byte-rotation masks (resident for the whole kernel) + db $C5, $7E, $6F, $30 // vmovdqu ymm14, yword [rax] + db $C5, $7E, $6F, $78, $20 // vmovdqu ymm15, yword [rax + $20] + push rbx push rbp push r12 @@ -246,8 +257,7 @@ db $C5, $FD, $FE, $04, $24 // vpaddd ymm0, ymm0, [rsp+0] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -256,9 +266,7 @@ db $C5, $FD, $FE, $44, $24, $20 // vpaddd ymm0, ymm0, [rsp+32] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -270,8 +278,7 @@ db $C5, $F5, $FE, $4C, $24, $40 // vpaddd ymm1, ymm1, [rsp+64] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -280,9 +287,7 @@ db $C5, $F5, $FE, $4C, $24, $60 // vpaddd ymm1, ymm1, [rsp+96] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -294,8 +299,7 @@ db $C5, $ED, $FE, $94, $24, $80, $00, $00, $00 // vpaddd ymm2, ymm2, [rsp+128] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -304,9 +308,7 @@ db $C5, $ED, $FE, $94, $24, $A0, $00, $00, $00 // vpaddd ymm2, ymm2, [rsp+160] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -318,8 +320,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+192] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -328,9 +329,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+224] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -342,8 +341,7 @@ db $C5, $FD, $FE, $84, $24, $00, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+256] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -352,9 +350,7 @@ db $C5, $FD, $FE, $84, $24, $20, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+288] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -366,8 +362,7 @@ db $C5, $F5, $FE, $8C, $24, $40, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+320] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -376,9 +371,7 @@ db $C5, $F5, $FE, $8C, $24, $60, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+352] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -390,8 +383,7 @@ db $C5, $ED, $FE, $94, $24, $80, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+384] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -400,9 +392,7 @@ db $C5, $ED, $FE, $94, $24, $A0, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+416] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -414,8 +404,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+448] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -424,9 +413,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+480] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 @@ -440,8 +427,7 @@ db $C5, $FD, $FE, $44, $24, $40 // vpaddd ymm0, ymm0, [rsp+64] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -450,9 +436,7 @@ db $C5, $FD, $FE, $84, $24, $C0, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+192] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -464,8 +448,7 @@ db $C5, $F5, $FE, $4C, $24, $60 // vpaddd ymm1, ymm1, [rsp+96] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -474,9 +457,7 @@ db $C5, $F5, $FE, $8C, $24, $40, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+320] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -488,8 +469,7 @@ db $C5, $ED, $FE, $94, $24, $E0, $00, $00, $00 // vpaddd ymm2, ymm2, [rsp+224] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -498,9 +478,7 @@ db $C5, $ED, $FE, $14, $24 // vpaddd ymm2, ymm2, [rsp+0] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -512,8 +490,7 @@ db $C5, $E5, $FE, $9C, $24, $80, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+128] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -522,9 +499,7 @@ db $C5, $E5, $FE, $9C, $24, $A0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+416] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -536,8 +511,7 @@ db $C5, $FD, $FE, $44, $24, $20 // vpaddd ymm0, ymm0, [rsp+32] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -546,9 +520,7 @@ db $C5, $FD, $FE, $84, $24, $60, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+352] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -560,8 +532,7 @@ db $C5, $F5, $FE, $8C, $24, $80, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+384] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -570,9 +541,7 @@ db $C5, $F5, $FE, $8C, $24, $A0, $00, $00, $00 // vpaddd ymm1, ymm1, [rsp+160] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -584,8 +553,7 @@ db $C5, $ED, $FE, $94, $24, $20, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+288] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -594,9 +562,7 @@ db $C5, $ED, $FE, $94, $24, $C0, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+448] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -608,8 +574,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+480] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -618,9 +583,7 @@ db $C5, $E5, $FE, $9C, $24, $00, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+256] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 @@ -634,8 +597,7 @@ db $C5, $FD, $FE, $44, $24, $60 // vpaddd ymm0, ymm0, [rsp+96] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -644,9 +606,7 @@ db $C5, $FD, $FE, $84, $24, $80, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+128] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -658,8 +618,7 @@ db $C5, $F5, $FE, $8C, $24, $40, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+320] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -668,9 +627,7 @@ db $C5, $F5, $FE, $8C, $24, $80, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+384] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -682,8 +639,7 @@ db $C5, $ED, $FE, $94, $24, $A0, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+416] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -692,9 +648,7 @@ db $C5, $ED, $FE, $54, $24, $40 // vpaddd ymm2, ymm2, [rsp+64] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -706,8 +660,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+224] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -716,9 +669,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+448] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -730,8 +681,7 @@ db $C5, $FD, $FE, $84, $24, $C0, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+192] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -740,9 +690,7 @@ db $C5, $FD, $FE, $84, $24, $A0, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+160] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -754,8 +702,7 @@ db $C5, $F5, $FE, $8C, $24, $20, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+288] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -764,9 +711,7 @@ db $C5, $F5, $FE, $0C, $24 // vpaddd ymm1, ymm1, [rsp+0] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -778,8 +723,7 @@ db $C5, $ED, $FE, $94, $24, $60, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+352] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -788,9 +732,7 @@ db $C5, $ED, $FE, $94, $24, $E0, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+480] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -802,8 +744,7 @@ db $C5, $E5, $FE, $9C, $24, $00, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+256] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -812,9 +753,7 @@ db $C5, $E5, $FE, $5C, $24, $20 // vpaddd ymm3, ymm3, [rsp+32] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 @@ -828,8 +767,7 @@ db $C5, $FD, $FE, $84, $24, $40, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+320] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -838,9 +776,7 @@ db $C5, $FD, $FE, $84, $24, $E0, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+224] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -852,8 +788,7 @@ db $C5, $F5, $FE, $8C, $24, $80, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+384] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -862,9 +797,7 @@ db $C5, $F5, $FE, $8C, $24, $20, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+288] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -876,8 +809,7 @@ db $C5, $ED, $FE, $94, $24, $C0, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+448] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -886,9 +818,7 @@ db $C5, $ED, $FE, $54, $24, $60 // vpaddd ymm2, ymm2, [rsp+96] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -900,8 +830,7 @@ db $C5, $E5, $FE, $9C, $24, $A0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+416] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -910,9 +839,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+480] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -924,8 +851,7 @@ db $C5, $FD, $FE, $84, $24, $80, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+128] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -934,9 +860,7 @@ db $C5, $FD, $FE, $04, $24 // vpaddd ymm0, ymm0, [rsp+0] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -948,8 +872,7 @@ db $C5, $F5, $FE, $8C, $24, $60, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+352] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -958,9 +881,7 @@ db $C5, $F5, $FE, $4C, $24, $40 // vpaddd ymm1, ymm1, [rsp+64] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -972,8 +893,7 @@ db $C5, $ED, $FE, $94, $24, $A0, $00, $00, $00 // vpaddd ymm2, ymm2, [rsp+160] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -982,9 +902,7 @@ db $C5, $ED, $FE, $94, $24, $00, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+256] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -996,8 +914,7 @@ db $C5, $E5, $FE, $5C, $24, $20 // vpaddd ymm3, ymm3, [rsp+32] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1006,9 +923,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+192] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 @@ -1022,8 +937,7 @@ db $C5, $FD, $FE, $84, $24, $80, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+384] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1032,9 +946,7 @@ db $C5, $FD, $FE, $84, $24, $A0, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+416] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -1046,8 +958,7 @@ db $C5, $F5, $FE, $8C, $24, $20, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+288] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -1056,9 +967,7 @@ db $C5, $F5, $FE, $8C, $24, $60, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+352] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -1070,8 +979,7 @@ db $C5, $ED, $FE, $94, $24, $E0, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+480] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -1080,9 +988,7 @@ db $C5, $ED, $FE, $94, $24, $40, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+320] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -1094,8 +1000,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+448] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -1104,9 +1009,7 @@ db $C5, $E5, $FE, $9C, $24, $00, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+256] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -1118,8 +1021,7 @@ db $C5, $FD, $FE, $84, $24, $E0, $00, $00, $00 // vpaddd ymm0, ymm0, [rsp+224] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -1128,9 +1030,7 @@ db $C5, $FD, $FE, $44, $24, $40 // vpaddd ymm0, ymm0, [rsp+64] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -1142,8 +1042,7 @@ db $C5, $F5, $FE, $8C, $24, $A0, $00, $00, $00 // vpaddd ymm1, ymm1, [rsp+160] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -1152,9 +1051,7 @@ db $C5, $F5, $FE, $4C, $24, $60 // vpaddd ymm1, ymm1, [rsp+96] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -1166,8 +1063,7 @@ db $C5, $ED, $FE, $14, $24 // vpaddd ymm2, ymm2, [rsp+0] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -1176,9 +1072,7 @@ db $C5, $ED, $FE, $54, $24, $20 // vpaddd ymm2, ymm2, [rsp+32] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -1190,8 +1084,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+192] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1200,9 +1093,7 @@ db $C5, $E5, $FE, $9C, $24, $80, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+128] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 @@ -1216,8 +1107,7 @@ db $C5, $FD, $FE, $84, $24, $20, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+288] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1226,9 +1116,7 @@ db $C5, $FD, $FE, $84, $24, $C0, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+448] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -1240,8 +1128,7 @@ db $C5, $F5, $FE, $8C, $24, $60, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+352] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -1250,9 +1137,7 @@ db $C5, $F5, $FE, $8C, $24, $A0, $00, $00, $00 // vpaddd ymm1, ymm1, [rsp+160] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -1264,8 +1149,7 @@ db $C5, $ED, $FE, $94, $24, $00, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+256] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -1274,9 +1158,7 @@ db $C5, $ED, $FE, $94, $24, $80, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+384] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -1288,8 +1170,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+480] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -1298,9 +1179,7 @@ db $C5, $E5, $FE, $5C, $24, $20 // vpaddd ymm3, ymm3, [rsp+32] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -1312,8 +1191,7 @@ db $C5, $FD, $FE, $84, $24, $A0, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+416] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -1322,9 +1200,7 @@ db $C5, $FD, $FE, $44, $24, $60 // vpaddd ymm0, ymm0, [rsp+96] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -1336,8 +1212,7 @@ db $C5, $F5, $FE, $0C, $24 // vpaddd ymm1, ymm1, [rsp+0] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -1346,9 +1221,7 @@ db $C5, $F5, $FE, $8C, $24, $40, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+320] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -1360,8 +1233,7 @@ db $C5, $ED, $FE, $54, $24, $40 // vpaddd ymm2, ymm2, [rsp+64] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -1370,9 +1242,7 @@ db $C5, $ED, $FE, $94, $24, $C0, $00, $00, $00 // vpaddd ymm2, ymm2, [rsp+192] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -1384,8 +1254,7 @@ db $C5, $E5, $FE, $9C, $24, $80, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+128] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1394,9 +1263,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+224] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 @@ -1410,8 +1277,7 @@ db $C5, $FD, $FE, $84, $24, $60, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+352] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1420,9 +1286,7 @@ db $C5, $FD, $FE, $84, $24, $E0, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+480] db $C5, $FD, $FE, $C4 // vpaddd ymm0, ymm0, ymm4 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $5D, $EF, $E0 // vpxor ymm4, ymm4, ymm8 @@ -1434,8 +1298,7 @@ db $C5, $F5, $FE, $8C, $24, $A0, $00, $00, $00 // vpaddd ymm1, ymm1, [rsp+160] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -1444,9 +1307,7 @@ db $C5, $F5, $FE, $0C, $24 // vpaddd ymm1, ymm1, [rsp+0] db $C5, $F5, $FE, $CD // vpaddd ymm1, ymm1, ymm5 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $55, $EF, $E9 // vpxor ymm5, ymm5, ymm9 @@ -1458,8 +1319,7 @@ db $C5, $ED, $FE, $54, $24, $20 // vpaddd ymm2, ymm2, [rsp+32] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -1468,9 +1328,7 @@ db $C5, $ED, $FE, $94, $24, $20, $01, $00, $00 // vpaddd ymm2, ymm2, [rsp+288] db $C5, $ED, $FE, $D6 // vpaddd ymm2, ymm2, ymm6 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $4D, $EF, $F2 // vpxor ymm6, ymm6, ymm10 @@ -1482,8 +1340,7 @@ db $C5, $E5, $FE, $9C, $24, $00, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+256] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -1492,9 +1349,7 @@ db $C5, $E5, $FE, $9C, $24, $C0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+192] db $C5, $E5, $FE, $DF // vpaddd ymm3, ymm3, ymm7 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $45, $EF, $FB // vpxor ymm7, ymm7, ymm11 @@ -1506,8 +1361,7 @@ db $C5, $FD, $FE, $84, $24, $C0, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+448] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 db $C5, $95, $72, $D5, $0C // vpsrld ymm13, ymm5, 12 @@ -1516,9 +1370,7 @@ db $C5, $FD, $FE, $84, $24, $40, $01, $00, $00 // vpaddd ymm0, ymm0, [rsp+320] db $C5, $FD, $FE, $C5 // vpaddd ymm0, ymm0, ymm5 db $C5, $1D, $EF, $E0 // vpxor ymm12, ymm12, ymm0 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $2D, $FE, $D4 // vpaddd ymm10, ymm10, ymm12 db $C5, $7E, $7F, $A4, $24, $60, $02, $00, $00 // vmovdqu [rsp+608], ymm12 db $C4, $C1, $55, $EF, $EA // vpxor ymm5, ymm5, ymm10 @@ -1530,8 +1382,7 @@ db $C5, $F5, $FE, $4C, $24, $40 // vpaddd ymm1, ymm1, [rsp+64] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 db $C5, $95, $72, $D6, $0C // vpsrld ymm13, ymm6, 12 @@ -1540,9 +1391,7 @@ db $C5, $F5, $FE, $8C, $24, $80, $01, $00, $00 // vpaddd ymm1, ymm1, [rsp+384] db $C5, $F5, $FE, $CE // vpaddd ymm1, ymm1, ymm6 db $C5, $1D, $EF, $E1 // vpxor ymm12, ymm12, ymm1 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $25, $FE, $DC // vpaddd ymm11, ymm11, ymm12 db $C5, $7E, $7F, $A4, $24, $00, $02, $00, $00 // vmovdqu [rsp+512], ymm12 db $C4, $C1, $4D, $EF, $F3 // vpxor ymm6, ymm6, ymm11 @@ -1554,8 +1403,7 @@ db $C5, $ED, $FE, $54, $24, $60 // vpaddd ymm2, ymm2, [rsp+96] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 db $C5, $95, $72, $D7, $0C // vpsrld ymm13, ymm7, 12 @@ -1564,9 +1412,7 @@ db $C5, $ED, $FE, $94, $24, $80, $00, $00, $00 // vpaddd ymm2, ymm2, [rsp+128] db $C5, $ED, $FE, $D7 // vpaddd ymm2, ymm2, ymm7 db $C5, $1D, $EF, $E2 // vpxor ymm12, ymm12, ymm2 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $3D, $FE, $C4 // vpaddd ymm8, ymm8, ymm12 db $C5, $7E, $7F, $A4, $24, $20, $02, $00, $00 // vmovdqu [rsp+544], ymm12 db $C4, $C1, $45, $EF, $F8 // vpxor ymm7, ymm7, ymm8 @@ -1578,8 +1424,7 @@ db $C5, $E5, $FE, $9C, $24, $E0, $00, $00, $00 // vpaddd ymm3, ymm3, [rsp+224] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $41, $7F, $70, $E4, $B1 // vpshuflw ymm12, ymm12, $B1 - db $C4, $41, $7E, $70, $E4, $B1 // vpshufhw ymm12, ymm12, $B1 + db $C4, $42, $1D, $00, $E6 // vpshufb ymm12, ymm12, ymm14 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 db $C5, $95, $72, $D4, $0C // vpsrld ymm13, ymm4, 12 @@ -1588,9 +1433,7 @@ db $C5, $E5, $FE, $9C, $24, $A0, $01, $00, $00 // vpaddd ymm3, ymm3, [rsp+416] db $C5, $E5, $FE, $DC // vpaddd ymm3, ymm3, ymm4 db $C5, $1D, $EF, $E3 // vpxor ymm12, ymm12, ymm3 - db $C4, $C1, $15, $72, $D4, $08 // vpsrld ymm13, ymm12, 8 - db $C4, $C1, $1D, $72, $F4, $18 // vpslld ymm12, ymm12, 24 - db $C4, $41, $1D, $EB, $E5 // vpor ymm12, ymm12, ymm13 + db $C4, $42, $1D, $00, $E7 // vpshufb ymm12, ymm12, ymm15 db $C4, $41, $35, $FE, $CC // vpaddd ymm9, ymm9, ymm12 db $C5, $7E, $7F, $A4, $24, $40, $02, $00, $00 // vmovdqu [rsp+576], ymm12 db $C4, $C1, $5D, $EF, $E1 // vpxor ymm4, ymm4, ymm9 diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc index c20cd52..86a24aa 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc @@ -4,10 +4,9 @@ // structure carries over 1:1 (all vector registers are volatile on IA-32 - // no save/restore needed, just vzeroupper before returning). // AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler -// compatibility; bytes machine-encoded via scripts/x86_s2db.py --i386 -// (binutils 2.28 lacks the 2018 VPCLMULQDQ-ymm form, so those are assembled -// as same-shape vpblendd and the opcode byte $02 -> $44 patched, each result -// asserted byte-identical to the verified x86_64 kernel's encoding). +// compatibility; every register-register byte sequence is identical to the +// verified x86_64 kernel's encoding (regs 0-7 carry no REX/VEX extension +// bits), and the memory forms are machine-assembled for the IA-32 bases. // // After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), // edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc index dfa5897..68c5209 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc @@ -4,10 +4,9 @@ // so the structure carries over 1:1 (all vector registers are volatile on // IA-32 - no save/restore needed, just vzeroupper before returning). // AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler -// compatibility; bytes machine-encoded via scripts/x86_s2db.py --i386 -// (binutils 2.28 lacks the 2018 VPCLMULQDQ-ymm form, so those are assembled -// as same-shape vpblendd and the opcode byte $02 -> $44 patched, each result -// asserted byte-identical to the verified x86_64 kernel's encoding). +// compatibility; every register-register byte sequence is identical to the +// verified x86_64 kernel's encoding (regs 0-7 carry no REX/VEX extension +// bits), and the memory forms are machine-assembled for the IA-32 bases. // // After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), // edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). diff --git a/HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_i386.inc b/HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_i386.inc new file mode 100644 index 0000000..f4ba0ab --- /dev/null +++ b/HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_i386.inc @@ -0,0 +1,39 @@ +// Shared SIMD procedure prologue for 7-parameter assembly functions. +// After inclusion: ebx = param1, esi = param2, edi = param3, eax = param4, +// ecx = param5 low, edx = param5 high (UInt64 split); param6/param7 are not +// loaded in this prologue (IA-32 has no free register left) - load them from +// the documented stack slots when needed. +// FPC: param4 at [esp+32]; param5 at [esp+24]/[esp+28]; param6 at [esp+20]; +// param7 at [esp+16] after push EBX/ESI/EDI (see asm). +// Delphi Win32: first 3 params in EAX/EDX/ECX; param4 at [ebp+24], +// param5 at [ebp+16]/[ebp+20], param6 at [ebp+12], param7 at [ebp+8]. +// Callee-saved EBX, ESI, EDI - epilogue must pop EDI, ESI, EBX; SIMD bodies may adjust ESP for locals. +// Usage: +// procedure MyProc(P1, P2, P3: Pointer; P4: Int32; P5: UInt64; P6: UInt32; P7: Pointer); +// {$I HlpSimdProc7Begin_i386.inc} +// // ... SIMD instructions using ebx, esi, edi, eax, ecx, edx (load param6/7 from stack if needed) ... +// end; +{$IFDEF FPC} + assembler; nostackframe; +asm + push ebx + push esi + push edi + mov ebx, eax + mov esi, edx + mov edi, ecx + mov eax, dword ptr [esp + 32] // param4 + mov ecx, dword ptr [esp + 24] // param5_lo + mov edx, dword ptr [esp + 28] // param5_hi +{$ELSE} +asm + push ebx + push esi + push edi + mov ebx, eax + mov esi, edx + mov edi, ecx + mov eax, dword ptr [ebp + 24] // param4 (first stack param = high address) + mov ecx, dword ptr [ebp + 16] // param5_lo + mov edx, dword ptr [ebp + 20] // param5_hi +{$ENDIF} diff --git a/HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_x86_64.inc b/HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_x86_64.inc new file mode 100644 index 0000000..9efa57c --- /dev/null +++ b/HashLib/src/Include/Simd/Common/HlpSimdProc7Begin_x86_64.inc @@ -0,0 +1,32 @@ +// Shared SIMD procedure prologue for 7-parameter assembly functions. +// After inclusion: rcx = param1, rdx = param2, r8 = param3, r9 = param4, +// r10 = param5, r11 = param6, rax = param7 (MS x64 ABI layout). +// When HASHLIB_SYSV_X64_ABI is defined, remaps rdi,rsi,rdx,rcx,r8,r9 -> +// rcx,rdx,r8,r9,r10,r11 and loads param7 from [rsp+8]. +// On MS x64, param5/6/7 are loaded from [rsp+40]/[rsp+48]/[rsp+56] +// (above shadow space + return addr). +// Usage: +// procedure MyProc(P1, P2, P3, P4: Pointer; P5: UInt64; P6: UInt32; P7: Pointer); +// {$I HlpSimdProc7Begin_x86_64.inc} +// // ... SIMD instructions using rcx, rdx, r8, r9, r10, r11, rax ... +// end; +{$IFDEF FPC} + assembler; nostackframe; +{$ENDIF} +asm +{$IFNDEF FPC} + .noframe +{$ENDIF} +{$IFDEF HASHLIB_SYSV_X64_ABI} + mov rax, [rsp + 8] + mov r11, r9 + mov r10, r8 + mov r9, rcx + mov r8, rdx + mov rdx, rsi + mov rcx, rdi +{$ELSE} + mov r10, [rsp + 40] + mov r11, [rsp + 48] + mov rax, [rsp + 56] +{$ENDIF} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc new file mode 100644 index 0000000..10a8b4d --- /dev/null +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc @@ -0,0 +1,1175 @@ +// SHA-1 AVX SIMD-schedule implementation (IA-32). VEX-128 (AVX1) +// instructions only - there is no i386 AVX2 SHA-1 upstream - dispatched at +// the AVX2 tier (every AVX2 CPU has AVX1; AVX1-only CPUs fall to the SSSE3 +// tier). The 3-operand VEX forms eliminate the SSSE3 kernel's register-copy +// movdqa traffic in the interleaved message schedule. All VEX instructions +// are db-encoded for broad assembler compatibility. +// The four round constants and the byte-swap mask are read from +// K_SHA1_Doubled at a 32-byte stride (VEX memory operands are read +// unaligned, so the Pascal const needs no special alignment) and spilled to +// the local frame like the original; the original's PIC table setup and +// stack-argument reads are replaced by the shared-prologue registers. +// Reference: OpenSSL CRYPTOGAMS sha1-586.pl (AVX function). +// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, +// edi = numblocks, eax = K_SHA1_Doubled ptr. HlpSimdProc4Begin pushes +// ebx/esi/edi; ebp is pushed here, giving the 4-deep frame the original +// epilogue unwinds via its saved-esp slot. + + push ebp + mov ebp, eax + db $C5, $FC, $77 // vzeroall + db $C5, $FA, $6F, $7D, $00 // vmovdqu xmm7, oword [ebp + $0] + db $C5, $FA, $6F, $45, $20 // vmovdqu xmm0, oword [ebp + $20] + db $C5, $FA, $6F, $4D, $40 // vmovdqu xmm1, oword [ebp + $40] + db $C5, $FA, $6F, $55, $60 // vmovdqu xmm2, oword [ebp + $60] + db $C5, $FA, $6F, $B5, $80, $00, $00, $00 // vmovdqu xmm6, oword [ebp + $80] + mov edx, edi + mov edi, ebx + mov ebp, esi + mov esi, esp + sub esp, $D0 + and esp, $FFFFFFC0 + db $C5, $F9, $7F, $44, $24, $70 // vmovdqa oword [esp + $70], xmm0 + db $C5, $F9, $7F, $8C, $24, $80, $00, $00, $00 // vmovdqa oword [esp + $80], xmm1 + db $C5, $F9, $7F, $94, $24, $90, $00, $00, $00 // vmovdqa oword [esp + $90], xmm2 + shl edx, $6 + db $C5, $F9, $7F, $BC, $24, $A0, $00, $00, $00 // vmovdqa oword [esp + $A0], xmm7 + add edx, ebp + db $C5, $F9, $7F, $B4, $24, $B0, $00, $00, $00 // vmovdqa oword [esp + $B0], xmm6 + add ebp, $40 + mov dword ptr [esp + $C0], edi + mov dword ptr [esp + $C4], ebp + mov dword ptr [esp + $C8], edx + mov dword ptr [esp + $CC], esi + mov eax, dword ptr [edi] + mov ebx, dword ptr [edi + $4] + mov ecx, dword ptr [edi + $8] + mov edx, dword ptr [edi + $C] + mov edi, dword ptr [edi + $10] + mov esi, ebx + db $C5, $FA, $6F, $45, $C0 // vmovdqu xmm0, oword [ebp - $40] + db $C5, $FA, $6F, $4D, $D0 // vmovdqu xmm1, oword [ebp - $30] + db $C5, $FA, $6F, $55, $E0 // vmovdqu xmm2, oword [ebp - $20] + db $C5, $FA, $6F, $5D, $F0 // vmovdqu xmm3, oword [ebp - $10] + db $C4, $E2, $79, $00, $C6 // vpshufb xmm0, xmm0, xmm6 + db $C4, $E2, $71, $00, $CE // vpshufb xmm1, xmm1, xmm6 + db $C4, $E2, $69, $00, $D6 // vpshufb xmm2, xmm2, xmm6 + db $C5, $F9, $7F, $7C, $24, $60 // vmovdqa oword [esp + $60], xmm7 + db $C4, $E2, $61, $00, $DE // vpshufb xmm3, xmm3, xmm6 + db $C5, $F9, $FE, $E7 // vpaddd xmm4, xmm0, xmm7 + db $C5, $F1, $FE, $EF // vpaddd xmm5, xmm1, xmm7 + db $C5, $E9, $FE, $F7 // vpaddd xmm6, xmm2, xmm7 + db $C5, $F9, $7F, $24, $24 // vmovdqa oword [esp], xmm4 + mov ebp, ecx + db $C5, $F9, $7F, $6C, $24, $10 // vmovdqa oword [esp + $10], xmm5 + xor ebp, edx + db $C5, $F9, $7F, $74, $24, $20 // vmovdqa oword [esp + $20], xmm6 + and esi, ebp + jmp @loop_009 + +@loop_009: + shrd ebx, ebx, $2 + xor esi, edx + db $C4, $E3, $71, $0F, $E0, $08 // vpalignr xmm4, xmm1, xmm0, $8 + mov ebp, eax + add edi, dword ptr [esp] + db $C5, $C1, $FE, $FB // vpaddd xmm7, xmm7, xmm3 + db $C5, $F9, $7F, $44, $24, $40 // vmovdqa oword [esp + $40], xmm0 + xor ebx, ecx + shld eax, eax, $5 + db $C5, $C9, $73, $DB, $04 // vpsrldq xmm6, xmm3, $4 + add edi, esi + and ebp, ebx + db $C5, $D9, $EF, $E0 // vpxor xmm4, xmm4, xmm0 + xor ebx, ecx + add edi, eax + db $C5, $C9, $EF, $F2 // vpxor xmm6, xmm6, xmm2 + shrd eax, eax, $7 + xor ebp, ecx + db $C5, $F9, $7F, $7C, $24, $30 // vmovdqa oword [esp + $30], xmm7 + mov esi, edi + add edx, dword ptr [esp + $4] + db $C5, $D9, $EF, $E6 // vpxor xmm4, xmm4, xmm6 + xor eax, ebx + shld edi, edi, $5 + add edx, ebp + and esi, eax + db $C5, $C9, $72, $D4, $1F // vpsrld xmm6, xmm4, $1F + xor eax, ebx + add edx, edi + shrd edi, edi, $7 + xor esi, ebx + db $C5, $F9, $73, $FC, $0C // vpslldq xmm0, xmm4, $C + db $C5, $D9, $FE, $E4 // vpaddd xmm4, xmm4, xmm4 + mov ebp, edx + add ecx, dword ptr [esp + $8] + xor edi, eax + shld edx, edx, $5 + db $C5, $C1, $72, $D0, $1E // vpsrld xmm7, xmm0, $1E + db $C5, $D9, $EB, $E6 // vpor xmm4, xmm4, xmm6 + add ecx, esi + and ebp, edi + xor edi, eax + add ecx, edx + db $C5, $F9, $72, $F0, $02 // vpslld xmm0, xmm0, $2 + shrd edx, edx, $7 + xor ebp, eax + db $C5, $D9, $EF, $E7 // vpxor xmm4, xmm4, xmm7 + mov esi, ecx + add ebx, dword ptr [esp + $C] + xor edx, edi + shld ecx, ecx, $5 + db $C5, $D9, $EF, $E0 // vpxor xmm4, xmm4, xmm0 + add ebx, ebp + and esi, edx + db $C5, $F9, $6F, $44, $24, $60 // vmovdqa xmm0, oword [esp + $60] + xor edx, edi + add ebx, ecx + shrd ecx, ecx, $7 + xor esi, edi + db $C4, $E3, $69, $0F, $E9, $08 // vpalignr xmm5, xmm2, xmm1, $8 + mov ebp, ebx + add eax, dword ptr [esp + $10] + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $F9, $7F, $4C, $24, $50 // vmovdqa oword [esp + $50], xmm1 + xor ecx, edx + shld ebx, ebx, $5 + db $C5, $C1, $73, $DC, $04 // vpsrldq xmm7, xmm4, $4 + add eax, esi + and ebp, ecx + db $C5, $D1, $EF, $E9 // vpxor xmm5, xmm5, xmm1 + xor ecx, edx + add eax, ebx + db $C5, $C1, $EF, $FB // vpxor xmm7, xmm7, xmm3 + shrd ebx, ebx, $7 + xor ebp, edx + db $C5, $F9, $7F, $04, $24 // vmovdqa oword [esp], xmm0 + mov esi, eax + add edi, dword ptr [esp + $14] + db $C5, $D1, $EF, $EF // vpxor xmm5, xmm5, xmm7 + xor ebx, ecx + shld eax, eax, $5 + add edi, ebp + and esi, ebx + db $C5, $C1, $72, $D5, $1F // vpsrld xmm7, xmm5, $1F + xor ebx, ecx + add edi, eax + shrd eax, eax, $7 + xor esi, ecx + db $C5, $F1, $73, $FD, $0C // vpslldq xmm1, xmm5, $C + db $C5, $D1, $FE, $ED // vpaddd xmm5, xmm5, xmm5 + mov ebp, edi + add edx, dword ptr [esp + $18] + xor eax, ebx + shld edi, edi, $5 + db $C5, $F9, $72, $D1, $1E // vpsrld xmm0, xmm1, $1E + db $C5, $D1, $EB, $EF // vpor xmm5, xmm5, xmm7 + add edx, esi + and ebp, eax + xor eax, ebx + add edx, edi + db $C5, $F1, $72, $F1, $02 // vpslld xmm1, xmm1, $2 + shrd edi, edi, $7 + xor ebp, ebx + db $C5, $D1, $EF, $E8 // vpxor xmm5, xmm5, xmm0 + mov esi, edx + add ecx, dword ptr [esp + $1C] + xor edi, eax + shld edx, edx, $5 + db $C5, $D1, $EF, $E9 // vpxor xmm5, xmm5, xmm1 + add ecx, ebp + and esi, edi + db $C5, $F9, $6F, $4C, $24, $70 // vmovdqa xmm1, oword [esp + $70] + xor edi, eax + add ecx, edx + shrd edx, edx, $7 + xor esi, eax + db $C4, $E3, $61, $0F, $F2, $08 // vpalignr xmm6, xmm3, xmm2, $8 + mov ebp, ecx + add ebx, dword ptr [esp + $20] + db $C5, $F1, $FE, $CD // vpaddd xmm1, xmm1, xmm5 + db $C5, $F9, $7F, $54, $24, $60 // vmovdqa oword [esp + $60], xmm2 + xor edx, edi + shld ecx, ecx, $5 + db $C5, $F9, $73, $DD, $04 // vpsrldq xmm0, xmm5, $4 + add ebx, esi + and ebp, edx + db $C5, $C9, $EF, $F2 // vpxor xmm6, xmm6, xmm2 + xor edx, edi + add ebx, ecx + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + shrd ecx, ecx, $7 + xor ebp, edi + db $C5, $F9, $7F, $4C, $24, $10 // vmovdqa oword [esp + $10], xmm1 + mov esi, ebx + add eax, dword ptr [esp + $24] + db $C5, $C9, $EF, $F0 // vpxor xmm6, xmm6, xmm0 + xor ecx, edx + shld ebx, ebx, $5 + add eax, ebp + and esi, ecx + db $C5, $F9, $72, $D6, $1F // vpsrld xmm0, xmm6, $1F + xor ecx, edx + add eax, ebx + shrd ebx, ebx, $7 + xor esi, edx + db $C5, $E9, $73, $FE, $0C // vpslldq xmm2, xmm6, $C + db $C5, $C9, $FE, $F6 // vpaddd xmm6, xmm6, xmm6 + mov ebp, eax + add edi, dword ptr [esp + $28] + xor ebx, ecx + shld eax, eax, $5 + db $C5, $F1, $72, $D2, $1E // vpsrld xmm1, xmm2, $1E + db $C5, $C9, $EB, $F0 // vpor xmm6, xmm6, xmm0 + add edi, esi + and ebp, ebx + xor ebx, ecx + add edi, eax + db $C5, $E9, $72, $F2, $02 // vpslld xmm2, xmm2, $2 + db $C5, $F9, $6F, $44, $24, $40 // vmovdqa xmm0, oword [esp + $40] + shrd eax, eax, $7 + xor ebp, ecx + db $C5, $C9, $EF, $F1 // vpxor xmm6, xmm6, xmm1 + mov esi, edi + add edx, dword ptr [esp + $2C] + xor eax, ebx + shld edi, edi, $5 + db $C5, $C9, $EF, $F2 // vpxor xmm6, xmm6, xmm2 + add edx, ebp + and esi, eax + db $C5, $F9, $6F, $54, $24, $70 // vmovdqa xmm2, oword [esp + $70] + xor eax, ebx + add edx, edi + shrd edi, edi, $7 + xor esi, ebx + db $C4, $E3, $59, $0F, $FB, $08 // vpalignr xmm7, xmm4, xmm3, $8 + mov ebp, edx + add ecx, dword ptr [esp + $30] + db $C5, $E9, $FE, $D6 // vpaddd xmm2, xmm2, xmm6 + db $C5, $F9, $7F, $5C, $24, $40 // vmovdqa oword [esp + $40], xmm3 + xor edi, eax + shld edx, edx, $5 + db $C5, $F1, $73, $DE, $04 // vpsrldq xmm1, xmm6, $4 + add ecx, esi + and ebp, edi + db $C5, $C1, $EF, $FB // vpxor xmm7, xmm7, xmm3 + xor edi, eax + add ecx, edx + db $C5, $F1, $EF, $CD // vpxor xmm1, xmm1, xmm5 + shrd edx, edx, $7 + xor ebp, eax + db $C5, $F9, $7F, $54, $24, $20 // vmovdqa oword [esp + $20], xmm2 + mov esi, ecx + add ebx, dword ptr [esp + $34] + db $C5, $C1, $EF, $F9 // vpxor xmm7, xmm7, xmm1 + xor edx, edi + shld ecx, ecx, $5 + add ebx, ebp + and esi, edx + db $C5, $F1, $72, $D7, $1F // vpsrld xmm1, xmm7, $1F + xor edx, edi + add ebx, ecx + shrd ecx, ecx, $7 + xor esi, edi + db $C5, $E1, $73, $FF, $0C // vpslldq xmm3, xmm7, $C + db $C5, $C1, $FE, $FF // vpaddd xmm7, xmm7, xmm7 + mov ebp, ebx + add eax, dword ptr [esp + $38] + xor ecx, edx + shld ebx, ebx, $5 + db $C5, $E9, $72, $D3, $1E // vpsrld xmm2, xmm3, $1E + db $C5, $C1, $EB, $F9 // vpor xmm7, xmm7, xmm1 + add eax, esi + and ebp, ecx + xor ecx, edx + add eax, ebx + db $C5, $E1, $72, $F3, $02 // vpslld xmm3, xmm3, $2 + db $C5, $F9, $6F, $4C, $24, $50 // vmovdqa xmm1, oword [esp + $50] + shrd ebx, ebx, $7 + xor ebp, edx + db $C5, $C1, $EF, $FA // vpxor xmm7, xmm7, xmm2 + mov esi, eax + add edi, dword ptr [esp + $3C] + xor ebx, ecx + shld eax, eax, $5 + db $C5, $C1, $EF, $FB // vpxor xmm7, xmm7, xmm3 + add edi, ebp + and esi, ebx + db $C5, $F9, $6F, $5C, $24, $70 // vmovdqa xmm3, oword [esp + $70] + xor ebx, ecx + add edi, eax + db $C4, $E3, $41, $0F, $D6, $08 // vpalignr xmm2, xmm7, xmm6, $8 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + shrd eax, eax, $7 + xor esi, ecx + mov ebp, edi + add edx, dword ptr [esp] + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C5, $F9, $7F, $64, $24, $50 // vmovdqa oword [esp + $50], xmm4 + xor eax, ebx + shld edi, edi, $5 + db $C5, $F9, $6F, $E3 // vmovdqa xmm4, xmm3 + db $C5, $E1, $FE, $DF // vpaddd xmm3, xmm3, xmm7 + add edx, esi + and ebp, eax + db $C5, $F9, $EF, $C2 // vpxor xmm0, xmm0, xmm2 + xor eax, ebx + add edx, edi + shrd edi, edi, $7 + xor ebp, ebx + db $C5, $E9, $72, $D0, $1E // vpsrld xmm2, xmm0, $1E + db $C5, $F9, $7F, $5C, $24, $30 // vmovdqa oword [esp + $30], xmm3 + mov esi, edx + add ecx, dword ptr [esp + $4] + xor edi, eax + shld edx, edx, $5 + db $C5, $F9, $72, $F0, $02 // vpslld xmm0, xmm0, $2 + add ecx, ebp + and esi, edi + xor edi, eax + add ecx, edx + shrd edx, edx, $7 + xor esi, eax + mov ebp, ecx + add ebx, dword ptr [esp + $8] + db $C5, $F9, $EB, $C2 // vpor xmm0, xmm0, xmm2 + xor edx, edi + shld ecx, ecx, $5 + db $C5, $F9, $6F, $54, $24, $60 // vmovdqa xmm2, oword [esp + $60] + add ebx, esi + and ebp, edx + xor edx, edi + add ebx, ecx + add eax, dword ptr [esp + $C] + xor ebp, edi + mov esi, ebx + shld ebx, ebx, $5 + add eax, ebp + xor esi, edx + shrd ecx, ecx, $7 + add eax, ebx + db $C4, $E3, $79, $0F, $DF, $08 // vpalignr xmm3, xmm0, xmm7, $8 + db $C5, $F1, $EF, $CD // vpxor xmm1, xmm1, xmm5 + add edi, dword ptr [esp + $10] + xor esi, ecx + mov ebp, eax + shld eax, eax, $5 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $F9, $7F, $6C, $24, $60 // vmovdqa oword [esp + $60], xmm5 + add edi, esi + xor ebp, ecx + db $C5, $F9, $6F, $EC // vmovdqa xmm5, xmm4 + db $C5, $D9, $FE, $E0 // vpaddd xmm4, xmm4, xmm0 + shrd ebx, ebx, $7 + add edi, eax + db $C5, $F1, $EF, $CB // vpxor xmm1, xmm1, xmm3 + add edx, dword ptr [esp + $14] + xor ebp, ebx + mov esi, edi + shld edi, edi, $5 + db $C5, $E1, $72, $D1, $1E // vpsrld xmm3, xmm1, $1E + db $C5, $F9, $7F, $24, $24 // vmovdqa oword [esp], xmm4 + add edx, ebp + xor esi, ebx + shrd eax, eax, $7 + add edx, edi + db $C5, $F1, $72, $F1, $02 // vpslld xmm1, xmm1, $2 + add ecx, dword ptr [esp + $18] + xor esi, eax + mov ebp, edx + shld edx, edx, $5 + add ecx, esi + xor ebp, eax + shrd edi, edi, $7 + add ecx, edx + db $C5, $F1, $EB, $CB // vpor xmm1, xmm1, xmm3 + add ebx, dword ptr [esp + $1C] + xor ebp, edi + db $C5, $F9, $6F, $5C, $24, $40 // vmovdqa xmm3, oword [esp + $40] + mov esi, ecx + shld ecx, ecx, $5 + add ebx, ebp + xor esi, edi + shrd edx, edx, $7 + add ebx, ecx + db $C4, $E3, $71, $0F, $E0, $08 // vpalignr xmm4, xmm1, xmm0, $8 + db $C5, $E9, $EF, $D6 // vpxor xmm2, xmm2, xmm6 + add eax, dword ptr [esp + $20] + xor esi, edx + mov ebp, ebx + shld ebx, ebx, $5 + db $C5, $E9, $EF, $D3 // vpxor xmm2, xmm2, xmm3 + db $C5, $F9, $7F, $74, $24, $40 // vmovdqa oword [esp + $40], xmm6 + add eax, esi + xor ebp, edx + db $C5, $F9, $6F, $B4, $24, $80, $00, $00, $00 // vmovdqa xmm6, oword [esp + $80] + db $C5, $D1, $FE, $E9 // vpaddd xmm5, xmm5, xmm1 + shrd ecx, ecx, $7 + add eax, ebx + db $C5, $E9, $EF, $D4 // vpxor xmm2, xmm2, xmm4 + add edi, dword ptr [esp + $24] + xor ebp, ecx + mov esi, eax + shld eax, eax, $5 + db $C5, $D9, $72, $D2, $1E // vpsrld xmm4, xmm2, $1E + db $C5, $F9, $7F, $6C, $24, $10 // vmovdqa oword [esp + $10], xmm5 + add edi, ebp + xor esi, ecx + shrd ebx, ebx, $7 + add edi, eax + db $C5, $E9, $72, $F2, $02 // vpslld xmm2, xmm2, $2 + add edx, dword ptr [esp + $28] + xor esi, ebx + mov ebp, edi + shld edi, edi, $5 + add edx, esi + xor ebp, ebx + shrd eax, eax, $7 + add edx, edi + db $C5, $E9, $EB, $D4 // vpor xmm2, xmm2, xmm4 + add ecx, dword ptr [esp + $2C] + xor ebp, eax + db $C5, $F9, $6F, $64, $24, $50 // vmovdqa xmm4, oword [esp + $50] + mov esi, edx + shld edx, edx, $5 + add ecx, ebp + xor esi, eax + shrd edi, edi, $7 + add ecx, edx + db $C4, $E3, $69, $0F, $E9, $08 // vpalignr xmm5, xmm2, xmm1, $8 + db $C5, $E1, $EF, $DF // vpxor xmm3, xmm3, xmm7 + add ebx, dword ptr [esp + $30] + xor esi, edi + mov ebp, ecx + shld ecx, ecx, $5 + db $C5, $E1, $EF, $DC // vpxor xmm3, xmm3, xmm4 + db $C5, $F9, $7F, $7C, $24, $50 // vmovdqa oword [esp + $50], xmm7 + add ebx, esi + xor ebp, edi + db $C5, $F9, $6F, $FE // vmovdqa xmm7, xmm6 + db $C5, $C9, $FE, $F2 // vpaddd xmm6, xmm6, xmm2 + shrd edx, edx, $7 + add ebx, ecx + db $C5, $E1, $EF, $DD // vpxor xmm3, xmm3, xmm5 + add eax, dword ptr [esp + $34] + xor ebp, edx + mov esi, ebx + shld ebx, ebx, $5 + db $C5, $D1, $72, $D3, $1E // vpsrld xmm5, xmm3, $1E + db $C5, $F9, $7F, $74, $24, $20 // vmovdqa oword [esp + $20], xmm6 + add eax, ebp + xor esi, edx + shrd ecx, ecx, $7 + add eax, ebx + db $C5, $E1, $72, $F3, $02 // vpslld xmm3, xmm3, $2 + add edi, dword ptr [esp + $38] + xor esi, ecx + mov ebp, eax + shld eax, eax, $5 + add edi, esi + xor ebp, ecx + shrd ebx, ebx, $7 + add edi, eax + db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + add edx, dword ptr [esp + $3C] + xor ebp, ebx + db $C5, $F9, $6F, $6C, $24, $60 // vmovdqa xmm5, oword [esp + $60] + mov esi, edi + shld edi, edi, $5 + add edx, ebp + xor esi, ebx + shrd eax, eax, $7 + add edx, edi + db $C4, $E3, $61, $0F, $F2, $08 // vpalignr xmm6, xmm3, xmm2, $8 + db $C5, $D9, $EF, $E0 // vpxor xmm4, xmm4, xmm0 + add ecx, dword ptr [esp] + xor esi, eax + mov ebp, edx + shld edx, edx, $5 + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + db $C5, $F9, $7F, $44, $24, $60 // vmovdqa oword [esp + $60], xmm0 + add ecx, esi + xor ebp, eax + db $C5, $F9, $6F, $C7 // vmovdqa xmm0, xmm7 + db $C5, $C1, $FE, $FB // vpaddd xmm7, xmm7, xmm3 + shrd edi, edi, $7 + add ecx, edx + db $C5, $D9, $EF, $E6 // vpxor xmm4, xmm4, xmm6 + add ebx, dword ptr [esp + $4] + xor ebp, edi + mov esi, ecx + shld ecx, ecx, $5 + db $C5, $C9, $72, $D4, $1E // vpsrld xmm6, xmm4, $1E + db $C5, $F9, $7F, $7C, $24, $30 // vmovdqa oword [esp + $30], xmm7 + add ebx, ebp + xor esi, edi + shrd edx, edx, $7 + add ebx, ecx + db $C5, $D9, $72, $F4, $02 // vpslld xmm4, xmm4, $2 + add eax, dword ptr [esp + $8] + xor esi, edx + mov ebp, ebx + shld ebx, ebx, $5 + add eax, esi + xor ebp, edx + shrd ecx, ecx, $7 + add eax, ebx + db $C5, $D9, $EB, $E6 // vpor xmm4, xmm4, xmm6 + add edi, dword ptr [esp + $C] + xor ebp, ecx + db $C5, $F9, $6F, $74, $24, $40 // vmovdqa xmm6, oword [esp + $40] + mov esi, eax + shld eax, eax, $5 + add edi, ebp + xor esi, ecx + shrd ebx, ebx, $7 + add edi, eax + db $C4, $E3, $59, $0F, $FB, $08 // vpalignr xmm7, xmm4, xmm3, $8 + db $C5, $D1, $EF, $E9 // vpxor xmm5, xmm5, xmm1 + add edx, dword ptr [esp + $10] + xor esi, ebx + mov ebp, edi + shld edi, edi, $5 + db $C5, $D1, $EF, $EE // vpxor xmm5, xmm5, xmm6 + db $C5, $F9, $7F, $4C, $24, $40 // vmovdqa oword [esp + $40], xmm1 + add edx, esi + xor ebp, ebx + db $C5, $F9, $6F, $C8 // vmovdqa xmm1, xmm0 + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + shrd eax, eax, $7 + add edx, edi + db $C5, $D1, $EF, $EF // vpxor xmm5, xmm5, xmm7 + add ecx, dword ptr [esp + $14] + xor ebp, eax + mov esi, edx + shld edx, edx, $5 + db $C5, $C1, $72, $D5, $1E // vpsrld xmm7, xmm5, $1E + db $C5, $F9, $7F, $04, $24 // vmovdqa oword [esp], xmm0 + add ecx, ebp + xor esi, eax + shrd edi, edi, $7 + add ecx, edx + db $C5, $D1, $72, $F5, $02 // vpslld xmm5, xmm5, $2 + add ebx, dword ptr [esp + $18] + xor esi, edi + mov ebp, ecx + shld ecx, ecx, $5 + add ebx, esi + xor ebp, edi + shrd edx, edx, $7 + add ebx, ecx + db $C5, $D1, $EB, $EF // vpor xmm5, xmm5, xmm7 + add eax, dword ptr [esp + $1C] + db $C5, $F9, $6F, $7C, $24, $50 // vmovdqa xmm7, oword [esp + $50] + shrd ecx, ecx, $7 + mov esi, ebx + xor ebp, edx + shld ebx, ebx, $5 + add eax, ebp + xor esi, ecx + xor ecx, edx + add eax, ebx + db $C4, $E3, $51, $0F, $C4, $08 // vpalignr xmm0, xmm5, xmm4, $8 + db $C5, $C9, $EF, $F2 // vpxor xmm6, xmm6, xmm2 + add edi, dword ptr [esp + $20] + and esi, ecx + xor ecx, edx + shrd ebx, ebx, $7 + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + db $C5, $F9, $7F, $54, $24, $50 // vmovdqa oword [esp + $50], xmm2 + mov ebp, eax + xor esi, ecx + db $C5, $F9, $6F, $D1 // vmovdqa xmm2, xmm1 + db $C5, $F1, $FE, $CD // vpaddd xmm1, xmm1, xmm5 + shld eax, eax, $5 + add edi, esi + db $C5, $C9, $EF, $F0 // vpxor xmm6, xmm6, xmm0 + xor ebp, ebx + xor ebx, ecx + add edi, eax + add edx, dword ptr [esp + $24] + db $C5, $F9, $72, $D6, $1E // vpsrld xmm0, xmm6, $1E + db $C5, $F9, $7F, $4C, $24, $10 // vmovdqa oword [esp + $10], xmm1 + and ebp, ebx + xor ebx, ecx + shrd eax, eax, $7 + mov esi, edi + db $C5, $C9, $72, $F6, $02 // vpslld xmm6, xmm6, $2 + xor ebp, ebx + shld edi, edi, $5 + add edx, ebp + xor esi, eax + xor eax, ebx + add edx, edi + add ecx, dword ptr [esp + $28] + and esi, eax + db $C5, $C9, $EB, $F0 // vpor xmm6, xmm6, xmm0 + xor eax, ebx + shrd edi, edi, $7 + db $C5, $F9, $6F, $44, $24, $60 // vmovdqa xmm0, oword [esp + $60] + mov ebp, edx + xor esi, eax + shld edx, edx, $5 + add ecx, esi + xor ebp, edi + xor edi, eax + add ecx, edx + add ebx, dword ptr [esp + $2C] + and ebp, edi + xor edi, eax + shrd edx, edx, $7 + mov esi, ecx + xor ebp, edi + shld ecx, ecx, $5 + add ebx, ebp + xor esi, edx + xor edx, edi + add ebx, ecx + db $C4, $E3, $49, $0F, $CD, $08 // vpalignr xmm1, xmm6, xmm5, $8 + db $C5, $C1, $EF, $FB // vpxor xmm7, xmm7, xmm3 + add eax, dword ptr [esp + $30] + and esi, edx + xor edx, edi + shrd ecx, ecx, $7 + db $C5, $C1, $EF, $F8 // vpxor xmm7, xmm7, xmm0 + db $C5, $F9, $7F, $5C, $24, $60 // vmovdqa oword [esp + $60], xmm3 + mov ebp, ebx + xor esi, edx + db $C5, $F9, $6F, $9C, $24, $90, $00, $00, $00 // vmovdqa xmm3, oword [esp + $90] + db $C5, $E9, $FE, $D6 // vpaddd xmm2, xmm2, xmm6 + shld ebx, ebx, $5 + add eax, esi + db $C5, $C1, $EF, $F9 // vpxor xmm7, xmm7, xmm1 + xor ebp, ecx + xor ecx, edx + add eax, ebx + add edi, dword ptr [esp + $34] + db $C5, $F1, $72, $D7, $1E // vpsrld xmm1, xmm7, $1E + db $C5, $F9, $7F, $54, $24, $20 // vmovdqa oword [esp + $20], xmm2 + and ebp, ecx + xor ecx, edx + shrd ebx, ebx, $7 + mov esi, eax + db $C5, $C1, $72, $F7, $02 // vpslld xmm7, xmm7, $2 + xor ebp, ecx + shld eax, eax, $5 + add edi, ebp + xor esi, ebx + xor ebx, ecx + add edi, eax + add edx, dword ptr [esp + $38] + and esi, ebx + db $C5, $C1, $EB, $F9 // vpor xmm7, xmm7, xmm1 + xor ebx, ecx + shrd eax, eax, $7 + db $C5, $F9, $6F, $4C, $24, $40 // vmovdqa xmm1, oword [esp + $40] + mov ebp, edi + xor esi, ebx + shld edi, edi, $5 + add edx, esi + xor ebp, eax + xor eax, ebx + add edx, edi + add ecx, dword ptr [esp + $3C] + and ebp, eax + xor eax, ebx + shrd edi, edi, $7 + mov esi, edx + xor ebp, eax + shld edx, edx, $5 + add ecx, ebp + xor esi, edi + xor edi, eax + add ecx, edx + db $C4, $E3, $41, $0F, $D6, $08 // vpalignr xmm2, xmm7, xmm6, $8 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + add ebx, dword ptr [esp] + and esi, edi + xor edi, eax + shrd edx, edx, $7 + db $C5, $F9, $EF, $C1 // vpxor xmm0, xmm0, xmm1 + db $C5, $F9, $7F, $64, $24, $40 // vmovdqa oword [esp + $40], xmm4 + mov ebp, ecx + xor esi, edi + db $C5, $F9, $6F, $E3 // vmovdqa xmm4, xmm3 + db $C5, $E1, $FE, $DF // vpaddd xmm3, xmm3, xmm7 + shld ecx, ecx, $5 + add ebx, esi + db $C5, $F9, $EF, $C2 // vpxor xmm0, xmm0, xmm2 + xor ebp, edx + xor edx, edi + add ebx, ecx + add eax, dword ptr [esp + $4] + db $C5, $E9, $72, $D0, $1E // vpsrld xmm2, xmm0, $1E + db $C5, $F9, $7F, $5C, $24, $30 // vmovdqa oword [esp + $30], xmm3 + and ebp, edx + xor edx, edi + shrd ecx, ecx, $7 + mov esi, ebx + db $C5, $F9, $72, $F0, $02 // vpslld xmm0, xmm0, $2 + xor ebp, edx + shld ebx, ebx, $5 + add eax, ebp + xor esi, ecx + xor ecx, edx + add eax, ebx + add edi, dword ptr [esp + $8] + and esi, ecx + db $C5, $F9, $EB, $C2 // vpor xmm0, xmm0, xmm2 + xor ecx, edx + shrd ebx, ebx, $7 + db $C5, $F9, $6F, $54, $24, $50 // vmovdqa xmm2, oword [esp + $50] + mov ebp, eax + xor esi, ecx + shld eax, eax, $5 + add edi, esi + xor ebp, ebx + xor ebx, ecx + add edi, eax + add edx, dword ptr [esp + $C] + and ebp, ebx + xor ebx, ecx + shrd eax, eax, $7 + mov esi, edi + xor ebp, ebx + shld edi, edi, $5 + add edx, ebp + xor esi, eax + xor eax, ebx + add edx, edi + db $C4, $E3, $79, $0F, $DF, $08 // vpalignr xmm3, xmm0, xmm7, $8 + db $C5, $F1, $EF, $CD // vpxor xmm1, xmm1, xmm5 + add ecx, dword ptr [esp + $10] + and esi, eax + xor eax, ebx + shrd edi, edi, $7 + db $C5, $F1, $EF, $CA // vpxor xmm1, xmm1, xmm2 + db $C5, $F9, $7F, $6C, $24, $50 // vmovdqa oword [esp + $50], xmm5 + mov ebp, edx + xor esi, eax + db $C5, $F9, $6F, $EC // vmovdqa xmm5, xmm4 + db $C5, $D9, $FE, $E0 // vpaddd xmm4, xmm4, xmm0 + shld edx, edx, $5 + add ecx, esi + db $C5, $F1, $EF, $CB // vpxor xmm1, xmm1, xmm3 + xor ebp, edi + xor edi, eax + add ecx, edx + add ebx, dword ptr [esp + $14] + db $C5, $E1, $72, $D1, $1E // vpsrld xmm3, xmm1, $1E + db $C5, $F9, $7F, $24, $24 // vmovdqa oword [esp], xmm4 + and ebp, edi + xor edi, eax + shrd edx, edx, $7 + mov esi, ecx + db $C5, $F1, $72, $F1, $02 // vpslld xmm1, xmm1, $2 + xor ebp, edi + shld ecx, ecx, $5 + add ebx, ebp + xor esi, edx + xor edx, edi + add ebx, ecx + add eax, dword ptr [esp + $18] + and esi, edx + db $C5, $F1, $EB, $CB // vpor xmm1, xmm1, xmm3 + xor edx, edi + shrd ecx, ecx, $7 + db $C5, $F9, $6F, $5C, $24, $60 // vmovdqa xmm3, oword [esp + $60] + mov ebp, ebx + xor esi, edx + shld ebx, ebx, $5 + add eax, esi + xor ebp, ecx + xor ecx, edx + add eax, ebx + add edi, dword ptr [esp + $1C] + and ebp, ecx + xor ecx, edx + shrd ebx, ebx, $7 + mov esi, eax + xor ebp, ecx + shld eax, eax, $5 + add edi, ebp + xor esi, ebx + xor ebx, ecx + add edi, eax + db $C4, $E3, $71, $0F, $E0, $08 // vpalignr xmm4, xmm1, xmm0, $8 + db $C5, $E9, $EF, $D6 // vpxor xmm2, xmm2, xmm6 + add edx, dword ptr [esp + $20] + and esi, ebx + xor ebx, ecx + shrd eax, eax, $7 + db $C5, $E9, $EF, $D3 // vpxor xmm2, xmm2, xmm3 + db $C5, $F9, $7F, $74, $24, $60 // vmovdqa oword [esp + $60], xmm6 + mov ebp, edi + xor esi, ebx + db $C5, $F9, $6F, $F5 // vmovdqa xmm6, xmm5 + db $C5, $D1, $FE, $E9 // vpaddd xmm5, xmm5, xmm1 + shld edi, edi, $5 + add edx, esi + db $C5, $E9, $EF, $D4 // vpxor xmm2, xmm2, xmm4 + xor ebp, eax + xor eax, ebx + add edx, edi + add ecx, dword ptr [esp + $24] + db $C5, $D9, $72, $D2, $1E // vpsrld xmm4, xmm2, $1E + db $C5, $F9, $7F, $6C, $24, $10 // vmovdqa oword [esp + $10], xmm5 + and ebp, eax + xor eax, ebx + shrd edi, edi, $7 + mov esi, edx + db $C5, $E9, $72, $F2, $02 // vpslld xmm2, xmm2, $2 + xor ebp, eax + shld edx, edx, $5 + add ecx, ebp + xor esi, edi + xor edi, eax + add ecx, edx + add ebx, dword ptr [esp + $28] + and esi, edi + db $C5, $E9, $EB, $D4 // vpor xmm2, xmm2, xmm4 + xor edi, eax + shrd edx, edx, $7 + db $C5, $F9, $6F, $64, $24, $40 // vmovdqa xmm4, oword [esp + $40] + mov ebp, ecx + xor esi, edi + shld ecx, ecx, $5 + add ebx, esi + xor ebp, edx + xor edx, edi + add ebx, ecx + add eax, dword ptr [esp + $2C] + and ebp, edx + xor edx, edi + shrd ecx, ecx, $7 + mov esi, ebx + xor ebp, edx + shld ebx, ebx, $5 + add eax, ebp + xor esi, edx + add eax, ebx + db $C4, $E3, $69, $0F, $E9, $08 // vpalignr xmm5, xmm2, xmm1, $8 + db $C5, $E1, $EF, $DF // vpxor xmm3, xmm3, xmm7 + add edi, dword ptr [esp + $30] + xor esi, ecx + mov ebp, eax + shld eax, eax, $5 + db $C5, $E1, $EF, $DC // vpxor xmm3, xmm3, xmm4 + db $C5, $F9, $7F, $7C, $24, $40 // vmovdqa oword [esp + $40], xmm7 + add edi, esi + xor ebp, ecx + db $C5, $F9, $6F, $FE // vmovdqa xmm7, xmm6 + db $C5, $C9, $FE, $F2 // vpaddd xmm6, xmm6, xmm2 + shrd ebx, ebx, $7 + add edi, eax + db $C5, $E1, $EF, $DD // vpxor xmm3, xmm3, xmm5 + add edx, dword ptr [esp + $34] + xor ebp, ebx + mov esi, edi + shld edi, edi, $5 + db $C5, $D1, $72, $D3, $1E // vpsrld xmm5, xmm3, $1E + db $C5, $F9, $7F, $74, $24, $20 // vmovdqa oword [esp + $20], xmm6 + add edx, ebp + xor esi, ebx + shrd eax, eax, $7 + add edx, edi + db $C5, $E1, $72, $F3, $02 // vpslld xmm3, xmm3, $2 + add ecx, dword ptr [esp + $38] + xor esi, eax + mov ebp, edx + shld edx, edx, $5 + add ecx, esi + xor ebp, eax + shrd edi, edi, $7 + add ecx, edx + db $C5, $E1, $EB, $DD // vpor xmm3, xmm3, xmm5 + add ebx, dword ptr [esp + $3C] + xor ebp, edi + mov esi, ecx + shld ecx, ecx, $5 + add ebx, ebp + xor esi, edi + shrd edx, edx, $7 + add ebx, ecx + add eax, dword ptr [esp] + db $C5, $C1, $FE, $FB // vpaddd xmm7, xmm7, xmm3 + xor esi, edx + mov ebp, ebx + shld ebx, ebx, $5 + add eax, esi + db $C5, $F9, $7F, $7C, $24, $30 // vmovdqa oword [esp + $30], xmm7 + xor ebp, edx + shrd ecx, ecx, $7 + add eax, ebx + add edi, dword ptr [esp + $4] + xor ebp, ecx + mov esi, eax + shld eax, eax, $5 + add edi, ebp + xor esi, ecx + shrd ebx, ebx, $7 + add edi, eax + add edx, dword ptr [esp + $8] + xor esi, ebx + mov ebp, edi + shld edi, edi, $5 + add edx, esi + xor ebp, ebx + shrd eax, eax, $7 + add edx, edi + add ecx, dword ptr [esp + $C] + xor ebp, eax + mov esi, edx + shld edx, edx, $5 + add ecx, ebp + xor esi, eax + shrd edi, edi, $7 + add ecx, edx + mov ebp, dword ptr [esp + $C4] + cmp ebp, dword ptr [esp + $C8] + je @done_010 + db $C5, $F9, $6F, $BC, $24, $A0, $00, $00, $00 // vmovdqa xmm7, oword [esp + $A0] + db $C5, $F9, $6F, $B4, $24, $B0, $00, $00, $00 // vmovdqa xmm6, oword [esp + $B0] + db $C5, $FA, $6F, $45, $00 // vmovdqu xmm0, oword [ebp + $0] + db $C5, $FA, $6F, $4D, $10 // vmovdqu xmm1, oword [ebp + $10] + db $C5, $FA, $6F, $55, $20 // vmovdqu xmm2, oword [ebp + $20] + db $C5, $FA, $6F, $5D, $30 // vmovdqu xmm3, oword [ebp + $30] + add ebp, $40 + db $C4, $E2, $79, $00, $C6 // vpshufb xmm0, xmm0, xmm6 + mov dword ptr [esp + $C4], ebp + db $C5, $F9, $7F, $7C, $24, $60 // vmovdqa oword [esp + $60], xmm7 + add ebx, dword ptr [esp + $10] + xor esi, edi + db $C4, $E2, $71, $00, $CE // vpshufb xmm1, xmm1, xmm6 + mov ebp, ecx + shld ecx, ecx, $5 + db $C5, $F9, $FE, $E7 // vpaddd xmm4, xmm0, xmm7 + add ebx, esi + xor ebp, edi + shrd edx, edx, $7 + add ebx, ecx + db $C5, $F9, $7F, $24, $24 // vmovdqa oword [esp], xmm4 + add eax, dword ptr [esp + $14] + xor ebp, edx + mov esi, ebx + shld ebx, ebx, $5 + add eax, ebp + xor esi, edx + shrd ecx, ecx, $7 + add eax, ebx + add edi, dword ptr [esp + $18] + xor esi, ecx + mov ebp, eax + shld eax, eax, $5 + add edi, esi + xor ebp, ecx + shrd ebx, ebx, $7 + add edi, eax + add edx, dword ptr [esp + $1C] + xor ebp, ebx + mov esi, edi + shld edi, edi, $5 + add edx, ebp + xor esi, ebx + shrd eax, eax, $7 + add edx, edi + add ecx, dword ptr [esp + $20] + xor esi, eax + db $C4, $E2, $69, $00, $D6 // vpshufb xmm2, xmm2, xmm6 + mov ebp, edx + shld edx, edx, $5 + db $C5, $F1, $FE, $EF // vpaddd xmm5, xmm1, xmm7 + add ecx, esi + xor ebp, eax + shrd edi, edi, $7 + add ecx, edx + db $C5, $F9, $7F, $6C, $24, $10 // vmovdqa oword [esp + $10], xmm5 + add ebx, dword ptr [esp + $24] + xor ebp, edi + mov esi, ecx + shld ecx, ecx, $5 + add ebx, ebp + xor esi, edi + shrd edx, edx, $7 + add ebx, ecx + add eax, dword ptr [esp + $28] + xor esi, edx + mov ebp, ebx + shld ebx, ebx, $5 + add eax, esi + xor ebp, edx + shrd ecx, ecx, $7 + add eax, ebx + add edi, dword ptr [esp + $2C] + xor ebp, ecx + mov esi, eax + shld eax, eax, $5 + add edi, ebp + xor esi, ecx + shrd ebx, ebx, $7 + add edi, eax + add edx, dword ptr [esp + $30] + xor esi, ebx + db $C4, $E2, $61, $00, $DE // vpshufb xmm3, xmm3, xmm6 + mov ebp, edi + shld edi, edi, $5 + db $C5, $E9, $FE, $F7 // vpaddd xmm6, xmm2, xmm7 + add edx, esi + xor ebp, ebx + shrd eax, eax, $7 + add edx, edi + db $C5, $F9, $7F, $74, $24, $20 // vmovdqa oword [esp + $20], xmm6 + add ecx, dword ptr [esp + $34] + xor ebp, eax + mov esi, edx + shld edx, edx, $5 + add ecx, ebp + xor esi, eax + shrd edi, edi, $7 + add ecx, edx + add ebx, dword ptr [esp + $38] + xor esi, edi + mov ebp, ecx + shld ecx, ecx, $5 + add ebx, esi + xor ebp, edi + shrd edx, edx, $7 + add ebx, ecx + add eax, dword ptr [esp + $3C] + xor ebp, edx + mov esi, ebx + shld ebx, ebx, $5 + add eax, ebp + shrd ecx, ecx, $7 + add eax, ebx + mov ebp, dword ptr [esp + $C0] + add eax, dword ptr [ebp + $0] + add esi, dword ptr [ebp + $4] + add ecx, dword ptr [ebp + $8] + mov dword ptr [ebp + $0], eax + add edx, dword ptr [ebp + $C] + mov dword ptr [ebp + $4], esi + add edi, dword ptr [ebp + $10] + mov ebx, ecx + mov dword ptr [ebp + $8], ecx + xor ebx, edx + mov dword ptr [ebp + $C], edx + mov dword ptr [ebp + $10], edi + mov ebp, esi + and esi, ebx + mov ebx, ebp + jmp @loop_009 + +@done_010: + add ebx, dword ptr [esp + $10] + xor esi, edi + mov ebp, ecx + shld ecx, ecx, $5 + add ebx, esi + xor ebp, edi + shrd edx, edx, $7 + add ebx, ecx + add eax, dword ptr [esp + $14] + xor ebp, edx + mov esi, ebx + shld ebx, ebx, $5 + add eax, ebp + xor esi, edx + shrd ecx, ecx, $7 + add eax, ebx + add edi, dword ptr [esp + $18] + xor esi, ecx + mov ebp, eax + shld eax, eax, $5 + add edi, esi + xor ebp, ecx + shrd ebx, ebx, $7 + add edi, eax + add edx, dword ptr [esp + $1C] + xor ebp, ebx + mov esi, edi + shld edi, edi, $5 + add edx, ebp + xor esi, ebx + shrd eax, eax, $7 + add edx, edi + add ecx, dword ptr [esp + $20] + xor esi, eax + mov ebp, edx + shld edx, edx, $5 + add ecx, esi + xor ebp, eax + shrd edi, edi, $7 + add ecx, edx + add ebx, dword ptr [esp + $24] + xor ebp, edi + mov esi, ecx + shld ecx, ecx, $5 + add ebx, ebp + xor esi, edi + shrd edx, edx, $7 + add ebx, ecx + add eax, dword ptr [esp + $28] + xor esi, edx + mov ebp, ebx + shld ebx, ebx, $5 + add eax, esi + xor ebp, edx + shrd ecx, ecx, $7 + add eax, ebx + add edi, dword ptr [esp + $2C] + xor ebp, ecx + mov esi, eax + shld eax, eax, $5 + add edi, ebp + xor esi, ecx + shrd ebx, ebx, $7 + add edi, eax + add edx, dword ptr [esp + $30] + xor esi, ebx + mov ebp, edi + shld edi, edi, $5 + add edx, esi + xor ebp, ebx + shrd eax, eax, $7 + add edx, edi + add ecx, dword ptr [esp + $34] + xor ebp, eax + mov esi, edx + shld edx, edx, $5 + add ecx, ebp + xor esi, eax + shrd edi, edi, $7 + add ecx, edx + add ebx, dword ptr [esp + $38] + xor esi, edi + mov ebp, ecx + shld ecx, ecx, $5 + add ebx, esi + xor ebp, edi + shrd edx, edx, $7 + add ebx, ecx + add eax, dword ptr [esp + $3C] + xor ebp, edx + mov esi, ebx + shld ebx, ebx, $5 + add eax, ebp + shrd ecx, ecx, $7 + add eax, ebx + db $C5, $FC, $77 // vzeroall + mov ebp, dword ptr [esp + $C0] + add eax, dword ptr [ebp + $0] + mov esp, dword ptr [esp + $CC] + add esi, dword ptr [ebp + $4] + add ecx, dword ptr [ebp + $8] + mov dword ptr [ebp + $0], eax + add edx, dword ptr [ebp + $C] + mov dword ptr [ebp + $4], esi + add edi, dword ptr [ebp + $10] + mov dword ptr [ebp + $8], ecx + mov dword ptr [ebp + $C], edx + mov dword ptr [ebp + $10], edi + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc index c334e8f..4adc220 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc @@ -1,9 +1,9 @@ -// SHA-1 AVX2 two-block implementation (VEX-256), ported from OpenSSL's -// sha1-x86_64.pl (CRYPTOGAMS). Two message blocks are scheduled together in -// 256-bit lanes and the 80 rounds are interleaved with the SIMD schedule, so the -// vector and integer units run in parallel. AVX2 and BMI (rorx/andn/shlx) -// instructions are db-encoded for broad assembler compatibility (every AVX2 CPU -// also provides BMI). +// SHA-1 AVX2 two-block implementation (VEX-256). Two message blocks are +// scheduled together in 256-bit lanes and the 80 rounds are interleaved with +// the SIMD schedule, so the vector and integer units run in parallel. AVX2 and +// BMI (rorx/andn/shlx) instructions are db-encoded for broad assembler +// compatibility (every AVX2 CPU also provides BMI). +// Reference: OpenSSL CRYPTOGAMS sha1-x86_64.pl (AVX2 kernel). // Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = K_SHA1_Doubled ptr (the four SHA-1 round constants each // replicated across 256 bits, then the byte-swap mask and a reverse mask; see diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc new file mode 100644 index 0000000..8439c38 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc @@ -0,0 +1,171 @@ +// SHA-1 SHA-NI implementation (IA-32; Intel SHA Extensions work in 32-bit +// mode). The twenty sha1rnds4 steps carry their round constants as +// immediates; the only table read is the 16-byte flip mask, taken from +// K_SHA1_Doubled at +160 (byte-identical to the original's .LK_XX_XX+80; read +// unaligned - Pascal consts have no alignment guarantee). SHA-NI and shuffle +// instructions are db-encoded for broad assembler compatibility. The +// original's PIC table setup and stack-argument reads are replaced by the +// shared-prologue registers. +// Reference: OpenSSL CRYPTOGAMS sha1-586.pl (shaext function). +// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, +// edi = numblocks, eax = K_SHA1_Doubled ptr. HlpSimdProc4Begin pushes +// ebx/esi/edi; ebp is pushed here, giving the 4-deep frame the original +// epilogue unwinds via its saved-esp register. + + push ebp + mov ebp, eax + mov ecx, edi + mov edi, ebx + mov ebx, esp + sub esp, $20 + movdqu xmm0, oword ptr [edi] + movd xmm1, dword ptr [edi + $10] + and esp, $FFFFFFE0 + movdqu xmm3, oword ptr [ebp + $A0] + movdqu xmm4, oword ptr [esi] + pshufd xmm0, xmm0, $1B + movdqu xmm5, oword ptr [esi + $10] + pshufd xmm1, xmm1, $1B + movdqu xmm6, oword ptr [esi + $20] + db $66, $0F, $38, $00, $E3 // pshufb xmm4, xmm3 + movdqu xmm7, oword ptr [esi + $30] + db $66, $0F, $38, $00, $EB // pshufb xmm5, xmm3 + db $66, $0F, $38, $00, $F3 // pshufb xmm6, xmm3 + db $66, $0F, $38, $00, $FB // pshufb xmm7, xmm3 + jmp @loop_shaext_004 + +@loop_shaext_004: + dec ecx + lea eax, [esi + $40] + movdqa oword ptr [esp], xmm1 + paddd xmm1, xmm4 + cmovne esi, eax + movdqa oword ptr [esp + $10], xmm0 + db $0F, $38, $C9, $E5 // sha1msg1 xmm4, xmm5 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $00 // sha1rnds4 xmm0, xmm1, $0 + db $0F, $38, $C8, $D5 // sha1nexte xmm2, xmm5 + pxor xmm4, xmm6 + db $0F, $38, $C9, $EE // sha1msg1 xmm5, xmm6 + db $0F, $38, $CA, $E7 // sha1msg2 xmm4, xmm7 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $00 // sha1rnds4 xmm0, xmm2, $0 + db $0F, $38, $C8, $CE // sha1nexte xmm1, xmm6 + pxor xmm5, xmm7 + db $0F, $38, $CA, $EC // sha1msg2 xmm5, xmm4 + db $0F, $38, $C9, $F7 // sha1msg1 xmm6, xmm7 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $00 // sha1rnds4 xmm0, xmm1, $0 + db $0F, $38, $C8, $D7 // sha1nexte xmm2, xmm7 + pxor xmm6, xmm4 + db $0F, $38, $C9, $FC // sha1msg1 xmm7, xmm4 + db $0F, $38, $CA, $F5 // sha1msg2 xmm6, xmm5 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $00 // sha1rnds4 xmm0, xmm2, $0 + db $0F, $38, $C8, $CC // sha1nexte xmm1, xmm4 + pxor xmm7, xmm5 + db $0F, $38, $CA, $FE // sha1msg2 xmm7, xmm6 + db $0F, $38, $C9, $E5 // sha1msg1 xmm4, xmm5 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $00 // sha1rnds4 xmm0, xmm1, $0 + db $0F, $38, $C8, $D5 // sha1nexte xmm2, xmm5 + pxor xmm4, xmm6 + db $0F, $38, $C9, $EE // sha1msg1 xmm5, xmm6 + db $0F, $38, $CA, $E7 // sha1msg2 xmm4, xmm7 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $01 // sha1rnds4 xmm0, xmm2, $1 + db $0F, $38, $C8, $CE // sha1nexte xmm1, xmm6 + pxor xmm5, xmm7 + db $0F, $38, $CA, $EC // sha1msg2 xmm5, xmm4 + db $0F, $38, $C9, $F7 // sha1msg1 xmm6, xmm7 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $01 // sha1rnds4 xmm0, xmm1, $1 + db $0F, $38, $C8, $D7 // sha1nexte xmm2, xmm7 + pxor xmm6, xmm4 + db $0F, $38, $C9, $FC // sha1msg1 xmm7, xmm4 + db $0F, $38, $CA, $F5 // sha1msg2 xmm6, xmm5 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $01 // sha1rnds4 xmm0, xmm2, $1 + db $0F, $38, $C8, $CC // sha1nexte xmm1, xmm4 + pxor xmm7, xmm5 + db $0F, $38, $CA, $FE // sha1msg2 xmm7, xmm6 + db $0F, $38, $C9, $E5 // sha1msg1 xmm4, xmm5 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $01 // sha1rnds4 xmm0, xmm1, $1 + db $0F, $38, $C8, $D5 // sha1nexte xmm2, xmm5 + pxor xmm4, xmm6 + db $0F, $38, $C9, $EE // sha1msg1 xmm5, xmm6 + db $0F, $38, $CA, $E7 // sha1msg2 xmm4, xmm7 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $01 // sha1rnds4 xmm0, xmm2, $1 + db $0F, $38, $C8, $CE // sha1nexte xmm1, xmm6 + pxor xmm5, xmm7 + db $0F, $38, $CA, $EC // sha1msg2 xmm5, xmm4 + db $0F, $38, $C9, $F7 // sha1msg1 xmm6, xmm7 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $02 // sha1rnds4 xmm0, xmm1, $2 + db $0F, $38, $C8, $D7 // sha1nexte xmm2, xmm7 + pxor xmm6, xmm4 + db $0F, $38, $C9, $FC // sha1msg1 xmm7, xmm4 + db $0F, $38, $CA, $F5 // sha1msg2 xmm6, xmm5 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $02 // sha1rnds4 xmm0, xmm2, $2 + db $0F, $38, $C8, $CC // sha1nexte xmm1, xmm4 + pxor xmm7, xmm5 + db $0F, $38, $CA, $FE // sha1msg2 xmm7, xmm6 + db $0F, $38, $C9, $E5 // sha1msg1 xmm4, xmm5 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $02 // sha1rnds4 xmm0, xmm1, $2 + db $0F, $38, $C8, $D5 // sha1nexte xmm2, xmm5 + pxor xmm4, xmm6 + db $0F, $38, $C9, $EE // sha1msg1 xmm5, xmm6 + db $0F, $38, $CA, $E7 // sha1msg2 xmm4, xmm7 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $02 // sha1rnds4 xmm0, xmm2, $2 + db $0F, $38, $C8, $CE // sha1nexte xmm1, xmm6 + pxor xmm5, xmm7 + db $0F, $38, $CA, $EC // sha1msg2 xmm5, xmm4 + db $0F, $38, $C9, $F7 // sha1msg1 xmm6, xmm7 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $02 // sha1rnds4 xmm0, xmm1, $2 + db $0F, $38, $C8, $D7 // sha1nexte xmm2, xmm7 + pxor xmm6, xmm4 + db $0F, $38, $C9, $FC // sha1msg1 xmm7, xmm4 + db $0F, $38, $CA, $F5 // sha1msg2 xmm6, xmm5 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $03 // sha1rnds4 xmm0, xmm2, $3 + db $0F, $38, $C8, $CC // sha1nexte xmm1, xmm4 + pxor xmm7, xmm5 + db $0F, $38, $CA, $FE // sha1msg2 xmm7, xmm6 + movdqu xmm4, oword ptr [esi] + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $03 // sha1rnds4 xmm0, xmm1, $3 + db $0F, $38, $C8, $D5 // sha1nexte xmm2, xmm5 + movdqu xmm5, oword ptr [esi + $10] + db $66, $0F, $38, $00, $E3 // pshufb xmm4, xmm3 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $03 // sha1rnds4 xmm0, xmm2, $3 + db $0F, $38, $C8, $CE // sha1nexte xmm1, xmm6 + movdqu xmm6, oword ptr [esi + $20] + db $66, $0F, $38, $00, $EB // pshufb xmm5, xmm3 + movdqa xmm2, xmm0 + db $0F, $3A, $CC, $C1, $03 // sha1rnds4 xmm0, xmm1, $3 + db $0F, $38, $C8, $D7 // sha1nexte xmm2, xmm7 + movdqu xmm7, oword ptr [esi + $30] + db $66, $0F, $38, $00, $F3 // pshufb xmm6, xmm3 + movdqa xmm1, xmm0 + db $0F, $3A, $CC, $C2, $03 // sha1rnds4 xmm0, xmm2, $3 + movdqa xmm2, oword ptr [esp] + db $66, $0F, $38, $00, $FB // pshufb xmm7, xmm3 + db $0F, $38, $C8, $CA // sha1nexte xmm1, xmm2 + paddd xmm0, oword ptr [esp + $10] + jnz @loop_shaext_004 + pshufd xmm0, xmm0, $1B + pshufd xmm1, xmm1, $1B + movdqu oword ptr [edi], xmm0 + movd dword ptr [edi + $10], xmm1 + mov esp, ebx + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc index 35e72da..8c3376f 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc @@ -1,11 +1,11 @@ -// SHA-1 SHA-NI implementation (Intel SHA Extensions), the same design as -// OpenSSL's x86_64 sha1_block_data_order_shaext (CRYPTOGAMS). The 20 sha1rnds4 +// SHA-1 SHA-NI implementation (Intel SHA Extensions). The 20 sha1rnds4 // groups run with the message schedule (sha1msg1/sha1msg2/sha1nexte) interleaved. // The input is byte-swapped with a single pshufb against a full-reverse mask // (byte-swap and dword-reverse folded into one mask, loaded once into xmm3), so // no per-word pshufd is needed. The next block's message loads are software- // pipelined into rounds 64-79 and the data pointer is advanced branchlessly // (cmovnz). +// Reference: OpenSSL CRYPTOGAMS x86_64 sha1_block_data_order_shaext. // // Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = round-constant ptr (unused - sha1rnds4 has the round diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc index 3cfb9fd..03cc2d7 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc @@ -1,9 +1,10 @@ -// SHA-1 SSE2 SIMD-schedule implementation (IA-32), derived from OpenSSL's -// sha1-586 (CRYPTOGAMS) SSSE3 kernel. The message schedule runs in SSE2 -// (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression rounds. -// OpenSSL's only SSSE3-only op is the pshufb input byte-swap, emulated in SSE2 as -// psrlw/psllw/por + pshuflw/pshufhw (the freed byte-swap-mask register xmm6 is the -// scratch); the W-schedule uses no palignr. +// SHA-1 SSE2 SIMD-schedule implementation (IA-32). The message schedule runs +// in SSE2 (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression +// rounds. The original's only SSSE3-only op is the pshufb input byte-swap, +// emulated in SSE2 as psrlw/psllw/por + pshuflw/pshufhw (the freed +// byte-swap-mask register xmm6 is the scratch); the W-schedule uses no +// palignr. +// Reference: OpenSSL CRYPTOGAMS sha1-586.pl (SSSE3 kernel). // Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, // eax = doubled-K_SHA1 ptr (read at a 32-byte stride so the duplicated halves // are skipped; see K_SHA1_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc index 7b9e57c..c997e8b 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc @@ -1,10 +1,10 @@ -// SHA-1 SSE2 SIMD-schedule implementation, derived from OpenSSL's SHA-1 SSSE3 -// kernel in sha1-x86_64.pl (CRYPTOGAMS). The message schedule runs in SSE2 +// SHA-1 SSE2 SIMD-schedule implementation. The message schedule runs in SSE2 // (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression rounds, so the -// vector and integer units run in parallel. OpenSSL's only SSSE3-only op here is -// the pshufb input byte-swap, which is emulated in SSE2 (psrlw/psllw/por + +// vector and integer units run in parallel. The original's only SSSE3-only op here +// is the pshufb input byte-swap, which is emulated in SSE2 (psrlw/psllw/por + // pshuflw/pshufhw; xmm12 is a free scratch); the W-schedule uses no palignr. The // appended masks go unused - the byte-swap is computed, not shuffled. +// Reference: OpenSSL CRYPTOGAMS sha1-x86_64.pl (SSSE3 kernel). // Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K_SHA1 ptr (read 128-bit at a 32-byte stride, // r14 = K + 64, so the duplicated halves are skipped; see K_SHA1_Doubled). diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc new file mode 100644 index 0000000..493837a --- /dev/null +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc @@ -0,0 +1,1221 @@ +// SHA-1 SSSE3 SIMD-schedule implementation (IA-32); SSE2 sibling: +// SHA1CompressSse2_i386.inc. +// The message schedule runs in SIMD (pxor/pshufd/psrldq/pslldq) interleaved +// with the GPR compression rounds. Unlike the SSE2 sibling the input +// byte-swaps are real pshufb (db-encoded for broad assembler compatibility) +// against the mask kept resident in xmm6; the W-schedule uses no palignr. +// Reference: OpenSSL CRYPTOGAMS sha1-586.pl (SSSE3 kernel). +// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, +// eax = doubled-K_SHA1 ptr (read at a 32-byte stride so the duplicated halves +// are skipped; see K_SHA1_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is +// pushed here as the K pointer, then reused as the data pointer and for the +// state writeback. + + push ebp + mov ebp, eax + + movdqu xmm7, oword [ebp + $0] + movdqu xmm0, oword [ebp + $20] + movdqu xmm1, oword [ebp + $40] + movdqu xmm2, oword [ebp + $60] + movdqu xmm6, oword [ebp + $80] + mov edx, edi + mov edi, ebx + mov ebp, esi + mov esi, esp + sub esp, $D0 + and esp, $FFFFFFC0 + movdqa oword [esp + $70], xmm0 + movdqa oword [esp + $80], xmm1 + movdqa oword [esp + $90], xmm2 + shl edx, $6 + movdqa oword [esp + $A0], xmm7 + add edx, ebp + movdqa oword [esp + $B0], xmm6 + add ebp, $40 + mov dword [esp + $C0], edi + mov dword [esp + $C4], ebp + mov dword [esp + $C8], edx + mov dword [esp + $CC], esi + mov eax, dword [edi] + mov ebx, dword [edi + $4] + mov ecx, dword [edi + $8] + mov edx, dword [edi + $C] + mov edi, dword [edi + $10] + mov esi, ebx + movdqu xmm0, oword [ebp - $40] + movdqu xmm1, oword [ebp - $30] + movdqu xmm2, oword [ebp - $20] + movdqu xmm3, oword [ebp - $10] + db $66, $0F, $38, $00, $C6 // pshufb xmm0, xmm6 + db $66, $0F, $38, $00, $CE // pshufb xmm1, xmm6 + db $66, $0F, $38, $00, $D6 // pshufb xmm2, xmm6 + movdqa oword [esp + $60], xmm7 + db $66, $0F, $38, $00, $DE // pshufb xmm3, xmm6 + paddd xmm0, xmm7 + paddd xmm1, xmm7 + paddd xmm2, xmm7 + movdqa oword [esp], xmm0 + psubd xmm0, xmm7 + movdqa oword [esp + $10], xmm1 + psubd xmm1, xmm7 + movdqa oword [esp + $20], xmm2 + mov ebp, ecx + psubd xmm2, xmm7 + xor ebp, edx + pshufd xmm4, xmm0, $EE + and esi, ebp + jmp @block_loop + +@block_loop: + ror ebx, $2 + xor esi, edx + mov ebp, eax + punpcklqdq xmm4, xmm1 + movdqa xmm6, xmm3 + add edi, dword [esp] + xor ebx, ecx + paddd xmm7, xmm3 + movdqa oword [esp + $40], xmm0 + rol eax, $5 + add edi, esi + psrldq xmm6, $4 + and ebp, ebx + xor ebx, ecx + pxor xmm4, xmm0 + add edi, eax + ror eax, $7 + pxor xmm6, xmm2 + xor ebp, ecx + mov esi, edi + add edx, dword [esp + $4] + pxor xmm4, xmm6 + xor eax, ebx + rol edi, $5 + movdqa oword [esp + $30], xmm7 + add edx, ebp + and esi, eax + movdqa xmm0, xmm4 + xor eax, ebx + add edx, edi + ror edi, $7 + movdqa xmm6, xmm4 + xor esi, ebx + pslldq xmm0, $C + paddd xmm4, xmm4 + mov ebp, edx + add ecx, dword [esp + $8] + psrld xmm6, $1F + xor edi, eax + rol edx, $5 + movdqa xmm7, xmm0 + add ecx, esi + and ebp, edi + xor edi, eax + psrld xmm0, $1E + add ecx, edx + ror edx, $7 + por xmm4, xmm6 + xor ebp, eax + mov esi, ecx + add ebx, dword [esp + $C] + pslld xmm7, $2 + xor edx, edi + rol ecx, $5 + pxor xmm4, xmm0 + movdqa xmm0, oword [esp + $60] + add ebx, ebp + and esi, edx + pxor xmm4, xmm7 + pshufd xmm5, xmm1, $EE + xor edx, edi + add ebx, ecx + ror ecx, $7 + xor esi, edi + mov ebp, ebx + punpcklqdq xmm5, xmm2 + movdqa xmm7, xmm4 + add eax, dword [esp + $10] + xor ecx, edx + paddd xmm0, xmm4 + movdqa oword [esp + $50], xmm1 + rol ebx, $5 + add eax, esi + psrldq xmm7, $4 + and ebp, ecx + xor ecx, edx + pxor xmm5, xmm1 + add eax, ebx + ror ebx, $7 + pxor xmm7, xmm3 + xor ebp, edx + mov esi, eax + add edi, dword [esp + $14] + pxor xmm5, xmm7 + xor ebx, ecx + rol eax, $5 + movdqa oword [esp], xmm0 + add edi, ebp + and esi, ebx + movdqa xmm1, xmm5 + xor ebx, ecx + add edi, eax + ror eax, $7 + movdqa xmm7, xmm5 + xor esi, ecx + pslldq xmm1, $C + paddd xmm5, xmm5 + mov ebp, edi + add edx, dword [esp + $18] + psrld xmm7, $1F + xor eax, ebx + rol edi, $5 + movdqa xmm0, xmm1 + add edx, esi + and ebp, eax + xor eax, ebx + psrld xmm1, $1E + add edx, edi + ror edi, $7 + por xmm5, xmm7 + xor ebp, ebx + mov esi, edx + add ecx, dword [esp + $1C] + pslld xmm0, $2 + xor edi, eax + rol edx, $5 + pxor xmm5, xmm1 + movdqa xmm1, oword [esp + $70] + add ecx, ebp + and esi, edi + pxor xmm5, xmm0 + pshufd xmm6, xmm2, $EE + xor edi, eax + add ecx, edx + ror edx, $7 + xor esi, eax + mov ebp, ecx + punpcklqdq xmm6, xmm3 + movdqa xmm0, xmm5 + add ebx, dword [esp + $20] + xor edx, edi + paddd xmm1, xmm5 + movdqa oword [esp + $60], xmm2 + rol ecx, $5 + add ebx, esi + psrldq xmm0, $4 + and ebp, edx + xor edx, edi + pxor xmm6, xmm2 + add ebx, ecx + ror ecx, $7 + pxor xmm0, xmm4 + xor ebp, edi + mov esi, ebx + add eax, dword [esp + $24] + pxor xmm6, xmm0 + xor ecx, edx + rol ebx, $5 + movdqa oword [esp + $10], xmm1 + add eax, ebp + and esi, ecx + movdqa xmm2, xmm6 + xor ecx, edx + add eax, ebx + ror ebx, $7 + movdqa xmm0, xmm6 + xor esi, edx + pslldq xmm2, $C + paddd xmm6, xmm6 + mov ebp, eax + add edi, dword [esp + $28] + psrld xmm0, $1F + xor ebx, ecx + rol eax, $5 + movdqa xmm1, xmm2 + add edi, esi + and ebp, ebx + xor ebx, ecx + psrld xmm2, $1E + add edi, eax + ror eax, $7 + por xmm6, xmm0 + xor ebp, ecx + movdqa xmm0, oword [esp + $40] + mov esi, edi + add edx, dword [esp + $2C] + pslld xmm1, $2 + xor eax, ebx + rol edi, $5 + pxor xmm6, xmm2 + movdqa xmm2, oword [esp + $70] + add edx, ebp + and esi, eax + pxor xmm6, xmm1 + pshufd xmm7, xmm3, $EE + xor eax, ebx + add edx, edi + ror edi, $7 + xor esi, ebx + mov ebp, edx + punpcklqdq xmm7, xmm4 + movdqa xmm1, xmm6 + add ecx, dword [esp + $30] + xor edi, eax + paddd xmm2, xmm6 + movdqa oword [esp + $40], xmm3 + rol edx, $5 + add ecx, esi + psrldq xmm1, $4 + and ebp, edi + xor edi, eax + pxor xmm7, xmm3 + add ecx, edx + ror edx, $7 + pxor xmm1, xmm5 + xor ebp, eax + mov esi, ecx + add ebx, dword [esp + $34] + pxor xmm7, xmm1 + xor edx, edi + rol ecx, $5 + movdqa oword [esp + $20], xmm2 + add ebx, ebp + and esi, edx + movdqa xmm3, xmm7 + xor edx, edi + add ebx, ecx + ror ecx, $7 + movdqa xmm1, xmm7 + xor esi, edi + pslldq xmm3, $C + paddd xmm7, xmm7 + mov ebp, ebx + add eax, dword [esp + $38] + psrld xmm1, $1F + xor ecx, edx + rol ebx, $5 + movdqa xmm2, xmm3 + add eax, esi + and ebp, ecx + xor ecx, edx + psrld xmm3, $1E + add eax, ebx + ror ebx, $7 + por xmm7, xmm1 + xor ebp, edx + movdqa xmm1, oword [esp + $50] + mov esi, eax + add edi, dword [esp + $3C] + pslld xmm2, $2 + xor ebx, ecx + rol eax, $5 + pxor xmm7, xmm3 + movdqa xmm3, oword [esp + $70] + add edi, ebp + and esi, ebx + pxor xmm7, xmm2 + pshufd xmm2, xmm6, $EE + xor ebx, ecx + add edi, eax + ror eax, $7 + pxor xmm0, xmm4 + punpcklqdq xmm2, xmm7 + xor esi, ecx + mov ebp, edi + add edx, dword [esp] + pxor xmm0, xmm1 + movdqa oword [esp + $50], xmm4 + xor eax, ebx + rol edi, $5 + movdqa xmm4, xmm3 + add edx, esi + paddd xmm3, xmm7 + and ebp, eax + pxor xmm0, xmm2 + xor eax, ebx + add edx, edi + ror edi, $7 + xor ebp, ebx + movdqa xmm2, xmm0 + movdqa oword [esp + $30], xmm3 + mov esi, edx + add ecx, dword [esp + $4] + xor edi, eax + rol edx, $5 + pslld xmm0, $2 + add ecx, ebp + and esi, edi + psrld xmm2, $1E + xor edi, eax + add ecx, edx + ror edx, $7 + xor esi, eax + mov ebp, ecx + add ebx, dword [esp + $8] + xor edx, edi + rol ecx, $5 + por xmm0, xmm2 + add ebx, esi + and ebp, edx + movdqa xmm2, oword [esp + $60] + xor edx, edi + add ebx, ecx + add eax, dword [esp + $C] + xor ebp, edi + mov esi, ebx + pshufd xmm3, xmm7, $EE + rol ebx, $5 + add eax, ebp + xor esi, edx + ror ecx, $7 + add eax, ebx + add edi, dword [esp + $10] + pxor xmm1, xmm5 + punpcklqdq xmm3, xmm0 + xor esi, ecx + mov ebp, eax + rol eax, $5 + pxor xmm1, xmm2 + movdqa oword [esp + $60], xmm5 + add edi, esi + xor ebp, ecx + movdqa xmm5, xmm4 + ror ebx, $7 + paddd xmm4, xmm0 + add edi, eax + pxor xmm1, xmm3 + add edx, dword [esp + $14] + xor ebp, ebx + mov esi, edi + rol edi, $5 + movdqa xmm3, xmm1 + movdqa oword [esp], xmm4 + add edx, ebp + xor esi, ebx + ror eax, $7 + add edx, edi + pslld xmm1, $2 + add ecx, dword [esp + $18] + xor esi, eax + psrld xmm3, $1E + mov ebp, edx + rol edx, $5 + add ecx, esi + xor ebp, eax + ror edi, $7 + add ecx, edx + por xmm1, xmm3 + add ebx, dword [esp + $1C] + xor ebp, edi + movdqa xmm3, oword [esp + $40] + mov esi, ecx + rol ecx, $5 + add ebx, ebp + xor esi, edi + ror edx, $7 + pshufd xmm4, xmm0, $EE + add ebx, ecx + add eax, dword [esp + $20] + pxor xmm2, xmm6 + punpcklqdq xmm4, xmm1 + xor esi, edx + mov ebp, ebx + rol ebx, $5 + pxor xmm2, xmm3 + movdqa oword [esp + $40], xmm6 + add eax, esi + xor ebp, edx + movdqa xmm6, oword [esp + $80] + ror ecx, $7 + paddd xmm5, xmm1 + add eax, ebx + pxor xmm2, xmm4 + add edi, dword [esp + $24] + xor ebp, ecx + mov esi, eax + rol eax, $5 + movdqa xmm4, xmm2 + movdqa oword [esp + $10], xmm5 + add edi, ebp + xor esi, ecx + ror ebx, $7 + add edi, eax + pslld xmm2, $2 + add edx, dword [esp + $28] + xor esi, ebx + psrld xmm4, $1E + mov ebp, edi + rol edi, $5 + add edx, esi + xor ebp, ebx + ror eax, $7 + add edx, edi + por xmm2, xmm4 + add ecx, dword [esp + $2C] + xor ebp, eax + movdqa xmm4, oword [esp + $50] + mov esi, edx + rol edx, $5 + add ecx, ebp + xor esi, eax + ror edi, $7 + pshufd xmm5, xmm1, $EE + add ecx, edx + add ebx, dword [esp + $30] + pxor xmm3, xmm7 + punpcklqdq xmm5, xmm2 + xor esi, edi + mov ebp, ecx + rol ecx, $5 + pxor xmm3, xmm4 + movdqa oword [esp + $50], xmm7 + add ebx, esi + xor ebp, edi + movdqa xmm7, xmm6 + ror edx, $7 + paddd xmm6, xmm2 + add ebx, ecx + pxor xmm3, xmm5 + add eax, dword [esp + $34] + xor ebp, edx + mov esi, ebx + rol ebx, $5 + movdqa xmm5, xmm3 + movdqa oword [esp + $20], xmm6 + add eax, ebp + xor esi, edx + ror ecx, $7 + add eax, ebx + pslld xmm3, $2 + add edi, dword [esp + $38] + xor esi, ecx + psrld xmm5, $1E + mov ebp, eax + rol eax, $5 + add edi, esi + xor ebp, ecx + ror ebx, $7 + add edi, eax + por xmm3, xmm5 + add edx, dword [esp + $3C] + xor ebp, ebx + movdqa xmm5, oword [esp + $60] + mov esi, edi + rol edi, $5 + add edx, ebp + xor esi, ebx + ror eax, $7 + pshufd xmm6, xmm2, $EE + add edx, edi + add ecx, dword [esp] + pxor xmm4, xmm0 + punpcklqdq xmm6, xmm3 + xor esi, eax + mov ebp, edx + rol edx, $5 + pxor xmm4, xmm5 + movdqa oword [esp + $60], xmm0 + add ecx, esi + xor ebp, eax + movdqa xmm0, xmm7 + ror edi, $7 + paddd xmm7, xmm3 + add ecx, edx + pxor xmm4, xmm6 + add ebx, dword [esp + $4] + xor ebp, edi + mov esi, ecx + rol ecx, $5 + movdqa xmm6, xmm4 + movdqa oword [esp + $30], xmm7 + add ebx, ebp + xor esi, edi + ror edx, $7 + add ebx, ecx + pslld xmm4, $2 + add eax, dword [esp + $8] + xor esi, edx + psrld xmm6, $1E + mov ebp, ebx + rol ebx, $5 + add eax, esi + xor ebp, edx + ror ecx, $7 + add eax, ebx + por xmm4, xmm6 + add edi, dword [esp + $C] + xor ebp, ecx + movdqa xmm6, oword [esp + $40] + mov esi, eax + rol eax, $5 + add edi, ebp + xor esi, ecx + ror ebx, $7 + pshufd xmm7, xmm3, $EE + add edi, eax + add edx, dword [esp + $10] + pxor xmm5, xmm1 + punpcklqdq xmm7, xmm4 + xor esi, ebx + mov ebp, edi + rol edi, $5 + pxor xmm5, xmm6 + movdqa oword [esp + $40], xmm1 + add edx, esi + xor ebp, ebx + movdqa xmm1, xmm0 + ror eax, $7 + paddd xmm0, xmm4 + add edx, edi + pxor xmm5, xmm7 + add ecx, dword [esp + $14] + xor ebp, eax + mov esi, edx + rol edx, $5 + movdqa xmm7, xmm5 + movdqa oword [esp], xmm0 + add ecx, ebp + xor esi, eax + ror edi, $7 + add ecx, edx + pslld xmm5, $2 + add ebx, dword [esp + $18] + xor esi, edi + psrld xmm7, $1E + mov ebp, ecx + rol ecx, $5 + add ebx, esi + xor ebp, edi + ror edx, $7 + add ebx, ecx + por xmm5, xmm7 + add eax, dword [esp + $1C] + movdqa xmm7, oword [esp + $50] + ror ecx, $7 + mov esi, ebx + xor ebp, edx + rol ebx, $5 + pshufd xmm0, xmm4, $EE + add eax, ebp + xor esi, ecx + xor ecx, edx + add eax, ebx + add edi, dword [esp + $20] + pxor xmm6, xmm2 + punpcklqdq xmm0, xmm5 + and esi, ecx + xor ecx, edx + ror ebx, $7 + pxor xmm6, xmm7 + movdqa oword [esp + $50], xmm2 + mov ebp, eax + xor esi, ecx + rol eax, $5 + movdqa xmm2, xmm1 + add edi, esi + paddd xmm1, xmm5 + xor ebp, ebx + pxor xmm6, xmm0 + xor ebx, ecx + add edi, eax + add edx, dword [esp + $24] + and ebp, ebx + movdqa xmm0, xmm6 + movdqa oword [esp + $10], xmm1 + xor ebx, ecx + ror eax, $7 + mov esi, edi + xor ebp, ebx + rol edi, $5 + pslld xmm6, $2 + add edx, ebp + xor esi, eax + psrld xmm0, $1E + xor eax, ebx + add edx, edi + add ecx, dword [esp + $28] + and esi, eax + xor eax, ebx + ror edi, $7 + por xmm6, xmm0 + mov ebp, edx + xor esi, eax + movdqa xmm0, oword [esp + $60] + rol edx, $5 + add ecx, esi + xor ebp, edi + xor edi, eax + add ecx, edx + pshufd xmm1, xmm5, $EE + add ebx, dword [esp + $2C] + and ebp, edi + xor edi, eax + ror edx, $7 + mov esi, ecx + xor ebp, edi + rol ecx, $5 + add ebx, ebp + xor esi, edx + xor edx, edi + add ebx, ecx + add eax, dword [esp + $30] + pxor xmm7, xmm3 + punpcklqdq xmm1, xmm6 + and esi, edx + xor edx, edi + ror ecx, $7 + pxor xmm7, xmm0 + movdqa oword [esp + $60], xmm3 + mov ebp, ebx + xor esi, edx + rol ebx, $5 + movdqa xmm3, oword [esp + $90] + add eax, esi + paddd xmm2, xmm6 + xor ebp, ecx + pxor xmm7, xmm1 + xor ecx, edx + add eax, ebx + add edi, dword [esp + $34] + and ebp, ecx + movdqa xmm1, xmm7 + movdqa oword [esp + $20], xmm2 + xor ecx, edx + ror ebx, $7 + mov esi, eax + xor ebp, ecx + rol eax, $5 + pslld xmm7, $2 + add edi, ebp + xor esi, ebx + psrld xmm1, $1E + xor ebx, ecx + add edi, eax + add edx, dword [esp + $38] + and esi, ebx + xor ebx, ecx + ror eax, $7 + por xmm7, xmm1 + mov ebp, edi + xor esi, ebx + movdqa xmm1, oword [esp + $40] + rol edi, $5 + add edx, esi + xor ebp, eax + xor eax, ebx + add edx, edi + pshufd xmm2, xmm6, $EE + add ecx, dword [esp + $3C] + and ebp, eax + xor eax, ebx + ror edi, $7 + mov esi, edx + xor ebp, eax + rol edx, $5 + add ecx, ebp + xor esi, edi + xor edi, eax + add ecx, edx + add ebx, dword [esp] + pxor xmm0, xmm4 + punpcklqdq xmm2, xmm7 + and esi, edi + xor edi, eax + ror edx, $7 + pxor xmm0, xmm1 + movdqa oword [esp + $40], xmm4 + mov ebp, ecx + xor esi, edi + rol ecx, $5 + movdqa xmm4, xmm3 + add ebx, esi + paddd xmm3, xmm7 + xor ebp, edx + pxor xmm0, xmm2 + xor edx, edi + add ebx, ecx + add eax, dword [esp + $4] + and ebp, edx + movdqa xmm2, xmm0 + movdqa oword [esp + $30], xmm3 + xor edx, edi + ror ecx, $7 + mov esi, ebx + xor ebp, edx + rol ebx, $5 + pslld xmm0, $2 + add eax, ebp + xor esi, ecx + psrld xmm2, $1E + xor ecx, edx + add eax, ebx + add edi, dword [esp + $8] + and esi, ecx + xor ecx, edx + ror ebx, $7 + por xmm0, xmm2 + mov ebp, eax + xor esi, ecx + movdqa xmm2, oword [esp + $50] + rol eax, $5 + add edi, esi + xor ebp, ebx + xor ebx, ecx + add edi, eax + pshufd xmm3, xmm7, $EE + add edx, dword [esp + $C] + and ebp, ebx + xor ebx, ecx + ror eax, $7 + mov esi, edi + xor ebp, ebx + rol edi, $5 + add edx, ebp + xor esi, eax + xor eax, ebx + add edx, edi + add ecx, dword [esp + $10] + pxor xmm1, xmm5 + punpcklqdq xmm3, xmm0 + and esi, eax + xor eax, ebx + ror edi, $7 + pxor xmm1, xmm2 + movdqa oword [esp + $50], xmm5 + mov ebp, edx + xor esi, eax + rol edx, $5 + movdqa xmm5, xmm4 + add ecx, esi + paddd xmm4, xmm0 + xor ebp, edi + pxor xmm1, xmm3 + xor edi, eax + add ecx, edx + add ebx, dword [esp + $14] + and ebp, edi + movdqa xmm3, xmm1 + movdqa oword [esp], xmm4 + xor edi, eax + ror edx, $7 + mov esi, ecx + xor ebp, edi + rol ecx, $5 + pslld xmm1, $2 + add ebx, ebp + xor esi, edx + psrld xmm3, $1E + xor edx, edi + add ebx, ecx + add eax, dword [esp + $18] + and esi, edx + xor edx, edi + ror ecx, $7 + por xmm1, xmm3 + mov ebp, ebx + xor esi, edx + movdqa xmm3, oword [esp + $60] + rol ebx, $5 + add eax, esi + xor ebp, ecx + xor ecx, edx + add eax, ebx + pshufd xmm4, xmm0, $EE + add edi, dword [esp + $1C] + and ebp, ecx + xor ecx, edx + ror ebx, $7 + mov esi, eax + xor ebp, ecx + rol eax, $5 + add edi, ebp + xor esi, ebx + xor ebx, ecx + add edi, eax + add edx, dword [esp + $20] + pxor xmm2, xmm6 + punpcklqdq xmm4, xmm1 + and esi, ebx + xor ebx, ecx + ror eax, $7 + pxor xmm2, xmm3 + movdqa oword [esp + $60], xmm6 + mov ebp, edi + xor esi, ebx + rol edi, $5 + movdqa xmm6, xmm5 + add edx, esi + paddd xmm5, xmm1 + xor ebp, eax + pxor xmm2, xmm4 + xor eax, ebx + add edx, edi + add ecx, dword [esp + $24] + and ebp, eax + movdqa xmm4, xmm2 + movdqa oword [esp + $10], xmm5 + xor eax, ebx + ror edi, $7 + mov esi, edx + xor ebp, eax + rol edx, $5 + pslld xmm2, $2 + add ecx, ebp + xor esi, edi + psrld xmm4, $1E + xor edi, eax + add ecx, edx + add ebx, dword [esp + $28] + and esi, edi + xor edi, eax + ror edx, $7 + por xmm2, xmm4 + mov ebp, ecx + xor esi, edi + movdqa xmm4, oword [esp + $40] + rol ecx, $5 + add ebx, esi + xor ebp, edx + xor edx, edi + add ebx, ecx + pshufd xmm5, xmm1, $EE + add eax, dword [esp + $2C] + and ebp, edx + xor edx, edi + ror ecx, $7 + mov esi, ebx + xor ebp, edx + rol ebx, $5 + add eax, ebp + xor esi, edx + add eax, ebx + add edi, dword [esp + $30] + pxor xmm3, xmm7 + punpcklqdq xmm5, xmm2 + xor esi, ecx + mov ebp, eax + rol eax, $5 + pxor xmm3, xmm4 + movdqa oword [esp + $40], xmm7 + add edi, esi + xor ebp, ecx + movdqa xmm7, xmm6 + ror ebx, $7 + paddd xmm6, xmm2 + add edi, eax + pxor xmm3, xmm5 + add edx, dword [esp + $34] + xor ebp, ebx + mov esi, edi + rol edi, $5 + movdqa xmm5, xmm3 + movdqa oword [esp + $20], xmm6 + add edx, ebp + xor esi, ebx + ror eax, $7 + add edx, edi + pslld xmm3, $2 + add ecx, dword [esp + $38] + xor esi, eax + psrld xmm5, $1E + mov ebp, edx + rol edx, $5 + add ecx, esi + xor ebp, eax + ror edi, $7 + add ecx, edx + por xmm3, xmm5 + add ebx, dword [esp + $3C] + xor ebp, edi + mov esi, ecx + rol ecx, $5 + add ebx, ebp + xor esi, edi + ror edx, $7 + add ebx, ecx + add eax, dword [esp] + xor esi, edx + mov ebp, ebx + rol ebx, $5 + add eax, esi + xor ebp, edx + ror ecx, $7 + paddd xmm7, xmm3 + add eax, ebx + add edi, dword [esp + $4] + xor ebp, ecx + mov esi, eax + movdqa oword [esp + $30], xmm7 + rol eax, $5 + add edi, ebp + xor esi, ecx + ror ebx, $7 + add edi, eax + add edx, dword [esp + $8] + xor esi, ebx + mov ebp, edi + rol edi, $5 + add edx, esi + xor ebp, ebx + ror eax, $7 + add edx, edi + add ecx, dword [esp + $C] + xor ebp, eax + mov esi, edx + rol edx, $5 + add ecx, ebp + xor esi, eax + ror edi, $7 + add ecx, edx + mov ebp, dword [esp + $C4] + cmp ebp, dword [esp + $C8] + je @done + movdqa xmm7, oword [esp + $A0] + movdqa xmm6, oword [esp + $B0] + movdqu xmm0, oword [ebp + $0] + movdqu xmm1, oword [ebp + $10] + movdqu xmm2, oword [ebp + $20] + movdqu xmm3, oword [ebp + $30] + add ebp, $40 + db $66, $0F, $38, $00, $C6 // pshufb xmm0, xmm6 + mov dword [esp + $C4], ebp + movdqa oword [esp + $60], xmm7 + add ebx, dword [esp + $10] + xor esi, edi + mov ebp, ecx + rol ecx, $5 + add ebx, esi + xor ebp, edi + ror edx, $7 + db $66, $0F, $38, $00, $CE // pshufb xmm1, xmm6 + add ebx, ecx + add eax, dword [esp + $14] + xor ebp, edx + mov esi, ebx + paddd xmm0, xmm7 + rol ebx, $5 + add eax, ebp + xor esi, edx + ror ecx, $7 + movdqa oword [esp], xmm0 + add eax, ebx + add edi, dword [esp + $18] + xor esi, ecx + mov ebp, eax + psubd xmm0, xmm7 + rol eax, $5 + add edi, esi + xor ebp, ecx + ror ebx, $7 + add edi, eax + add edx, dword [esp + $1C] + xor ebp, ebx + mov esi, edi + rol edi, $5 + add edx, ebp + xor esi, ebx + ror eax, $7 + add edx, edi + add ecx, dword [esp + $20] + xor esi, eax + mov ebp, edx + rol edx, $5 + add ecx, esi + xor ebp, eax + ror edi, $7 + db $66, $0F, $38, $00, $D6 // pshufb xmm2, xmm6 + add ecx, edx + add ebx, dword [esp + $24] + xor ebp, edi + mov esi, ecx + paddd xmm1, xmm7 + rol ecx, $5 + add ebx, ebp + xor esi, edi + ror edx, $7 + movdqa oword [esp + $10], xmm1 + add ebx, ecx + add eax, dword [esp + $28] + xor esi, edx + mov ebp, ebx + psubd xmm1, xmm7 + rol ebx, $5 + add eax, esi + xor ebp, edx + ror ecx, $7 + add eax, ebx + add edi, dword [esp + $2C] + xor ebp, ecx + mov esi, eax + rol eax, $5 + add edi, ebp + xor esi, ecx + ror ebx, $7 + add edi, eax + add edx, dword [esp + $30] + xor esi, ebx + mov ebp, edi + rol edi, $5 + add edx, esi + xor ebp, ebx + ror eax, $7 + db $66, $0F, $38, $00, $DE // pshufb xmm3, xmm6 + add edx, edi + add ecx, dword [esp + $34] + xor ebp, eax + mov esi, edx + paddd xmm2, xmm7 + rol edx, $5 + add ecx, ebp + xor esi, eax + ror edi, $7 + movdqa oword [esp + $20], xmm2 + add ecx, edx + add ebx, dword [esp + $38] + xor esi, edi + mov ebp, ecx + psubd xmm2, xmm7 + rol ecx, $5 + add ebx, esi + xor ebp, edi + ror edx, $7 + add ebx, ecx + add eax, dword [esp + $3C] + xor ebp, edx + mov esi, ebx + rol ebx, $5 + add eax, ebp + ror ecx, $7 + add eax, ebx + mov ebp, dword [esp + $C0] + add eax, dword [ebp + $0] + add esi, dword [ebp + $4] + add ecx, dword [ebp + $8] + mov dword [ebp + $0], eax + add edx, dword [ebp + $C] + mov dword [ebp + $4], esi + add edi, dword [ebp + $10] + mov dword [ebp + $8], ecx + mov ebx, ecx + mov dword [ebp + $C], edx + xor ebx, edx + mov dword [ebp + $10], edi + mov ebp, esi + pshufd xmm4, xmm0, $EE + and esi, ebx + mov ebx, ebp + jmp @block_loop + +@done: + add ebx, dword [esp + $10] + xor esi, edi + mov ebp, ecx + rol ecx, $5 + add ebx, esi + xor ebp, edi + ror edx, $7 + add ebx, ecx + add eax, dword [esp + $14] + xor ebp, edx + mov esi, ebx + rol ebx, $5 + add eax, ebp + xor esi, edx + ror ecx, $7 + add eax, ebx + add edi, dword [esp + $18] + xor esi, ecx + mov ebp, eax + rol eax, $5 + add edi, esi + xor ebp, ecx + ror ebx, $7 + add edi, eax + add edx, dword [esp + $1C] + xor ebp, ebx + mov esi, edi + rol edi, $5 + add edx, ebp + xor esi, ebx + ror eax, $7 + add edx, edi + add ecx, dword [esp + $20] + xor esi, eax + mov ebp, edx + rol edx, $5 + add ecx, esi + xor ebp, eax + ror edi, $7 + add ecx, edx + add ebx, dword [esp + $24] + xor ebp, edi + mov esi, ecx + rol ecx, $5 + add ebx, ebp + xor esi, edi + ror edx, $7 + add ebx, ecx + add eax, dword [esp + $28] + xor esi, edx + mov ebp, ebx + rol ebx, $5 + add eax, esi + xor ebp, edx + ror ecx, $7 + add eax, ebx + add edi, dword [esp + $2C] + xor ebp, ecx + mov esi, eax + rol eax, $5 + add edi, ebp + xor esi, ecx + ror ebx, $7 + add edi, eax + add edx, dword [esp + $30] + xor esi, ebx + mov ebp, edi + rol edi, $5 + add edx, esi + xor ebp, ebx + ror eax, $7 + add edx, edi + add ecx, dword [esp + $34] + xor ebp, eax + mov esi, edx + rol edx, $5 + add ecx, ebp + xor esi, eax + ror edi, $7 + add ecx, edx + add ebx, dword [esp + $38] + xor esi, edi + mov ebp, ecx + rol ecx, $5 + add ebx, esi + xor ebp, edi + ror edx, $7 + add ebx, ecx + add eax, dword [esp + $3C] + xor ebp, edx + mov esi, ebx + rol ebx, $5 + add eax, ebp + ror ecx, $7 + add eax, ebx + mov ebp, dword [esp + $C0] + add eax, dword [ebp + $0] + mov esp, dword [esp + $CC] + add esi, dword [ebp + $4] + add ecx, dword [ebp + $8] + mov dword [ebp + $0], eax + add edx, dword [ebp + $C] + mov dword [ebp + $4], esi + add edi, dword [ebp + $10] + mov dword [ebp + $8], ecx + mov dword [ebp + $C], edx + mov dword [ebp + $10], edi + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc new file mode 100644 index 0000000..a7ecbc5 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc @@ -0,0 +1,1193 @@ +// SHA-1 SSSE3 SIMD-schedule implementation; SSE2 sibling: +// SHA1CompressSse2_x86_64.inc. +// The message schedule runs in SIMD (pxor/pshufd/psrldq/pslldq) interleaved +// with the GPR compression rounds, so the vector and integer units run in +// parallel. Unlike the SSE2 sibling the input byte-swaps are real pshufb +// (db-encoded for broad assembler compatibility) against the mask kept +// resident in xmm12 (K_SHA1_Doubled + 128); the W-schedule uses no palignr. +// Reference: OpenSSL CRYPTOGAMS sha1-x86_64.pl (SSSE3 kernel). +// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K_SHA1 ptr (read 128-bit at a 32-byte stride, +// r14 = K + 64, so the duplicated halves are skipped; see K_SHA1_Doubled). +// +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 +// holds the caller rsp across the kernel for the unwind. + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + mov r11, rsp + push r9 + push rbx + push rbp + push r12 + push r13 + push r14 + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + lea rsp, [rsp - $A0] + and rsp, $FFFFFFFFFFFFFFC0 + mov r8, rdi + mov r9, rsi + mov r10, rdx + shl r10, $6 + add r10, r9 + mov r14, qword [r11 - $8] + movdqu xmm12, oword [r14 + $80] // byte-swap mask (K_SHA1_Doubled + 128) + add r14, $40 + mov eax, dword [r8] + mov ebx, dword [r8 + $4] + mov ecx, dword [r8 + $8] + mov edx, dword [r8 + $C] + mov esi, ebx + mov ebp, dword [r8 + $10] + mov edi, ecx + xor edi, edx + and esi, edi + movdqu xmm6, oword [r14 + $40] + movdqu xmm9, oword [r14 - $40] + movdqu xmm0, oword [r9] + movdqu xmm1, oword [r9 + $10] + movdqu xmm2, oword [r9 + $20] + movdqu xmm3, oword [r9 + $30] + db $66, $41, $0F, $38, $00, $C4 // pshufb xmm0, xmm12 + db $66, $41, $0F, $38, $00, $CC // pshufb xmm1, xmm12 + db $66, $41, $0F, $38, $00, $D4 // pshufb xmm2, xmm12 + add r9, $40 + paddd xmm0, xmm9 + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + paddd xmm1, xmm9 + paddd xmm2, xmm9 + movdqa oword [rsp], xmm0 + psubd xmm0, xmm9 + movdqa oword [rsp + $10], xmm1 + psubd xmm1, xmm9 + movdqa oword [rsp + $20], xmm2 + psubd xmm2, xmm9 + jmp @block_loop + +@block_loop: + ror ebx, $2 + pshufd xmm4, xmm0, $EE + xor esi, edx + movdqa xmm8, xmm3 + paddd xmm9, xmm3 + mov edi, eax + add ebp, dword [rsp] + punpcklqdq xmm4, xmm1 + xor ebx, ecx + rol eax, $5 + add ebp, esi + psrldq xmm8, $4 + and edi, ebx + xor ebx, ecx + pxor xmm4, xmm0 + add ebp, eax + ror eax, $7 + pxor xmm8, xmm2 + xor edi, ecx + mov esi, ebp + add edx, dword [rsp + $4] + pxor xmm4, xmm8 + xor eax, ebx + rol ebp, $5 + movdqa oword [rsp + $30], xmm9 + add edx, edi + and esi, eax + movdqa xmm10, xmm4 + xor eax, ebx + add edx, ebp + ror ebp, $7 + movdqa xmm8, xmm4 + xor esi, ebx + pslldq xmm10, $C + paddd xmm4, xmm4 + mov edi, edx + add ecx, dword [rsp + $8] + psrld xmm8, $1F + xor ebp, eax + rol edx, $5 + add ecx, esi + movdqa xmm9, xmm10 + and edi, ebp + xor ebp, eax + psrld xmm10, $1E + add ecx, edx + ror edx, $7 + por xmm4, xmm8 + xor edi, eax + mov esi, ecx + add ebx, dword [rsp + $C] + pslld xmm9, $2 + pxor xmm4, xmm10 + xor edx, ebp + movdqu xmm10, oword [r14 - $40] + rol ecx, $5 + add ebx, edi + and esi, edx + pxor xmm4, xmm9 + xor edx, ebp + add ebx, ecx + ror ecx, $7 + pshufd xmm5, xmm1, $EE + xor esi, ebp + movdqa xmm9, xmm4 + paddd xmm10, xmm4 + mov edi, ebx + add eax, dword [rsp + $10] + punpcklqdq xmm5, xmm2 + xor ecx, edx + rol ebx, $5 + add eax, esi + psrldq xmm9, $4 + and edi, ecx + xor ecx, edx + pxor xmm5, xmm1 + add eax, ebx + ror ebx, $7 + pxor xmm9, xmm3 + xor edi, edx + mov esi, eax + add ebp, dword [rsp + $14] + pxor xmm5, xmm9 + xor ebx, ecx + rol eax, $5 + movdqa oword [rsp], xmm10 + add ebp, edi + and esi, ebx + movdqa xmm8, xmm5 + xor ebx, ecx + add ebp, eax + ror eax, $7 + movdqa xmm9, xmm5 + xor esi, ecx + pslldq xmm8, $C + paddd xmm5, xmm5 + mov edi, ebp + add edx, dword [rsp + $18] + psrld xmm9, $1F + xor eax, ebx + rol ebp, $5 + add edx, esi + movdqa xmm10, xmm8 + and edi, eax + xor eax, ebx + psrld xmm8, $1E + add edx, ebp + ror ebp, $7 + por xmm5, xmm9 + xor edi, ebx + mov esi, edx + add ecx, dword [rsp + $1C] + pslld xmm10, $2 + pxor xmm5, xmm8 + xor ebp, eax + movdqu xmm8, oword [r14 - $20] + rol edx, $5 + add ecx, edi + and esi, ebp + pxor xmm5, xmm10 + xor ebp, eax + add ecx, edx + ror edx, $7 + pshufd xmm6, xmm2, $EE + xor esi, eax + movdqa xmm10, xmm5 + paddd xmm8, xmm5 + mov edi, ecx + add ebx, dword [rsp + $20] + punpcklqdq xmm6, xmm3 + xor edx, ebp + rol ecx, $5 + add ebx, esi + psrldq xmm10, $4 + and edi, edx + xor edx, ebp + pxor xmm6, xmm2 + add ebx, ecx + ror ecx, $7 + pxor xmm10, xmm4 + xor edi, ebp + mov esi, ebx + add eax, dword [rsp + $24] + pxor xmm6, xmm10 + xor ecx, edx + rol ebx, $5 + movdqa oword [rsp + $10], xmm8 + add eax, edi + and esi, ecx + movdqa xmm9, xmm6 + xor ecx, edx + add eax, ebx + ror ebx, $7 + movdqa xmm10, xmm6 + xor esi, edx + pslldq xmm9, $C + paddd xmm6, xmm6 + mov edi, eax + add ebp, dword [rsp + $28] + psrld xmm10, $1F + xor ebx, ecx + rol eax, $5 + add ebp, esi + movdqa xmm8, xmm9 + and edi, ebx + xor ebx, ecx + psrld xmm9, $1E + add ebp, eax + ror eax, $7 + por xmm6, xmm10 + xor edi, ecx + mov esi, ebp + add edx, dword [rsp + $2C] + pslld xmm8, $2 + pxor xmm6, xmm9 + xor eax, ebx + movdqu xmm9, oword [r14 - $20] + rol ebp, $5 + add edx, edi + and esi, eax + pxor xmm6, xmm8 + xor eax, ebx + add edx, ebp + ror ebp, $7 + pshufd xmm7, xmm3, $EE + xor esi, ebx + movdqa xmm8, xmm6 + paddd xmm9, xmm6 + mov edi, edx + add ecx, dword [rsp + $30] + punpcklqdq xmm7, xmm4 + xor ebp, eax + rol edx, $5 + add ecx, esi + psrldq xmm8, $4 + and edi, ebp + xor ebp, eax + pxor xmm7, xmm3 + add ecx, edx + ror edx, $7 + pxor xmm8, xmm5 + xor edi, eax + mov esi, ecx + add ebx, dword [rsp + $34] + pxor xmm7, xmm8 + xor edx, ebp + rol ecx, $5 + movdqa oword [rsp + $20], xmm9 + add ebx, edi + and esi, edx + movdqa xmm10, xmm7 + xor edx, ebp + add ebx, ecx + ror ecx, $7 + movdqa xmm8, xmm7 + xor esi, ebp + pslldq xmm10, $C + paddd xmm7, xmm7 + mov edi, ebx + add eax, dword [rsp + $38] + psrld xmm8, $1F + xor ecx, edx + rol ebx, $5 + add eax, esi + movdqa xmm9, xmm10 + and edi, ecx + xor ecx, edx + psrld xmm10, $1E + add eax, ebx + ror ebx, $7 + por xmm7, xmm8 + xor edi, edx + mov esi, eax + add ebp, dword [rsp + $3C] + pslld xmm9, $2 + pxor xmm7, xmm10 + xor ebx, ecx + movdqu xmm10, oword [r14 - $20] + rol eax, $5 + add ebp, edi + and esi, ebx + pxor xmm7, xmm9 + pshufd xmm9, xmm6, $EE + xor ebx, ecx + add ebp, eax + ror eax, $7 + pxor xmm0, xmm4 + xor esi, ecx + mov edi, ebp + add edx, dword [rsp] + punpcklqdq xmm9, xmm7 + xor eax, ebx + rol ebp, $5 + pxor xmm0, xmm1 + add edx, esi + and edi, eax + movdqa xmm8, xmm10 + xor eax, ebx + paddd xmm10, xmm7 + add edx, ebp + pxor xmm0, xmm9 + ror ebp, $7 + xor edi, ebx + mov esi, edx + add ecx, dword [rsp + $4] + movdqa xmm9, xmm0 + xor ebp, eax + rol edx, $5 + movdqa oword [rsp + $30], xmm10 + add ecx, edi + and esi, ebp + xor ebp, eax + pslld xmm0, $2 + add ecx, edx + ror edx, $7 + psrld xmm9, $1E + xor esi, eax + mov edi, ecx + add ebx, dword [rsp + $8] + por xmm0, xmm9 + xor edx, ebp + rol ecx, $5 + pshufd xmm10, xmm7, $EE + add ebx, esi + and edi, edx + xor edx, ebp + add ebx, ecx + add eax, dword [rsp + $C] + xor edi, ebp + mov esi, ebx + rol ebx, $5 + add eax, edi + xor esi, edx + ror ecx, $7 + add eax, ebx + pxor xmm1, xmm5 + add ebp, dword [rsp + $10] + xor esi, ecx + punpcklqdq xmm10, xmm0 + mov edi, eax + rol eax, $5 + pxor xmm1, xmm2 + add ebp, esi + xor edi, ecx + movdqa xmm9, xmm8 + ror ebx, $7 + paddd xmm8, xmm0 + add ebp, eax + pxor xmm1, xmm10 + add edx, dword [rsp + $14] + xor edi, ebx + mov esi, ebp + rol ebp, $5 + movdqa xmm10, xmm1 + add edx, edi + xor esi, ebx + movdqa oword [rsp], xmm8 + ror eax, $7 + add edx, ebp + add ecx, dword [rsp + $18] + pslld xmm1, $2 + xor esi, eax + mov edi, edx + psrld xmm10, $1E + rol edx, $5 + add ecx, esi + xor edi, eax + ror ebp, $7 + por xmm1, xmm10 + add ecx, edx + add ebx, dword [rsp + $1C] + pshufd xmm8, xmm0, $EE + xor edi, ebp + mov esi, ecx + rol ecx, $5 + add ebx, edi + xor esi, ebp + ror edx, $7 + add ebx, ecx + pxor xmm2, xmm6 + add eax, dword [rsp + $20] + xor esi, edx + punpcklqdq xmm8, xmm1 + mov edi, ebx + rol ebx, $5 + pxor xmm2, xmm3 + add eax, esi + xor edi, edx + movdqu xmm10, oword [r14] + ror ecx, $7 + paddd xmm9, xmm1 + add eax, ebx + pxor xmm2, xmm8 + add ebp, dword [rsp + $24] + xor edi, ecx + mov esi, eax + rol eax, $5 + movdqa xmm8, xmm2 + add ebp, edi + xor esi, ecx + movdqa oword [rsp + $10], xmm9 + ror ebx, $7 + add ebp, eax + add edx, dword [rsp + $28] + pslld xmm2, $2 + xor esi, ebx + mov edi, ebp + psrld xmm8, $1E + rol ebp, $5 + add edx, esi + xor edi, ebx + ror eax, $7 + por xmm2, xmm8 + add edx, ebp + add ecx, dword [rsp + $2C] + pshufd xmm9, xmm1, $EE + xor edi, eax + mov esi, edx + rol edx, $5 + add ecx, edi + xor esi, eax + ror ebp, $7 + add ecx, edx + pxor xmm3, xmm7 + add ebx, dword [rsp + $30] + xor esi, ebp + punpcklqdq xmm9, xmm2 + mov edi, ecx + rol ecx, $5 + pxor xmm3, xmm4 + add ebx, esi + xor edi, ebp + movdqa xmm8, xmm10 + ror edx, $7 + paddd xmm10, xmm2 + add ebx, ecx + pxor xmm3, xmm9 + add eax, dword [rsp + $34] + xor edi, edx + mov esi, ebx + rol ebx, $5 + movdqa xmm9, xmm3 + add eax, edi + xor esi, edx + movdqa oword [rsp + $20], xmm10 + ror ecx, $7 + add eax, ebx + add ebp, dword [rsp + $38] + pslld xmm3, $2 + xor esi, ecx + mov edi, eax + psrld xmm9, $1E + rol eax, $5 + add ebp, esi + xor edi, ecx + ror ebx, $7 + por xmm3, xmm9 + add ebp, eax + add edx, dword [rsp + $3C] + pshufd xmm10, xmm2, $EE + xor edi, ebx + mov esi, ebp + rol ebp, $5 + add edx, edi + xor esi, ebx + ror eax, $7 + add edx, ebp + pxor xmm4, xmm0 + add ecx, dword [rsp] + xor esi, eax + punpcklqdq xmm10, xmm3 + mov edi, edx + rol edx, $5 + pxor xmm4, xmm5 + add ecx, esi + xor edi, eax + movdqa xmm9, xmm8 + ror ebp, $7 + paddd xmm8, xmm3 + add ecx, edx + pxor xmm4, xmm10 + add ebx, dword [rsp + $4] + xor edi, ebp + mov esi, ecx + rol ecx, $5 + movdqa xmm10, xmm4 + add ebx, edi + xor esi, ebp + movdqa oword [rsp + $30], xmm8 + ror edx, $7 + add ebx, ecx + add eax, dword [rsp + $8] + pslld xmm4, $2 + xor esi, edx + mov edi, ebx + psrld xmm10, $1E + rol ebx, $5 + add eax, esi + xor edi, edx + ror ecx, $7 + por xmm4, xmm10 + add eax, ebx + add ebp, dword [rsp + $C] + pshufd xmm8, xmm3, $EE + xor edi, ecx + mov esi, eax + rol eax, $5 + add ebp, edi + xor esi, ecx + ror ebx, $7 + add ebp, eax + pxor xmm5, xmm1 + add edx, dword [rsp + $10] + xor esi, ebx + punpcklqdq xmm8, xmm4 + mov edi, ebp + rol ebp, $5 + pxor xmm5, xmm6 + add edx, esi + xor edi, ebx + movdqa xmm10, xmm9 + ror eax, $7 + paddd xmm9, xmm4 + add edx, ebp + pxor xmm5, xmm8 + add ecx, dword [rsp + $14] + xor edi, eax + mov esi, edx + rol edx, $5 + movdqa xmm8, xmm5 + add ecx, edi + xor esi, eax + movdqa oword [rsp], xmm9 + ror ebp, $7 + add ecx, edx + add ebx, dword [rsp + $18] + pslld xmm5, $2 + xor esi, ebp + mov edi, ecx + psrld xmm8, $1E + rol ecx, $5 + add ebx, esi + xor edi, ebp + ror edx, $7 + por xmm5, xmm8 + add ebx, ecx + add eax, dword [rsp + $1C] + pshufd xmm9, xmm4, $EE + ror ecx, $7 + mov esi, ebx + xor edi, edx + rol ebx, $5 + add eax, edi + xor esi, ecx + xor ecx, edx + add eax, ebx + pxor xmm6, xmm2 + add ebp, dword [rsp + $20] + and esi, ecx + xor ecx, edx + ror ebx, $7 + punpcklqdq xmm9, xmm5 + mov edi, eax + xor esi, ecx + pxor xmm6, xmm7 + rol eax, $5 + add ebp, esi + movdqa xmm8, xmm10 + xor edi, ebx + paddd xmm10, xmm5 + xor ebx, ecx + pxor xmm6, xmm9 + add ebp, eax + add edx, dword [rsp + $24] + and edi, ebx + xor ebx, ecx + ror eax, $7 + movdqa xmm9, xmm6 + mov esi, ebp + xor edi, ebx + movdqa oword [rsp + $10], xmm10 + rol ebp, $5 + add edx, edi + xor esi, eax + pslld xmm6, $2 + xor eax, ebx + add edx, ebp + psrld xmm9, $1E + add ecx, dword [rsp + $28] + and esi, eax + xor eax, ebx + por xmm6, xmm9 + ror ebp, $7 + mov edi, edx + xor esi, eax + rol edx, $5 + pshufd xmm10, xmm5, $EE + add ecx, esi + xor edi, ebp + xor ebp, eax + add ecx, edx + add ebx, dword [rsp + $2C] + and edi, ebp + xor ebp, eax + ror edx, $7 + mov esi, ecx + xor edi, ebp + rol ecx, $5 + add ebx, edi + xor esi, edx + xor edx, ebp + add ebx, ecx + pxor xmm7, xmm3 + add eax, dword [rsp + $30] + and esi, edx + xor edx, ebp + ror ecx, $7 + punpcklqdq xmm10, xmm6 + mov edi, ebx + xor esi, edx + pxor xmm7, xmm0 + rol ebx, $5 + add eax, esi + movdqu xmm9, oword [r14 + $20] + xor edi, ecx + paddd xmm8, xmm6 + xor ecx, edx + pxor xmm7, xmm10 + add eax, ebx + add ebp, dword [rsp + $34] + and edi, ecx + xor ecx, edx + ror ebx, $7 + movdqa xmm10, xmm7 + mov esi, eax + xor edi, ecx + movdqa oword [rsp + $20], xmm8 + rol eax, $5 + add ebp, edi + xor esi, ebx + pslld xmm7, $2 + xor ebx, ecx + add ebp, eax + psrld xmm10, $1E + add edx, dword [rsp + $38] + and esi, ebx + xor ebx, ecx + por xmm7, xmm10 + ror eax, $7 + mov edi, ebp + xor esi, ebx + rol ebp, $5 + pshufd xmm8, xmm6, $EE + add edx, esi + xor edi, eax + xor eax, ebx + add edx, ebp + add ecx, dword [rsp + $3C] + and edi, eax + xor eax, ebx + ror ebp, $7 + mov esi, edx + xor edi, eax + rol edx, $5 + add ecx, edi + xor esi, ebp + xor ebp, eax + add ecx, edx + pxor xmm0, xmm4 + add ebx, dword [rsp] + and esi, ebp + xor ebp, eax + ror edx, $7 + punpcklqdq xmm8, xmm7 + mov edi, ecx + xor esi, ebp + pxor xmm0, xmm1 + rol ecx, $5 + add ebx, esi + movdqa xmm10, xmm9 + xor edi, edx + paddd xmm9, xmm7 + xor edx, ebp + pxor xmm0, xmm8 + add ebx, ecx + add eax, dword [rsp + $4] + and edi, edx + xor edx, ebp + ror ecx, $7 + movdqa xmm8, xmm0 + mov esi, ebx + xor edi, edx + movdqa oword [rsp + $30], xmm9 + rol ebx, $5 + add eax, edi + xor esi, ecx + pslld xmm0, $2 + xor ecx, edx + add eax, ebx + psrld xmm8, $1E + add ebp, dword [rsp + $8] + and esi, ecx + xor ecx, edx + por xmm0, xmm8 + ror ebx, $7 + mov edi, eax + xor esi, ecx + rol eax, $5 + pshufd xmm9, xmm7, $EE + add ebp, esi + xor edi, ebx + xor ebx, ecx + add ebp, eax + add edx, dword [rsp + $C] + and edi, ebx + xor ebx, ecx + ror eax, $7 + mov esi, ebp + xor edi, ebx + rol ebp, $5 + add edx, edi + xor esi, eax + xor eax, ebx + add edx, ebp + pxor xmm1, xmm5 + add ecx, dword [rsp + $10] + and esi, eax + xor eax, ebx + ror ebp, $7 + punpcklqdq xmm9, xmm0 + mov edi, edx + xor esi, eax + pxor xmm1, xmm2 + rol edx, $5 + add ecx, esi + movdqa xmm8, xmm10 + xor edi, ebp + paddd xmm10, xmm0 + xor ebp, eax + pxor xmm1, xmm9 + add ecx, edx + add ebx, dword [rsp + $14] + and edi, ebp + xor ebp, eax + ror edx, $7 + movdqa xmm9, xmm1 + mov esi, ecx + xor edi, ebp + movdqa oword [rsp], xmm10 + rol ecx, $5 + add ebx, edi + xor esi, edx + pslld xmm1, $2 + xor edx, ebp + add ebx, ecx + psrld xmm9, $1E + add eax, dword [rsp + $18] + and esi, edx + xor edx, ebp + por xmm1, xmm9 + ror ecx, $7 + mov edi, ebx + xor esi, edx + rol ebx, $5 + pshufd xmm10, xmm0, $EE + add eax, esi + xor edi, ecx + xor ecx, edx + add eax, ebx + add ebp, dword [rsp + $1C] + and edi, ecx + xor ecx, edx + ror ebx, $7 + mov esi, eax + xor edi, ecx + rol eax, $5 + add ebp, edi + xor esi, ebx + xor ebx, ecx + add ebp, eax + pxor xmm2, xmm6 + add edx, dword [rsp + $20] + and esi, ebx + xor ebx, ecx + ror eax, $7 + punpcklqdq xmm10, xmm1 + mov edi, ebp + xor esi, ebx + pxor xmm2, xmm3 + rol ebp, $5 + add edx, esi + movdqa xmm9, xmm8 + xor edi, eax + paddd xmm8, xmm1 + xor eax, ebx + pxor xmm2, xmm10 + add edx, ebp + add ecx, dword [rsp + $24] + and edi, eax + xor eax, ebx + ror ebp, $7 + movdqa xmm10, xmm2 + mov esi, edx + xor edi, eax + movdqa oword [rsp + $10], xmm8 + rol edx, $5 + add ecx, edi + xor esi, ebp + pslld xmm2, $2 + xor ebp, eax + add ecx, edx + psrld xmm10, $1E + add ebx, dword [rsp + $28] + and esi, ebp + xor ebp, eax + por xmm2, xmm10 + ror edx, $7 + mov edi, ecx + xor esi, ebp + rol ecx, $5 + pshufd xmm8, xmm1, $EE + add ebx, esi + xor edi, edx + xor edx, ebp + add ebx, ecx + add eax, dword [rsp + $2C] + and edi, edx + xor edx, ebp + ror ecx, $7 + mov esi, ebx + xor edi, edx + rol ebx, $5 + add eax, edi + xor esi, edx + add eax, ebx + pxor xmm3, xmm7 + add ebp, dword [rsp + $30] + xor esi, ecx + punpcklqdq xmm8, xmm2 + mov edi, eax + rol eax, $5 + pxor xmm3, xmm4 + add ebp, esi + xor edi, ecx + movdqa xmm10, xmm9 + ror ebx, $7 + paddd xmm9, xmm2 + add ebp, eax + pxor xmm3, xmm8 + add edx, dword [rsp + $34] + xor edi, ebx + mov esi, ebp + rol ebp, $5 + movdqa xmm8, xmm3 + add edx, edi + xor esi, ebx + movdqa oword [rsp + $20], xmm9 + ror eax, $7 + add edx, ebp + add ecx, dword [rsp + $38] + pslld xmm3, $2 + xor esi, eax + mov edi, edx + psrld xmm8, $1E + rol edx, $5 + add ecx, esi + xor edi, eax + ror ebp, $7 + por xmm3, xmm8 + add ecx, edx + add ebx, dword [rsp + $3C] + xor edi, ebp + mov esi, ecx + rol ecx, $5 + add ebx, edi + xor esi, ebp + ror edx, $7 + add ebx, ecx + add eax, dword [rsp] + xor esi, edx + mov edi, ebx + rol ebx, $5 + paddd xmm10, xmm3 + add eax, esi + xor edi, edx + movdqa oword [rsp + $30], xmm10 + ror ecx, $7 + add eax, ebx + add ebp, dword [rsp + $4] + xor edi, ecx + mov esi, eax + rol eax, $5 + add ebp, edi + xor esi, ecx + ror ebx, $7 + add ebp, eax + add edx, dword [rsp + $8] + xor esi, ebx + mov edi, ebp + rol ebp, $5 + add edx, esi + xor edi, ebx + ror eax, $7 + add edx, ebp + add ecx, dword [rsp + $C] + xor edi, eax + mov esi, edx + rol edx, $5 + add ecx, edi + xor esi, eax + ror ebp, $7 + add ecx, edx + cmp r9, r10 + je @done + movdqu xmm6, oword [r14 + $40] + movdqu xmm9, oword [r14 - $40] + movdqu xmm0, oword [r9] + movdqu xmm1, oword [r9 + $10] + movdqu xmm2, oword [r9 + $20] + movdqu xmm3, oword [r9 + $30] + db $66, $41, $0F, $38, $00, $C4 // pshufb xmm0, xmm12 + add r9, $40 + add ebx, dword [rsp + $10] + xor esi, ebp + mov edi, ecx + db $66, $41, $0F, $38, $00, $CC // pshufb xmm1, xmm12 + rol ecx, $5 + add ebx, esi + xor edi, ebp + ror edx, $7 + paddd xmm0, xmm9 + add ebx, ecx + add eax, dword [rsp + $14] + xor edi, edx + mov esi, ebx + movdqa oword [rsp], xmm0 + rol ebx, $5 + add eax, edi + xor esi, edx + ror ecx, $7 + psubd xmm0, xmm9 + add eax, ebx + add ebp, dword [rsp + $18] + xor esi, ecx + mov edi, eax + rol eax, $5 + add ebp, esi + xor edi, ecx + ror ebx, $7 + add ebp, eax + add edx, dword [rsp + $1C] + xor edi, ebx + mov esi, ebp + rol ebp, $5 + add edx, edi + xor esi, ebx + ror eax, $7 + add edx, ebp + add ecx, dword [rsp + $20] + xor esi, eax + mov edi, edx + db $66, $41, $0F, $38, $00, $D4 // pshufb xmm2, xmm12 + rol edx, $5 + add ecx, esi + xor edi, eax + ror ebp, $7 + paddd xmm1, xmm9 + add ecx, edx + add ebx, dword [rsp + $24] + xor edi, ebp + mov esi, ecx + movdqa oword [rsp + $10], xmm1 + rol ecx, $5 + add ebx, edi + xor esi, ebp + ror edx, $7 + psubd xmm1, xmm9 + add ebx, ecx + add eax, dword [rsp + $28] + xor esi, edx + mov edi, ebx + rol ebx, $5 + add eax, esi + xor edi, edx + ror ecx, $7 + add eax, ebx + add ebp, dword [rsp + $2C] + xor edi, ecx + mov esi, eax + rol eax, $5 + add ebp, edi + xor esi, ecx + ror ebx, $7 + add ebp, eax + add edx, dword [rsp + $30] + xor esi, ebx + mov edi, ebp + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + rol ebp, $5 + add edx, esi + xor edi, ebx + ror eax, $7 + paddd xmm2, xmm9 + add edx, ebp + add ecx, dword [rsp + $34] + xor edi, eax + mov esi, edx + movdqa oword [rsp + $20], xmm2 + rol edx, $5 + add ecx, edi + xor esi, eax + ror ebp, $7 + psubd xmm2, xmm9 + add ecx, edx + add ebx, dword [rsp + $38] + xor esi, ebp + mov edi, ecx + rol ecx, $5 + add ebx, esi + xor edi, ebp + ror edx, $7 + add ebx, ecx + add eax, dword [rsp + $3C] + xor edi, edx + mov esi, ebx + rol ebx, $5 + add eax, edi + ror ecx, $7 + add eax, ebx + add eax, dword [r8] + add esi, dword [r8 + $4] + add ecx, dword [r8 + $8] + add edx, dword [r8 + $C] + mov dword [r8], eax + add ebp, dword [r8 + $10] + mov dword [r8 + $4], esi + mov ebx, esi + mov dword [r8 + $8], ecx + mov edi, ecx + mov dword [r8 + $C], edx + xor edi, edx + mov dword [r8 + $10], ebp + and esi, edi + jmp @block_loop + +@done: + add ebx, dword [rsp + $10] + xor esi, ebp + mov edi, ecx + rol ecx, $5 + add ebx, esi + xor edi, ebp + ror edx, $7 + add ebx, ecx + add eax, dword [rsp + $14] + xor edi, edx + mov esi, ebx + rol ebx, $5 + add eax, edi + xor esi, edx + ror ecx, $7 + add eax, ebx + add ebp, dword [rsp + $18] + xor esi, ecx + mov edi, eax + rol eax, $5 + add ebp, esi + xor edi, ecx + ror ebx, $7 + add ebp, eax + add edx, dword [rsp + $1C] + xor edi, ebx + mov esi, ebp + rol ebp, $5 + add edx, edi + xor esi, ebx + ror eax, $7 + add edx, ebp + add ecx, dword [rsp + $20] + xor esi, eax + mov edi, edx + rol edx, $5 + add ecx, esi + xor edi, eax + ror ebp, $7 + add ecx, edx + add ebx, dword [rsp + $24] + xor edi, ebp + mov esi, ecx + rol ecx, $5 + add ebx, edi + xor esi, ebp + ror edx, $7 + add ebx, ecx + add eax, dword [rsp + $28] + xor esi, edx + mov edi, ebx + rol ebx, $5 + add eax, esi + xor edi, edx + ror ecx, $7 + add eax, ebx + add ebp, dword [rsp + $2C] + xor edi, ecx + mov esi, eax + rol eax, $5 + add ebp, edi + xor esi, ecx + ror ebx, $7 + add ebp, eax + add edx, dword [rsp + $30] + xor esi, ebx + mov edi, ebp + rol ebp, $5 + add edx, esi + xor edi, ebx + ror eax, $7 + add edx, ebp + add ecx, dword [rsp + $34] + xor edi, eax + mov esi, edx + rol edx, $5 + add ecx, edi + xor esi, eax + ror ebp, $7 + add ecx, edx + add ebx, dword [rsp + $38] + xor esi, ebp + mov edi, ecx + rol ecx, $5 + add ebx, esi + xor edi, ebp + ror edx, $7 + add ebx, ecx + add eax, dword [rsp + $3C] + xor edi, edx + mov esi, ebx + rol ebx, $5 + add eax, edi + ror ecx, $7 + add eax, ebx + add eax, dword [r8] + add esi, dword [r8 + $4] + add ecx, dword [r8 + $8] + mov dword [r8], eax + add edx, dword [r8 + $C] + mov dword [r8 + $4], esi + add ebp, dword [r8 + $10] + mov dword [r8 + $8], ecx + mov dword [r8 + $C], edx + mov dword [r8 + $10], ebp + mov rsi, qword [r11 - $40] + mov rdi, qword [r11 - $38] + mov r14, qword [r11 - $30] + mov r13, qword [r11 - $28] + mov r12, qword [r11 - $20] + mov rbp, qword [r11 - $18] + mov rbx, qword [r11 - $10] + lea rsp, [r11] + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc new file mode 100644 index 0000000..6f198cb --- /dev/null +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc @@ -0,0 +1,1208 @@ +// SHA-256 AVX SIMD-schedule implementation (IA-32). VEX-128 (AVX1) +// instructions only - there is no i386 AVX2 SHA-256 upstream - dispatched at +// the AVX2 tier (every AVX2 CPU has AVX1; AVX1-only CPUs fall to the SSSE3 +// tier). The 3-operand VEX forms eliminate the SSSE3 kernel's register-copy +// movdqa traffic; the byte-swap mask stays resident in xmm7. All VEX +// instructions are db-encoded for broad assembler compatibility. +// K256 is read from K256_Doubled at a 32-byte stride (the walk and offsets +// are doubled relative to the original; VEX memory operands are read +// unaligned, so the Pascal const needs no special alignment). +// Reference: OpenSSL CRYPTOGAMS sha256-586.pl (AVX section). +// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, +// edi = numblocks, eax = K256_Doubled ptr. HlpSimdProc4Begin pushes +// ebx/esi/edi; ebp is pushed here as the K walk pointer. Frame and slot +// layout (ctx@96/data@100/end@104/savedsp@108) mirror the SSE2/SSSE3 +// siblings. + + push ebp + mov ebp, eax + mov eax, edi + mov edi, esi + mov esi, ebx + mov ebx, esp + sub esp, $10 + and esp, $FFFFFFC0 + shl eax, $6 + add eax, edi + mov dword ptr [esp], esi + mov dword ptr [esp + $4], edi + mov dword ptr [esp + $8], eax + mov dword ptr [esp + $C], ebx + lea esp, [esp - $60] + db $C5, $FC, $77 // vzeroall + mov eax, dword ptr [esi] + mov ebx, dword ptr [esi + $4] + mov ecx, dword ptr [esi + $8] + mov edi, dword ptr [esi + $C] + mov dword ptr [esp + $4], ebx + xor ebx, ecx + mov dword ptr [esp + $8], ecx + mov dword ptr [esp + $C], edi + mov edx, dword ptr [esi + $10] + mov edi, dword ptr [esi + $14] + mov ecx, dword ptr [esi + $18] + mov esi, dword ptr [esi + $1C] + mov dword ptr [esp + $14], edi + mov edi, dword ptr [esp + $64] + mov dword ptr [esp + $18], ecx + mov dword ptr [esp + $1C], esi + db $C5, $FA, $6F, $BD, $00, $02, $00, $00 // vmovdqu xmm7, oword [ebp + $200] + jmp @grand_avx_014 + +@grand_avx_014: + db $C5, $FA, $6F, $07 // vmovdqu xmm0, oword [edi] + db $C5, $FA, $6F, $4F, $10 // vmovdqu xmm1, oword [edi + $10] + db $C5, $FA, $6F, $57, $20 // vmovdqu xmm2, oword [edi + $20] + db $C5, $FA, $6F, $5F, $30 // vmovdqu xmm3, oword [edi + $30] + add edi, $40 + db $C4, $E2, $79, $00, $C7 // vpshufb xmm0, xmm0, xmm7 + mov dword ptr [esp + $64], edi + db $C4, $E2, $71, $00, $CF // vpshufb xmm1, xmm1, xmm7 + db $C4, $E2, $69, $00, $D7 // vpshufb xmm2, xmm2, xmm7 + db $C5, $F9, $FE, $65, $00 // vpaddd xmm4, xmm0, oword [ebp + $0] + db $C4, $E2, $61, $00, $DF // vpshufb xmm3, xmm3, xmm7 + db $C5, $F1, $FE, $6D, $20 // vpaddd xmm5, xmm1, oword [ebp + $20] + db $C5, $E9, $FE, $75, $40 // vpaddd xmm6, xmm2, oword [ebp + $40] + db $C5, $E1, $FE, $7D, $60 // vpaddd xmm7, xmm3, oword [ebp + $60] + db $C5, $F9, $7F, $64, $24, $20 // vmovdqa oword [esp + $20], xmm4 + db $C5, $F9, $7F, $6C, $24, $30 // vmovdqa oword [esp + $30], xmm5 + db $C5, $F9, $7F, $74, $24, $40 // vmovdqa oword [esp + $40], xmm6 + db $C5, $F9, $7F, $7C, $24, $50 // vmovdqa oword [esp + $50], xmm7 + jmp @avx_00_47_015 + +@avx_00_47_015: + add ebp, $80 + db $C4, $E3, $71, $0F, $E0, $04 // vpalignr xmm4, xmm1, xmm0, $4 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $14] + db $C4, $E3, $61, $0F, $FA, $04 // vpalignr xmm7, xmm3, xmm2, $4 + xor edx, ecx + mov edi, dword ptr [esp + $18] + xor esi, edi + db $C5, $C9, $72, $D4, $07 // vpsrld xmm6, xmm4, $7 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $10], ecx + db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $C1, $72, $D4, $03 // vpsrld xmm7, xmm4, $3 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $4] + db $C5, $D1, $72, $F4, $0E // vpslld xmm5, xmm4, $E + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp], eax + db $C5, $C1, $EF, $E6 // vpxor xmm4, xmm7, xmm6 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $1C] + db $C5, $F9, $70, $FB, $FA // vpshufd xmm7, xmm3, $FA + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $C9, $72, $D6, $0B // vpsrld xmm6, xmm6, $B + add edx, dword ptr [esp + $20] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + add ebx, edx + add edx, dword ptr [esp + $C] + add ebx, ecx + db $C5, $D1, $72, $F5, $0B // vpslld xmm5, xmm5, $B + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $10] + db $C5, $D9, $EF, $E6 // vpxor xmm4, xmm4, xmm6 + xor edx, ecx + mov edi, dword ptr [esp + $14] + xor esi, edi + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $C], ecx + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp] + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $1C], ebx + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $18] + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + add edx, dword ptr [esp + $24] + xor eax, edi + shrd ecx, ecx, $2 + db $C5, $F9, $70, $FE, $84 // vpshufd xmm7, xmm6, $84 + add eax, edx + add edx, dword ptr [esp + $8] + add eax, ecx + db $C5, $C1, $73, $DF, $08 // vpsrldq xmm7, xmm7, $8 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $C] + db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 + xor edx, ecx + mov edi, dword ptr [esp + $10] + xor esi, edi + db $C5, $F9, $70, $F8, $50 // vpshufd xmm7, xmm0, $50 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $8], ecx + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $1C] + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $18], eax + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $14] + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $F9, $70, $FE, $E8 // vpshufd xmm7, xmm6, $E8 + add edx, dword ptr [esp + $28] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $C1, $73, $FF, $08 // vpslldq xmm7, xmm7, $8 + add ebx, edx + add edx, dword ptr [esp + $4] + add ebx, ecx + db $C5, $F9, $FE, $C7 // vpaddd xmm0, xmm0, xmm7 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $8] + db $C5, $F9, $FE, $75, $00 // vpaddd xmm6, xmm0, oword [ebp + $0] + xor edx, ecx + mov edi, dword ptr [esp + $C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $4], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $18] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $10] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $2C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp] + add eax, ecx + db $C5, $F9, $7F, $74, $24, $20 // vmovdqa oword [esp + $20], xmm6 + db $C4, $E3, $69, $0F, $E1, $04 // vpalignr xmm4, xmm2, xmm1, $4 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $4] + db $C4, $E3, $79, $0F, $FB, $04 // vpalignr xmm7, xmm0, xmm3, $4 + xor edx, ecx + mov edi, dword ptr [esp + $8] + xor esi, edi + db $C5, $C9, $72, $D4, $07 // vpsrld xmm6, xmm4, $7 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp], ecx + db $C5, $F1, $FE, $CF // vpaddd xmm1, xmm1, xmm7 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $C1, $72, $D4, $03 // vpsrld xmm7, xmm4, $3 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $14] + db $C5, $D1, $72, $F4, $0E // vpslld xmm5, xmm4, $E + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $10], eax + db $C5, $C1, $EF, $E6 // vpxor xmm4, xmm7, xmm6 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $C] + db $C5, $F9, $70, $F8, $FA // vpshufd xmm7, xmm0, $FA + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $C9, $72, $D6, $0B // vpsrld xmm6, xmm6, $B + add edx, dword ptr [esp + $30] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + add ebx, edx + add edx, dword ptr [esp + $1C] + add ebx, ecx + db $C5, $D1, $72, $F5, $0B // vpslld xmm5, xmm5, $B + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp] + db $C5, $D9, $EF, $E6 // vpxor xmm4, xmm4, xmm6 + xor edx, ecx + mov edi, dword ptr [esp + $4] + xor esi, edi + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $1C], ecx + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $10] + db $C5, $F1, $FE, $CC // vpaddd xmm1, xmm1, xmm4 + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $C], ebx + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $8] + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + add edx, dword ptr [esp + $34] + xor eax, edi + shrd ecx, ecx, $2 + db $C5, $F9, $70, $FE, $84 // vpshufd xmm7, xmm6, $84 + add eax, edx + add edx, dword ptr [esp + $18] + add eax, ecx + db $C5, $C1, $73, $DF, $08 // vpsrldq xmm7, xmm7, $8 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $1C] + db $C5, $F1, $FE, $CF // vpaddd xmm1, xmm1, xmm7 + xor edx, ecx + mov edi, dword ptr [esp] + xor esi, edi + db $C5, $F9, $70, $F9, $50 // vpshufd xmm7, xmm1, $50 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $18], ecx + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $C] + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $8], eax + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $4] + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $F9, $70, $FE, $E8 // vpshufd xmm7, xmm6, $E8 + add edx, dword ptr [esp + $38] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $C1, $73, $FF, $08 // vpslldq xmm7, xmm7, $8 + add ebx, edx + add edx, dword ptr [esp + $14] + add ebx, ecx + db $C5, $F1, $FE, $CF // vpaddd xmm1, xmm1, xmm7 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $18] + db $C5, $F1, $FE, $75, $20 // vpaddd xmm6, xmm1, oword [ebp + $20] + xor edx, ecx + mov edi, dword ptr [esp + $1C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $14], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $8] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $3C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $10] + add eax, ecx + db $C5, $F9, $7F, $74, $24, $30 // vmovdqa oword [esp + $30], xmm6 + db $C4, $E3, $61, $0F, $E2, $04 // vpalignr xmm4, xmm3, xmm2, $4 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $14] + db $C4, $E3, $71, $0F, $F8, $04 // vpalignr xmm7, xmm1, xmm0, $4 + xor edx, ecx + mov edi, dword ptr [esp + $18] + xor esi, edi + db $C5, $C9, $72, $D4, $07 // vpsrld xmm6, xmm4, $7 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $10], ecx + db $C5, $E9, $FE, $D7 // vpaddd xmm2, xmm2, xmm7 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $C1, $72, $D4, $03 // vpsrld xmm7, xmm4, $3 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $4] + db $C5, $D1, $72, $F4, $0E // vpslld xmm5, xmm4, $E + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp], eax + db $C5, $C1, $EF, $E6 // vpxor xmm4, xmm7, xmm6 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $1C] + db $C5, $F9, $70, $F9, $FA // vpshufd xmm7, xmm1, $FA + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $C9, $72, $D6, $0B // vpsrld xmm6, xmm6, $B + add edx, dword ptr [esp + $40] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + add ebx, edx + add edx, dword ptr [esp + $C] + add ebx, ecx + db $C5, $D1, $72, $F5, $0B // vpslld xmm5, xmm5, $B + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $10] + db $C5, $D9, $EF, $E6 // vpxor xmm4, xmm4, xmm6 + xor edx, ecx + mov edi, dword ptr [esp + $14] + xor esi, edi + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $C], ecx + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp] + db $C5, $E9, $FE, $D4 // vpaddd xmm2, xmm2, xmm4 + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $1C], ebx + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $18] + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + add edx, dword ptr [esp + $44] + xor eax, edi + shrd ecx, ecx, $2 + db $C5, $F9, $70, $FE, $84 // vpshufd xmm7, xmm6, $84 + add eax, edx + add edx, dword ptr [esp + $8] + add eax, ecx + db $C5, $C1, $73, $DF, $08 // vpsrldq xmm7, xmm7, $8 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $C] + db $C5, $E9, $FE, $D7 // vpaddd xmm2, xmm2, xmm7 + xor edx, ecx + mov edi, dword ptr [esp + $10] + xor esi, edi + db $C5, $F9, $70, $FA, $50 // vpshufd xmm7, xmm2, $50 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $8], ecx + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $1C] + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $18], eax + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $14] + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $F9, $70, $FE, $E8 // vpshufd xmm7, xmm6, $E8 + add edx, dword ptr [esp + $48] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $C1, $73, $FF, $08 // vpslldq xmm7, xmm7, $8 + add ebx, edx + add edx, dword ptr [esp + $4] + add ebx, ecx + db $C5, $E9, $FE, $D7 // vpaddd xmm2, xmm2, xmm7 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $8] + db $C5, $E9, $FE, $75, $40 // vpaddd xmm6, xmm2, oword [ebp + $40] + xor edx, ecx + mov edi, dword ptr [esp + $C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $4], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $18] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $10] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $4C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp] + add eax, ecx + db $C5, $F9, $7F, $74, $24, $40 // vmovdqa oword [esp + $40], xmm6 + db $C4, $E3, $79, $0F, $E3, $04 // vpalignr xmm4, xmm0, xmm3, $4 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $4] + db $C4, $E3, $69, $0F, $F9, $04 // vpalignr xmm7, xmm2, xmm1, $4 + xor edx, ecx + mov edi, dword ptr [esp + $8] + xor esi, edi + db $C5, $C9, $72, $D4, $07 // vpsrld xmm6, xmm4, $7 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp], ecx + db $C5, $E1, $FE, $DF // vpaddd xmm3, xmm3, xmm7 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $C1, $72, $D4, $03 // vpsrld xmm7, xmm4, $3 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $14] + db $C5, $D1, $72, $F4, $0E // vpslld xmm5, xmm4, $E + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $10], eax + db $C5, $C1, $EF, $E6 // vpxor xmm4, xmm7, xmm6 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $C] + db $C5, $F9, $70, $FA, $FA // vpshufd xmm7, xmm2, $FA + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $C9, $72, $D6, $0B // vpsrld xmm6, xmm6, $B + add edx, dword ptr [esp + $50] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + add ebx, edx + add edx, dword ptr [esp + $1C] + add ebx, ecx + db $C5, $D1, $72, $F5, $0B // vpslld xmm5, xmm5, $B + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp] + db $C5, $D9, $EF, $E6 // vpxor xmm4, xmm4, xmm6 + xor edx, ecx + mov edi, dword ptr [esp + $4] + xor esi, edi + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $1C], ecx + db $C5, $D9, $EF, $E5 // vpxor xmm4, xmm4, xmm5 + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $10] + db $C5, $E1, $FE, $DC // vpaddd xmm3, xmm3, xmm4 + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $C], ebx + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $8] + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + add edx, dword ptr [esp + $54] + xor eax, edi + shrd ecx, ecx, $2 + db $C5, $F9, $70, $FE, $84 // vpshufd xmm7, xmm6, $84 + add eax, edx + add edx, dword ptr [esp + $18] + add eax, ecx + db $C5, $C1, $73, $DF, $08 // vpsrldq xmm7, xmm7, $8 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $1C] + db $C5, $E1, $FE, $DF // vpaddd xmm3, xmm3, xmm7 + xor edx, ecx + mov edi, dword ptr [esp] + xor esi, edi + db $C5, $F9, $70, $FB, $50 // vpshufd xmm7, xmm3, $50 + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $18], ecx + db $C5, $C9, $72, $D7, $0A // vpsrld xmm6, xmm7, $A + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + db $C5, $D1, $73, $D7, $11 // vpsrlq xmm5, xmm7, $11 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $C] + db $C5, $C9, $EF, $F5 // vpxor xmm6, xmm6, xmm5 + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $8], eax + db $C5, $C1, $73, $D7, $13 // vpsrlq xmm7, xmm7, $13 + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $4] + db $C5, $C9, $EF, $F7 // vpxor xmm6, xmm6, xmm7 + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + db $C5, $F9, $70, $FE, $E8 // vpshufd xmm7, xmm6, $E8 + add edx, dword ptr [esp + $58] + xor ebx, edi + shrd ecx, ecx, $2 + db $C5, $C1, $73, $FF, $08 // vpslldq xmm7, xmm7, $8 + add ebx, edx + add edx, dword ptr [esp + $14] + add ebx, ecx + db $C5, $E1, $FE, $DF // vpaddd xmm3, xmm3, xmm7 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $18] + db $C5, $E1, $FE, $75, $60 // vpaddd xmm6, xmm3, oword [ebp + $60] + xor edx, ecx + mov edi, dword ptr [esp + $1C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $14], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $8] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $5C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $10] + add eax, ecx + db $C5, $F9, $7F, $74, $24, $50 // vmovdqa oword [esp + $50], xmm6 + cmp dword ptr [ebp + $80], $10203 + jne @avx_00_47_015 + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $14] + xor edx, ecx + mov edi, dword ptr [esp + $18] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $10], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $4] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $1C] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $20] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $C] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $10] + xor edx, ecx + mov edi, dword ptr [esp + $14] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $C], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $1C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $18] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $24] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $8] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $C] + xor edx, ecx + mov edi, dword ptr [esp + $10] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $8], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $1C] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $18], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $14] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $28] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $4] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $8] + xor edx, ecx + mov edi, dword ptr [esp + $C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $4], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $18] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $10] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $2C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $4] + xor edx, ecx + mov edi, dword ptr [esp + $8] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $14] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $10], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $C] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $30] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $1C] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp] + xor edx, ecx + mov edi, dword ptr [esp + $4] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $1C], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $10] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $8] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $34] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $18] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $1C] + xor edx, ecx + mov edi, dword ptr [esp] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $18], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $C] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $8], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $4] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $38] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $14] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $18] + xor edx, ecx + mov edi, dword ptr [esp + $1C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $14], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $8] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $3C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $10] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $14] + xor edx, ecx + mov edi, dword ptr [esp + $18] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $10], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $4] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $1C] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $40] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $C] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $10] + xor edx, ecx + mov edi, dword ptr [esp + $14] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $C], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $1C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $18] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $44] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $8] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $C] + xor edx, ecx + mov edi, dword ptr [esp + $10] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $8], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $1C] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $18], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $14] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $48] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $4] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $8] + xor edx, ecx + mov edi, dword ptr [esp + $C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $4], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $18] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $10] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $4C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $4] + xor edx, ecx + mov edi, dword ptr [esp + $8] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $14] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $10], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $C] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $50] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $1C] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp] + xor edx, ecx + mov edi, dword ptr [esp + $4] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $1C], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $10] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp + $8] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $54] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $18] + add eax, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $1C] + xor edx, ecx + mov edi, dword ptr [esp] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $18], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword ptr [esp + $C] + mov esi, eax + shrd ecx, ecx, $9 + mov dword ptr [esp + $8], eax + xor ecx, eax + xor eax, edi + add edx, dword ptr [esp + $4] + shrd ecx, ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword ptr [esp + $58] + xor ebx, edi + shrd ecx, ecx, $2 + add ebx, edx + add edx, dword ptr [esp + $14] + add ebx, ecx + mov ecx, edx + shrd edx, edx, $E + mov esi, dword ptr [esp + $18] + xor edx, ecx + mov edi, dword ptr [esp + $1C] + xor esi, edi + shrd edx, edx, $5 + and esi, ecx + mov dword ptr [esp + $14], ecx + xor edx, ecx + xor edi, esi + shrd edx, edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword ptr [esp + $8] + mov esi, ebx + shrd ecx, ecx, $9 + mov dword ptr [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword ptr [esp] + shrd ecx, ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword ptr [esp + $5C] + xor eax, edi + shrd ecx, ecx, $2 + add eax, edx + add edx, dword ptr [esp + $10] + add eax, ecx + mov esi, dword ptr [esp + $60] + xor ebx, edi + mov ecx, dword ptr [esp + $C] + add eax, dword ptr [esi] + add ebx, dword ptr [esi + $4] + add edi, dword ptr [esi + $8] + add ecx, dword ptr [esi + $C] + mov dword ptr [esi], eax + mov dword ptr [esi + $4], ebx + mov dword ptr [esi + $8], edi + mov dword ptr [esi + $C], ecx + mov dword ptr [esp + $4], ebx + xor ebx, edi + mov dword ptr [esp + $8], edi + mov dword ptr [esp + $C], ecx + mov edi, dword ptr [esp + $14] + mov ecx, dword ptr [esp + $18] + add edx, dword ptr [esi + $10] + add edi, dword ptr [esi + $14] + add ecx, dword ptr [esi + $18] + mov dword ptr [esi + $10], edx + mov dword ptr [esi + $14], edi + mov dword ptr [esp + $14], edi + mov edi, dword ptr [esp + $1C] + mov dword ptr [esi + $18], ecx + add edi, dword ptr [esi + $1C] + mov dword ptr [esp + $18], ecx + mov dword ptr [esi + $1C], edi + mov dword ptr [esp + $1C], edi + mov edi, dword ptr [esp + $64] + db $C5, $FA, $6F, $BD, $80, $00, $00, $00 // vmovdqu xmm7, oword [ebp + $80] + sub ebp, $180 + cmp edi, dword ptr [esp + $68] + jb @grand_avx_014 + mov esp, dword ptr [esp + $6C] + db $C5, $FC, $77 // vzeroall + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc index af245c1..afafd99 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc @@ -1,10 +1,11 @@ -// SHA-256 AVX2 two-block implementation (VEX-256), ported from OpenSSL's -// sha512-x86_64.pl (CRYPTOGAMS; that generator emits both the SHA-256 and the -// SHA-512 kernels). Two message blocks are scheduled together in 256-bit lanes; -// the compression rounds stay serial (as SHA-256 requires), so scheduling two -// blocks at once is what makes this faster than the single-block AVX path. AVX2 -// and BMI2 (rorx/andn) instructions are db-encoded for broad assembler -// compatibility (every AVX2 CPU also provides BMI2). +// SHA-256 AVX2 two-block implementation (VEX-256). Two message blocks are +// scheduled together in 256-bit lanes; the compression rounds stay serial (as +// SHA-256 requires), so scheduling two blocks at once is what makes this faster +// than the single-block AVX path. AVX2 and BMI2 (rorx/andn) instructions are +// db-encoded for broad assembler compatibility (every AVX2 CPU also provides +// BMI2). +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX2 kernel; that generator +// emits both the SHA-256 and the SHA-512 kernels). // Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K256 ptr (each 128-bit K256 quadruple stored // twice so one table feeds both 256-bit lanes, with the byte-swap and two diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc new file mode 100644 index 0000000..41469e5 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc @@ -0,0 +1,222 @@ +// SHA-256 SHA-NI implementation (IA-32; Intel SHA Extensions work in 32-bit +// mode), with the unified function's common prologue reproduced by the same +// proven head as the SSE2/SSSE3/AVX siblings (slots ctx/data/end/savedsp; +// the section's sub $32 shifts them to 32/36/40/44). K256 is read from +// K256_Doubled at a 32-byte stride (bias and offsets doubled; read unaligned +// - Pascal consts have no alignment guarantee); the byte-swap mask sits at +// the doubled +512 (= biased +256). SHA-NI and shuffle instructions are +// db-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha256-586.pl (shaext section). +// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, +// edi = numblocks, eax = K256_Doubled ptr. HlpSimdProc4Begin pushes +// ebx/esi/edi; ebp is pushed here as the K pointer. + + push ebp + mov ebp, eax + mov eax, edi + mov edi, esi + mov esi, ebx + mov ebx, esp + sub esp, $10 + and esp, $FFFFFFC0 + shl eax, $6 + add eax, edi + mov dword ptr [esp], esi + mov dword ptr [esp + $4], edi + mov dword ptr [esp + $8], eax + mov dword ptr [esp + $C], ebx + sub esp, $20 + movdqu xmm1, oword ptr [esi] + lea ebp, [ebp + $100] + movdqu xmm2, oword ptr [esi + $10] + movdqu xmm7, oword ptr [ebp + $100] + pshufd xmm0, xmm1, $1B + pshufd xmm1, xmm1, $B1 + pshufd xmm2, xmm2, $1B + db $66, $0F, $3A, $0F, $CA, $08 // palignr xmm1, xmm2, $8 + db $66, $0F, $6C, $D0 // punpcklqdq xmm2, xmm0 + jmp @loop_shaext_011 + +@loop_shaext_011: + movdqu xmm3, oword ptr [edi] + movdqu xmm4, oword ptr [edi + $10] + movdqu xmm5, oword ptr [edi + $20] + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + movdqu xmm6, oword ptr [edi + $30] + movdqa oword ptr [esp + $10], xmm2 + movdqu xmm0, oword ptr [ebp - $100] + paddd xmm0, xmm3 + db $66, $0F, $38, $00, $E7 // pshufb xmm4, xmm7 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + nop + movdqa oword ptr [esp], xmm1 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $E0] + paddd xmm0, xmm4 + db $66, $0F, $38, $00, $EF // pshufb xmm5, xmm7 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + lea edi, [edi + $40] + db $0F, $38, $CC, $DC // sha256msg1 xmm3, xmm4 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $C0] + paddd xmm0, xmm5 + db $66, $0F, $38, $00, $F7 // pshufb xmm6, xmm7 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm6 + db $66, $0F, $3A, $0F, $FD, $04 // palignr xmm7, xmm5, $4 + nop + paddd xmm3, xmm7 + db $0F, $38, $CC, $E5 // sha256msg1 xmm4, xmm5 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $A0] + paddd xmm0, xmm6 + db $0F, $38, $CD, $DE // sha256msg2 xmm3, xmm6 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm3 + db $66, $0F, $3A, $0F, $FE, $04 // palignr xmm7, xmm6, $4 + nop + paddd xmm4, xmm7 + db $0F, $38, $CC, $EE // sha256msg1 xmm5, xmm6 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $80] + paddd xmm0, xmm3 + db $0F, $38, $CD, $E3 // sha256msg2 xmm4, xmm3 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm4 + db $66, $0F, $3A, $0F, $FB, $04 // palignr xmm7, xmm3, $4 + nop + paddd xmm5, xmm7 + db $0F, $38, $CC, $F3 // sha256msg1 xmm6, xmm3 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $60] + paddd xmm0, xmm4 + db $0F, $38, $CD, $EC // sha256msg2 xmm5, xmm4 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm5 + db $66, $0F, $3A, $0F, $FC, $04 // palignr xmm7, xmm4, $4 + nop + paddd xmm6, xmm7 + db $0F, $38, $CC, $DC // sha256msg1 xmm3, xmm4 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $40] + paddd xmm0, xmm5 + db $0F, $38, $CD, $F5 // sha256msg2 xmm6, xmm5 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm6 + db $66, $0F, $3A, $0F, $FD, $04 // palignr xmm7, xmm5, $4 + nop + paddd xmm3, xmm7 + db $0F, $38, $CC, $E5 // sha256msg1 xmm4, xmm5 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp - $20] + paddd xmm0, xmm6 + db $0F, $38, $CD, $DE // sha256msg2 xmm3, xmm6 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm3 + db $66, $0F, $3A, $0F, $FE, $04 // palignr xmm7, xmm6, $4 + nop + paddd xmm4, xmm7 + db $0F, $38, $CC, $EE // sha256msg1 xmm5, xmm6 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $0] + paddd xmm0, xmm3 + db $0F, $38, $CD, $E3 // sha256msg2 xmm4, xmm3 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm4 + db $66, $0F, $3A, $0F, $FB, $04 // palignr xmm7, xmm3, $4 + nop + paddd xmm5, xmm7 + db $0F, $38, $CC, $F3 // sha256msg1 xmm6, xmm3 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $20] + paddd xmm0, xmm4 + db $0F, $38, $CD, $EC // sha256msg2 xmm5, xmm4 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm5 + db $66, $0F, $3A, $0F, $FC, $04 // palignr xmm7, xmm4, $4 + nop + paddd xmm6, xmm7 + db $0F, $38, $CC, $DC // sha256msg1 xmm3, xmm4 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $40] + paddd xmm0, xmm5 + db $0F, $38, $CD, $F5 // sha256msg2 xmm6, xmm5 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm6 + db $66, $0F, $3A, $0F, $FD, $04 // palignr xmm7, xmm5, $4 + nop + paddd xmm3, xmm7 + db $0F, $38, $CC, $E5 // sha256msg1 xmm4, xmm5 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $60] + paddd xmm0, xmm6 + db $0F, $38, $CD, $DE // sha256msg2 xmm3, xmm6 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm3 + db $66, $0F, $3A, $0F, $FE, $04 // palignr xmm7, xmm6, $4 + nop + paddd xmm4, xmm7 + db $0F, $38, $CC, $EE // sha256msg1 xmm5, xmm6 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $80] + paddd xmm0, xmm3 + db $0F, $38, $CD, $E3 // sha256msg2 xmm4, xmm3 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm4 + db $66, $0F, $3A, $0F, $FB, $04 // palignr xmm7, xmm3, $4 + nop + paddd xmm5, xmm7 + db $0F, $38, $CC, $F3 // sha256msg1 xmm6, xmm3 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $A0] + paddd xmm0, xmm4 + db $0F, $38, $CD, $EC // sha256msg2 xmm5, xmm4 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + movdqa xmm7, xmm5 + db $66, $0F, $3A, $0F, $FC, $04 // palignr xmm7, xmm4, $4 + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + paddd xmm6, xmm7 + movdqu xmm0, oword ptr [ebp + $C0] + paddd xmm0, xmm5 + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + db $0F, $38, $CD, $F5 // sha256msg2 xmm6, xmm5 + movdqu xmm7, oword ptr [ebp + $100] + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + movdqu xmm0, oword ptr [ebp + $E0] + paddd xmm0, xmm6 + nop + db $0F, $38, $CB, $D1 // sha256rnds2 xmm2, xmm1, xmm0 + pshufd xmm0, xmm0, $E + cmp eax, edi + nop + db $0F, $38, $CB, $CA // sha256rnds2 xmm1, xmm2, xmm0 + paddd xmm2, oword ptr [esp + $10] + paddd xmm1, oword ptr [esp] + jnz @loop_shaext_011 + pshufd xmm2, xmm2, $B1 + pshufd xmm7, xmm1, $1B + pshufd xmm1, xmm1, $B1 + db $66, $0F, $6D, $CA // punpckhqdq xmm1, xmm2 + db $66, $0F, $3A, $0F, $D7, $08 // palignr xmm2, xmm7, $8 + mov esp, dword ptr [esp + $2C] + movdqu oword ptr [esi], xmm1 + movdqu oword ptr [esi + $10], xmm2 + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc index 0b1f0f3..5ed2a80 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc @@ -1,9 +1,9 @@ -// SHA-256 SHA-NI implementation (Intel SHA Extensions), the same design as -// OpenSSL's x86_64 sha256_block_data_order_shaext (CRYPTOGAMS). Each 4-round +// SHA-256 SHA-NI implementation (Intel SHA Extensions). Each 4-round // group is two sha256rnds2 with the message schedule (sha256msg1/sha256msg2 + // palignr) interleaved. The input is byte-swapped with pshufb against // BSWAP32_MASK (a plain per-dword swap - SHA-256 consumes its words in natural // order, so no dword reversal is needed). +// Reference: OpenSSL CRYPTOGAMS x86_64 sha256_block_data_order_shaext. // // Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = K256 ptr (64 UInt32 round constants), r10 = byte-swap diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc index e994d13..9425610 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc @@ -1,10 +1,10 @@ -// SHA-256 SSE2 SIMD-schedule implementation (IA-32), derived from OpenSSL's -// sha256-586 (CRYPTOGAMS) SSSE3 kernel. The message schedule runs in SSE2 -// (paddd/psrld/pslld/pxor/pshufd/psrldq/pslldq) interleaved with the GPR +// SHA-256 SSE2 SIMD-schedule implementation (IA-32). The message schedule runs +// in SSE2 (paddd/psrld/pslld/pxor/pshufd/psrldq/pslldq) interleaved with the GPR // compression rounds; the 32-bit state lives in eax/ebx/ecx plus the local frame -// (IA-32 has too few GPRs to keep all eight in registers). OpenSSL's two SSSE3-only -// ops are emulated in SSE2: the pshufb dword byte-swap becomes psrlw/psllw/por + -// pshuflw/pshufhw, and palignr becomes psrldq/pslldq/por. +// (IA-32 has too few GPRs to keep all eight in registers). The original's two +// SSSE3-only ops are emulated in SSE2: the pshufb dword byte-swap becomes +// psrlw/psllw/por + pshuflw/pshufhw, and palignr becomes psrldq/pslldq/por. +// Reference: OpenSSL CRYPTOGAMS sha256-586.pl (SSSE3 kernel). // Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, // eax = doubled-K256 ptr (read at a 32-byte stride so the duplicated halves are // skipped; see K256_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is pushed diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc index 7829cb9..0374ce6 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc @@ -1,10 +1,10 @@ -// SHA-256 SSE2 SIMD-schedule implementation, derived from OpenSSL's SHA-256 -// SSSE3 kernel in sha512-x86_64.pl (CRYPTOGAMS). The message schedule runs in +// SHA-256 SSE2 SIMD-schedule implementation. The message schedule runs in // SSE2 (paddd/psrld/pslld/pxor/pshufd) interleaved with the GPR compression -// rounds, so the vector and integer units run in parallel. OpenSSL's two +// rounds, so the vector and integer units run in parallel. The original's two // SSSE3-only ops are emulated in SSE2: the pshufb dword byte-swap becomes // psrlw/psllw/por + pshuflw/pshufhw, and palignr becomes psrldq/pslldq/por // (xmm8 is a free scratch). +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (SHA-256 SSSE3 kernel). // Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K256 ptr (read at a 32-byte stride so the // duplicated halves are skipped; see K256_Doubled). No byte-swap mask table is diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc new file mode 100644 index 0000000..426a494 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc @@ -0,0 +1,1235 @@ +// SHA-256 SSSE3 SIMD-schedule implementation (IA-32); SSE2 sibling: +// SHA256CompressSse2_i386.inc. +// The message schedule runs in SIMD interleaved with the GPR compression +// rounds; the 32-bit state lives in eax/ebx/ecx plus the local frame (IA-32 +// has too few GPRs to keep all eight in registers). Unlike the SSE2 sibling, +// the two SSSE3 ops are the real instructions (db-encoded for broad assembler +// compatibility): pshufb dword byte-swap against the mask kept in xmm7 for +// the block head, and palignr $4 in the schedule. +// Reference: OpenSSL CRYPTOGAMS sha256-586.pl (SSSE3 kernel). +// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, +// eax = doubled-K256 ptr (read at a 32-byte stride so the duplicated halves are +// skipped; see K256_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is pushed +// here as the K256 walk pointer; state loads into eax/ebx/ecx and the frame. + + push ebp + mov ebp, eax + mov eax, edi + mov edi, esi + mov esi, ebx + mov ebx, esp + sub esp, $10 + and esp, $FFFFFFC0 + shl eax, $6 + add eax, edi + mov dword [esp], esi + mov dword [esp + $4], edi + mov dword [esp + $8], eax + mov dword [esp + $C], ebx + lea esp, [esp - $60] + mov eax, dword [esi] + mov ebx, dword [esi + $4] + mov ecx, dword [esi + $8] + mov edi, dword [esi + $C] + mov dword [esp + $4], ebx + xor ebx, ecx + mov dword [esp + $8], ecx + mov dword [esp + $C], edi + mov edx, dword [esi + $10] + mov edi, dword [esi + $14] + mov ecx, dword [esi + $18] + mov esi, dword [esi + $1C] + mov dword [esp + $14], edi + mov edi, dword [esp + $64] + mov dword [esp + $18], ecx + mov dword [esp + $1C], esi + jmp @block_loop + +@block_loop: + movdqu xmm0, oword [edi] + movdqu xmm1, oword [edi + $10] + movdqu xmm2, oword [edi + $20] + movdqu xmm3, oword [edi + $30] + add edi, $40 + movdqu xmm7, oword [ebp + $200] // dword byte-swap mask (K256_Doubled + 512) + db $66, $0F, $38, $00, $C7 // pshufb xmm0, xmm7 + mov dword [esp + $64], edi + db $66, $0F, $38, $00, $CF // pshufb xmm1, xmm7 + movdqu xmm4, oword [ebp + $0] + db $66, $0F, $38, $00, $D7 // pshufb xmm2, xmm7 + movdqu xmm5, oword [ebp + $20] + paddd xmm4, xmm0 + db $66, $0F, $38, $00, $DF // pshufb xmm3, xmm7 + movdqu xmm6, oword [ebp + $40] + paddd xmm5, xmm1 + movdqu xmm7, oword [ebp + $60] + movdqa oword [esp + $20], xmm4 + paddd xmm6, xmm2 + movdqa oword [esp + $30], xmm5 + paddd xmm7, xmm3 + movdqa oword [esp + $40], xmm6 + movdqa oword [esp + $50], xmm7 + jmp @sched_loop + +@sched_loop: + add ebp, $80 + mov ecx, edx + movdqa xmm4, xmm1 + ror edx, $E + mov esi, dword [esp + $14] + movdqa xmm7, xmm3 + xor edx, ecx + mov edi, dword [esp + $18] + db $66, $0F, $3A, $0F, $E0, $04 // palignr xmm4, xmm0, 4 + xor esi, edi + ror edx, $5 + and esi, ecx + db $66, $0F, $3A, $0F, $FA, $04 // palignr xmm7, xmm2, 4 + mov dword [esp + $10], ecx + xor edx, ecx + xor edi, esi + movdqa xmm5, xmm4 + ror edx, $6 + mov ecx, eax + movdqa xmm6, xmm4 + add edx, edi + mov edi, dword [esp + $4] + psrld xmm4, $3 + mov esi, eax + ror ecx, $9 + paddd xmm0, xmm7 + mov dword [esp], eax + xor ecx, eax + psrld xmm6, $7 + xor eax, edi + add edx, dword [esp + $1C] + ror ecx, $B + and ebx, eax + pshufd xmm7, xmm3, $FA + xor ecx, esi + add edx, dword [esp + $20] + pslld xmm5, $E + xor ebx, edi + ror ecx, $2 + pxor xmm4, xmm6 + add ebx, edx + add edx, dword [esp + $C] + psrld xmm6, $B + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm4, xmm5 + mov esi, dword [esp + $10] + xor edx, ecx + pslld xmm5, $B + mov edi, dword [esp + $14] + xor esi, edi + ror edx, $5 + pxor xmm4, xmm6 + and esi, ecx + mov dword [esp + $C], ecx + movdqa xmm6, xmm7 + xor edx, ecx + xor edi, esi + ror edx, $6 + pxor xmm4, xmm5 + mov ecx, ebx + add edx, edi + psrld xmm7, $A + mov edi, dword [esp] + mov esi, ebx + ror ecx, $9 + paddd xmm0, xmm4 + mov dword [esp + $1C], ebx + xor ecx, ebx + psrlq xmm6, $11 + xor ebx, edi + add edx, dword [esp + $18] + ror ecx, $B + pxor xmm7, xmm6 + and eax, ebx + xor ecx, esi + psrlq xmm6, $2 + add edx, dword [esp + $24] + xor eax, edi + ror ecx, $2 + pxor xmm7, xmm6 + add eax, edx + add edx, dword [esp + $8] + pshufd xmm7, xmm7, $80 + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $C] + xor edx, ecx + mov edi, dword [esp + $10] + xor esi, edi + ror edx, $5 + and esi, ecx + psrldq xmm7, $8 + mov dword [esp + $8], ecx + xor edx, ecx + xor edi, esi + paddd xmm0, xmm7 + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $1C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $18], eax + pshufd xmm7, xmm0, $50 + xor ecx, eax + xor eax, edi + add edx, dword [esp + $14] + movdqa xmm6, xmm7 + ror ecx, $B + psrld xmm7, $A + and ebx, eax + psrlq xmm6, $11 + xor ecx, esi + add edx, dword [esp + $28] + xor ebx, edi + ror ecx, $2 + pxor xmm7, xmm6 + add ebx, edx + add edx, dword [esp + $4] + psrlq xmm6, $2 + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm7, xmm6 + mov esi, dword [esp + $8] + xor edx, ecx + mov edi, dword [esp + $C] + pshufd xmm7, xmm7, $8 + xor esi, edi + ror edx, $5 + movdqu xmm6, oword [ebp + $0] + and esi, ecx + mov dword [esp + $4], ecx + pslldq xmm7, $8 + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $18] + mov esi, ebx + ror ecx, $9 + paddd xmm0, xmm7 + mov dword [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $10] + paddd xmm6, xmm0 + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $2C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp] + add eax, ecx + movdqa oword [esp + $20], xmm6 + mov ecx, edx + movdqa xmm4, xmm2 + ror edx, $E + mov esi, dword [esp + $4] + movdqa xmm7, xmm0 + xor edx, ecx + mov edi, dword [esp + $8] + db $66, $0F, $3A, $0F, $E1, $04 // palignr xmm4, xmm1, 4 + xor esi, edi + ror edx, $5 + and esi, ecx + db $66, $0F, $3A, $0F, $FB, $04 // palignr xmm7, xmm3, 4 + mov dword [esp], ecx + xor edx, ecx + xor edi, esi + movdqa xmm5, xmm4 + ror edx, $6 + mov ecx, eax + movdqa xmm6, xmm4 + add edx, edi + mov edi, dword [esp + $14] + psrld xmm4, $3 + mov esi, eax + ror ecx, $9 + paddd xmm1, xmm7 + mov dword [esp + $10], eax + xor ecx, eax + psrld xmm6, $7 + xor eax, edi + add edx, dword [esp + $C] + ror ecx, $B + and ebx, eax + pshufd xmm7, xmm0, $FA + xor ecx, esi + add edx, dword [esp + $30] + pslld xmm5, $E + xor ebx, edi + ror ecx, $2 + pxor xmm4, xmm6 + add ebx, edx + add edx, dword [esp + $1C] + psrld xmm6, $B + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm4, xmm5 + mov esi, dword [esp] + xor edx, ecx + pslld xmm5, $B + mov edi, dword [esp + $4] + xor esi, edi + ror edx, $5 + pxor xmm4, xmm6 + and esi, ecx + mov dword [esp + $1C], ecx + movdqa xmm6, xmm7 + xor edx, ecx + xor edi, esi + ror edx, $6 + pxor xmm4, xmm5 + mov ecx, ebx + add edx, edi + psrld xmm7, $A + mov edi, dword [esp + $10] + mov esi, ebx + ror ecx, $9 + paddd xmm1, xmm4 + mov dword [esp + $C], ebx + xor ecx, ebx + psrlq xmm6, $11 + xor ebx, edi + add edx, dword [esp + $8] + ror ecx, $B + pxor xmm7, xmm6 + and eax, ebx + xor ecx, esi + psrlq xmm6, $2 + add edx, dword [esp + $34] + xor eax, edi + ror ecx, $2 + pxor xmm7, xmm6 + add eax, edx + add edx, dword [esp + $18] + pshufd xmm7, xmm7, $80 + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $1C] + xor edx, ecx + mov edi, dword [esp] + xor esi, edi + ror edx, $5 + and esi, ecx + psrldq xmm7, $8 + mov dword [esp + $18], ecx + xor edx, ecx + xor edi, esi + paddd xmm1, xmm7 + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $8], eax + pshufd xmm7, xmm1, $50 + xor ecx, eax + xor eax, edi + add edx, dword [esp + $4] + movdqa xmm6, xmm7 + ror ecx, $B + psrld xmm7, $A + and ebx, eax + psrlq xmm6, $11 + xor ecx, esi + add edx, dword [esp + $38] + xor ebx, edi + ror ecx, $2 + pxor xmm7, xmm6 + add ebx, edx + add edx, dword [esp + $14] + psrlq xmm6, $2 + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm7, xmm6 + mov esi, dword [esp + $18] + xor edx, ecx + mov edi, dword [esp + $1C] + pshufd xmm7, xmm7, $8 + xor esi, edi + ror edx, $5 + movdqu xmm6, oword [ebp + $20] + and esi, ecx + mov dword [esp + $14], ecx + pslldq xmm7, $8 + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $8] + mov esi, ebx + ror ecx, $9 + paddd xmm1, xmm7 + mov dword [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp] + paddd xmm6, xmm1 + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $3C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $10] + add eax, ecx + movdqa oword [esp + $30], xmm6 + mov ecx, edx + movdqa xmm4, xmm3 + ror edx, $E + mov esi, dword [esp + $14] + movdqa xmm7, xmm1 + xor edx, ecx + mov edi, dword [esp + $18] + db $66, $0F, $3A, $0F, $E2, $04 // palignr xmm4, xmm2, 4 + xor esi, edi + ror edx, $5 + and esi, ecx + db $66, $0F, $3A, $0F, $F8, $04 // palignr xmm7, xmm0, 4 + mov dword [esp + $10], ecx + xor edx, ecx + xor edi, esi + movdqa xmm5, xmm4 + ror edx, $6 + mov ecx, eax + movdqa xmm6, xmm4 + add edx, edi + mov edi, dword [esp + $4] + psrld xmm4, $3 + mov esi, eax + ror ecx, $9 + paddd xmm2, xmm7 + mov dword [esp], eax + xor ecx, eax + psrld xmm6, $7 + xor eax, edi + add edx, dword [esp + $1C] + ror ecx, $B + and ebx, eax + pshufd xmm7, xmm1, $FA + xor ecx, esi + add edx, dword [esp + $40] + pslld xmm5, $E + xor ebx, edi + ror ecx, $2 + pxor xmm4, xmm6 + add ebx, edx + add edx, dword [esp + $C] + psrld xmm6, $B + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm4, xmm5 + mov esi, dword [esp + $10] + xor edx, ecx + pslld xmm5, $B + mov edi, dword [esp + $14] + xor esi, edi + ror edx, $5 + pxor xmm4, xmm6 + and esi, ecx + mov dword [esp + $C], ecx + movdqa xmm6, xmm7 + xor edx, ecx + xor edi, esi + ror edx, $6 + pxor xmm4, xmm5 + mov ecx, ebx + add edx, edi + psrld xmm7, $A + mov edi, dword [esp] + mov esi, ebx + ror ecx, $9 + paddd xmm2, xmm4 + mov dword [esp + $1C], ebx + xor ecx, ebx + psrlq xmm6, $11 + xor ebx, edi + add edx, dword [esp + $18] + ror ecx, $B + pxor xmm7, xmm6 + and eax, ebx + xor ecx, esi + psrlq xmm6, $2 + add edx, dword [esp + $44] + xor eax, edi + ror ecx, $2 + pxor xmm7, xmm6 + add eax, edx + add edx, dword [esp + $8] + pshufd xmm7, xmm7, $80 + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $C] + xor edx, ecx + mov edi, dword [esp + $10] + xor esi, edi + ror edx, $5 + and esi, ecx + psrldq xmm7, $8 + mov dword [esp + $8], ecx + xor edx, ecx + xor edi, esi + paddd xmm2, xmm7 + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $1C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $18], eax + pshufd xmm7, xmm2, $50 + xor ecx, eax + xor eax, edi + add edx, dword [esp + $14] + movdqa xmm6, xmm7 + ror ecx, $B + psrld xmm7, $A + and ebx, eax + psrlq xmm6, $11 + xor ecx, esi + add edx, dword [esp + $48] + xor ebx, edi + ror ecx, $2 + pxor xmm7, xmm6 + add ebx, edx + add edx, dword [esp + $4] + psrlq xmm6, $2 + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm7, xmm6 + mov esi, dword [esp + $8] + xor edx, ecx + mov edi, dword [esp + $C] + pshufd xmm7, xmm7, $8 + xor esi, edi + ror edx, $5 + movdqu xmm6, oword [ebp + $40] + and esi, ecx + mov dword [esp + $4], ecx + pslldq xmm7, $8 + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $18] + mov esi, ebx + ror ecx, $9 + paddd xmm2, xmm7 + mov dword [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $10] + paddd xmm6, xmm2 + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $4C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp] + add eax, ecx + movdqa oword [esp + $40], xmm6 + mov ecx, edx + movdqa xmm4, xmm0 + ror edx, $E + mov esi, dword [esp + $4] + movdqa xmm7, xmm2 + xor edx, ecx + mov edi, dword [esp + $8] + db $66, $0F, $3A, $0F, $E3, $04 // palignr xmm4, xmm3, 4 + xor esi, edi + ror edx, $5 + and esi, ecx + db $66, $0F, $3A, $0F, $F9, $04 // palignr xmm7, xmm1, 4 + mov dword [esp], ecx + xor edx, ecx + xor edi, esi + movdqa xmm5, xmm4 + ror edx, $6 + mov ecx, eax + movdqa xmm6, xmm4 + add edx, edi + mov edi, dword [esp + $14] + psrld xmm4, $3 + mov esi, eax + ror ecx, $9 + paddd xmm3, xmm7 + mov dword [esp + $10], eax + xor ecx, eax + psrld xmm6, $7 + xor eax, edi + add edx, dword [esp + $C] + ror ecx, $B + and ebx, eax + pshufd xmm7, xmm2, $FA + xor ecx, esi + add edx, dword [esp + $50] + pslld xmm5, $E + xor ebx, edi + ror ecx, $2 + pxor xmm4, xmm6 + add ebx, edx + add edx, dword [esp + $1C] + psrld xmm6, $B + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm4, xmm5 + mov esi, dword [esp] + xor edx, ecx + pslld xmm5, $B + mov edi, dword [esp + $4] + xor esi, edi + ror edx, $5 + pxor xmm4, xmm6 + and esi, ecx + mov dword [esp + $1C], ecx + movdqa xmm6, xmm7 + xor edx, ecx + xor edi, esi + ror edx, $6 + pxor xmm4, xmm5 + mov ecx, ebx + add edx, edi + psrld xmm7, $A + mov edi, dword [esp + $10] + mov esi, ebx + ror ecx, $9 + paddd xmm3, xmm4 + mov dword [esp + $C], ebx + xor ecx, ebx + psrlq xmm6, $11 + xor ebx, edi + add edx, dword [esp + $8] + ror ecx, $B + pxor xmm7, xmm6 + and eax, ebx + xor ecx, esi + psrlq xmm6, $2 + add edx, dword [esp + $54] + xor eax, edi + ror ecx, $2 + pxor xmm7, xmm6 + add eax, edx + add edx, dword [esp + $18] + pshufd xmm7, xmm7, $80 + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $1C] + xor edx, ecx + mov edi, dword [esp] + xor esi, edi + ror edx, $5 + and esi, ecx + psrldq xmm7, $8 + mov dword [esp + $18], ecx + xor edx, ecx + xor edi, esi + paddd xmm3, xmm7 + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $8], eax + pshufd xmm7, xmm3, $50 + xor ecx, eax + xor eax, edi + add edx, dword [esp + $4] + movdqa xmm6, xmm7 + ror ecx, $B + psrld xmm7, $A + and ebx, eax + psrlq xmm6, $11 + xor ecx, esi + add edx, dword [esp + $58] + xor ebx, edi + ror ecx, $2 + pxor xmm7, xmm6 + add ebx, edx + add edx, dword [esp + $14] + psrlq xmm6, $2 + add ebx, ecx + mov ecx, edx + ror edx, $E + pxor xmm7, xmm6 + mov esi, dword [esp + $18] + xor edx, ecx + mov edi, dword [esp + $1C] + pshufd xmm7, xmm7, $8 + xor esi, edi + ror edx, $5 + movdqu xmm6, oword [ebp + $60] + and esi, ecx + mov dword [esp + $14], ecx + pslldq xmm7, $8 + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $8] + mov esi, ebx + ror ecx, $9 + paddd xmm3, xmm7 + mov dword [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp] + paddd xmm6, xmm3 + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $5C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $10] + add eax, ecx + movdqa oword [esp + $50], xmm6 + cmp dword [ebp + $80], $10203 + jne @sched_loop + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $14] + xor edx, ecx + mov edi, dword [esp + $18] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $10], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $4] + mov esi, eax + ror ecx, $9 + mov dword [esp], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $1C] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $20] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $C] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $10] + xor edx, ecx + mov edi, dword [esp + $14] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $C], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $1C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $18] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $24] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $8] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $C] + xor edx, ecx + mov edi, dword [esp + $10] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $8], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $1C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $18], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $14] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $28] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $4] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $8] + xor edx, ecx + mov edi, dword [esp + $C] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $4], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $18] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $10] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $2C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $4] + xor edx, ecx + mov edi, dword [esp + $8] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $14] + mov esi, eax + ror ecx, $9 + mov dword [esp + $10], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $C] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $30] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $1C] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp] + xor edx, ecx + mov edi, dword [esp + $4] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $1C], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $10] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $8] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $34] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $18] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $1C] + xor edx, ecx + mov edi, dword [esp] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $18], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $8], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $4] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $38] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $14] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $18] + xor edx, ecx + mov edi, dword [esp + $1C] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $14], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $8] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $3C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $10] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $14] + xor edx, ecx + mov edi, dword [esp + $18] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $10], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $4] + mov esi, eax + ror ecx, $9 + mov dword [esp], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $1C] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $40] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $C] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $10] + xor edx, ecx + mov edi, dword [esp + $14] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $C], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $1C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $18] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $44] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $8] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $C] + xor edx, ecx + mov edi, dword [esp + $10] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $8], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $1C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $18], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $14] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $48] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $4] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $8] + xor edx, ecx + mov edi, dword [esp + $C] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $4], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $18] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $14], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $10] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $4C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $4] + xor edx, ecx + mov edi, dword [esp + $8] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $14] + mov esi, eax + ror ecx, $9 + mov dword [esp + $10], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $C] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $50] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $1C] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp] + xor edx, ecx + mov edi, dword [esp + $4] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $1C], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $10] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $C], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp + $8] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $54] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $18] + add eax, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $1C] + xor edx, ecx + mov edi, dword [esp] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $18], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, eax + add edx, edi + mov edi, dword [esp + $C] + mov esi, eax + ror ecx, $9 + mov dword [esp + $8], eax + xor ecx, eax + xor eax, edi + add edx, dword [esp + $4] + ror ecx, $B + and ebx, eax + xor ecx, esi + add edx, dword [esp + $58] + xor ebx, edi + ror ecx, $2 + add ebx, edx + add edx, dword [esp + $14] + add ebx, ecx + mov ecx, edx + ror edx, $E + mov esi, dword [esp + $18] + xor edx, ecx + mov edi, dword [esp + $1C] + xor esi, edi + ror edx, $5 + and esi, ecx + mov dword [esp + $14], ecx + xor edx, ecx + xor edi, esi + ror edx, $6 + mov ecx, ebx + add edx, edi + mov edi, dword [esp + $8] + mov esi, ebx + ror ecx, $9 + mov dword [esp + $4], ebx + xor ecx, ebx + xor ebx, edi + add edx, dword [esp] + ror ecx, $B + and eax, ebx + xor ecx, esi + add edx, dword [esp + $5C] + xor eax, edi + ror ecx, $2 + add eax, edx + add edx, dword [esp + $10] + add eax, ecx + mov esi, dword [esp + $60] + xor ebx, edi + mov ecx, dword [esp + $C] + add eax, dword [esi] + add ebx, dword [esi + $4] + add edi, dword [esi + $8] + add ecx, dword [esi + $C] + mov dword [esi], eax + mov dword [esi + $4], ebx + mov dword [esi + $8], edi + mov dword [esi + $C], ecx + mov dword [esp + $4], ebx + xor ebx, edi + mov dword [esp + $8], edi + mov dword [esp + $C], ecx + mov edi, dword [esp + $14] + mov ecx, dword [esp + $18] + add edx, dword [esi + $10] + add edi, dword [esi + $14] + add ecx, dword [esi + $18] + mov dword [esi + $10], edx + mov dword [esi + $14], edi + mov dword [esp + $14], edi + mov edi, dword [esp + $1C] + mov dword [esi + $18], ecx + add edi, dword [esi + $1C] + mov dword [esp + $18], ecx + mov dword [esi + $1C], edi + mov dword [esp + $1C], edi + mov edi, dword [esp + $64] + sub ebp, $180 + cmp edi, dword [esp + $68] + jb @block_loop + mov esp, dword [esp + $6C] + pop ebp + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc new file mode 100644 index 0000000..80d7d19 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc @@ -0,0 +1,1110 @@ +// SHA-256 SSSE3 SIMD-schedule implementation; SSE2 sibling: +// SHA256CompressSse2_x86_64.inc. The message schedule runs in SIMD +// (paddd/psrld/pslld/pxor/pshufd) interleaved with the GPR compression +// rounds, so the vector and integer units run in parallel. Unlike the SSE2 +// sibling, the two SSSE3 ops are the real instructions (db-encoded for broad +// assembler compatibility): pshufb dword byte-swap against the mask kept in +// xmm8 for the whole kernel, and palignr $4 in the schedule. +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (SHA-256 SSSE3 kernel). +// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K256 ptr (read at a 32-byte stride so the +// duplicated halves are skipped; the byte-swap mask sits at +512). +// +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + mov rax, rsp + push r9 + movdqu xmm8, oword [r9 + $200] // dword byte-swap mask (K256_Doubled + 512) + push rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + mov rdi, rcx + mov rsi, rdx + mov edx, r8d + shl rdx, $4 + sub rsp, $A0 + lea rdx, [rsi + rdx*4] + and rsp, $FFFFFFFFFFFFFFC0 + mov qword [rsp + $40], rdi + mov qword [rsp + $48], rsi + mov qword [rsp + $50], rdx + mov qword [rsp + $58], rax + +@prologue: + mov eax, dword [rdi] + mov ebx, dword [rdi + $4] + mov ecx, dword [rdi + $8] + mov edx, dword [rdi + $C] + mov r8d, dword [rdi + $10] + mov r9d, dword [rdi + $14] + mov r10d, dword [rdi + $18] + mov r11d, dword [rdi + $1C] + jmp @block_loop + +@block_loop: + movdqu xmm0, oword [rsi] + movdqu xmm1, oword [rsi + $10] + movdqu xmm2, oword [rsi + $20] + db $66, $41, $0F, $38, $00, $C0 // pshufb xmm0, xmm8 + movdqu xmm3, oword [rsi + $30] + mov rbp, qword [rsp + $58] + mov rbp, qword [rbp - $8] + db $66, $41, $0F, $38, $00, $C8 // pshufb xmm1, xmm8 + movdqu xmm4, oword [rbp + $0] + movdqu xmm5, oword [rbp + $20] + db $66, $41, $0F, $38, $00, $D0 // pshufb xmm2, xmm8 + paddd xmm4, xmm0 + movdqu xmm6, oword [rbp + $40] + db $66, $41, $0F, $38, $00, $D8 // pshufb xmm3, xmm8 + movdqu xmm7, oword [rbp + $60] + paddd xmm5, xmm1 + paddd xmm6, xmm2 + paddd xmm7, xmm3 + movdqa oword [rsp], xmm4 + mov r14d, eax + movdqa oword [rsp + $10], xmm5 + mov edi, ebx + movdqa oword [rsp + $20], xmm6 + xor edi, ecx + movdqa oword [rsp + $30], xmm7 + mov r13d, r8d + jmp @sched_loop + +@sched_loop: + sub rbp, $FFFFFFFFFFFFFF80 + ror r13d, $E + movdqa xmm4, xmm1 + mov eax, r14d + mov r12d, r9d + movdqa xmm7, xmm3 + ror r14d, $9 + xor r13d, r8d + xor r12d, r10d + ror r13d, $5 + xor r14d, eax + db $66, $0F, $3A, $0F, $E0, $04 // palignr xmm4, xmm0, 4 + and r12d, r8d + xor r13d, r8d + db $66, $0F, $3A, $0F, $FA, $04 // palignr xmm7, xmm2, 4 + add r11d, dword [rsp] + mov r15d, eax + xor r12d, r10d + ror r14d, $B + movdqa xmm5, xmm4 + xor r15d, ebx + add r11d, r12d + movdqa xmm6, xmm4 + ror r13d, $6 + and edi, r15d + psrld xmm4, $3 + xor r14d, eax + add r11d, r13d + xor edi, ebx + paddd xmm0, xmm7 + ror r14d, $2 + add edx, r11d + psrld xmm6, $7 + add r11d, edi + mov r13d, edx + pshufd xmm7, xmm3, $FA + add r14d, r11d + ror r13d, $E + pslld xmm5, $E + mov r11d, r14d + mov r12d, r8d + pxor xmm4, xmm6 + ror r14d, $9 + xor r13d, edx + xor r12d, r9d + ror r13d, $5 + psrld xmm6, $B + xor r14d, r11d + pxor xmm4, xmm5 + and r12d, edx + xor r13d, edx + pslld xmm5, $B + add r10d, dword [rsp + $4] + mov edi, r11d + pxor xmm4, xmm6 + xor r12d, r9d + ror r14d, $B + movdqa xmm6, xmm7 + xor edi, eax + add r10d, r12d + pxor xmm4, xmm5 + ror r13d, $6 + and r15d, edi + xor r14d, r11d + psrld xmm7, $A + add r10d, r13d + xor r15d, eax + paddd xmm0, xmm4 + ror r14d, $2 + add ecx, r10d + psrlq xmm6, $11 + add r10d, r15d + mov r13d, ecx + add r14d, r10d + pxor xmm7, xmm6 + ror r13d, $E + mov r10d, r14d + mov r12d, edx + ror r14d, $9 + psrlq xmm6, $2 + xor r13d, ecx + xor r12d, r8d + pxor xmm7, xmm6 + ror r13d, $5 + xor r14d, r10d + and r12d, ecx + pshufd xmm7, xmm7, $80 + xor r13d, ecx + add r9d, dword [rsp + $8] + mov r15d, r10d + psrldq xmm7, $8 + xor r12d, r8d + ror r14d, $B + xor r15d, r11d + add r9d, r12d + ror r13d, $6 + paddd xmm0, xmm7 + and edi, r15d + xor r14d, r10d + add r9d, r13d + pshufd xmm7, xmm0, $50 + xor edi, r11d + ror r14d, $2 + add ebx, r9d + movdqa xmm6, xmm7 + add r9d, edi + mov r13d, ebx + psrld xmm7, $A + add r14d, r9d + ror r13d, $E + psrlq xmm6, $11 + mov r9d, r14d + mov r12d, ecx + pxor xmm7, xmm6 + ror r14d, $9 + xor r13d, ebx + xor r12d, edx + ror r13d, $5 + xor r14d, r9d + psrlq xmm6, $2 + and r12d, ebx + xor r13d, ebx + add r8d, dword [rsp + $C] + pxor xmm7, xmm6 + mov edi, r9d + xor r12d, edx + ror r14d, $B + pshufd xmm7, xmm7, $8 + xor edi, r10d + add r8d, r12d + movdqu xmm6, oword [rbp + $0] + ror r13d, $6 + and r15d, edi + pslldq xmm7, $8 + xor r14d, r9d + add r8d, r13d + xor r15d, r10d + paddd xmm0, xmm7 + ror r14d, $2 + add eax, r8d + add r8d, r15d + paddd xmm6, xmm0 + mov r13d, eax + add r14d, r8d + movdqa oword [rsp], xmm6 + ror r13d, $E + movdqa xmm4, xmm2 + mov r8d, r14d + mov r12d, ebx + movdqa xmm7, xmm0 + ror r14d, $9 + xor r13d, eax + xor r12d, ecx + ror r13d, $5 + xor r14d, r8d + db $66, $0F, $3A, $0F, $E1, $04 // palignr xmm4, xmm1, 4 + and r12d, eax + xor r13d, eax + db $66, $0F, $3A, $0F, $FB, $04 // palignr xmm7, xmm3, 4 + add edx, dword [rsp + $10] + mov r15d, r8d + xor r12d, ecx + ror r14d, $B + movdqa xmm5, xmm4 + xor r15d, r9d + add edx, r12d + movdqa xmm6, xmm4 + ror r13d, $6 + and edi, r15d + psrld xmm4, $3 + xor r14d, r8d + add edx, r13d + xor edi, r9d + paddd xmm1, xmm7 + ror r14d, $2 + add r11d, edx + psrld xmm6, $7 + add edx, edi + mov r13d, r11d + pshufd xmm7, xmm0, $FA + add r14d, edx + ror r13d, $E + pslld xmm5, $E + mov edx, r14d + mov r12d, eax + pxor xmm4, xmm6 + ror r14d, $9 + xor r13d, r11d + xor r12d, ebx + ror r13d, $5 + psrld xmm6, $B + xor r14d, edx + pxor xmm4, xmm5 + and r12d, r11d + xor r13d, r11d + pslld xmm5, $B + add ecx, dword [rsp + $14] + mov edi, edx + pxor xmm4, xmm6 + xor r12d, ebx + ror r14d, $B + movdqa xmm6, xmm7 + xor edi, r8d + add ecx, r12d + pxor xmm4, xmm5 + ror r13d, $6 + and r15d, edi + xor r14d, edx + psrld xmm7, $A + add ecx, r13d + xor r15d, r8d + paddd xmm1, xmm4 + ror r14d, $2 + add r10d, ecx + psrlq xmm6, $11 + add ecx, r15d + mov r13d, r10d + add r14d, ecx + pxor xmm7, xmm6 + ror r13d, $E + mov ecx, r14d + mov r12d, r11d + ror r14d, $9 + psrlq xmm6, $2 + xor r13d, r10d + xor r12d, eax + pxor xmm7, xmm6 + ror r13d, $5 + xor r14d, ecx + and r12d, r10d + pshufd xmm7, xmm7, $80 + xor r13d, r10d + add ebx, dword [rsp + $18] + mov r15d, ecx + psrldq xmm7, $8 + xor r12d, eax + ror r14d, $B + xor r15d, edx + add ebx, r12d + ror r13d, $6 + paddd xmm1, xmm7 + and edi, r15d + xor r14d, ecx + add ebx, r13d + pshufd xmm7, xmm1, $50 + xor edi, edx + ror r14d, $2 + add r9d, ebx + movdqa xmm6, xmm7 + add ebx, edi + mov r13d, r9d + psrld xmm7, $A + add r14d, ebx + ror r13d, $E + psrlq xmm6, $11 + mov ebx, r14d + mov r12d, r10d + pxor xmm7, xmm6 + ror r14d, $9 + xor r13d, r9d + xor r12d, r11d + ror r13d, $5 + xor r14d, ebx + psrlq xmm6, $2 + and r12d, r9d + xor r13d, r9d + add eax, dword [rsp + $1C] + pxor xmm7, xmm6 + mov edi, ebx + xor r12d, r11d + ror r14d, $B + pshufd xmm7, xmm7, $8 + xor edi, ecx + add eax, r12d + movdqu xmm6, oword [rbp + $20] + ror r13d, $6 + and r15d, edi + pslldq xmm7, $8 + xor r14d, ebx + add eax, r13d + xor r15d, ecx + paddd xmm1, xmm7 + ror r14d, $2 + add r8d, eax + add eax, r15d + paddd xmm6, xmm1 + mov r13d, r8d + add r14d, eax + movdqa oword [rsp + $10], xmm6 + ror r13d, $E + movdqa xmm4, xmm3 + mov eax, r14d + mov r12d, r9d + movdqa xmm7, xmm1 + ror r14d, $9 + xor r13d, r8d + xor r12d, r10d + ror r13d, $5 + xor r14d, eax + db $66, $0F, $3A, $0F, $E2, $04 // palignr xmm4, xmm2, 4 + and r12d, r8d + xor r13d, r8d + db $66, $0F, $3A, $0F, $F8, $04 // palignr xmm7, xmm0, 4 + add r11d, dword [rsp + $20] + mov r15d, eax + xor r12d, r10d + ror r14d, $B + movdqa xmm5, xmm4 + xor r15d, ebx + add r11d, r12d + movdqa xmm6, xmm4 + ror r13d, $6 + and edi, r15d + psrld xmm4, $3 + xor r14d, eax + add r11d, r13d + xor edi, ebx + paddd xmm2, xmm7 + ror r14d, $2 + add edx, r11d + psrld xmm6, $7 + add r11d, edi + mov r13d, edx + pshufd xmm7, xmm1, $FA + add r14d, r11d + ror r13d, $E + pslld xmm5, $E + mov r11d, r14d + mov r12d, r8d + pxor xmm4, xmm6 + ror r14d, $9 + xor r13d, edx + xor r12d, r9d + ror r13d, $5 + psrld xmm6, $B + xor r14d, r11d + pxor xmm4, xmm5 + and r12d, edx + xor r13d, edx + pslld xmm5, $B + add r10d, dword [rsp + $24] + mov edi, r11d + pxor xmm4, xmm6 + xor r12d, r9d + ror r14d, $B + movdqa xmm6, xmm7 + xor edi, eax + add r10d, r12d + pxor xmm4, xmm5 + ror r13d, $6 + and r15d, edi + xor r14d, r11d + psrld xmm7, $A + add r10d, r13d + xor r15d, eax + paddd xmm2, xmm4 + ror r14d, $2 + add ecx, r10d + psrlq xmm6, $11 + add r10d, r15d + mov r13d, ecx + add r14d, r10d + pxor xmm7, xmm6 + ror r13d, $E + mov r10d, r14d + mov r12d, edx + ror r14d, $9 + psrlq xmm6, $2 + xor r13d, ecx + xor r12d, r8d + pxor xmm7, xmm6 + ror r13d, $5 + xor r14d, r10d + and r12d, ecx + pshufd xmm7, xmm7, $80 + xor r13d, ecx + add r9d, dword [rsp + $28] + mov r15d, r10d + psrldq xmm7, $8 + xor r12d, r8d + ror r14d, $B + xor r15d, r11d + add r9d, r12d + ror r13d, $6 + paddd xmm2, xmm7 + and edi, r15d + xor r14d, r10d + add r9d, r13d + pshufd xmm7, xmm2, $50 + xor edi, r11d + ror r14d, $2 + add ebx, r9d + movdqa xmm6, xmm7 + add r9d, edi + mov r13d, ebx + psrld xmm7, $A + add r14d, r9d + ror r13d, $E + psrlq xmm6, $11 + mov r9d, r14d + mov r12d, ecx + pxor xmm7, xmm6 + ror r14d, $9 + xor r13d, ebx + xor r12d, edx + ror r13d, $5 + xor r14d, r9d + psrlq xmm6, $2 + and r12d, ebx + xor r13d, ebx + add r8d, dword [rsp + $2C] + pxor xmm7, xmm6 + mov edi, r9d + xor r12d, edx + ror r14d, $B + pshufd xmm7, xmm7, $8 + xor edi, r10d + add r8d, r12d + movdqu xmm6, oword [rbp + $40] + ror r13d, $6 + and r15d, edi + pslldq xmm7, $8 + xor r14d, r9d + add r8d, r13d + xor r15d, r10d + paddd xmm2, xmm7 + ror r14d, $2 + add eax, r8d + add r8d, r15d + paddd xmm6, xmm2 + mov r13d, eax + add r14d, r8d + movdqa oword [rsp + $20], xmm6 + ror r13d, $E + movdqa xmm4, xmm0 + mov r8d, r14d + mov r12d, ebx + movdqa xmm7, xmm2 + ror r14d, $9 + xor r13d, eax + xor r12d, ecx + ror r13d, $5 + xor r14d, r8d + db $66, $0F, $3A, $0F, $E3, $04 // palignr xmm4, xmm3, 4 + and r12d, eax + xor r13d, eax + db $66, $0F, $3A, $0F, $F9, $04 // palignr xmm7, xmm1, 4 + add edx, dword [rsp + $30] + mov r15d, r8d + xor r12d, ecx + ror r14d, $B + movdqa xmm5, xmm4 + xor r15d, r9d + add edx, r12d + movdqa xmm6, xmm4 + ror r13d, $6 + and edi, r15d + psrld xmm4, $3 + xor r14d, r8d + add edx, r13d + xor edi, r9d + paddd xmm3, xmm7 + ror r14d, $2 + add r11d, edx + psrld xmm6, $7 + add edx, edi + mov r13d, r11d + pshufd xmm7, xmm2, $FA + add r14d, edx + ror r13d, $E + pslld xmm5, $E + mov edx, r14d + mov r12d, eax + pxor xmm4, xmm6 + ror r14d, $9 + xor r13d, r11d + xor r12d, ebx + ror r13d, $5 + psrld xmm6, $B + xor r14d, edx + pxor xmm4, xmm5 + and r12d, r11d + xor r13d, r11d + pslld xmm5, $B + add ecx, dword [rsp + $34] + mov edi, edx + pxor xmm4, xmm6 + xor r12d, ebx + ror r14d, $B + movdqa xmm6, xmm7 + xor edi, r8d + add ecx, r12d + pxor xmm4, xmm5 + ror r13d, $6 + and r15d, edi + xor r14d, edx + psrld xmm7, $A + add ecx, r13d + xor r15d, r8d + paddd xmm3, xmm4 + ror r14d, $2 + add r10d, ecx + psrlq xmm6, $11 + add ecx, r15d + mov r13d, r10d + add r14d, ecx + pxor xmm7, xmm6 + ror r13d, $E + mov ecx, r14d + mov r12d, r11d + ror r14d, $9 + psrlq xmm6, $2 + xor r13d, r10d + xor r12d, eax + pxor xmm7, xmm6 + ror r13d, $5 + xor r14d, ecx + and r12d, r10d + pshufd xmm7, xmm7, $80 + xor r13d, r10d + add ebx, dword [rsp + $38] + mov r15d, ecx + psrldq xmm7, $8 + xor r12d, eax + ror r14d, $B + xor r15d, edx + add ebx, r12d + ror r13d, $6 + paddd xmm3, xmm7 + and edi, r15d + xor r14d, ecx + add ebx, r13d + pshufd xmm7, xmm3, $50 + xor edi, edx + ror r14d, $2 + add r9d, ebx + movdqa xmm6, xmm7 + add ebx, edi + mov r13d, r9d + psrld xmm7, $A + add r14d, ebx + ror r13d, $E + psrlq xmm6, $11 + mov ebx, r14d + mov r12d, r10d + pxor xmm7, xmm6 + ror r14d, $9 + xor r13d, r9d + xor r12d, r11d + ror r13d, $5 + xor r14d, ebx + psrlq xmm6, $2 + and r12d, r9d + xor r13d, r9d + add eax, dword [rsp + $3C] + pxor xmm7, xmm6 + mov edi, ebx + xor r12d, r11d + ror r14d, $B + pshufd xmm7, xmm7, $8 + xor edi, ecx + add eax, r12d + movdqu xmm6, oword [rbp + $60] + ror r13d, $6 + and r15d, edi + pslldq xmm7, $8 + xor r14d, ebx + add eax, r13d + xor r15d, ecx + paddd xmm3, xmm7 + ror r14d, $2 + add r8d, eax + add eax, r15d + paddd xmm6, xmm3 + mov r13d, r8d + add r14d, eax + movdqa oword [rsp + $30], xmm6 + cmp byte [rbp + $83], $0 + jne @sched_loop + ror r13d, $E + mov eax, r14d + mov r12d, r9d + ror r14d, $9 + xor r13d, r8d + xor r12d, r10d + ror r13d, $5 + xor r14d, eax + and r12d, r8d + xor r13d, r8d + add r11d, dword [rsp] + mov r15d, eax + xor r12d, r10d + ror r14d, $B + xor r15d, ebx + add r11d, r12d + ror r13d, $6 + and edi, r15d + xor r14d, eax + add r11d, r13d + xor edi, ebx + ror r14d, $2 + add edx, r11d + add r11d, edi + mov r13d, edx + add r14d, r11d + ror r13d, $E + mov r11d, r14d + mov r12d, r8d + ror r14d, $9 + xor r13d, edx + xor r12d, r9d + ror r13d, $5 + xor r14d, r11d + and r12d, edx + xor r13d, edx + add r10d, dword [rsp + $4] + mov edi, r11d + xor r12d, r9d + ror r14d, $B + xor edi, eax + add r10d, r12d + ror r13d, $6 + and r15d, edi + xor r14d, r11d + add r10d, r13d + xor r15d, eax + ror r14d, $2 + add ecx, r10d + add r10d, r15d + mov r13d, ecx + add r14d, r10d + ror r13d, $E + mov r10d, r14d + mov r12d, edx + ror r14d, $9 + xor r13d, ecx + xor r12d, r8d + ror r13d, $5 + xor r14d, r10d + and r12d, ecx + xor r13d, ecx + add r9d, dword [rsp + $8] + mov r15d, r10d + xor r12d, r8d + ror r14d, $B + xor r15d, r11d + add r9d, r12d + ror r13d, $6 + and edi, r15d + xor r14d, r10d + add r9d, r13d + xor edi, r11d + ror r14d, $2 + add ebx, r9d + add r9d, edi + mov r13d, ebx + add r14d, r9d + ror r13d, $E + mov r9d, r14d + mov r12d, ecx + ror r14d, $9 + xor r13d, ebx + xor r12d, edx + ror r13d, $5 + xor r14d, r9d + and r12d, ebx + xor r13d, ebx + add r8d, dword [rsp + $C] + mov edi, r9d + xor r12d, edx + ror r14d, $B + xor edi, r10d + add r8d, r12d + ror r13d, $6 + and r15d, edi + xor r14d, r9d + add r8d, r13d + xor r15d, r10d + ror r14d, $2 + add eax, r8d + add r8d, r15d + mov r13d, eax + add r14d, r8d + ror r13d, $E + mov r8d, r14d + mov r12d, ebx + ror r14d, $9 + xor r13d, eax + xor r12d, ecx + ror r13d, $5 + xor r14d, r8d + and r12d, eax + xor r13d, eax + add edx, dword [rsp + $10] + mov r15d, r8d + xor r12d, ecx + ror r14d, $B + xor r15d, r9d + add edx, r12d + ror r13d, $6 + and edi, r15d + xor r14d, r8d + add edx, r13d + xor edi, r9d + ror r14d, $2 + add r11d, edx + add edx, edi + mov r13d, r11d + add r14d, edx + ror r13d, $E + mov edx, r14d + mov r12d, eax + ror r14d, $9 + xor r13d, r11d + xor r12d, ebx + ror r13d, $5 + xor r14d, edx + and r12d, r11d + xor r13d, r11d + add ecx, dword [rsp + $14] + mov edi, edx + xor r12d, ebx + ror r14d, $B + xor edi, r8d + add ecx, r12d + ror r13d, $6 + and r15d, edi + xor r14d, edx + add ecx, r13d + xor r15d, r8d + ror r14d, $2 + add r10d, ecx + add ecx, r15d + mov r13d, r10d + add r14d, ecx + ror r13d, $E + mov ecx, r14d + mov r12d, r11d + ror r14d, $9 + xor r13d, r10d + xor r12d, eax + ror r13d, $5 + xor r14d, ecx + and r12d, r10d + xor r13d, r10d + add ebx, dword [rsp + $18] + mov r15d, ecx + xor r12d, eax + ror r14d, $B + xor r15d, edx + add ebx, r12d + ror r13d, $6 + and edi, r15d + xor r14d, ecx + add ebx, r13d + xor edi, edx + ror r14d, $2 + add r9d, ebx + add ebx, edi + mov r13d, r9d + add r14d, ebx + ror r13d, $E + mov ebx, r14d + mov r12d, r10d + ror r14d, $9 + xor r13d, r9d + xor r12d, r11d + ror r13d, $5 + xor r14d, ebx + and r12d, r9d + xor r13d, r9d + add eax, dword [rsp + $1C] + mov edi, ebx + xor r12d, r11d + ror r14d, $B + xor edi, ecx + add eax, r12d + ror r13d, $6 + and r15d, edi + xor r14d, ebx + add eax, r13d + xor r15d, ecx + ror r14d, $2 + add r8d, eax + add eax, r15d + mov r13d, r8d + add r14d, eax + ror r13d, $E + mov eax, r14d + mov r12d, r9d + ror r14d, $9 + xor r13d, r8d + xor r12d, r10d + ror r13d, $5 + xor r14d, eax + and r12d, r8d + xor r13d, r8d + add r11d, dword [rsp + $20] + mov r15d, eax + xor r12d, r10d + ror r14d, $B + xor r15d, ebx + add r11d, r12d + ror r13d, $6 + and edi, r15d + xor r14d, eax + add r11d, r13d + xor edi, ebx + ror r14d, $2 + add edx, r11d + add r11d, edi + mov r13d, edx + add r14d, r11d + ror r13d, $E + mov r11d, r14d + mov r12d, r8d + ror r14d, $9 + xor r13d, edx + xor r12d, r9d + ror r13d, $5 + xor r14d, r11d + and r12d, edx + xor r13d, edx + add r10d, dword [rsp + $24] + mov edi, r11d + xor r12d, r9d + ror r14d, $B + xor edi, eax + add r10d, r12d + ror r13d, $6 + and r15d, edi + xor r14d, r11d + add r10d, r13d + xor r15d, eax + ror r14d, $2 + add ecx, r10d + add r10d, r15d + mov r13d, ecx + add r14d, r10d + ror r13d, $E + mov r10d, r14d + mov r12d, edx + ror r14d, $9 + xor r13d, ecx + xor r12d, r8d + ror r13d, $5 + xor r14d, r10d + and r12d, ecx + xor r13d, ecx + add r9d, dword [rsp + $28] + mov r15d, r10d + xor r12d, r8d + ror r14d, $B + xor r15d, r11d + add r9d, r12d + ror r13d, $6 + and edi, r15d + xor r14d, r10d + add r9d, r13d + xor edi, r11d + ror r14d, $2 + add ebx, r9d + add r9d, edi + mov r13d, ebx + add r14d, r9d + ror r13d, $E + mov r9d, r14d + mov r12d, ecx + ror r14d, $9 + xor r13d, ebx + xor r12d, edx + ror r13d, $5 + xor r14d, r9d + and r12d, ebx + xor r13d, ebx + add r8d, dword [rsp + $2C] + mov edi, r9d + xor r12d, edx + ror r14d, $B + xor edi, r10d + add r8d, r12d + ror r13d, $6 + and r15d, edi + xor r14d, r9d + add r8d, r13d + xor r15d, r10d + ror r14d, $2 + add eax, r8d + add r8d, r15d + mov r13d, eax + add r14d, r8d + ror r13d, $E + mov r8d, r14d + mov r12d, ebx + ror r14d, $9 + xor r13d, eax + xor r12d, ecx + ror r13d, $5 + xor r14d, r8d + and r12d, eax + xor r13d, eax + add edx, dword [rsp + $30] + mov r15d, r8d + xor r12d, ecx + ror r14d, $B + xor r15d, r9d + add edx, r12d + ror r13d, $6 + and edi, r15d + xor r14d, r8d + add edx, r13d + xor edi, r9d + ror r14d, $2 + add r11d, edx + add edx, edi + mov r13d, r11d + add r14d, edx + ror r13d, $E + mov edx, r14d + mov r12d, eax + ror r14d, $9 + xor r13d, r11d + xor r12d, ebx + ror r13d, $5 + xor r14d, edx + and r12d, r11d + xor r13d, r11d + add ecx, dword [rsp + $34] + mov edi, edx + xor r12d, ebx + ror r14d, $B + xor edi, r8d + add ecx, r12d + ror r13d, $6 + and r15d, edi + xor r14d, edx + add ecx, r13d + xor r15d, r8d + ror r14d, $2 + add r10d, ecx + add ecx, r15d + mov r13d, r10d + add r14d, ecx + ror r13d, $E + mov ecx, r14d + mov r12d, r11d + ror r14d, $9 + xor r13d, r10d + xor r12d, eax + ror r13d, $5 + xor r14d, ecx + and r12d, r10d + xor r13d, r10d + add ebx, dword [rsp + $38] + mov r15d, ecx + xor r12d, eax + ror r14d, $B + xor r15d, edx + add ebx, r12d + ror r13d, $6 + and edi, r15d + xor r14d, ecx + add ebx, r13d + xor edi, edx + ror r14d, $2 + add r9d, ebx + add ebx, edi + mov r13d, r9d + add r14d, ebx + ror r13d, $E + mov ebx, r14d + mov r12d, r10d + ror r14d, $9 + xor r13d, r9d + xor r12d, r11d + ror r13d, $5 + xor r14d, ebx + and r12d, r9d + xor r13d, r9d + add eax, dword [rsp + $3C] + mov edi, ebx + xor r12d, r11d + ror r14d, $B + xor edi, ecx + add eax, r12d + ror r13d, $6 + and r15d, edi + xor r14d, ebx + add eax, r13d + xor r15d, ecx + ror r14d, $2 + add r8d, eax + add eax, r15d + mov r13d, r8d + add r14d, eax + mov rdi, qword [rsp + $40] + mov eax, r14d + add eax, dword [rdi] + lea rsi, [rsi + $40] + add ebx, dword [rdi + $4] + add ecx, dword [rdi + $8] + add edx, dword [rdi + $C] + add r8d, dword [rdi + $10] + add r9d, dword [rdi + $14] + add r10d, dword [rdi + $18] + add r11d, dword [rdi + $1C] + cmp rsi, qword [rsp + $50] + mov dword [rdi], eax + mov dword [rdi + $4], ebx + mov dword [rdi + $8], ecx + mov dword [rdi + $C], edx + mov dword [rdi + $10], r8d + mov dword [rdi + $14], r9d + mov dword [rdi + $18], r10d + mov dword [rdi + $1C], r11d + jb @block_loop + mov rsi, qword [rsp + $58] + mov r15, qword [rsi - $48] + mov r14, qword [rsi - $40] + mov r13, qword [rsi - $38] + mov r12, qword [rsi - $30] + mov rdi, qword [rsi - $28] + mov rbp, qword [rsi - $18] + mov rbx, qword [rsi - $10] + mov rax, qword [rsi - $20] + lea rsp, [rsi] + mov rsi, rax + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc index 2729c93..5c225b8 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc @@ -1,6 +1,6 @@ // Keccak-f[1600] AVX2 multi-block absorb. // Fuses data-XOR + permutation into a single loop with one gather/scatter. -// Ported from Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS project), +// Reference: Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS project), // as adopted by XKCP (eXtended Keccak Code Package): // https://github.com/dot-asm/cryptogams/blob/master/x86_64/keccak1600-avx2.pl // https://github.com/XKCP/XKCP/blob/master/lib/low/KeccakP-1600/AVX2/KeccakP-1600-AVX2.s diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc index 9f97422..561cf53 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc @@ -1,5 +1,5 @@ // Keccak-f[1600] AVX2 permutation. -// Ported from Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS project), +// Reference: Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS project), // as adopted by XKCP (eXtended Keccak Code Package): // https://github.com/dot-asm/cryptogams/blob/master/x86_64/keccak1600-avx2.pl // https://github.com/XKCP/XKCP/blob/master/lib/low/KeccakP-1600/AVX2/KeccakP-1600-AVX2.s diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc new file mode 100644 index 0000000..a9ba75a --- /dev/null +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc @@ -0,0 +1,427 @@ +// Keccak-f[1600] sponge absorb for IA-32, pure SSE2 - the asm twin of the +// x86-64 absorb for the SSE2 dispatch slot: XORs whole blocks into the state +// and permutes. MMX converted to SSE2 like the permute. +// The permutation body is the same inner as KeccakF1600Sse2_i386.inc +// (embedded again because local labels cannot cross include files). +// Reference: OpenSSL CRYPTOGAMS keccak1600-mmx.pl (SHA3_absorb) by +// Andy Polyakov. +// +// After HlpSimdProc5Begin_i386: ebx = AState (25 x UInt64, standard layout), +// esi = AData, edi = ABlockCount, eax = ABlockSize, ecx = AConstants +// (iotas: 24 x UInt64 round constants). +// Frame mirrors the OpenSSL wrapper: ebp = saved esp with spills at +// [ebp-4/-8], 248-byte scratch, esp 8-aligned, inner scratch plane at +// esp+140, state biased by +100. Clobbers eax, ecx, edx, xmm0-xmm7; +// ebp saved here (the shared prologue saves ebx/esi/edi). + + push ebp + mov ebp, esp + + // remap to the OpenSSL absorb roles: + // esi = state+100, edi = xor walk, eax = input, ecx = remaining length, + // edx = block size, ebx = iotas + imul edi, eax // total length in bytes (count * size) + mov edx, eax // block size + mov eax, esi // input pointer + mov esi, ebx // state + mov ebx, ecx // iotas + mov ecx, edi // remaining length + mov edi, esi // xor walk = state base + lea esi, [esi + 100] // biased state pointer + + mov dword ptr [ebp - 4], edx // block size, reloaded after each permute + sub esp, 248 + and esp, $FFFFFFF8 + +@absorb_loop: + cmp ecx, edx + jb @absorb_done + + shr edx, 3 + +@absorb_block: + movq xmm0, qword ptr [eax] + lea eax, [eax + 8] + movq xmm1, qword ptr [edi] + pxor xmm0, xmm1 + lea edi, [edi + 8] + sub ecx, 8 + movq qword ptr [edi - 8], xmm0 + dec edx + jnz @absorb_block + + lea edi, [esp + 140] // scratch plane for the inner routine + mov dword ptr [ebp - 8], ecx + call @keccak_inner + mov ecx, dword ptr [ebp - 8] + mov edx, dword ptr [ebp - 4] + lea edi, [esi - 100] // reset the xor walk to the state base + jmp @absorb_loop + +@absorb_done: + mov esp, ebp + pop ebp + pop edi + pop esi + pop ebx + jmp @absorb_end + +@keccak_inner: + movq xmm0, qword ptr [esi + 60] + movq xmm1, qword ptr [esi + 68] + movq xmm2, qword ptr [esi + 76] + movq xmm3, qword ptr [esi + 84] + movq xmm4, qword ptr [esi + 92] + mov ecx, 24 + jmp @keccak_round_loop + +@keccak_round_loop: + movq xmm5, qword ptr [esi - 100] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi - 92] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi - 84] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi - 76] + pxor xmm3, xmm5 + movq xmm5, qword ptr [esi - 68] + pxor xmm4, xmm5 + movq xmm5, qword ptr [esi - 60] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi - 52] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi - 44] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi - 36] + pxor xmm3, xmm5 + movq xmm5, qword ptr [esi - 28] + pxor xmm4, xmm5 + movq xmm5, qword ptr [esi - 20] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi - 12] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi - 4] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi + 4] + pxor xmm3, xmm5 + movq xmm5, qword ptr [esi + 12] + pxor xmm4, xmm5 + movq xmm5, qword ptr [esi + 36] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi + 20] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi + 28] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi + 44] + pxor xmm3, xmm5 + movq xmm5, xmm2 + movq xmm6, qword ptr [esi + 52] + pxor xmm4, xmm6 + movq xmm7, xmm2 + psrlq xmm5, 63 + movq xmm6, xmm0 + psllq xmm7, 1 + pxor xmm5, xmm0 + psrlq xmm0, 63 + pxor xmm5, xmm7 + psllq xmm6, 1 + movq xmm7, xmm1 + movq qword ptr [esp + 12], xmm5 + pxor xmm6, xmm0 + psrlq xmm7, 63 + pxor xmm6, xmm3 + movq xmm0, xmm1 + movq qword ptr [esp + 36], xmm6 + psllq xmm0, 1 + pxor xmm7, xmm4 + pxor xmm0, xmm7 + movq xmm7, xmm3 + psrlq xmm3, 63 + movq qword ptr [esp + 4], xmm0 + psllq xmm7, 1 + movq xmm5, xmm4 + psrlq xmm4, 63 + pxor xmm1, xmm3 + psllq xmm5, 1 + pxor xmm1, xmm7 + pxor xmm2, xmm4 + movq qword ptr [esp + 20], xmm1 + pxor xmm2, xmm5 + movq xmm3, qword ptr [esi + 44] + movq qword ptr [esp + 28], xmm2 + pxor xmm3, xmm2 + movq xmm4, qword ptr [esi + 92] + movq xmm7, xmm3 + psrlq xmm3, 43 + pxor xmm4, xmm6 + psllq xmm7, 21 + movq xmm6, xmm4 + psrlq xmm4, 50 + por xmm3, xmm7 + psllq xmm6, 14 + movq xmm2, qword ptr [esi - 4] + por xmm4, xmm6 + pxor xmm2, xmm1 + movq xmm1, qword ptr [esi - 52] + movq xmm6, xmm2 + psrlq xmm2, 21 + movq xmm5, qword ptr [esp + 12] + pxor xmm1, xmm5 + psllq xmm6, 43 + movq xmm7, xmm1 + psrlq xmm1, 20 + por xmm2, xmm6 + psllq xmm7, 44 + movq xmm5, qword ptr [esi - 100] + pxor xmm0, xmm5 + por xmm1, xmm7 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, qword ptr [ebx] + pxor xmm5, xmm7 + lea ebx, [ebx + 8] + movq xmm7, xmm3 + movq qword ptr [edi - 100], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi - 92], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 76] + movq qword ptr [edi - 84], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi - 76], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 28] + pxor xmm7, xmm1 + movq qword ptr [edi - 68], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 36 + movq xmm1, qword ptr [esi - 28] + psllq xmm0, 28 + movq xmm2, qword ptr [esp + 36] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 44 + movq xmm2, qword ptr [esi - 20] + psllq xmm6, 20 + movq xmm3, qword ptr [esp + 4] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 61 + movq xmm3, qword ptr [esi + 28] + psllq xmm7, 3 + movq xmm4, qword ptr [esp + 12] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 19 + movq xmm4, qword ptr [esi + 76] + psllq xmm5, 45 + movq xmm6, qword ptr [esp + 20] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 3 + psllq xmm6, 61 + por xmm4, xmm6 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, xmm3 + movq qword ptr [edi - 60], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi - 52], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 92] + movq qword ptr [edi - 44], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi - 36], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 12] + pxor xmm7, xmm1 + movq qword ptr [edi - 28], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 63 + movq xmm1, qword ptr [esi - 44] + psllq xmm0, 1 + movq xmm2, qword ptr [esp + 20] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 58 + movq xmm2, qword ptr [esi + 4] + psllq xmm6, 6 + movq xmm3, qword ptr [esp + 28] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 39 + movq xmm3, qword ptr [esi + 52] + psllq xmm7, 25 + movq xmm4, qword ptr [esp + 36] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 56 + movq xmm4, qword ptr [esi + 60] + psllq xmm5, 8 + movq xmm6, qword ptr [esp + 4] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 46 + psllq xmm6, 18 + por xmm4, xmm6 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, xmm3 + movq qword ptr [edi - 20], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi - 12], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 68] + movq qword ptr [edi - 4], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi + 4], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 36] + pxor xmm7, xmm1 + movq qword ptr [edi + 12], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 37 + movq xmm1, qword ptr [esi - 60] + psllq xmm0, 27 + movq xmm2, qword ptr [esp + 4] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 28 + movq xmm2, qword ptr [esi - 12] + psllq xmm6, 36 + movq xmm3, qword ptr [esp + 12] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 54 + movq xmm3, qword ptr [esi + 36] + psllq xmm7, 10 + movq xmm4, qword ptr [esp + 20] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 49 + movq xmm4, qword ptr [esi + 84] + psllq xmm5, 15 + movq xmm6, qword ptr [esp + 28] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 8 + psllq xmm6, 56 + por xmm4, xmm6 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, xmm3 + movq qword ptr [edi + 20], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi + 28], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 84] + movq qword ptr [edi + 36], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi + 44], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 20] + pxor xmm7, xmm1 + movq qword ptr [edi + 52], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 2 + movq xmm1, qword ptr [esi - 36] + psllq xmm0, 62 + movq xmm2, qword ptr [esp + 28] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 9 + movq xmm2, qword ptr [esi + 12] + psllq xmm6, 55 + movq xmm3, qword ptr [esp + 36] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 25 + movq xmm3, qword ptr [esi + 20] + psllq xmm7, 39 + movq xmm4, qword ptr [esp + 4] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 23 + movq xmm4, qword ptr [esi + 68] + psllq xmm5, 41 + movq xmm6, qword ptr [esp + 12] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 62 + psllq xmm6, 2 + por xmm4, xmm6 + movq xmm5, xmm0 + xor edi, esi + movq qword ptr [esp + 12], xmm1 + xor esi, edi + xor edi, esi + movq xmm6, xmm1 + movq xmm7, xmm2 + pandn xmm6, xmm2 + pandn xmm7, xmm3 + pxor xmm0, xmm6 + pxor xmm1, xmm7 + movq xmm6, xmm3 + movq qword ptr [esi + 60], xmm0 + pandn xmm6, xmm4 + movq qword ptr [esi + 68], xmm1 + pxor xmm2, xmm6 + movq xmm7, xmm4 + movq qword ptr [esi + 76], xmm2 + pandn xmm7, xmm5 + movq xmm6, qword ptr [esp + 12] + pandn xmm5, xmm6 + pxor xmm3, xmm7 + pxor xmm4, xmm5 + movq qword ptr [esi + 84], xmm3 + sub ecx, 1 + movq qword ptr [esi + 92], xmm4 + jnz @keccak_round_loop + lea ebx, [ebx - 192] + ret + +@absorb_end: diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc new file mode 100644 index 0000000..cac5aa3 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc @@ -0,0 +1,307 @@ +// Keccak-f[1600] sponge absorb for x86-64, pure 64-bit GPR code - the +// asm twin of the AVX2 absorb for the SSE2 dispatch slot: XORs whole blocks +// into the state and permutes, keeping the state in the lane-complemented +// domain across the entire batch (the NOT conversion is hoisted out of the +// block loop - the standalone permute pays it per call). +// The permutation body is the same inner as KeccakF1600Sse2_x86_64.inc +// (embedded again because local labels cannot cross include files), with the +// same end-pointer loop termination via the sentinel at [rsp]. +// Reference: OpenSSL CRYPTOGAMS keccak1600-x86_64.pl (SHA3_absorb) by +// Andy Polyakov. +// +// After HlpSimdProc5Begin_x86_64: rcx = AState (25 x UInt64, standard +// layout), rdx = AData, r8 = ABlockCount, r9 = ABlockSize (both Int32 - +// upper halves undefined, zero-extended here), r10 = AConstants (iotas: +// 24 x UInt64 round constants). +// Frame: 200-byte scratch plane at [rsp+16] (rsi biased +100), sentinel at +// [rsp], spills at [rsi+100..116]. Clobbers all GPRs; every callee-saved +// one is pushed here. + + push rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + + mov r11d, r9d // ABlockSize, zero-extended + mov eax, r8d // ABlockCount, zero-extended + imul rax, r11 // total length in bytes + + lea rdi, [rcx + 100] // biased state pointer + mov r9, rdx // input pointer + mov rdx, rax // remaining length + mov rcx, r11 // block size in bytes + mov r15, r10 // iotas + + sub rsp, 240 + lea rsi, [rsp + 116] // scratch plane, biased by +100 + lea rax, [r15 + 192] + mov qword [rsp], rax // iotas end sentinel (inner: [rsp + 8]) + mov qword [rsi + 116], rcx // block size, reloaded after each permute + + // enter the complemented-lane domain once for the whole batch + not qword [rdi - 92] + not qword [rdi - 84] + not qword [rdi - 36] + not qword [rdi - 4] + not qword [rdi + 36] + not qword [rdi + 60] + +@absorb_loop: + cmp rdx, rcx + jb @absorb_done + + shr rcx, 3 + lea r8, [rdi - 100] + +@absorb_block: + mov rax, qword [r9] + lea r9, [r9 + 8] + xor rax, qword [r8] + lea r8, [r8 + 8] + sub rdx, 8 + mov qword [r8 - 8], rax + sub rcx, 1 + jnz @absorb_block + + mov qword [rsi + 100], r9 + mov qword [rsi + 108], rdx + call @keccak_inner + mov r9, qword [rsi + 100] + mov rdx, qword [rsi + 108] + mov rcx, qword [rsi + 116] + jmp @absorb_loop + +@absorb_done: + // leave the complemented-lane domain + not qword [rdi - 92] + not qword [rdi - 84] + not qword [rdi - 36] + not qword [rdi - 4] + not qword [rdi + 36] + not qword [rdi + 60] + + add rsp, 240 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + pop rbx + jmp @absorb_end + +@keccak_inner: + mov rax, qword [rdi + $3C] + mov rbx, qword [rdi + $44] + mov rcx, qword [rdi + $4C] + mov rdx, qword [rdi + $54] + mov rbp, qword [rdi + $5C] + jmp @keccak_round_loop + +@keccak_round_loop: + mov r8, qword [rdi - $64] + mov r9, qword [rdi - $34] + mov r10, qword [rdi - $4] + mov r11, qword [rdi + $2C] + xor rcx, qword [rdi - $54] + xor rdx, qword [rdi - $4C] + xor rax, r8 + xor rbx, qword [rdi - $5C] + xor rcx, qword [rdi - $2C] + xor rax, qword [rdi - $3C] + mov r12, rbp + xor rbp, qword [rdi - $44] + xor rcx, r10 + xor rax, qword [rdi - $14] + xor rdx, qword [rdi - $24] + xor rbx, r9 + xor rbp, qword [rdi - $1C] + xor rcx, qword [rdi + $24] + xor rax, qword [rdi + $14] + xor rdx, qword [rdi + $4] + xor rbx, qword [rdi - $C] + xor rbp, qword [rdi + $C] + mov r13, rcx + rol rcx, 1 + xor rcx, rax + xor rdx, r11 + rol rax, 1 + xor rax, rdx + xor rbx, qword [rdi + $1C] + rol rdx, 1 + xor rdx, rbx + xor rbp, qword [rdi + $34] + rol rbx, 1 + xor rbx, rbp + rol rbp, 1 + xor rbp, r13 + xor r9, rcx + xor r10, rdx + rol r9, $2C + xor r11, rbp + xor r12, rax + rol r10, $2B + xor r8, rbx + mov r13, r9 + rol r11, $15 + or r9, r10 + xor r9, r8 + rol r12, $E + xor r9, qword [r15] + lea r15, [r15 + $8] + mov r14, r12 + and r12, r11 + mov qword [rsi - $64], r9 + xor r12, r10 + not r10 + mov qword [rsi - $54], r12 + or r10, r11 + mov r12, qword [rdi + $4C] + xor r10, r13 + mov qword [rsi - $5C], r10 + and r13, r8 + mov r9, qword [rdi - $1C] + xor r13, r14 + mov r10, qword [rdi - $14] + mov qword [rsi - $44], r13 + or r14, r8 + mov r8, qword [rdi - $4C] + xor r14, r11 + mov r11, qword [rdi + $1C] + mov qword [rsi - $4C], r14 + xor r8, rbp + xor r12, rdx + rol r8, $1C + xor r11, rcx + xor r9, rax + rol r12, $3D + rol r11, $2D + xor r10, rbx + rol r9, $14 + mov r13, r8 + or r8, r12 + rol r10, $3 + xor r8, r11 + mov qword [rsi - $24], r8 + mov r14, r9 + and r9, r13 + mov r8, qword [rdi - $5C] + xor r9, r12 + not r12 + mov qword [rsi - $1C], r9 + or r12, r11 + mov r9, qword [rdi - $2C] + xor r12, r10 + mov qword [rsi - $2C], r12 + and r11, r10 + mov r12, qword [rdi + $3C] + xor r11, r14 + mov qword [rsi - $34], r11 + or r14, r10 + mov r10, qword [rdi + $4] + xor r14, r13 + mov r11, qword [rdi + $34] + mov qword [rsi - $3C], r14 + xor r10, rbp + xor r11, rax + rol r10, $19 + xor r9, rdx + rol r11, $8 + xor r12, rbx + rol r9, $6 + xor r8, rcx + rol r12, $12 + mov r13, r10 + and r10, r11 + rol r8, 1 + not r11 + xor r10, r9 + mov qword [rsi - $C], r10 + mov r14, r12 + and r12, r11 + mov r10, qword [rdi - $C] + xor r12, r13 + mov qword [rsi - $4], r12 + or r13, r9 + mov r12, qword [rdi + $54] + xor r13, r8 + mov qword [rsi - $14], r13 + and r9, r8 + xor r9, r14 + mov qword [rsi + $C], r9 + or r14, r8 + mov r9, qword [rdi - $3C] + xor r14, r11 + mov r11, qword [rdi + $24] + mov qword [rsi + $4], r14 + mov r8, qword [rdi - $44] + xor r10, rcx + xor r11, rdx + rol r10, $A + xor r9, rbx + rol r11, $F + xor r12, rbp + rol r9, $24 + xor r8, rax + rol r12, $38 + mov r13, r10 + or r10, r11 + rol r8, $1B + not r11 + xor r10, r9 + mov qword [rsi + $1C], r10 + mov r14, r12 + or r12, r11 + xor r12, r13 + mov qword [rsi + $24], r12 + and r13, r9 + xor r13, r8 + mov qword [rsi + $14], r13 + or r9, r8 + xor r9, r14 + mov qword [rsi + $34], r9 + and r8, r14 + xor r8, r11 + mov qword [rsi + $2C], r8 + xor rdx, qword [rdi - $54] + xor rbp, qword [rdi - $24] + rol rdx, $3E + xor rcx, qword [rdi + $44] + rol rbp, $37 + xor rax, qword [rdi + $C] + rol rcx, $2 + xor rbx, qword [rdi + $14] + xchg rdi, rsi + rol rax, $27 + rol rbx, $29 + mov r13, rdx + and rdx, rbp + not rbp + xor rdx, rcx + mov qword [rdi + $5C], rdx + mov r14, rax + and rax, rbp + xor rax, r13 + mov qword [rdi + $3C], rax + or r13, rcx + xor r13, rbx + mov qword [rdi + $54], r13 + and rcx, rbx + xor rcx, r14 + mov qword [rdi + $4C], rcx + or rbx, r14 + xor rbx, rbp + mov qword [rdi + $44], rbx + mov rbp, rdx + mov rdx, r13 + cmp r15, qword [rsp + $8] + jb @keccak_round_loop + lea r15, [r15 - $C0] + ret + +@absorb_end: diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc new file mode 100644 index 0000000..40610c9 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc @@ -0,0 +1,397 @@ +// Keccak-f[1600] permutation for IA-32, pure SSE2 (64-bit lanes in the low +// qwords of xmm0-xmm7; upper halves carry garbage that is never stored). +// The original MMX inner function is converted to SSE2: mm0-7 -> xmm0-7, +// packed memory-source ops rewritten through a liveness-proven dead scratch +// register (SSE2 has no m64 forms), emms dropped. The round loop XOR-swaps +// esi/edi to ping-pong between the state and the stack scratch plane each +// round (24 rounds = even, so pointers end where they started). +// Reference: OpenSSL CRYPTOGAMS keccak1600-mmx.pl by Andy Polyakov. +// +// After HlpSimdProc2Begin_i386: ebx = AState (25 x UInt64, standard layout), +// esi = AConstants (iotas: 24 x UInt64 round constants). +// The inner routine keeps the original calling shape (call/ret) so its +// esp-relative spill slots stay valid; frame mirrors the OpenSSL wrapper: +// 240-byte scratch, esp 8-aligned, edi = esp + 140, esi biased by +100. +// Clobbers eax, ecx, edx, xmm0-xmm7; edi/ebp saved here (the shared prologue +// only saves ebx/esi). + + push edi + push ebp + + mov eax, ebx // AState + mov ebx, esi // iotas -> ebx (inner's table pointer) + lea esi, [eax + 100] // biased state pointer (lanes at esi - 100 .. + 96) + + mov ebp, esp + sub esp, 240 + and esp, $FFFFFFF8 + lea edi, [esp + 140] + + call @keccak_inner + + mov esp, ebp + pop ebp + pop edi + jmp @keccak_done + +@keccak_inner: + movq xmm0, qword ptr [esi + 60] + movq xmm1, qword ptr [esi + 68] + movq xmm2, qword ptr [esi + 76] + movq xmm3, qword ptr [esi + 84] + movq xmm4, qword ptr [esi + 92] + mov ecx, 24 + jmp @keccak_round_loop + +@keccak_round_loop: + movq xmm5, qword ptr [esi - 100] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi - 92] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi - 84] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi - 76] + pxor xmm3, xmm5 + movq xmm5, qword ptr [esi - 68] + pxor xmm4, xmm5 + movq xmm5, qword ptr [esi - 60] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi - 52] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi - 44] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi - 36] + pxor xmm3, xmm5 + movq xmm5, qword ptr [esi - 28] + pxor xmm4, xmm5 + movq xmm5, qword ptr [esi - 20] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi - 12] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi - 4] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi + 4] + pxor xmm3, xmm5 + movq xmm5, qword ptr [esi + 12] + pxor xmm4, xmm5 + movq xmm5, qword ptr [esi + 36] + pxor xmm2, xmm5 + movq xmm5, qword ptr [esi + 20] + pxor xmm0, xmm5 + movq xmm5, qword ptr [esi + 28] + pxor xmm1, xmm5 + movq xmm5, qword ptr [esi + 44] + pxor xmm3, xmm5 + movq xmm5, xmm2 + movq xmm6, qword ptr [esi + 52] + pxor xmm4, xmm6 + movq xmm7, xmm2 + psrlq xmm5, 63 + movq xmm6, xmm0 + psllq xmm7, 1 + pxor xmm5, xmm0 + psrlq xmm0, 63 + pxor xmm5, xmm7 + psllq xmm6, 1 + movq xmm7, xmm1 + movq qword ptr [esp + 12], xmm5 + pxor xmm6, xmm0 + psrlq xmm7, 63 + pxor xmm6, xmm3 + movq xmm0, xmm1 + movq qword ptr [esp + 36], xmm6 + psllq xmm0, 1 + pxor xmm7, xmm4 + pxor xmm0, xmm7 + movq xmm7, xmm3 + psrlq xmm3, 63 + movq qword ptr [esp + 4], xmm0 + psllq xmm7, 1 + movq xmm5, xmm4 + psrlq xmm4, 63 + pxor xmm1, xmm3 + psllq xmm5, 1 + pxor xmm1, xmm7 + pxor xmm2, xmm4 + movq qword ptr [esp + 20], xmm1 + pxor xmm2, xmm5 + movq xmm3, qword ptr [esi + 44] + movq qword ptr [esp + 28], xmm2 + pxor xmm3, xmm2 + movq xmm4, qword ptr [esi + 92] + movq xmm7, xmm3 + psrlq xmm3, 43 + pxor xmm4, xmm6 + psllq xmm7, 21 + movq xmm6, xmm4 + psrlq xmm4, 50 + por xmm3, xmm7 + psllq xmm6, 14 + movq xmm2, qword ptr [esi - 4] + por xmm4, xmm6 + pxor xmm2, xmm1 + movq xmm1, qword ptr [esi - 52] + movq xmm6, xmm2 + psrlq xmm2, 21 + movq xmm5, qword ptr [esp + 12] + pxor xmm1, xmm5 + psllq xmm6, 43 + movq xmm7, xmm1 + psrlq xmm1, 20 + por xmm2, xmm6 + psllq xmm7, 44 + movq xmm5, qword ptr [esi - 100] + pxor xmm0, xmm5 + por xmm1, xmm7 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, qword ptr [ebx] + pxor xmm5, xmm7 + lea ebx, [ebx + 8] + movq xmm7, xmm3 + movq qword ptr [edi - 100], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi - 92], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 76] + movq qword ptr [edi - 84], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi - 76], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 28] + pxor xmm7, xmm1 + movq qword ptr [edi - 68], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 36 + movq xmm1, qword ptr [esi - 28] + psllq xmm0, 28 + movq xmm2, qword ptr [esp + 36] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 44 + movq xmm2, qword ptr [esi - 20] + psllq xmm6, 20 + movq xmm3, qword ptr [esp + 4] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 61 + movq xmm3, qword ptr [esi + 28] + psllq xmm7, 3 + movq xmm4, qword ptr [esp + 12] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 19 + movq xmm4, qword ptr [esi + 76] + psllq xmm5, 45 + movq xmm6, qword ptr [esp + 20] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 3 + psllq xmm6, 61 + por xmm4, xmm6 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, xmm3 + movq qword ptr [edi - 60], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi - 52], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 92] + movq qword ptr [edi - 44], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi - 36], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 12] + pxor xmm7, xmm1 + movq qword ptr [edi - 28], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 63 + movq xmm1, qword ptr [esi - 44] + psllq xmm0, 1 + movq xmm2, qword ptr [esp + 20] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 58 + movq xmm2, qword ptr [esi + 4] + psllq xmm6, 6 + movq xmm3, qword ptr [esp + 28] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 39 + movq xmm3, qword ptr [esi + 52] + psllq xmm7, 25 + movq xmm4, qword ptr [esp + 36] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 56 + movq xmm4, qword ptr [esi + 60] + psllq xmm5, 8 + movq xmm6, qword ptr [esp + 4] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 46 + psllq xmm6, 18 + por xmm4, xmm6 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, xmm3 + movq qword ptr [edi - 20], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi - 12], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 68] + movq qword ptr [edi - 4], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi + 4], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 36] + pxor xmm7, xmm1 + movq qword ptr [edi + 12], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 37 + movq xmm1, qword ptr [esi - 60] + psllq xmm0, 27 + movq xmm2, qword ptr [esp + 4] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 28 + movq xmm2, qword ptr [esi - 12] + psllq xmm6, 36 + movq xmm3, qword ptr [esp + 12] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 54 + movq xmm3, qword ptr [esi + 36] + psllq xmm7, 10 + movq xmm4, qword ptr [esp + 20] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 49 + movq xmm4, qword ptr [esi + 84] + psllq xmm5, 15 + movq xmm6, qword ptr [esp + 28] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 8 + psllq xmm6, 56 + por xmm4, xmm6 + movq xmm5, xmm1 + movq xmm6, xmm2 + pandn xmm5, xmm2 + pandn xmm2, xmm3 + pxor xmm5, xmm0 + pxor xmm2, xmm1 + movq xmm7, xmm3 + movq qword ptr [edi + 20], xmm5 + movq xmm5, xmm4 + pandn xmm3, xmm4 + pandn xmm4, xmm0 + pxor xmm3, xmm6 + movq qword ptr [edi + 28], xmm2 + pxor xmm4, xmm7 + movq xmm7, qword ptr [esi - 84] + movq qword ptr [edi + 36], xmm3 + pandn xmm0, xmm1 + movq qword ptr [edi + 44], xmm4 + pxor xmm0, xmm5 + movq xmm1, qword ptr [esp + 20] + pxor xmm7, xmm1 + movq qword ptr [edi + 52], xmm0 + movq xmm0, xmm7 + psrlq xmm7, 2 + movq xmm1, qword ptr [esi - 36] + psllq xmm0, 62 + movq xmm2, qword ptr [esp + 28] + pxor xmm1, xmm2 + por xmm0, xmm7 + movq xmm6, xmm1 + psrlq xmm1, 9 + movq xmm2, qword ptr [esi + 12] + psllq xmm6, 55 + movq xmm3, qword ptr [esp + 36] + pxor xmm2, xmm3 + por xmm1, xmm6 + movq xmm7, xmm2 + psrlq xmm2, 25 + movq xmm3, qword ptr [esi + 20] + psllq xmm7, 39 + movq xmm4, qword ptr [esp + 4] + pxor xmm3, xmm4 + por xmm2, xmm7 + movq xmm5, xmm3 + psrlq xmm3, 23 + movq xmm4, qword ptr [esi + 68] + psllq xmm5, 41 + movq xmm6, qword ptr [esp + 12] + pxor xmm4, xmm6 + por xmm3, xmm5 + movq xmm6, xmm4 + psrlq xmm4, 62 + psllq xmm6, 2 + por xmm4, xmm6 + movq xmm5, xmm0 + xor edi, esi + movq qword ptr [esp + 12], xmm1 + xor esi, edi + xor edi, esi + movq xmm6, xmm1 + movq xmm7, xmm2 + pandn xmm6, xmm2 + pandn xmm7, xmm3 + pxor xmm0, xmm6 + pxor xmm1, xmm7 + movq xmm6, xmm3 + movq qword ptr [esi + 60], xmm0 + pandn xmm6, xmm4 + movq qword ptr [esi + 68], xmm1 + pxor xmm2, xmm6 + movq xmm7, xmm4 + movq qword ptr [esi + 76], xmm2 + pandn xmm7, xmm5 + movq xmm6, qword ptr [esp + 12] + pandn xmm5, xmm6 + pxor xmm3, xmm7 + pxor xmm4, xmm5 + movq qword ptr [esi + 84], xmm3 + sub ecx, 1 + movq qword ptr [esi + 92], xmm4 + jnz @keccak_round_loop + lea ebx, [ebx - 192] + ret + +@keccak_done: + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc new file mode 100644 index 0000000..3fc19e5 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc @@ -0,0 +1,275 @@ +// Keccak-f[1600] permutation for x86-64, pure 64-bit GPR code (no SIMD +// registers at all) - the fastest non-AVX2 form of Keccak on x86-64, so it +// fills the SSE2 dispatch slot for pre-AVX2 CPUs (house precedent: the CRC +// "SSE2" slicing kernels are GPR too). +// Reference: OpenSSL CRYPTOGAMS keccak1600-x86_64.pl by Andy Polyakov. +// +// The inner routine works in the LANE-COMPLEMENTED domain (lanes 1, 2, 8, +// 12, 17 and 20 stored inverted to save NOTs in chi); this wrapper converts +// in and out around the call. The original loop terminated on a 256-aligned +// iotas table (test r15, 255) which a Pascal const cannot guarantee - the +// termination is patched to compare against an end pointer stashed at +// [rsp] (the inner sees it at [rsp + 8] across the call). +// +// After HlpSimdProc2Begin_x86_64: rcx = AState (25 x UInt64, standard +// layout), rdx = AConstants (iotas: 24 x UInt64 round constants). +// The inner keeps the original called shape; frame mirrors the OpenSSL +// wrapper: 200-byte scratch plane (+16 for the sentinel slot), rdi/rsi +// biased by +100, r15 = iotas. Clobbers rax-rdx, r8-r15, rsi, rdi (all +// GPRs); every callee-saved one is pushed here. + + push rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + + lea rdi, [rcx + 100] // biased state pointer + mov r15, rdx // iotas + sub rsp, 216 + lea rax, [rdx + 192] + mov qword [rsp], rax // iotas end sentinel (inner: [rsp + 8]) + lea rsi, [rsp + 116] // scratch plane, biased by +100 + + // enter the complemented-lane domain (lanes 1, 2, 8, 12, 17, 20) + not qword [rdi - 92] + not qword [rdi - 84] + not qword [rdi - 36] + not qword [rdi - 4] + not qword [rdi + 36] + not qword [rdi + 60] + + call @keccak_inner + + // leave the complemented-lane domain + not qword [rdi - 92] + not qword [rdi - 84] + not qword [rdi - 36] + not qword [rdi - 4] + not qword [rdi + 36] + not qword [rdi + 60] + + add rsp, 216 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + pop rbx + jmp @keccak_done + +@keccak_inner: + mov rax, qword [rdi + $3C] + mov rbx, qword [rdi + $44] + mov rcx, qword [rdi + $4C] + mov rdx, qword [rdi + $54] + mov rbp, qword [rdi + $5C] + jmp @keccak_round_loop + +@keccak_round_loop: + mov r8, qword [rdi - $64] + mov r9, qword [rdi - $34] + mov r10, qword [rdi - $4] + mov r11, qword [rdi + $2C] + xor rcx, qword [rdi - $54] + xor rdx, qword [rdi - $4C] + xor rax, r8 + xor rbx, qword [rdi - $5C] + xor rcx, qword [rdi - $2C] + xor rax, qword [rdi - $3C] + mov r12, rbp + xor rbp, qword [rdi - $44] + xor rcx, r10 + xor rax, qword [rdi - $14] + xor rdx, qword [rdi - $24] + xor rbx, r9 + xor rbp, qword [rdi - $1C] + xor rcx, qword [rdi + $24] + xor rax, qword [rdi + $14] + xor rdx, qword [rdi + $4] + xor rbx, qword [rdi - $C] + xor rbp, qword [rdi + $C] + mov r13, rcx + rol rcx, 1 + xor rcx, rax + xor rdx, r11 + rol rax, 1 + xor rax, rdx + xor rbx, qword [rdi + $1C] + rol rdx, 1 + xor rdx, rbx + xor rbp, qword [rdi + $34] + rol rbx, 1 + xor rbx, rbp + rol rbp, 1 + xor rbp, r13 + xor r9, rcx + xor r10, rdx + rol r9, $2C + xor r11, rbp + xor r12, rax + rol r10, $2B + xor r8, rbx + mov r13, r9 + rol r11, $15 + or r9, r10 + xor r9, r8 + rol r12, $E + xor r9, qword [r15] + lea r15, [r15 + $8] + mov r14, r12 + and r12, r11 + mov qword [rsi - $64], r9 + xor r12, r10 + not r10 + mov qword [rsi - $54], r12 + or r10, r11 + mov r12, qword [rdi + $4C] + xor r10, r13 + mov qword [rsi - $5C], r10 + and r13, r8 + mov r9, qword [rdi - $1C] + xor r13, r14 + mov r10, qword [rdi - $14] + mov qword [rsi - $44], r13 + or r14, r8 + mov r8, qword [rdi - $4C] + xor r14, r11 + mov r11, qword [rdi + $1C] + mov qword [rsi - $4C], r14 + xor r8, rbp + xor r12, rdx + rol r8, $1C + xor r11, rcx + xor r9, rax + rol r12, $3D + rol r11, $2D + xor r10, rbx + rol r9, $14 + mov r13, r8 + or r8, r12 + rol r10, $3 + xor r8, r11 + mov qword [rsi - $24], r8 + mov r14, r9 + and r9, r13 + mov r8, qword [rdi - $5C] + xor r9, r12 + not r12 + mov qword [rsi - $1C], r9 + or r12, r11 + mov r9, qword [rdi - $2C] + xor r12, r10 + mov qword [rsi - $2C], r12 + and r11, r10 + mov r12, qword [rdi + $3C] + xor r11, r14 + mov qword [rsi - $34], r11 + or r14, r10 + mov r10, qword [rdi + $4] + xor r14, r13 + mov r11, qword [rdi + $34] + mov qword [rsi - $3C], r14 + xor r10, rbp + xor r11, rax + rol r10, $19 + xor r9, rdx + rol r11, $8 + xor r12, rbx + rol r9, $6 + xor r8, rcx + rol r12, $12 + mov r13, r10 + and r10, r11 + rol r8, 1 + not r11 + xor r10, r9 + mov qword [rsi - $C], r10 + mov r14, r12 + and r12, r11 + mov r10, qword [rdi - $C] + xor r12, r13 + mov qword [rsi - $4], r12 + or r13, r9 + mov r12, qword [rdi + $54] + xor r13, r8 + mov qword [rsi - $14], r13 + and r9, r8 + xor r9, r14 + mov qword [rsi + $C], r9 + or r14, r8 + mov r9, qword [rdi - $3C] + xor r14, r11 + mov r11, qword [rdi + $24] + mov qword [rsi + $4], r14 + mov r8, qword [rdi - $44] + xor r10, rcx + xor r11, rdx + rol r10, $A + xor r9, rbx + rol r11, $F + xor r12, rbp + rol r9, $24 + xor r8, rax + rol r12, $38 + mov r13, r10 + or r10, r11 + rol r8, $1B + not r11 + xor r10, r9 + mov qword [rsi + $1C], r10 + mov r14, r12 + or r12, r11 + xor r12, r13 + mov qword [rsi + $24], r12 + and r13, r9 + xor r13, r8 + mov qword [rsi + $14], r13 + or r9, r8 + xor r9, r14 + mov qword [rsi + $34], r9 + and r8, r14 + xor r8, r11 + mov qword [rsi + $2C], r8 + xor rdx, qword [rdi - $54] + xor rbp, qword [rdi - $24] + rol rdx, $3E + xor rcx, qword [rdi + $44] + rol rbp, $37 + xor rax, qword [rdi + $C] + rol rcx, $2 + xor rbx, qword [rdi + $14] + xchg rdi, rsi + rol rax, $27 + rol rbx, $29 + mov r13, rdx + and rdx, rbp + not rbp + xor rdx, rcx + mov qword [rdi + $5C], rdx + mov r14, rax + and rax, rbp + xor rax, r13 + mov qword [rdi + $3C], rax + or r13, rcx + xor r13, rbx + mov qword [rdi + $54], r13 + and rcx, rbx + xor rcx, r14 + mov qword [rdi + $4C], rcx + or rbx, r14 + xor rbx, rbp + mov qword [rdi + $44], rbx + mov rbp, rdx + mov rdx, r13 + cmp r15, qword [rsp + $8] + jb @keccak_round_loop + lea r15, [r15 - $C0] + ret + +@keccak_done: diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc index 9bfd15a..63edf8c 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc @@ -1,9 +1,10 @@ -// SHA-512 AVX2 two-block implementation (VEX-256), ported from OpenSSL's -// sha512-x86_64.pl (CRYPTOGAMS). Two message blocks are scheduled together in -// 256-bit lanes; the compression rounds stay serial (as SHA-512 requires), so -// scheduling two blocks at once is what makes this faster than the single-block -// AVX path. AVX2 and BMI2 (rorx/andn) instructions are db-encoded for broad -// assembler compatibility (every AVX2 CPU also provides BMI2). +// SHA-512 AVX2 two-block implementation (VEX-256). Two message blocks are +// scheduled together in 256-bit lanes; the compression rounds stay serial (as +// SHA-512 requires), so scheduling two blocks at once is what makes this faster +// than the single-block AVX path. AVX2 and BMI2 (rorx/andn) instructions are +// db-encoded for broad assembler compatibility (every AVX2 CPU also provides +// BMI2). +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX2 kernel). // Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K512 ptr (each 128-bit K512 pair stored twice // so one table feeds both 256-bit lanes, with the BSWAP64 mask appended; see diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc index 5af39e5..d5e9c05 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc @@ -1,7 +1,8 @@ -// SHA-512 SSE2 implementation (IA-32), derived from OpenSSL's sha512-586 -// (CRYPTOGAMS). The 64-bit state and message schedule are held in xmm0-xmm7 (low -// 64 bits) and computed entirely in SSE2 (paddq/psrlq/psllq/pxor), so the whole -// hash runs in the vector unit - avoiding IA-32's 32-bit-GPR bottleneck. +// SHA-512 SSE2 implementation (IA-32). The 64-bit state and message schedule +// are held in xmm0-xmm7 (low 64 bits) and computed entirely in SSE2 +// (paddq/psrlq/psllq/pxor), so the whole hash runs in the vector unit - +// avoiding IA-32's 32-bit-GPR bottleneck. +// Reference: OpenSSL CRYPTOGAMS sha512-586.pl. // Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, // eax = K512 ptr (80 UInt64). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is pushed // here as the K512 walk pointer; state is loaded into xmm0-xmm7. diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc index 56852e8..3d42fe7 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc @@ -1,8 +1,8 @@ -// SHA-512 SSE2 implementation with a SIMD message schedule, downported from the -// AVX single-block kernel (OpenSSL / CRYPTOGAMS design): the sigma schedule runs -// in 128-bit SSE2 and is interleaved with the 64-bit GPR compression rounds, so -// the vector and integer units run in parallel. This is much faster than a scalar -// message schedule. +// SHA-512 SSE2 implementation with a SIMD message schedule: the sigma schedule +// runs in 128-bit SSE2 and is interleaved with the 64-bit GPR compression +// rounds, so the vector and integer units run in parallel. This is much faster +// than a scalar message schedule. +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX single-block kernel). // Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K512 ptr (K512_Doubled: each 128-bit K512 pair // stored twice, read at a 32-byte stride). The big-endian input byte-swap is diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc new file mode 100644 index 0000000..456c4a7 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc @@ -0,0 +1,1259 @@ +// SHA-512 SSSE3 implementation with a SIMD message schedule; SSE2 sibling: +// SHA512CompressSse2_x86_64.inc. The sigma schedule runs in 128-bit SIMD and +// is interleaved with the 64-bit GPR compression rounds, so the vector and +// integer units run in parallel. Unlike the SSE2 sibling the big-endian input +// byte-swaps are real pshufb (db-encoded for broad assembler compatibility) +// against the BSWAP64 mask kept resident in xmm12 for the whole kernel. +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX single-block kernel). +// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K512 ptr (K512_Doubled: each 128-bit K512 pair +// stored twice, read at a 32-byte stride; the BSWAP64 mask sits at +1280). +// +// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore +// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} + + push rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + mov rax, rsp + sub rsp, $100 + and rsp, $FFFFFFFFFFFFFFC0 + mov qword [rsp + $98], rax + mov qword [rsp + $A0], r9 + movdqu xmm12, oword [r9 + $500] // BSWAP64 mask (K512_Doubled + 1280) + mov qword [rsp + $80], rcx + mov r11d, r8d + shl r11, $7 + lea r11, [rdx + r11*1] + mov qword [rsp + $90], r11 + mov rsi, rdx + mov rdi, qword [rsp + $80] + mov rax, qword [rdi] + mov rbx, qword [rdi + $8] + mov rcx, qword [rdi + $10] + mov rdx, qword [rdi + $18] + mov r8, qword [rdi + $20] + mov r9, qword [rdi + $28] + mov r10, qword [rdi + $30] + mov r11, qword [rdi + $38] + +@block_loop: + movdqu xmm0, oword [rsi] + mov rbp, qword [rsp + $A0] + add rbp, $80 + movdqu xmm1, oword [rsi + $10] + movdqu xmm2, oword [rsi + $20] + db $66, $41, $0F, $38, $00, $C4 // pshufb xmm0, xmm12 + movdqu xmm3, oword [rsi + $30] + db $66, $41, $0F, $38, $00, $CC // pshufb xmm1, xmm12 + movdqu xmm4, oword [rsi + $40] + db $66, $41, $0F, $38, $00, $D4 // pshufb xmm2, xmm12 + movdqu xmm5, oword [rsi + $50] + db $66, $41, $0F, $38, $00, $DC // pshufb xmm3, xmm12 + movdqu xmm6, oword [rsi + $60] + db $66, $41, $0F, $38, $00, $E4 // pshufb xmm4, xmm12 + movdqu xmm7, oword [rsi + $70] + db $66, $41, $0F, $38, $00, $EC // pshufb xmm5, xmm12 + movdqa xmm8, xmm0 + movdqu xmm13, oword [rbp - $80] + paddq xmm8, xmm13 + db $66, $41, $0F, $38, $00, $F4 // pshufb xmm6, xmm12 + movdqa xmm9, xmm1 + movdqu xmm13, oword [rbp - $60] + paddq xmm9, xmm13 + db $66, $41, $0F, $38, $00, $FC // pshufb xmm7, xmm12 + movdqa xmm10, xmm2 + movdqu xmm13, oword [rbp - $40] + paddq xmm10, xmm13 + movdqa xmm11, xmm3 + movdqu xmm13, oword [rbp - $20] + paddq xmm11, xmm13 + movdqa oword [rsp], xmm8 + movdqa xmm8, xmm4 + movdqu xmm13, oword [rbp + $0] + paddq xmm8, xmm13 + movdqa oword [rsp + $10], xmm9 + movdqa xmm9, xmm5 + movdqu xmm13, oword [rbp + $20] + paddq xmm9, xmm13 + movdqa oword [rsp + $20], xmm10 + movdqa xmm10, xmm6 + movdqu xmm13, oword [rbp + $40] + paddq xmm10, xmm13 + movdqa oword [rsp + $30], xmm11 + movdqa xmm11, xmm7 + movdqu xmm13, oword [rbp + $60] + paddq xmm11, xmm13 + movdqa oword [rsp + $40], xmm8 + mov r14, rax + movdqa oword [rsp + $50], xmm9 + mov rdi, rbx + movdqa oword [rsp + $60], xmm10 + xor rdi, rcx + movdqa oword [rsp + $70], xmm11 + mov r13, r8 + jmp @sched_loop + +@sched_loop: + add rbp, $100 + movdqa xmm8, xmm0 + shufpd xmm8, xmm1, $1 + shrd r13, r13, $17 + mov rax, r14 + movdqa xmm11, xmm4 + shufpd xmm11, xmm5, $1 + mov r12, r9 + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, r8 + xor r12, r10 + paddq xmm0, xmm11 + shrd r13, r13, $4 + xor r14, rax + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, r8 + xor r13, r8 + movdqa xmm9, xmm8 + psllq xmm9, $38 + add r11, qword [rsp] + mov r15, rax + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, r10 + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, rbx + add r11, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, rax + add r11, r13 + pxor xmm8, xmm10 + xor rdi, rbx + shrd r14, r14, $1C + movdqa xmm11, xmm7 + psrlq xmm11, $6 + add rdx, r11 + add r11, rdi + pxor xmm8, xmm9 + mov r13, rdx + add r14, r11 + movdqa xmm10, xmm7 + psllq xmm10, $3 + shrd r13, r13, $17 + mov r11, r14 + paddq xmm0, xmm8 + mov r12, r8 + shrd r14, r14, $5 + movdqa xmm9, xmm7 + psrlq xmm9, $13 + xor r13, rdx + xor r12, r9 + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, r11 + psllq xmm10, $2A + and r12, rdx + xor r13, rdx + pxor xmm11, xmm9 + add r10, qword [rsp + $8] + mov rdi, r11 + psrlq xmm9, $2A + xor r12, r9 + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, rax + add r10, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm0, xmm11 + xor r14, r11 + add r10, r13 + movdqa xmm10, xmm0 + movdqu xmm13, oword [rbp - $80] + paddq xmm10, xmm13 + xor r15, rax + shrd r14, r14, $1C + add rcx, r10 + add r10, r15 + mov r13, rcx + add r14, r10 + movdqa oword [rsp], xmm10 + movdqa xmm8, xmm1 + shufpd xmm8, xmm2, $1 + shrd r13, r13, $17 + mov r10, r14 + movdqa xmm11, xmm5 + shufpd xmm11, xmm6, $1 + mov r12, rdx + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, rcx + xor r12, r8 + paddq xmm1, xmm11 + shrd r13, r13, $4 + xor r14, r10 + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, rcx + xor r13, rcx + movdqa xmm9, xmm8 + psllq xmm9, $38 + add r9, qword [rsp + $10] + mov r15, r10 + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, r8 + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, r11 + add r9, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, r10 + add r9, r13 + pxor xmm8, xmm10 + xor rdi, r11 + shrd r14, r14, $1C + movdqa xmm11, xmm0 + psrlq xmm11, $6 + add rbx, r9 + add r9, rdi + pxor xmm8, xmm9 + mov r13, rbx + add r14, r9 + movdqa xmm10, xmm0 + psllq xmm10, $3 + shrd r13, r13, $17 + mov r9, r14 + paddq xmm1, xmm8 + mov r12, rcx + shrd r14, r14, $5 + movdqa xmm9, xmm0 + psrlq xmm9, $13 + xor r13, rbx + xor r12, rdx + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, r9 + psllq xmm10, $2A + and r12, rbx + xor r13, rbx + pxor xmm11, xmm9 + add r8, qword [rsp + $18] + mov rdi, r9 + psrlq xmm9, $2A + xor r12, rdx + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, r10 + add r8, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm1, xmm11 + xor r14, r9 + add r8, r13 + movdqa xmm10, xmm1 + movdqu xmm13, oword [rbp - $60] + paddq xmm10, xmm13 + xor r15, r10 + shrd r14, r14, $1C + add rax, r8 + add r8, r15 + mov r13, rax + add r14, r8 + movdqa oword [rsp + $10], xmm10 + movdqa xmm8, xmm2 + shufpd xmm8, xmm3, $1 + shrd r13, r13, $17 + mov r8, r14 + movdqa xmm11, xmm6 + shufpd xmm11, xmm7, $1 + mov r12, rbx + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, rax + xor r12, rcx + paddq xmm2, xmm11 + shrd r13, r13, $4 + xor r14, r8 + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, rax + xor r13, rax + movdqa xmm9, xmm8 + psllq xmm9, $38 + add rdx, qword [rsp + $20] + mov r15, r8 + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, rcx + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, r9 + add rdx, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, r8 + add rdx, r13 + pxor xmm8, xmm10 + xor rdi, r9 + shrd r14, r14, $1C + movdqa xmm11, xmm1 + psrlq xmm11, $6 + add r11, rdx + add rdx, rdi + pxor xmm8, xmm9 + mov r13, r11 + add r14, rdx + movdqa xmm10, xmm1 + psllq xmm10, $3 + shrd r13, r13, $17 + mov rdx, r14 + paddq xmm2, xmm8 + mov r12, rax + shrd r14, r14, $5 + movdqa xmm9, xmm1 + psrlq xmm9, $13 + xor r13, r11 + xor r12, rbx + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, rdx + psllq xmm10, $2A + and r12, r11 + xor r13, r11 + pxor xmm11, xmm9 + add rcx, qword [rsp + $28] + mov rdi, rdx + psrlq xmm9, $2A + xor r12, rbx + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, r8 + add rcx, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm2, xmm11 + xor r14, rdx + add rcx, r13 + movdqa xmm10, xmm2 + movdqu xmm13, oword [rbp - $40] + paddq xmm10, xmm13 + xor r15, r8 + shrd r14, r14, $1C + add r10, rcx + add rcx, r15 + mov r13, r10 + add r14, rcx + movdqa oword [rsp + $20], xmm10 + movdqa xmm8, xmm3 + shufpd xmm8, xmm4, $1 + shrd r13, r13, $17 + mov rcx, r14 + movdqa xmm11, xmm7 + shufpd xmm11, xmm0, $1 + mov r12, r11 + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, r10 + xor r12, rax + paddq xmm3, xmm11 + shrd r13, r13, $4 + xor r14, rcx + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, r10 + xor r13, r10 + movdqa xmm9, xmm8 + psllq xmm9, $38 + add rbx, qword [rsp + $30] + mov r15, rcx + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, rax + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, rdx + add rbx, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, rcx + add rbx, r13 + pxor xmm8, xmm10 + xor rdi, rdx + shrd r14, r14, $1C + movdqa xmm11, xmm2 + psrlq xmm11, $6 + add r9, rbx + add rbx, rdi + pxor xmm8, xmm9 + mov r13, r9 + add r14, rbx + movdqa xmm10, xmm2 + psllq xmm10, $3 + shrd r13, r13, $17 + mov rbx, r14 + paddq xmm3, xmm8 + mov r12, r10 + shrd r14, r14, $5 + movdqa xmm9, xmm2 + psrlq xmm9, $13 + xor r13, r9 + xor r12, r11 + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, rbx + psllq xmm10, $2A + and r12, r9 + xor r13, r9 + pxor xmm11, xmm9 + add rax, qword [rsp + $38] + mov rdi, rbx + psrlq xmm9, $2A + xor r12, r11 + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, rcx + add rax, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm3, xmm11 + xor r14, rbx + add rax, r13 + movdqa xmm10, xmm3 + movdqu xmm13, oword [rbp - $20] + paddq xmm10, xmm13 + xor r15, rcx + shrd r14, r14, $1C + add r8, rax + add rax, r15 + mov r13, r8 + add r14, rax + movdqa oword [rsp + $30], xmm10 + movdqa xmm8, xmm4 + shufpd xmm8, xmm5, $1 + shrd r13, r13, $17 + mov rax, r14 + movdqa xmm11, xmm0 + shufpd xmm11, xmm1, $1 + mov r12, r9 + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, r8 + xor r12, r10 + paddq xmm4, xmm11 + shrd r13, r13, $4 + xor r14, rax + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, r8 + xor r13, r8 + movdqa xmm9, xmm8 + psllq xmm9, $38 + add r11, qword [rsp + $40] + mov r15, rax + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, r10 + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, rbx + add r11, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, rax + add r11, r13 + pxor xmm8, xmm10 + xor rdi, rbx + shrd r14, r14, $1C + movdqa xmm11, xmm3 + psrlq xmm11, $6 + add rdx, r11 + add r11, rdi + pxor xmm8, xmm9 + mov r13, rdx + add r14, r11 + movdqa xmm10, xmm3 + psllq xmm10, $3 + shrd r13, r13, $17 + mov r11, r14 + paddq xmm4, xmm8 + mov r12, r8 + shrd r14, r14, $5 + movdqa xmm9, xmm3 + psrlq xmm9, $13 + xor r13, rdx + xor r12, r9 + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, r11 + psllq xmm10, $2A + and r12, rdx + xor r13, rdx + pxor xmm11, xmm9 + add r10, qword [rsp + $48] + mov rdi, r11 + psrlq xmm9, $2A + xor r12, r9 + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, rax + add r10, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm4, xmm11 + xor r14, r11 + add r10, r13 + movdqa xmm10, xmm4 + movdqu xmm13, oword [rbp + $0] + paddq xmm10, xmm13 + xor r15, rax + shrd r14, r14, $1C + add rcx, r10 + add r10, r15 + mov r13, rcx + add r14, r10 + movdqa oword [rsp + $40], xmm10 + movdqa xmm8, xmm5 + shufpd xmm8, xmm6, $1 + shrd r13, r13, $17 + mov r10, r14 + movdqa xmm11, xmm1 + shufpd xmm11, xmm2, $1 + mov r12, rdx + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, rcx + xor r12, r8 + paddq xmm5, xmm11 + shrd r13, r13, $4 + xor r14, r10 + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, rcx + xor r13, rcx + movdqa xmm9, xmm8 + psllq xmm9, $38 + add r9, qword [rsp + $50] + mov r15, r10 + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, r8 + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, r11 + add r9, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, r10 + add r9, r13 + pxor xmm8, xmm10 + xor rdi, r11 + shrd r14, r14, $1C + movdqa xmm11, xmm4 + psrlq xmm11, $6 + add rbx, r9 + add r9, rdi + pxor xmm8, xmm9 + mov r13, rbx + add r14, r9 + movdqa xmm10, xmm4 + psllq xmm10, $3 + shrd r13, r13, $17 + mov r9, r14 + paddq xmm5, xmm8 + mov r12, rcx + shrd r14, r14, $5 + movdqa xmm9, xmm4 + psrlq xmm9, $13 + xor r13, rbx + xor r12, rdx + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, r9 + psllq xmm10, $2A + and r12, rbx + xor r13, rbx + pxor xmm11, xmm9 + add r8, qword [rsp + $58] + mov rdi, r9 + psrlq xmm9, $2A + xor r12, rdx + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, r10 + add r8, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm5, xmm11 + xor r14, r9 + add r8, r13 + movdqa xmm10, xmm5 + movdqu xmm13, oword [rbp + $20] + paddq xmm10, xmm13 + xor r15, r10 + shrd r14, r14, $1C + add rax, r8 + add r8, r15 + mov r13, rax + add r14, r8 + movdqa oword [rsp + $50], xmm10 + movdqa xmm8, xmm6 + shufpd xmm8, xmm7, $1 + shrd r13, r13, $17 + mov r8, r14 + movdqa xmm11, xmm2 + shufpd xmm11, xmm3, $1 + mov r12, rbx + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, rax + xor r12, rcx + paddq xmm6, xmm11 + shrd r13, r13, $4 + xor r14, r8 + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, rax + xor r13, rax + movdqa xmm9, xmm8 + psllq xmm9, $38 + add rdx, qword [rsp + $60] + mov r15, r8 + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, rcx + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, r9 + add rdx, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, r8 + add rdx, r13 + pxor xmm8, xmm10 + xor rdi, r9 + shrd r14, r14, $1C + movdqa xmm11, xmm5 + psrlq xmm11, $6 + add r11, rdx + add rdx, rdi + pxor xmm8, xmm9 + mov r13, r11 + add r14, rdx + movdqa xmm10, xmm5 + psllq xmm10, $3 + shrd r13, r13, $17 + mov rdx, r14 + paddq xmm6, xmm8 + mov r12, rax + shrd r14, r14, $5 + movdqa xmm9, xmm5 + psrlq xmm9, $13 + xor r13, r11 + xor r12, rbx + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, rdx + psllq xmm10, $2A + and r12, r11 + xor r13, r11 + pxor xmm11, xmm9 + add rcx, qword [rsp + $68] + mov rdi, rdx + psrlq xmm9, $2A + xor r12, rbx + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, r8 + add rcx, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm6, xmm11 + xor r14, rdx + add rcx, r13 + movdqa xmm10, xmm6 + movdqu xmm13, oword [rbp + $40] + paddq xmm10, xmm13 + xor r15, r8 + shrd r14, r14, $1C + add r10, rcx + add rcx, r15 + mov r13, r10 + add r14, rcx + movdqa oword [rsp + $60], xmm10 + movdqa xmm8, xmm7 + shufpd xmm8, xmm0, $1 + shrd r13, r13, $17 + mov rcx, r14 + movdqa xmm11, xmm3 + shufpd xmm11, xmm4, $1 + mov r12, r11 + shrd r14, r14, $5 + movdqa xmm10, xmm8 + psrlq xmm10, $1 + xor r13, r10 + xor r12, rax + paddq xmm7, xmm11 + shrd r13, r13, $4 + xor r14, rcx + movdqa xmm11, xmm8 + psrlq xmm11, $7 + and r12, r10 + xor r13, r10 + movdqa xmm9, xmm8 + psllq xmm9, $38 + add rbx, qword [rsp + $70] + mov r15, rcx + movdqa xmm8, xmm11 + pxor xmm8, xmm10 + xor r12, rax + shrd r14, r14, $6 + psrlq xmm10, $7 + xor r15, rdx + add rbx, r12 + pxor xmm8, xmm9 + shrd r13, r13, $E + and rdi, r15 + psllq xmm9, $7 + xor r14, rcx + add rbx, r13 + pxor xmm8, xmm10 + xor rdi, rdx + shrd r14, r14, $1C + movdqa xmm11, xmm6 + psrlq xmm11, $6 + add r9, rbx + add rbx, rdi + pxor xmm8, xmm9 + mov r13, r9 + add r14, rbx + movdqa xmm10, xmm6 + psllq xmm10, $3 + shrd r13, r13, $17 + mov rbx, r14 + paddq xmm7, xmm8 + mov r12, r10 + shrd r14, r14, $5 + movdqa xmm9, xmm6 + psrlq xmm9, $13 + xor r13, r9 + xor r12, r11 + pxor xmm11, xmm10 + shrd r13, r13, $4 + xor r14, rbx + psllq xmm10, $2A + and r12, r9 + xor r13, r9 + pxor xmm11, xmm9 + add rax, qword [rsp + $78] + mov rdi, rbx + psrlq xmm9, $2A + xor r12, r11 + shrd r14, r14, $6 + pxor xmm11, xmm10 + xor rdi, rcx + add rax, r12 + pxor xmm11, xmm9 + shrd r13, r13, $E + and r15, rdi + paddq xmm7, xmm11 + xor r14, rbx + add rax, r13 + movdqa xmm10, xmm7 + movdqu xmm13, oword [rbp + $60] + paddq xmm10, xmm13 + xor r15, rcx + shrd r14, r14, $1C + add r8, rax + add rax, r15 + mov r13, r8 + add r14, rax + movdqa oword [rsp + $70], xmm10 + cmp byte [rbp + $87], $0 + jne @sched_loop + shrd r13, r13, $17 + mov rax, r14 + mov r12, r9 + shrd r14, r14, $5 + xor r13, r8 + xor r12, r10 + shrd r13, r13, $4 + xor r14, rax + and r12, r8 + xor r13, r8 + add r11, qword [rsp] + mov r15, rax + xor r12, r10 + shrd r14, r14, $6 + xor r15, rbx + add r11, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, rax + add r11, r13 + xor rdi, rbx + shrd r14, r14, $1C + add rdx, r11 + add r11, rdi + mov r13, rdx + add r14, r11 + shrd r13, r13, $17 + mov r11, r14 + mov r12, r8 + shrd r14, r14, $5 + xor r13, rdx + xor r12, r9 + shrd r13, r13, $4 + xor r14, r11 + and r12, rdx + xor r13, rdx + add r10, qword [rsp + $8] + mov rdi, r11 + xor r12, r9 + shrd r14, r14, $6 + xor rdi, rax + add r10, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, r11 + add r10, r13 + xor r15, rax + shrd r14, r14, $1C + add rcx, r10 + add r10, r15 + mov r13, rcx + add r14, r10 + shrd r13, r13, $17 + mov r10, r14 + mov r12, rdx + shrd r14, r14, $5 + xor r13, rcx + xor r12, r8 + shrd r13, r13, $4 + xor r14, r10 + and r12, rcx + xor r13, rcx + add r9, qword [rsp + $10] + mov r15, r10 + xor r12, r8 + shrd r14, r14, $6 + xor r15, r11 + add r9, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, r10 + add r9, r13 + xor rdi, r11 + shrd r14, r14, $1C + add rbx, r9 + add r9, rdi + mov r13, rbx + add r14, r9 + shrd r13, r13, $17 + mov r9, r14 + mov r12, rcx + shrd r14, r14, $5 + xor r13, rbx + xor r12, rdx + shrd r13, r13, $4 + xor r14, r9 + and r12, rbx + xor r13, rbx + add r8, qword [rsp + $18] + mov rdi, r9 + xor r12, rdx + shrd r14, r14, $6 + xor rdi, r10 + add r8, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, r9 + add r8, r13 + xor r15, r10 + shrd r14, r14, $1C + add rax, r8 + add r8, r15 + mov r13, rax + add r14, r8 + shrd r13, r13, $17 + mov r8, r14 + mov r12, rbx + shrd r14, r14, $5 + xor r13, rax + xor r12, rcx + shrd r13, r13, $4 + xor r14, r8 + and r12, rax + xor r13, rax + add rdx, qword [rsp + $20] + mov r15, r8 + xor r12, rcx + shrd r14, r14, $6 + xor r15, r9 + add rdx, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, r8 + add rdx, r13 + xor rdi, r9 + shrd r14, r14, $1C + add r11, rdx + add rdx, rdi + mov r13, r11 + add r14, rdx + shrd r13, r13, $17 + mov rdx, r14 + mov r12, rax + shrd r14, r14, $5 + xor r13, r11 + xor r12, rbx + shrd r13, r13, $4 + xor r14, rdx + and r12, r11 + xor r13, r11 + add rcx, qword [rsp + $28] + mov rdi, rdx + xor r12, rbx + shrd r14, r14, $6 + xor rdi, r8 + add rcx, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, rdx + add rcx, r13 + xor r15, r8 + shrd r14, r14, $1C + add r10, rcx + add rcx, r15 + mov r13, r10 + add r14, rcx + shrd r13, r13, $17 + mov rcx, r14 + mov r12, r11 + shrd r14, r14, $5 + xor r13, r10 + xor r12, rax + shrd r13, r13, $4 + xor r14, rcx + and r12, r10 + xor r13, r10 + add rbx, qword [rsp + $30] + mov r15, rcx + xor r12, rax + shrd r14, r14, $6 + xor r15, rdx + add rbx, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, rcx + add rbx, r13 + xor rdi, rdx + shrd r14, r14, $1C + add r9, rbx + add rbx, rdi + mov r13, r9 + add r14, rbx + shrd r13, r13, $17 + mov rbx, r14 + mov r12, r10 + shrd r14, r14, $5 + xor r13, r9 + xor r12, r11 + shrd r13, r13, $4 + xor r14, rbx + and r12, r9 + xor r13, r9 + add rax, qword [rsp + $38] + mov rdi, rbx + xor r12, r11 + shrd r14, r14, $6 + xor rdi, rcx + add rax, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, rbx + add rax, r13 + xor r15, rcx + shrd r14, r14, $1C + add r8, rax + add rax, r15 + mov r13, r8 + add r14, rax + shrd r13, r13, $17 + mov rax, r14 + mov r12, r9 + shrd r14, r14, $5 + xor r13, r8 + xor r12, r10 + shrd r13, r13, $4 + xor r14, rax + and r12, r8 + xor r13, r8 + add r11, qword [rsp + $40] + mov r15, rax + xor r12, r10 + shrd r14, r14, $6 + xor r15, rbx + add r11, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, rax + add r11, r13 + xor rdi, rbx + shrd r14, r14, $1C + add rdx, r11 + add r11, rdi + mov r13, rdx + add r14, r11 + shrd r13, r13, $17 + mov r11, r14 + mov r12, r8 + shrd r14, r14, $5 + xor r13, rdx + xor r12, r9 + shrd r13, r13, $4 + xor r14, r11 + and r12, rdx + xor r13, rdx + add r10, qword [rsp + $48] + mov rdi, r11 + xor r12, r9 + shrd r14, r14, $6 + xor rdi, rax + add r10, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, r11 + add r10, r13 + xor r15, rax + shrd r14, r14, $1C + add rcx, r10 + add r10, r15 + mov r13, rcx + add r14, r10 + shrd r13, r13, $17 + mov r10, r14 + mov r12, rdx + shrd r14, r14, $5 + xor r13, rcx + xor r12, r8 + shrd r13, r13, $4 + xor r14, r10 + and r12, rcx + xor r13, rcx + add r9, qword [rsp + $50] + mov r15, r10 + xor r12, r8 + shrd r14, r14, $6 + xor r15, r11 + add r9, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, r10 + add r9, r13 + xor rdi, r11 + shrd r14, r14, $1C + add rbx, r9 + add r9, rdi + mov r13, rbx + add r14, r9 + shrd r13, r13, $17 + mov r9, r14 + mov r12, rcx + shrd r14, r14, $5 + xor r13, rbx + xor r12, rdx + shrd r13, r13, $4 + xor r14, r9 + and r12, rbx + xor r13, rbx + add r8, qword [rsp + $58] + mov rdi, r9 + xor r12, rdx + shrd r14, r14, $6 + xor rdi, r10 + add r8, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, r9 + add r8, r13 + xor r15, r10 + shrd r14, r14, $1C + add rax, r8 + add r8, r15 + mov r13, rax + add r14, r8 + shrd r13, r13, $17 + mov r8, r14 + mov r12, rbx + shrd r14, r14, $5 + xor r13, rax + xor r12, rcx + shrd r13, r13, $4 + xor r14, r8 + and r12, rax + xor r13, rax + add rdx, qword [rsp + $60] + mov r15, r8 + xor r12, rcx + shrd r14, r14, $6 + xor r15, r9 + add rdx, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, r8 + add rdx, r13 + xor rdi, r9 + shrd r14, r14, $1C + add r11, rdx + add rdx, rdi + mov r13, r11 + add r14, rdx + shrd r13, r13, $17 + mov rdx, r14 + mov r12, rax + shrd r14, r14, $5 + xor r13, r11 + xor r12, rbx + shrd r13, r13, $4 + xor r14, rdx + and r12, r11 + xor r13, r11 + add rcx, qword [rsp + $68] + mov rdi, rdx + xor r12, rbx + shrd r14, r14, $6 + xor rdi, r8 + add rcx, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, rdx + add rcx, r13 + xor r15, r8 + shrd r14, r14, $1C + add r10, rcx + add rcx, r15 + mov r13, r10 + add r14, rcx + shrd r13, r13, $17 + mov rcx, r14 + mov r12, r11 + shrd r14, r14, $5 + xor r13, r10 + xor r12, rax + shrd r13, r13, $4 + xor r14, rcx + and r12, r10 + xor r13, r10 + add rbx, qword [rsp + $70] + mov r15, rcx + xor r12, rax + shrd r14, r14, $6 + xor r15, rdx + add rbx, r12 + shrd r13, r13, $E + and rdi, r15 + xor r14, rcx + add rbx, r13 + xor rdi, rdx + shrd r14, r14, $1C + add r9, rbx + add rbx, rdi + mov r13, r9 + add r14, rbx + shrd r13, r13, $17 + mov rbx, r14 + mov r12, r10 + shrd r14, r14, $5 + xor r13, r9 + xor r12, r11 + shrd r13, r13, $4 + xor r14, rbx + and r12, r9 + xor r13, r9 + add rax, qword [rsp + $78] + mov rdi, rbx + xor r12, r11 + shrd r14, r14, $6 + xor rdi, rcx + add rax, r12 + shrd r13, r13, $E + and r15, rdi + xor r14, rbx + add rax, r13 + xor r15, rcx + shrd r14, r14, $1C + add r8, rax + add rax, r15 + mov r13, r8 + add r14, rax + mov rdi, qword [rsp + $80] + mov rax, r14 + add rax, qword [rdi] + lea rsi, [rsi + $80] + add rbx, qword [rdi + $8] + add rcx, qword [rdi + $10] + add rdx, qword [rdi + $18] + add r8, qword [rdi + $20] + add r9, qword [rdi + $28] + add r10, qword [rdi + $30] + add r11, qword [rdi + $38] + cmp rsi, qword [rsp + $90] + mov qword [rdi], rax + mov qword [rdi + $8], rbx + mov qword [rdi + $10], rcx + mov qword [rdi + $18], rdx + mov qword [rdi + $20], r8 + mov qword [rdi + $28], r9 + mov qword [rdi + $30], r10 + mov qword [rdi + $38], r11 + jb @block_loop + mov rsp, qword [rsp + $98] + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + pop rbx + + {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileRestore_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc new file mode 100644 index 0000000..0966dfa --- /dev/null +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc @@ -0,0 +1,130 @@ +// AVX2 (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted +// data (IA-32). Same structure as ScryptSalsa8Avx2_x86_64.inc; the state +// save/reload uses vmovdqu (IA-32 stacks are only 4-aligned), so the frame is +// 64 bytes with no alignment padding. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// +// Reference: Colin Percival, "Stronger Key Derivation via Sequential +// Memory-Hard Functions" (2009), and the Tarsnap scrypt reference +// implementation (crypto_scrypt-sse.c). The (i*5 mod 16) data permutation +// arranges each 16-word Salsa20 state into role-based diagonal order, +// enabling lane-parallel SIMD processing of column and row quarter-rounds +// with vpshufd-based diagonalize/undiagonalize between them. +// +// Identical algorithm to the SSE2 variant but uses VEX-128 3-operand +// encoding, eliminating movdqa register copies and reducing each QR step +// from 7 to 5 instructions. +// +// IA-32: after HlpSimdProc2Begin_i386 - ebx = State ptr, esi = Input ptr +// (parallel to MS x64 ABI: rcx, rdx). +// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: +// xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, +// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}. +// Operation: State = Salsa20/8(State XOR Input) +// Uses xmm0-xmm5 and eax (all volatile). No spills needed. + + sub esp, $40 + + // Load state, XOR with input, save for final addition + db $C5, $FA, $6F, $03 // vmovdqu xmm0, oword [ebx] + db $C5, $FA, $6F, $26 // vmovdqu xmm4, oword [esi] + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + db $C5, $FA, $6F, $4B, $10 // vmovdqu xmm1, oword [ebx + $10] + db $C5, $FA, $6F, $66, $10 // vmovdqu xmm4, oword [esi + $10] + db $C5, $F1, $EF, $CC // vpxor xmm1, xmm1, xmm4 + db $C5, $FA, $6F, $53, $20 // vmovdqu xmm2, oword [ebx + $20] + db $C5, $FA, $6F, $66, $20 // vmovdqu xmm4, oword [esi + $20] + db $C5, $E9, $EF, $D4 // vpxor xmm2, xmm2, xmm4 + db $C5, $FA, $6F, $5B, $30 // vmovdqu xmm3, oword [ebx + $30] + db $C5, $FA, $6F, $66, $30 // vmovdqu xmm4, oword [esi + $30] + db $C5, $E1, $EF, $DC // vpxor xmm3, xmm3, xmm4 + + db $C5, $FA, $7F, $04, $24 // vmovdqu oword [esp], xmm0 + db $C5, $FA, $7F, $4C, $24, $10 // vmovdqu oword [esp + $10], xmm1 + db $C5, $FA, $7F, $54, $24, $20 // vmovdqu oword [esp + $20], xmm2 + db $C5, $FA, $7F, $5C, $24, $30 // vmovdqu oword [esp + $30], xmm3 + + // 4 double-rounds (= 8 rounds = Salsa20/8) + mov eax, $4 +@double_round: + // --- Column quarter-round --- + // xmm1 ^= rotl(xmm0 + xmm3, 7) + db $C5, $F9, $FE, $E3 // vpaddd xmm4, xmm0, xmm3 + db $C5, $D1, $72, $F4, $07 // vpslld xmm5, xmm4, $7 + db $C5, $D9, $72, $D4, $19 // vpsrld xmm4, xmm4, $19 + db $C5, $F1, $EF, $CD // vpxor xmm1, xmm1, xmm5 + db $C5, $F1, $EF, $CC // vpxor xmm1, xmm1, xmm4 + // xmm2 ^= rotl(xmm1 + xmm0, 9) + db $C5, $F1, $FE, $E0 // vpaddd xmm4, xmm1, xmm0 + db $C5, $D1, $72, $F4, $09 // vpslld xmm5, xmm4, $9 + db $C5, $D9, $72, $D4, $17 // vpsrld xmm4, xmm4, $17 + db $C5, $E9, $EF, $D5 // vpxor xmm2, xmm2, xmm5 + db $C5, $E9, $EF, $D4 // vpxor xmm2, xmm2, xmm4 + // xmm3 ^= rotl(xmm2 + xmm1, 13) + db $C5, $E9, $FE, $E1 // vpaddd xmm4, xmm2, xmm1 + db $C5, $D1, $72, $F4, $0D // vpslld xmm5, xmm4, $D + db $C5, $D9, $72, $D4, $13 // vpsrld xmm4, xmm4, $13 + db $C5, $E1, $EF, $DD // vpxor xmm3, xmm3, xmm5 + db $C5, $E1, $EF, $DC // vpxor xmm3, xmm3, xmm4 + // xmm0 ^= rotl(xmm3 + xmm2, 18) + db $C5, $E1, $FE, $E2 // vpaddd xmm4, xmm3, xmm2 + db $C5, $D1, $72, $F4, $12 // vpslld xmm5, xmm4, $12 + db $C5, $D9, $72, $D4, $0E // vpsrld xmm4, xmm4, $E + db $C5, $F9, $EF, $C5 // vpxor xmm0, xmm0, xmm5 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + // Diagonalize: rotate B right by 1, C by 2, D left by 1 + db $C5, $F9, $70, $C9, $93 // vpshufd xmm1, xmm1, $93 + db $C5, $F9, $70, $D2, $4E // vpshufd xmm2, xmm2, $4E + db $C5, $F9, $70, $DB, $39 // vpshufd xmm3, xmm3, $39 + + // --- Row quarter-round (B/D roles swapped after diagonal shuffle) --- + // xmm3 ^= rotl(xmm0 + xmm1, 7) + db $C5, $F9, $FE, $E1 // vpaddd xmm4, xmm0, xmm1 + db $C5, $D1, $72, $F4, $07 // vpslld xmm5, xmm4, $7 + db $C5, $D9, $72, $D4, $19 // vpsrld xmm4, xmm4, $19 + db $C5, $E1, $EF, $DD // vpxor xmm3, xmm3, xmm5 + db $C5, $E1, $EF, $DC // vpxor xmm3, xmm3, xmm4 + // xmm2 ^= rotl(xmm3 + xmm0, 9) + db $C5, $E1, $FE, $E0 // vpaddd xmm4, xmm3, xmm0 + db $C5, $D1, $72, $F4, $09 // vpslld xmm5, xmm4, $9 + db $C5, $D9, $72, $D4, $17 // vpsrld xmm4, xmm4, $17 + db $C5, $E9, $EF, $D5 // vpxor xmm2, xmm2, xmm5 + db $C5, $E9, $EF, $D4 // vpxor xmm2, xmm2, xmm4 + // xmm1 ^= rotl(xmm2 + xmm3, 13) + db $C5, $E9, $FE, $E3 // vpaddd xmm4, xmm2, xmm3 + db $C5, $D1, $72, $F4, $0D // vpslld xmm5, xmm4, $D + db $C5, $D9, $72, $D4, $13 // vpsrld xmm4, xmm4, $13 + db $C5, $F1, $EF, $CD // vpxor xmm1, xmm1, xmm5 + db $C5, $F1, $EF, $CC // vpxor xmm1, xmm1, xmm4 + // xmm0 ^= rotl(xmm1 + xmm2, 18) + db $C5, $F1, $FE, $E2 // vpaddd xmm4, xmm1, xmm2 + db $C5, $D1, $72, $F4, $12 // vpslld xmm5, xmm4, $12 + db $C5, $D9, $72, $D4, $0E // vpsrld xmm4, xmm4, $E + db $C5, $F9, $EF, $C5 // vpxor xmm0, xmm0, xmm5 + db $C5, $F9, $EF, $C4 // vpxor xmm0, xmm0, xmm4 + // Undiagonalize: reverse the shuffles + db $C5, $F9, $70, $C9, $39 // vpshufd xmm1, xmm1, $39 + db $C5, $F9, $70, $D2, $4E // vpshufd xmm2, xmm2, $4E + db $C5, $F9, $70, $DB, $93 // vpshufd xmm3, xmm3, $93 + + dec eax + jnz @double_round + + // Final addition and store + db $C5, $FA, $6F, $24, $24 // vmovdqu xmm4, oword [esp] + db $C5, $F9, $FE, $C4 // vpaddd xmm0, xmm0, xmm4 + db $C5, $FA, $6F, $64, $24, $10 // vmovdqu xmm4, oword [esp + $10] + db $C5, $F1, $FE, $CC // vpaddd xmm1, xmm1, xmm4 + db $C5, $FA, $6F, $64, $24, $20 // vmovdqu xmm4, oword [esp + $20] + db $C5, $E9, $FE, $D4 // vpaddd xmm2, xmm2, xmm4 + db $C5, $FA, $6F, $64, $24, $30 // vmovdqu xmm4, oword [esp + $30] + db $C5, $E1, $FE, $DC // vpaddd xmm3, xmm3, xmm4 + + db $C5, $FA, $7F, $03 // vmovdqu oword [ebx], xmm0 + db $C5, $FA, $7F, $4B, $10 // vmovdqu oword [ebx + $10], xmm1 + db $C5, $FA, $7F, $53, $20 // vmovdqu oword [ebx + $20], xmm2 + db $C5, $FA, $7F, $5B, $30 // vmovdqu oword [ebx + $30], xmm3 + + add esp, $40 + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc new file mode 100644 index 0000000..0816966 --- /dev/null +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc @@ -0,0 +1,37 @@ +// AVX2 implementation of XXH3_accumulate_512 (IA-32; fully unrolled, +// 2 x 32-byte chunks). Same structure as XXH3Acc512Avx2_x86_64.inc. +// IA-32: after HlpSimdProc3Begin_i386 - ebx = acc, esi = input, edi = secret +// (parallel to MS x64 ABI: rcx, rdx, r8). +// Uses only volatile registers: ymm0-ymm3. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: official xxHash C - XXH3_accumulate_512_avx2 in xxhash.h, +// HashLib XXH3Acc512Avx2_x86_64.inc. + + // --- Chunk 0: acc[0..3], input[0..31], secret[0..31] --- + db $C5, $FE, $6F, $03 // vmovdqu ymm0, yword [ebx] + db $C5, $FE, $6F, $0E // vmovdqu ymm1, yword [esi] + db $C5, $FE, $6F, $17 // vmovdqu ymm2, yword [edi] + db $C5, $ED, $EF, $D1 // vpxor ymm2, ymm2, ymm1 + db $C5, $E5, $73, $D2, $20 // vpsrlq ymm3, ymm2, $20 + db $C5, $ED, $F4, $D3 // vpmuludq ymm2, ymm2, ymm3 + db $C5, $FD, $70, $C9, $4E // vpshufd ymm1, ymm1, $4E + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C2 // vpaddq ymm0, ymm0, ymm2 + db $C5, $FE, $7F, $03 // vmovdqu yword [ebx], ymm0 + + // --- Chunk 1: acc[4..7], input[32..63], secret[32..63] --- + db $C5, $FE, $6F, $43, $20 // vmovdqu ymm0, yword [ebx + $20] + db $C5, $FE, $6F, $4E, $20 // vmovdqu ymm1, yword [esi + $20] + db $C5, $FE, $6F, $57, $20 // vmovdqu ymm2, yword [edi + $20] + db $C5, $ED, $EF, $D1 // vpxor ymm2, ymm2, ymm1 + db $C5, $E5, $73, $D2, $20 // vpsrlq ymm3, ymm2, $20 + db $C5, $ED, $F4, $D3 // vpmuludq ymm2, ymm2, ymm3 + db $C5, $FD, $70, $C9, $4E // vpshufd ymm1, ymm1, $4E + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C2 // vpaddq ymm0, ymm0, ymm2 + db $C5, $FE, $7F, $43, $20 // vmovdqu yword [ebx + $20], ymm0 + + db $C5, $F8, $77 // vzeroupper + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc new file mode 100644 index 0000000..220699d --- /dev/null +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc @@ -0,0 +1,69 @@ +// AVX2 implementation of XXH3_initCustomSecret (IA-32; fully unrolled, +// 6 x 32-byte chunks). Same structure as XXH3InitSecretAvx2_x86_64.inc; the +// x86_64 version's vmovq xmm, r64 seed transfers (not encodable in 32-bit +// mode) become the SSE2 i386 sibling's push/vmovq-from-stack pattern, with +// the negation done in 32-bit halves (not/not + add/adc carry). +// IA-32: after HlpSimdProc3Begin_i386 - ebx = customSecret, +// esi = defaultSecret, edi = seed.lo32, dword [esp+16] = seed.hi32 +// (UInt64 third parameter; high dword on stack). +// Uses only volatile registers: ymm0-ymm1, eax, ecx, edx (edi reused). +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: official xxHash C - XXH3_initCustomSecret_avx2 in xxhash.h, +// HashLib XXH3InitSecretAvx2_x86_64.inc. + + // Build seed vector ymm0 = [seed, -seed, seed, -seed] + mov eax, edi + mov edx, dword ptr [esp + $10] + + push eax + push edx + db $C5, $FA, $7E, $04, $24 // vmovq xmm0, qword [esp] + add esp, $8 + + mov ecx, eax + mov edi, edx + not ecx + not edi + add ecx, $1 + adc edi, $0 + push ecx + push edi + db $C5, $FA, $7E, $0C, $24 // vmovq xmm1, qword [esp] + add esp, $8 + db $C5, $F9, $6C, $C1 // vpunpcklqdq xmm0, xmm0, xmm1 + db $C4, $E3, $7D, $38, $C0, $01 // vinserti128 ymm0, ymm0, xmm0, $1 + + // Block 0 + db $C5, $FE, $6F, $0E // vmovdqu ymm1, yword [esi] + db $C5, $F5, $D4, $C8 // vpaddq ymm1, ymm1, ymm0 + db $C5, $FE, $7F, $0B // vmovdqu yword [ebx], ymm1 + + // Block 1 + db $C5, $FE, $6F, $4E, $20 // vmovdqu ymm1, yword [esi + $20] + db $C5, $F5, $D4, $C8 // vpaddq ymm1, ymm1, ymm0 + db $C5, $FE, $7F, $4B, $20 // vmovdqu yword [ebx + $20], ymm1 + + // Block 2 + db $C5, $FE, $6F, $4E, $40 // vmovdqu ymm1, yword [esi + $40] + db $C5, $F5, $D4, $C8 // vpaddq ymm1, ymm1, ymm0 + db $C5, $FE, $7F, $4B, $40 // vmovdqu yword [ebx + $40], ymm1 + + // Block 3 + db $C5, $FE, $6F, $4E, $60 // vmovdqu ymm1, yword [esi + $60] + db $C5, $F5, $D4, $C8 // vpaddq ymm1, ymm1, ymm0 + db $C5, $FE, $7F, $4B, $60 // vmovdqu yword [ebx + $60], ymm1 + + // Block 4 + db $C5, $FE, $6F, $8E, $80, $00, $00, $00 // vmovdqu ymm1, yword [esi + $80] + db $C5, $F5, $D4, $C8 // vpaddq ymm1, ymm1, ymm0 + db $C5, $FE, $7F, $8B, $80, $00, $00, $00 // vmovdqu yword [ebx + $80], ymm1 + + // Block 5 + db $C5, $FE, $6F, $8E, $A0, $00, $00, $00 // vmovdqu ymm1, yword [esi + $A0] + db $C5, $F5, $D4, $C8 // vpaddq ymm1, ymm1, ymm0 + db $C5, $FE, $7F, $8B, $A0, $00, $00, $00 // vmovdqu yword [ebx + $A0], ymm1 + + db $C5, $F8, $77 // vzeroupper + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc new file mode 100644 index 0000000..716e832 --- /dev/null +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc @@ -0,0 +1,44 @@ +// AVX2 implementation of XXH3_scrambleAcc (IA-32; fully unrolled, +// 2 x 32-byte chunks). Same structure as XXH3ScrambleAvx2_x86_64.inc. +// IA-32: after HlpSimdProc2Begin_i386 - ebx = acc, esi = secret +// (parallel to MS x64 ABI: rcx, rdx). +// Uses only volatile registers: ymm0-ymm4, eax. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: official xxHash C - XXH3_scrambleAcc_avx2 in xxhash.h, +// HashLib XXH3ScrambleAvx2_x86_64.inc. + + // Broadcast XXH_PRIME32_1 ($9E3779B1) to all dword lanes of ymm4 + mov eax, $9E3779B1 + db $C5, $F9, $6E, $E0 // vmovd xmm4, eax + db $C4, $E2, $7D, $58, $E4 // vpbroadcastd ymm4, xmm4 + + // --- Chunk 0: acc[0..3], secret[0..31] --- + db $C5, $FE, $6F, $03 // vmovdqu ymm0, yword [ebx] + db $C5, $F5, $73, $D0, $2F // vpsrlq ymm1, ymm0, $2F + db $C5, $FD, $EF, $C1 // vpxor ymm0, ymm0, ymm1 + db $C5, $FE, $6F, $0E // vmovdqu ymm1, yword [esi] + db $C5, $FD, $EF, $C1 // vpxor ymm0, ymm0, ymm1 + // Multiply 64-bit lanes by PRIME32_1 + db $C5, $F5, $73, $D0, $20 // vpsrlq ymm1, ymm0, $20 + db $C5, $FD, $F4, $D4 // vpmuludq ymm2, ymm0, ymm4 + db $C5, $F5, $F4, $CC // vpmuludq ymm1, ymm1, ymm4 + db $C5, $F5, $73, $F1, $20 // vpsllq ymm1, ymm1, $20 + db $C5, $ED, $D4, $C1 // vpaddq ymm0, ymm2, ymm1 + db $C5, $FE, $7F, $03 // vmovdqu yword [ebx], ymm0 + + // --- Chunk 1: acc[4..7], secret[32..63] --- + db $C5, $FE, $6F, $43, $20 // vmovdqu ymm0, yword [ebx + $20] + db $C5, $F5, $73, $D0, $2F // vpsrlq ymm1, ymm0, $2F + db $C5, $FD, $EF, $C1 // vpxor ymm0, ymm0, ymm1 + db $C5, $FE, $6F, $4E, $20 // vmovdqu ymm1, yword [esi + $20] + db $C5, $FD, $EF, $C1 // vpxor ymm0, ymm0, ymm1 + db $C5, $F5, $73, $D0, $20 // vpsrlq ymm1, ymm0, $20 + db $C5, $FD, $F4, $D4 // vpmuludq ymm2, ymm0, ymm4 + db $C5, $F5, $F4, $CC // vpmuludq ymm1, ymm1, ymm4 + db $C5, $F5, $73, $F1, $20 // vpsllq ymm1, ymm1, $20 + db $C5, $ED, $D4, $C1 // vpaddq ymm0, ymm2, ymm1 + db $C5, $FE, $7F, $43, $20 // vmovdqu yword [ebx + $20], ymm0 + + db $C5, $F8, $77 // vzeroupper + pop esi + pop ebx diff --git a/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas b/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas index 0c7e967..883f76a 100644 --- a/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas @@ -30,7 +30,7 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2, SSSE3 +// i386: AVX2, SSSE3, SSE2 // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= @@ -48,6 +48,12 @@ procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; {$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_i386.inc} end; +procedure Adler32_ProcessBlocks_Avx2(AData: PByte; ANumBlocks: UInt32; + ASums, AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\Adler32\Adler32BlocksAvx2_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -82,32 +88,26 @@ procedure Adler32_Update_Ssse3(AData: PByte; ALength: UInt32; ASums: Pointer); Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Ssse3); end; -{$IFDEF HASHLIB_X86_64_ASM} - procedure Adler32_Update_Avx2(AData: PByte; ALength: UInt32; ASums: Pointer); begin Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Avx2); end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TAdler32X86Backend } class function TAdler32X86Backend.Select(AScalar: TAdler32UpdateProc): TAdler32UpdateProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSSE3: Exit(@Adler32_Update_Ssse3); - TX86SimdLevel.SSE2: Exit(@Adler32_Update_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@Adler32_Update_Avx2); - TX86SimdLevel.SSSE3: Exit(@Adler32_Update_Ssse3); - TX86SimdLevel.SSE2: Exit(@Adler32_Update_Sse2); +{$IFDEF HASHLIB_X86_SIMD} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Adler32_Update_Avx2); + TX86SimdLevel.SSSE3: + Exit(@Adler32_Update_Ssse3); + TX86SimdLevel.SSE2: + Exit(@Adler32_Update_Sse2); end; {$ENDIF} Result := AScalar; diff --git a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas index 53f3aa5..e80062c 100644 --- a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas @@ -27,10 +27,23 @@ implementation HlpCpuFeatures, HlpSimdLevels; +const + // vpshufb byte-rotation masks for the AVX2 and SSSE3 kernels: rotr64 by 24 + // (at +0) and by 16 (at +32) as single byte shuffles - Argon2's G uses the + // BLAKE2b rotations, so these match the official BLAKE2 AVX2 r24/r16 + // constants. Each 128-bit pattern is stored twice so one table serves both + // the 256-bit AVX2 loads and the 128-bit SSSE3 loads. + ARGON2_ROT_MASKS: array [0 .. 7] of UInt64 = ( + UInt64($0201000706050403), UInt64($0A09080F0E0D0C0B), + UInt64($0201000706050403), UInt64($0A09080F0E0D0C0B), + UInt64($0100070605040302), UInt64($09080F0E0D0C0B0A), + UInt64($0100070605040302), UInt64($09080F0E0D0C0B0A) + ); + // ============================================================================= // SIMD kernels // i386: SSE2 -// x86_64: AVX2, SSE2 +// x86_64: AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} @@ -49,11 +62,32 @@ procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int3 {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_x86_64.inc} end; -procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +procedure Argon2_FillBlock_Ssse3(ALeft, ARight, ACurrent: Pointer; + AWithXor: Int32; AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSsse3_x86_64.inc} +end; + +procedure Argon2_FillBlock_Ssse3_Wrap(ALeft, ARight, ACurrent: Pointer; + AWithXor: Int32); +begin + Argon2_FillBlock_Ssse3(ALeft, ARight, ACurrent, AWithXor, + @ARGON2_ROT_MASKS); +end; + +procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; + AWithXor: Int32; AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} {$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_x86_64.inc} end; +procedure Argon2_FillBlock_Avx2_Wrap(ALeft, ARight, ACurrent: Pointer; + AWithXor: Int32); +begin + Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent, AWithXor, + @ARGON2_ROT_MASKS); +end; + {$ENDIF HASHLIB_X86_64_ASM} {$ENDIF HASHLIB_X86_SIMD} @@ -64,13 +98,19 @@ class function TArgon2X86Backend.Select(AScalar: TArgon2FillBlockProc): TArgon2F begin {$IFDEF HASHLIB_I386_ASM} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: Exit(@Argon2_FillBlock_Sse2); + TX86SimdLevel.SSE2: + Exit(@Argon2_FillBlock_Sse2); end; {$ENDIF} {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@Argon2_FillBlock_Avx2); - TX86SimdLevel.SSE2: Exit(@Argon2_FillBlock_Sse2); + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Argon2_FillBlock_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@Argon2_FillBlock_Ssse3_Wrap); + TX86SimdLevel.SSE2: + Exit(@Argon2_FillBlock_Sse2); end; {$ENDIF} Result := AScalar; diff --git a/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas index 3356856..56b558b 100644 --- a/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas @@ -27,10 +27,22 @@ implementation HlpCpuFeatures, HlpSimdLevels; +const + // vpshufb byte-rotation masks for the AVX2 kernel: rotr64 by 24 (at +0) and + // by 16 (at +32) as single byte shuffles. Each 128-bit pattern is stored + // twice to fill a 256-bit register. Matches the official BLAKE2 AVX2 + // implementation's r24/r16 shuffle constants. + BLAKE2B_ROT_MASKS: array [0 .. 7] of UInt64 = ( + UInt64($0201000706050403), UInt64($0A09080F0E0D0C0B), + UInt64($0201000706050403), UInt64($0A09080F0E0D0C0B), + UInt64($0100070605040302), UInt64($09080F0E0D0C0B0A), + UInt64($0100070605040302), UInt64($09080F0E0D0C0B0A) + ); + // ============================================================================= // SIMD kernels -// i386: SSE2 -// x86_64: AVX2, SSE2 +// i386: AVX2, SSSE3, SSE2 +// x86_64: AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} @@ -40,6 +52,32 @@ procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_i386.inc} end; +procedure Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSsse3_i386.inc} +end; + +procedure Blake2B_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + @BLAKE2B_ROT_MASKS); +end; + +procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_i386.inc} +end; + +procedure Blake2B_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + @BLAKE2B_ROT_MASKS); +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -49,11 +87,32 @@ procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_x86_64.inc} end; -procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +procedure Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSsse3_x86_64.inc} +end; + +procedure Blake2B_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + @BLAKE2B_ROT_MASKS); +end; + +procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} {$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_x86_64.inc} end; +procedure Blake2B_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + @BLAKE2B_ROT_MASKS); +end; + {$ENDIF HASHLIB_X86_64_ASM} {$ENDIF HASHLIB_X86_SIMD} @@ -62,16 +121,13 @@ procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); class function TBlake2BX86Backend.Select(AScalar: TBlake2BCompressProc): TBlake2BCompressProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - Exit(@Blake2B_Compress_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of +{$IFDEF HASHLIB_X86_SIMD} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@Blake2B_Compress_Avx2); + Exit(@Blake2B_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@Blake2B_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@Blake2B_Compress_Sse2); end; diff --git a/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas index 0abf8c9..07af353 100644 --- a/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas @@ -27,10 +27,19 @@ implementation HlpCpuFeatures, HlpSimdLevels; +const + // pshufb byte-rotation masks for the AVX2 kernel: rotr32 by 16 (at +0) and + // by 8 (at +16) as single byte shuffles. Matches the official BLAKE2 SSSE3+ + // implementation's r16/r8 shuffle constants. + BLAKE2S_ROT_MASKS: array [0 .. 3] of UInt64 = ( + UInt64($0504070601000302), UInt64($0D0C0F0E09080B0A), + UInt64($0407060500030201), UInt64($0C0F0E0D080B0A09) + ); + // ============================================================================= // SIMD kernels -// i386: SSE2 -// x86_64: AVX2, SSE2 +// i386: AVX2, SSSE3, SSE2 +// x86_64: AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} @@ -40,6 +49,32 @@ procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_i386.inc} end; +procedure Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSsse3_i386.inc} +end; + +procedure Blake2S_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + @BLAKE2S_ROT_MASKS); +end; + +procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx2_i386.inc} +end; + +procedure Blake2S_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + @BLAKE2S_ROT_MASKS); +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -49,11 +84,32 @@ procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_x86_64.inc} end; -procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +procedure Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSsse3_x86_64.inc} +end; + +procedure Blake2S_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, + @BLAKE2S_ROT_MASKS); +end; + +procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} {$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx2_x86_64.inc} end; +procedure Blake2S_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, + AIV: Pointer); +begin + Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + @BLAKE2S_ROT_MASKS); +end; + {$ENDIF HASHLIB_X86_64_ASM} {$ENDIF HASHLIB_X86_SIMD} @@ -62,16 +118,13 @@ procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV: Pointer); class function TBlake2SX86Backend.Select(AScalar: TBlake2SCompressProc): TBlake2SCompressProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: - Exit(@Blake2S_Compress_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of +{$IFDEF HASHLIB_X86_SIMD} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@Blake2S_Compress_Avx2); + Exit(@Blake2S_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@Blake2S_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@Blake2S_Compress_Sse2); end; diff --git a/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas index 575b368..c24c86d 100644 --- a/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas @@ -31,10 +31,23 @@ implementation HlpCpuFeatures, HlpSimdLevels; +const + // vpshufb byte-rotation masks for the AVX2 kernels: rotr32 by 16 (at +0) + // and by 8 (at +32) as single byte shuffles. Each 128-bit pattern is stored + // twice so one table serves both the 256-bit Hash8 loads and the 128-bit + // Compress loads. Matches the official BLAKE3 AVX2 implementation's + // ROT16/ROT8 shuffle constants. + BLAKE3_ROT_MASKS: array [0 .. 7] of UInt64 = ( + UInt64($0504070601000302), UInt64($0D0C0F0E09080B0A), + UInt64($0504070601000302), UInt64($0D0C0F0E09080B0A), + UInt64($0407060500030201), UInt64($0C0F0E0D080B0A09), + UInt64($0407060500030201), UInt64($0C0F0E0D080B0A09) + ); + // ============================================================================= // SIMD kernels // i386: SSE2 -// x86_64: AVX2, SSE2 +// x86_64: AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} @@ -59,20 +72,47 @@ procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); {$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_x86_64.inc} end; -procedure Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +procedure Blake3_Compress_Ssse3(AState, AMsg, ACV, ACounterFlags, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3CompressSsse3_x86_64.inc} +end; + +procedure Blake3_Compress_Ssse3_Wrap(AState, AMsg, ACV, + ACounterFlags: Pointer); +begin + Blake3_Compress_Ssse3(AState, AMsg, ACV, ACounterFlags, + @BLAKE3_ROT_MASKS); +end; + +procedure Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags, + AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} {$I ..\..\Include\Simd\Blake3\Blake3CompressAvx2_x86_64.inc} end; +procedure Blake3_Compress_Avx2_Wrap(AState, AMsg, ACV, + ACounterFlags: Pointer); +begin + Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags, + @BLAKE3_ROT_MASKS); +end; + procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} {$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_x86_64.inc} end; +procedure Blake3_Hash4_Ssse3(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32; AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc7Begin_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3Hash4Ssse3_x86_64.inc} +end; + procedure Blake3_Hash8_Avx2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32; AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc7Begin_x86_64.inc} {$I ..\..\Include\Simd\Blake3\Blake3Hash8Avx2_x86_64.inc} end; @@ -100,7 +140,28 @@ procedure Blake3_HashMany_Sse2(AInput, AKey, AOut: Pointer; {$IFDEF HASHLIB_X86_64_ASM} -// AVX2 hash_many: hash8 -> delegate remainder to SSE2 hash_many +// SSSE3 hash_many: hash4 -> delegate remainder to scalar hash_many +procedure Blake3_HashMany_Ssse3(AInput, AKey, AOut: Pointer; + ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); +var + LPInput, LPOut: PByte; +begin + LPInput := PByte(AInput); + LPOut := PByte(AOut); + while ANumChunks >= 4 do + begin + Blake3_Hash4_Ssse3(LPInput, AKey, LPOut, 4, ACounter, AFlags, + @BLAKE3_ROT_MASKS); + System.Inc(LPInput, 4 * 1024); + System.Inc(LPOut, 4 * 32); + System.Inc(ACounter, 4); + System.Dec(ANumChunks, 4); + end; + if ANumChunks > 0 then + Blake3_HashMany_Scalar(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); +end; + +// AVX2 hash_many: hash8 -> delegate remainder to SSSE3 hash_many procedure Blake3_HashMany_Avx2(AInput, AKey, AOut: Pointer; ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); var @@ -110,14 +171,15 @@ procedure Blake3_HashMany_Avx2(AInput, AKey, AOut: Pointer; LPOut := PByte(AOut); while ANumChunks >= 8 do begin - Blake3_Hash8_Avx2(LPInput, AKey, LPOut, 8, ACounter, AFlags); + Blake3_Hash8_Avx2(LPInput, AKey, LPOut, 8, ACounter, AFlags, + @BLAKE3_ROT_MASKS); System.Inc(LPInput, 8 * 1024); System.Inc(LPOut, 8 * 32); System.Inc(ACounter, 8); System.Dec(ANumChunks, 8); end; if ANumChunks > 0 then - Blake3_HashMany_Sse2(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); + Blake3_HashMany_Ssse3(LPInput, AKey, LPOut, ANumChunks, ACounter, AFlags); end; {$ENDIF HASHLIB_X86_64_ASM} @@ -135,9 +197,12 @@ class function TBlake3X86Backend.SelectCompress(AScalar: TBlake3CompressProc): T end; {$ENDIF} {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@Blake3_Compress_Avx2); + Exit(@Blake3_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@Blake3_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@Blake3_Compress_Sse2); end; @@ -154,9 +219,12 @@ class function TBlake3X86Backend.SelectHashMany(AScalar: TBlake3HashManyProc): T end; {$ENDIF} {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(@Blake3_HashMany_Avx2); + TX86SimdLevel.SSSE3: + Exit(@Blake3_HashMany_Ssse3); TX86SimdLevel.SSE2: Exit(@Blake3_HashMany_Sse2); end; @@ -173,10 +241,11 @@ class function TBlake3X86Backend.SelectParallelDegree(ADefault: Int32): Int32; end; {$ENDIF} {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(8); - TX86SimdLevel.SSE2: + TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2: Exit(4); end; {$ENDIF} diff --git a/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas index b2819ed..5cf4c38 100644 --- a/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas @@ -58,18 +58,41 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2 -// x86_64: ShaNi, AVX2, SSE2 +// i386: ShaNi, AVX2, SSSE3, SSE2 +// x86_64: ShaNi, AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} +procedure SHA1_Compress_ShaNi(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressShaNi_i386.inc} +end; + +procedure SHA1_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_ShaNi(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} {$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_i386.inc} end; +procedure SHA1_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressSsse3_i386.inc} +end; + +procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx2_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -91,15 +114,16 @@ procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; {$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_x86_64.inc} end; -procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; +procedure SHA1_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx2_x86_64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressSsse3_x86_64.inc} end; -procedure SHA1_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_Avx2(AState, AData, ANumBlocks, @K_SHA1_Doubled); +procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx2_x86_64.inc} end; {$ENDIF HASHLIB_X86_64_ASM} @@ -109,6 +133,16 @@ procedure SHA1_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); SHA1_Compress_Sse2(AState, AData, ANumBlocks, @K_SHA1_Doubled); end; +procedure SHA1_Compress_Ssse3_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_Ssse3(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + +procedure SHA1_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_Avx2(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + {$ENDIF HASHLIB_X86_SIMD} { TSHA1X86Backend } @@ -116,7 +150,14 @@ procedure SHA1_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); class function TSHA1X86Backend.Select(AScalar: TSHA1CompressProc): TSHA1CompressProc; begin {$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + if TCpuFeatures.X86.HasSHANI() then + Exit(@SHA1_Compress_ShaNi_Wrap); + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@SHA1_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@SHA1_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@SHA1_Compress_Sse2_Wrap); end; @@ -124,9 +165,12 @@ class function TSHA1X86Backend.Select(AScalar: TSHA1CompressProc): TSHA1Compress {$IFDEF HASHLIB_X86_64_ASM} if TCpuFeatures.X86.HasSHANI() then Exit(@SHA1_Compress_ShaNi_Wrap); - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(@SHA1_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@SHA1_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@SHA1_Compress_Sse2_Wrap); end; diff --git a/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas index 474cbe9..c81baf2 100644 --- a/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas @@ -85,18 +85,41 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2 -// x86_64: ShaNi, AVX2, SSE2 +// i386: ShaNi, AVX2, SSSE3, SSE2 +// x86_64: ShaNi, AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} +procedure SHA256_Compress_ShaNi(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressShaNi_i386.inc} +end; + +procedure SHA256_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_ShaNi(AState, AData, ANumBlocks, @K256_Doubled); +end; + procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} {$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_i386.inc} end; +procedure SHA256_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressSsse3_i386.inc} +end; + +procedure SHA256_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressAvx2_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -118,19 +141,30 @@ procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; {$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_x86_64.inc} end; +procedure SHA256_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressSsse3_x86_64.inc} +end; + procedure SHA256_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} {$I ..\..\Include\Simd\SHA256\SHA256CompressAvx2_x86_64.inc} end; +{$ENDIF HASHLIB_X86_64_ASM} + +procedure SHA256_Compress_Ssse3_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_Ssse3(AState, AData, ANumBlocks, @K256_Doubled); +end; + procedure SHA256_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); begin SHA256_Compress_Avx2(AState, AData, ANumBlocks, @K256_Doubled); end; -{$ENDIF HASHLIB_X86_64_ASM} - procedure SHA256_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); begin SHA256_Compress_Sse2(AState, AData, ANumBlocks, @K256_Doubled); @@ -143,7 +177,14 @@ procedure SHA256_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); class function TSHA2_256X86Backend.Select(AScalar: TSHA256CompressProc): TSHA256CompressProc; begin {$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + if TCpuFeatures.X86.HasSHANI() then + Exit(@SHA256_Compress_ShaNi_Wrap); + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@SHA256_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@SHA256_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@SHA256_Compress_Sse2_Wrap); end; @@ -151,9 +192,12 @@ class function TSHA2_256X86Backend.Select(AScalar: TSHA256CompressProc): TSHA256 {$IFDEF HASHLIB_X86_64_ASM} if TCpuFeatures.X86.HasSHANI() then Exit(@SHA256_Compress_ShaNi_Wrap); - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(@SHA256_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@SHA256_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@SHA256_Compress_Sse2_Wrap); end; diff --git a/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas index 8ac1a46..486621f 100644 --- a/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas @@ -122,7 +122,7 @@ implementation // ============================================================================= // SIMD kernels // i386: SSE2 -// x86_64: AVX2, SSE2 +// x86_64: AVX2, SSSE3, SSE2 // ============================================================================= {$IFDEF HASHLIB_I386_ASM} @@ -143,12 +143,23 @@ procedure SHA512_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; {$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_x86_64.inc} end; +procedure SHA512_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA512\SHA512CompressSsse3_x86_64.inc} +end; + procedure SHA512_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} {$I ..\..\Include\Simd\SHA512\SHA512CompressAvx2_x86_64.inc} end; +procedure SHA512_Compress_Ssse3_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA512_Compress_Ssse3(AState, AData, ANumBlocks, @K512_Doubled); +end; + procedure SHA512_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); begin SHA512_Compress_Avx2(AState, AData, ANumBlocks, @K512_Doubled); @@ -178,9 +189,12 @@ class function TSHA2_512X86Backend.Select(AScalar: TSHA512CompressProc): TSHA512 end; {$ENDIF} {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, + TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(@SHA512_Compress_Avx2_Wrap); + TX86SimdLevel.SSSE3: + Exit(@SHA512_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: Exit(@SHA512_Compress_Sse2_Wrap); end; diff --git a/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas index 846fc13..8fce55a 100644 --- a/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas @@ -9,10 +9,11 @@ interface type /// - /// x86 SIMD backend for Keccak-F1600: owns the AVX2 permute / absorb kernels - /// (bodies in Include\Simd\SHA3\) and the runtime tier selection via - /// TCpuFeatures.X86 (AVX2 only; there is no i386 SIMD path). Compiles on - /// every target - without AVX2 the selectors return the scalar routines. + /// x86 SIMD backend for Keccak-F1600: owns the x86_64 AVX2 permute / absorb + /// kernels and the i386 SSE2 permute kernel (bodies in + /// Include\Simd\SHA3\) plus the runtime tier selection via + /// TCpuFeatures.X86. Compiles on every target - without a matching + /// tier the selectors return the scalar routines. /// TSHA3X86Backend = class sealed public @@ -22,13 +23,30 @@ TSHA3X86Backend = class sealed implementation -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} uses HlpCpuFeatures, HlpSimdLevels; const + // Plain 24-entry iota round constants (stride 8) for the scalar-layout + // kernels (i386 + x86_64 SSE2; the AVX2 kernel uses the x4-broadcast + // table below). + K_KECCAK_IOTAS: array [0 .. 23] of UInt64 = ( + UInt64($0000000000000001), UInt64($0000000000008082), + UInt64($800000000000808A), UInt64($8000000080008000), + UInt64($000000000000808B), UInt64($0000000080000001), + UInt64($8000000080008081), UInt64($8000000000008009), + UInt64($000000000000008A), UInt64($0000000000000088), + UInt64($0000000080008009), UInt64($000000008000000A), + UInt64($000000008000808B), UInt64($800000000000008B), + UInt64($8000000000008089), UInt64($8000000000008003), + UInt64($8000000000008002), UInt64($8000000000000080), + UInt64($000000000000800A), UInt64($800000008000000A), + UInt64($8000000080008081), UInt64($8000000000008080), + UInt64($0000000080000001), UInt64($8000000080008008)); + K_KECCAK: packed record RhotatesLeft: array [0..23] of UInt64; RhotatesRight: array [0..23] of UInt64; @@ -82,25 +100,39 @@ implementation // ============================================================================= // SIMD kernels -// x86_64: AVX2 +// i386: SSE2 +// x86_64: AVX2, SSE2 // ============================================================================= +{$IFDEF HASHLIB_X86_64_ASM} + procedure KeccakF1600_Avx2(AState: Pointer; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} {$I ..\..\Include\Simd\SHA3\KeccakF1600Avx2_x86_64.inc} end; -procedure KeccakF1600_Avx2_Wrap(AState: Pointer); -begin - KeccakF1600_Avx2(AState, @K_KECCAK); -end; - procedure KeccakF1600_Avx2_Absorb(AState: Pointer; AData: PByte; ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} {$I ..\..\Include\Simd\SHA3\KeccakF1600Avx2Absorb_x86_64.inc} end; +procedure KeccakF1600_Sse2(AState: Pointer; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2_x86_64.inc} +end; + +procedure KeccakF1600_Sse2_Absorb(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2Absorb_x86_64.inc} +end; + +procedure KeccakF1600_Avx2_Wrap(AState: Pointer); +begin + KeccakF1600_Avx2(AState, @K_KECCAK); +end; + procedure KeccakF1600_Avx2_Absorb_Wrap(AState: Pointer; AData: PByte; ABlockCount: Int32; ABlockSize: Int32); begin @@ -109,14 +141,51 @@ procedure KeccakF1600_Avx2_Absorb_Wrap(AState: Pointer; AData: PByte; {$ENDIF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_I386_ASM} + +procedure KeccakF1600_Sse2(AState: Pointer; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2_i386.inc} +end; + +procedure KeccakF1600_Sse2_Absorb(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2Absorb_i386.inc} +end; + +{$ENDIF HASHLIB_I386_ASM} + +procedure KeccakF1600_Sse2_Wrap(AState: Pointer); +begin + KeccakF1600_Sse2(AState, @K_KECCAK_IOTAS); +end; + +procedure KeccakF1600_Sse2_Absorb_Wrap(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); +begin + KeccakF1600_Sse2_Absorb(AState, AData, ABlockCount, ABlockSize, + @K_KECCAK_IOTAS); +end; + +{$ENDIF HASHLIB_X86_SIMD} + { TSHA3X86Backend } class function TSHA3X86Backend.SelectPermute(AScalar: TKeccakF1600Proc): TKeccakF1600Proc; begin {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(@KeccakF1600_Avx2_Wrap); + TX86SimdLevel.SSE2: + Exit(@KeccakF1600_Sse2_Wrap); + end; +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@KeccakF1600_Sse2_Wrap); end; {$ENDIF} Result := AScalar; @@ -125,9 +194,17 @@ class function TSHA3X86Backend.SelectPermute(AScalar: TKeccakF1600Proc): TKeccak class function TSHA3X86Backend.SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TKeccakF1600AbsorbProc; begin {$IFDEF HASHLIB_X86_64_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: Exit(@KeccakF1600_Avx2_Absorb_Wrap); + TX86SimdLevel.SSE2: + Exit(@KeccakF1600_Sse2_Absorb_Wrap); + end; +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + TX86SimdLevel.SSE2: + Exit(@KeccakF1600_Sse2_Absorb_Wrap); end; {$ENDIF} Result := AScalar; diff --git a/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas b/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas index 4659a94..117a7a0 100644 --- a/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas @@ -29,7 +29,7 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2 +// i386: AVX2, SSE2 // x86_64: AVX2, SSE2 // ============================================================================= @@ -40,6 +40,11 @@ procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_i386.inc} end; +procedure Scrypt_SalsaXor_Avx2(AState, AInput: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} + {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Avx2_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -62,15 +67,12 @@ procedure Scrypt_SalsaXor_Avx2(AState, AInput: Pointer); class function TScryptX86Backend.Select(AScalar: TScryptSalsaXorProc): TScryptSalsaXorProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: Exit(@Scrypt_SalsaXor_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@Scrypt_SalsaXor_Avx2); - TX86SimdLevel.SSE2: Exit(@Scrypt_SalsaXor_Sse2); + TX86SimdLevel.AVX2: + Exit(@Scrypt_SalsaXor_Avx2); + TX86SimdLevel.SSE2: + Exit(@Scrypt_SalsaXor_Sse2); end; {$ENDIF} Result := AScalar; diff --git a/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas b/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas index 01a5040..383875f 100644 --- a/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas @@ -32,7 +32,7 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2 +// i386: AVX2, SSE2 // x86_64: AVX2, SSE2 // ============================================================================= @@ -55,6 +55,23 @@ procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; {$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_i386.inc} end; +procedure XXH3_Accumulate512_Avx2(AAcc: Pointer; AInput: Pointer; + ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} + {$I ..\..\Include\Simd\XXH3\XXH3Acc512Avx2_i386.inc} +end; + +procedure XXH3_ScrambleAcc_Avx2(AAcc: Pointer; ASecret: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} + {$I ..\..\Include\Simd\XXH3\XXH3ScrambleAvx2_i386.inc} +end; + +procedure XXH3_InitSecret_Avx2(ACustomSecret: Pointer; + ADefaultSecret: Pointer; ASeed: UInt64); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} + {$I ..\..\Include\Simd\XXH3\XXH3InitSecretAvx2_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -101,31 +118,24 @@ procedure XXH3_Accumulate_Sse2(AAcc: Pointer; AInput: Pointer; XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Sse2); end; -{$IFDEF HASHLIB_X86_64_ASM} - procedure XXH3_Accumulate_Avx2(AAcc: Pointer; AInput: Pointer; ASecret: Pointer; ANbStripes: Int32); begin XXH3_Accumulate_Loop(AAcc, AInput, ASecret, ANbStripes, @XXH3_Accumulate512_Avx2); end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TXXHash3X86Backend } class function TXXHash3X86Backend.SelectAccumulate512(AScalar: TXXH3Accumulate512Proc): TXXH3Accumulate512Proc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate512_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@XXH3_Accumulate512_Avx2); - TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate512_Sse2); + TX86SimdLevel.AVX2: + Exit(@XXH3_Accumulate512_Avx2); + TX86SimdLevel.SSE2: + Exit(@XXH3_Accumulate512_Sse2); end; {$ENDIF} Result := AScalar; @@ -133,15 +143,12 @@ class function TXXHash3X86Backend.SelectAccumulate512(AScalar: TXXH3Accumulate51 class function TXXHash3X86Backend.SelectAccumulate(AScalar: TXXH3AccumulateProc): TXXH3AccumulateProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@XXH3_Accumulate_Avx2); - TX86SimdLevel.SSE2: Exit(@XXH3_Accumulate_Sse2); + TX86SimdLevel.AVX2: + Exit(@XXH3_Accumulate_Avx2); + TX86SimdLevel.SSE2: + Exit(@XXH3_Accumulate_Sse2); end; {$ENDIF} Result := AScalar; @@ -149,15 +156,12 @@ class function TXXHash3X86Backend.SelectAccumulate(AScalar: TXXH3AccumulateProc) class function TXXHash3X86Backend.SelectScrambleAcc(AScalar: TXXH3ScrambleAccProc): TXXH3ScrambleAccProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: Exit(@XXH3_ScrambleAcc_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@XXH3_ScrambleAcc_Avx2); - TX86SimdLevel.SSE2: Exit(@XXH3_ScrambleAcc_Sse2); + TX86SimdLevel.AVX2: + Exit(@XXH3_ScrambleAcc_Avx2); + TX86SimdLevel.SSE2: + Exit(@XXH3_ScrambleAcc_Sse2); end; {$ENDIF} Result := AScalar; @@ -165,15 +169,12 @@ class function TXXHash3X86Backend.SelectScrambleAcc(AScalar: TXXH3ScrambleAccPro class function TXXHash3X86Backend.SelectInitSecret(AScalar: TXXH3InitSecretProc): TXXH3InitSecretProc; begin -{$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of - TX86SimdLevel.SSE2: Exit(@XXH3_InitSecret_Sse2); - end; -{$ENDIF} -{$IFDEF HASHLIB_X86_64_ASM} +{$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of - TX86SimdLevel.AVX2: Exit(@XXH3_InitSecret_Avx2); - TX86SimdLevel.SSE2: Exit(@XXH3_InitSecret_Sse2); + TX86SimdLevel.AVX2: + Exit(@XXH3_InitSecret_Avx2); + TX86SimdLevel.SSE2: + Exit(@XXH3_InitSecret_Sse2); end; {$ENDIF} Result := AScalar; From 910b0f3157a7475047e0802d10f356836b25b7e1 Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sun, 12 Jul 2026 21:40:30 +0100 Subject: [PATCH 05/10] move maintenance scripts --- scripts/{ => maintenance}/check-duplicate-guids.ps1 | 4 ++-- scripts/{ => maintenance}/sync-mobile-testdata.ps1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename scripts/{ => maintenance}/check-duplicate-guids.ps1 (90%) rename scripts/{ => maintenance}/sync-mobile-testdata.ps1 (99%) diff --git a/scripts/check-duplicate-guids.ps1 b/scripts/maintenance/check-duplicate-guids.ps1 similarity index 90% rename from scripts/check-duplicate-guids.ps1 rename to scripts/maintenance/check-duplicate-guids.ps1 index 13ac5a2..1f8ad07 100644 --- a/scripts/check-duplicate-guids.ps1 +++ b/scripts/maintenance/check-duplicate-guids.ps1 @@ -10,8 +10,8 @@ $ErrorActionPreference = 'Stop' -# Repo root: script lives in /scripts/check-duplicate-guids.ps1 -$root = if ($PSScriptRoot) { Split-Path $PSScriptRoot -Parent } else { Get-Location } +# Repo root: script lives in /scripts/maintenance/check-duplicate-guids.ps1 +$root = if ($PSScriptRoot) { Split-Path (Split-Path $PSScriptRoot -Parent) -Parent } else { Get-Location } $pasFiles = Get-ChildItem -Path $root -Filter '*.pas' -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch '\.git\\' } diff --git a/scripts/sync-mobile-testdata.ps1 b/scripts/maintenance/sync-mobile-testdata.ps1 similarity index 99% rename from scripts/sync-mobile-testdata.ps1 rename to scripts/maintenance/sync-mobile-testdata.ps1 index 9abd6e4..f8cbf79 100644 --- a/scripts/sync-mobile-testdata.ps1 +++ b/scripts/maintenance/sync-mobile-testdata.ps1 @@ -5,7 +5,7 @@ # Re-run when files under HashLib.Tests/Data change (or AppDeployFolderName changes), then rebuild the mobile test host. param( - [string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path, + [string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path, [string]$DeployProjName = "HashLib.Tests.Mobile.TestData.deployproj", [string]$AppDeployFolderName = "HashLib.Tests.Mobile" ) From 2e4f49a9292381ec3f3da915c1f9275c32d4bb7f Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sun, 12 Jul 2026 22:51:12 +0100 Subject: [PATCH 06/10] add Argon2 Avx2 i386 kernel --- .../Simd/Argon2/Argon2FillBlockAvx2_i386.inc | 276 ++++++++++++++++++ .../src/Simd/Backend/HlpArgon2X86Backend.pas | 16 +- 2 files changed, 288 insertions(+), 4 deletions(-) create mode 100644 HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc new file mode 100644 index 0000000..0745ef5 --- /dev/null +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc @@ -0,0 +1,276 @@ +// AVX2 implementation of Argon2 FillBlock (IA-32). 256-bit ymm integer ops +// work in 32-bit mode; same algorithm and buffer layout as +// Argon2FillBlockAvx2_x86_64.inc, redesigned for the IA-32 register budget: +// - the byte-rotation masks are VEX memory operands (rot24 at [masks], +// rot16 at [masks+$20]; read unaligned, so the Pascal const needs no +// special alignment) - the kernel touches only ymm0-ymm4, all volatile, +// so nothing is saved; +// - R_buf/Z_buf sit at [esp]/[esp+1024] and are addressed [esp+edx+disp] +// (edx = loop offset) - no buffer pointer registers are needed; +// - Left/Right are dead after step 1's XOR. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// IA-32: after HlpSimdProc5Begin_i386 - ebx = Left ptr, esi = Right ptr, +// edi = Current ptr, eax = WithXor (0 or 1; live until the final step), +// ecx = byte-rotation masks ptr (ARGON2_ROT_MASKS; live throughout). +// Each pointer addresses 128 QWords (1024 bytes). +// Stack layout (sub esp, 2048): [esp+0..1023] R_buf, [esp+1024..2047] Z_buf. +// ARight and ACurrent may alias; R_buf buffering handles this. +// Diagonalize/Undiagonalize via vpermq (cross-lane 64-bit permute). +// vzeroupper required before return. +// Reference: official Argon2 AVX2 (blamka-round-opt.h), HashLib +// Argon2FillBlockAvx2_x86_64.inc. + + sub esp, $800 + + // Step 1: R_buf = Left XOR Right at [esp] (Left/Right dead afterwards) + xor edx, edx + +@xor_loop: + db $C5, $FE, $6F, $04, $13 // vmovdqu ymm0, yword [ebx + edx*1] + db $C5, $FD, $EF, $04, $16 // vpxor ymm0, ymm0, yword [esi + edx*1] + db $C5, $FE, $7F, $04, $14 // vmovdqu yword [esp + edx*1], ymm0 + add edx, $20 + cmp edx, $400 + jb @xor_loop + + // Step 2: copy R_buf to Z_buf at [esp+1024] + xor edx, edx + +@copy_loop: + db $C5, $FE, $6F, $04, $14 // vmovdqu ymm0, yword [esp + edx*1] + db $C5, $FE, $7F, $84, $14, $00, $04, $00, $00// vmovdqu yword [esp + edx*1 + $400], ymm0 + add edx, $20 + cmp edx, $400 + jb @copy_loop + + // Step 3: column rounds on Z_buf (8 iterations, 128 bytes each) + xor edx, edx + +@col_loop: + db $C5, $FE, $6F, $84, $14, $00, $04, $00, $00// vmovdqu ymm0, yword [esp + edx*1 + $400] + db $C5, $FE, $6F, $8C, $14, $20, $04, $00, $00// vmovdqu ymm1, yword [esp + edx*1 + $420] + db $C5, $FE, $6F, $94, $14, $40, $04, $00, $00// vmovdqu ymm2, yword [esp + edx*1 + $440] + db $C5, $FE, $6F, $9C, $14, $60, $04, $00, $00// vmovdqu ymm3, yword [esp + edx*1 + $460] + // ----- Column G ----- + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 32) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 24) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $09 // vpshufb ymm1, ymm1, yword [ecx] + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 16) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $59, $20 // vpshufb ymm3, ymm3, yword [ecx + $20] + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 63) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $DD, $73, $D1, $3F // vpsrlq ymm4, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + // ----- Diagonalize ----- + db $C4, $E3, $FD, $00, $C9, $39 // vpermq ymm1, ymm1, $39 + db $C4, $E3, $FD, $00, $D2, $4E // vpermq ymm2, ymm2, $4E + db $C4, $E3, $FD, $00, $DB, $93 // vpermq ymm3, ymm3, $93 + // ----- Diagonal G ----- + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 32) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 24) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $09 // vpshufb ymm1, ymm1, yword [ecx] + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 16) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $59, $20 // vpshufb ymm3, ymm3, yword [ecx + $20] + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 63) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $DD, $73, $D1, $3F // vpsrlq ymm4, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + // ----- Undiagonalize ----- + db $C4, $E3, $FD, $00, $C9, $93 // vpermq ymm1, ymm1, $93 + db $C4, $E3, $FD, $00, $D2, $4E // vpermq ymm2, ymm2, $4E + db $C4, $E3, $FD, $00, $DB, $39 // vpermq ymm3, ymm3, $39 + db $C5, $FE, $7F, $84, $14, $00, $04, $00, $00// vmovdqu yword [esp + edx*1 + $400], ymm0 + db $C5, $FE, $7F, $8C, $14, $20, $04, $00, $00// vmovdqu yword [esp + edx*1 + $420], ymm1 + db $C5, $FE, $7F, $94, $14, $40, $04, $00, $00// vmovdqu yword [esp + edx*1 + $440], ymm2 + db $C5, $FE, $7F, $9C, $14, $60, $04, $00, $00// vmovdqu yword [esp + edx*1 + $460], ymm3 + add edx, $80 + cmp edx, $400 + jb @col_loop + + // Step 4: row rounds on Z_buf (8 iterations, stride-16-QWord gathers) + xor edx, edx + +@row_loop: + db $C5, $FA, $6F, $84, $14, $00, $04, $00, $00// vmovdqu xmm0, oword [esp + edx*1 + $400] + db $C4, $E3, $7D, $38, $84, $14, $80, $04, $00, $00, $01// vinserti128 ymm0, ymm0, oword [esp + edx*1 + $480], $1 + db $C5, $FA, $6F, $8C, $14, $00, $05, $00, $00// vmovdqu xmm1, oword [esp + edx*1 + $500] + db $C4, $E3, $75, $38, $8C, $14, $80, $05, $00, $00, $01// vinserti128 ymm1, ymm1, oword [esp + edx*1 + $580], $1 + db $C5, $FA, $6F, $94, $14, $00, $06, $00, $00// vmovdqu xmm2, oword [esp + edx*1 + $600] + db $C4, $E3, $6D, $38, $94, $14, $80, $06, $00, $00, $01// vinserti128 ymm2, ymm2, oword [esp + edx*1 + $680], $1 + db $C5, $FA, $6F, $9C, $14, $00, $07, $00, $00// vmovdqu xmm3, oword [esp + edx*1 + $700] + db $C4, $E3, $65, $38, $9C, $14, $80, $07, $00, $00, $01// vinserti128 ymm3, ymm3, oword [esp + edx*1 + $780], $1 + // ----- Column G ----- + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 32) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 24) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $09 // vpshufb ymm1, ymm1, yword [ecx] + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 16) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $59, $20 // vpshufb ymm3, ymm3, yword [ecx + $20] + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 63) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $DD, $73, $D1, $3F // vpsrlq ymm4, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + // ----- Diagonalize ----- + db $C4, $E3, $FD, $00, $C9, $39 // vpermq ymm1, ymm1, $39 + db $C4, $E3, $FD, $00, $D2, $4E // vpermq ymm2, ymm2, $4E + db $C4, $E3, $FD, $00, $DB, $93 // vpermq ymm3, ymm3, $93 + // ----- Diagonal G ----- + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 32) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C5, $FD, $70, $DB, $B1 // vpshufd ymm3, ymm3, $B1 + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 24) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C4, $E2, $75, $00, $09 // vpshufb ymm1, ymm1, yword [ecx] + // fBlaMka(0, 1): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $FD, $F4, $E1 // vpmuludq ymm4, ymm0, ymm1 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $FD, $D4, $C1 // vpaddq ymm0, ymm0, ymm1 + db $C5, $FD, $D4, $C4 // vpaddq ymm0, ymm0, ymm4 + // d = rotr64(d ^ a, 16) + db $C5, $E5, $EF, $D8 // vpxor ymm3, ymm3, ymm0 + db $C4, $E2, $65, $00, $59, $20 // vpshufb ymm3, ymm3, yword [ecx + $20] + // fBlaMka(2, 3): a = a + b + 2*lo32(a)*lo32(b) + db $C5, $ED, $F4, $E3 // vpmuludq ymm4, ymm2, ymm3 + db $C5, $DD, $73, $F4, $01 // vpsllq ymm4, ymm4, $1 + db $C5, $ED, $D4, $D3 // vpaddq ymm2, ymm2, ymm3 + db $C5, $ED, $D4, $D4 // vpaddq ymm2, ymm2, ymm4 + // b = rotr64(b ^ c, 63) + db $C5, $F5, $EF, $CA // vpxor ymm1, ymm1, ymm2 + db $C5, $DD, $73, $D1, $3F // vpsrlq ymm4, ymm1, $3F + db $C5, $F5, $D4, $C9 // vpaddq ymm1, ymm1, ymm1 + db $C5, $F5, $EB, $CC // vpor ymm1, ymm1, ymm4 + // ----- Undiagonalize ----- + db $C4, $E3, $FD, $00, $C9, $93 // vpermq ymm1, ymm1, $93 + db $C4, $E3, $FD, $00, $D2, $4E // vpermq ymm2, ymm2, $4E + db $C4, $E3, $FD, $00, $DB, $39 // vpermq ymm3, ymm3, $39 + db $C5, $FA, $7F, $84, $14, $00, $04, $00, $00// vmovdqu oword [esp + edx*1 + $400], xmm0 + db $C4, $E3, $7D, $39, $84, $14, $80, $04, $00, $00, $01// vextracti128 oword [esp + edx*1 + $480], ymm0, $1 + db $C5, $FA, $7F, $8C, $14, $00, $05, $00, $00// vmovdqu oword [esp + edx*1 + $500], xmm1 + db $C4, $E3, $7D, $39, $8C, $14, $80, $05, $00, $00, $01// vextracti128 oword [esp + edx*1 + $580], ymm1, $1 + db $C5, $FA, $7F, $94, $14, $00, $06, $00, $00// vmovdqu oword [esp + edx*1 + $600], xmm2 + db $C4, $E3, $7D, $39, $94, $14, $80, $06, $00, $00, $01// vextracti128 oword [esp + edx*1 + $680], ymm2, $1 + db $C5, $FA, $7F, $9C, $14, $00, $07, $00, $00// vmovdqu oword [esp + edx*1 + $700], xmm3 + db $C4, $E3, $7D, $39, $9C, $14, $80, $07, $00, $00, $01// vextracti128 oword [esp + edx*1 + $780], ymm3, $1 + add edx, $10 + cmp edx, $80 + jb @row_loop + + // Step 5: Current = R_buf XOR Z_buf [XOR Current] + test eax, eax + jnz @final_with_xor + + xor edx, edx + +@final_noxor_loop: + db $C5, $FE, $6F, $04, $14 // vmovdqu ymm0, yword [esp + edx*1] + db $C5, $FD, $EF, $84, $14, $00, $04, $00, $00// vpxor ymm0, ymm0, yword [esp + edx*1 + $400] + db $C5, $FE, $7F, $04, $17 // vmovdqu yword [edi + edx*1], ymm0 + add edx, $20 + cmp edx, $400 + jb @final_noxor_loop + jmp @epilogue + + +@final_with_xor: + xor edx, edx + +@final_xor_loop: + db $C5, $FE, $6F, $04, $14 // vmovdqu ymm0, yword [esp + edx*1] + db $C5, $FD, $EF, $84, $14, $00, $04, $00, $00// vpxor ymm0, ymm0, yword [esp + edx*1 + $400] + db $C5, $FD, $EF, $04, $17 // vpxor ymm0, ymm0, yword [edi + edx*1] + db $C5, $FE, $7F, $04, $17 // vmovdqu yword [edi + edx*1], ymm0 + add edx, $20 + cmp edx, $400 + jb @final_xor_loop + + +@epilogue: + add esp, $800 + db $C5, $F8, $77 // vzeroupper + pop edi + pop esi + pop ebx diff --git a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas index e80062c..715e7cd 100644 --- a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas @@ -42,7 +42,7 @@ implementation // ============================================================================= // SIMD kernels -// i386: SSE2 +// i386: AVX2, SSE2 // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= @@ -53,6 +53,12 @@ procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int3 {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_i386.inc} end; +procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; + AWithXor: Int32; AMasks: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_i386.inc} +end; + {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -81,6 +87,8 @@ procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; {$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_x86_64.inc} end; +{$ENDIF HASHLIB_X86_64_ASM} + procedure Argon2_FillBlock_Avx2_Wrap(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); begin @@ -88,8 +96,6 @@ procedure Argon2_FillBlock_Avx2_Wrap(ALeft, ARight, ACurrent: Pointer; @ARGON2_ROT_MASKS); end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TArgon2X86Backend } @@ -97,7 +103,9 @@ procedure Argon2_FillBlock_Avx2_Wrap(ALeft, ARight, ACurrent: Pointer; class function TArgon2X86Backend.Select(AScalar: TArgon2FillBlockProc): TArgon2FillBlockProc; begin {$IFDEF HASHLIB_I386_ASM} - case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.SSE2]) of + case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of + TX86SimdLevel.AVX2: + Exit(@Argon2_FillBlock_Avx2_Wrap); TX86SimdLevel.SSE2: Exit(@Argon2_FillBlock_Sse2); end; From f68159963288feb50cb6406639f88843925a5374 Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 05:48:33 +0100 Subject: [PATCH 07/10] Some improvements (#98) * Rename kernels to their true minimum ISA and add aarch64 pure-GPR fallbacks Naming pass: a kernel's name now states the ISA its body actually requires, not the dispatch slot it serves - pure-GPR bodies are named Gpr, VEX-128-only bodies Avx. - KeccakF1600Sse2(+Absorb)_x86_64 -> KeccakF1600Gpr(+Absorb)_x86_64 - CRCFoldForwardSse2_{i386,x86_64} -> CRCFoldForwardGpr_* - SHA1/SHA256CompressAvx2_i386 -> *CompressAvx_i386 - Blake2SCompressAvx2_{i386,x86_64} -> Blake2SCompressAvx_* - Blake3CompressAvx2_x86_64 -> Blake3CompressAvx_x86_64 - ScryptSalsa8Avx2_{i386,x86_64} -> ScryptSalsa8Avx_* - backend procs/wraps follow; banner comments list the dispatch tiers, kernel headers no longer mention them - Reflected-CRC keeps its Sse2 name (SSE2 genuinely required for the 128-bit loads and the CRC state shuttle) - headers now say so New aarch64 fallbacks for the Crypto-Extensions-only hashes: SHA-1/ SHA-256/SHA-512 compress and Keccak-f[1600] permute + multi-block absorb gain baseline-AArch64 GPR kernels dispatched at the NEON slot when FEAT_SHA1/SHA256/SHA512/SHA3 are absent - previously scalar Pascal. Bodies are the OpenSSL CRYPTOGAMS plain paths, .long-encoded and verified byte-exact against the GNU-as reference objects. - SHA-256/SHA-512 use sentinel-terminated K tables (K256_Gpr/K512_Gpr with a zero terminator - the schedule loop ends on a zero K word); SHA-1 needs no table (movz/movk round constants) - Keccak's original round loop ends on a 256-aligned iotas table, which a Pascal const cannot guarantee; the termination is patched to an end-pointer compare so both kernels reuse the plain RC table * force neon mode * Cut NEON rotates to 2-op insert forms across the Blake/Argon2 kernels Every 32/64-bit lane rotate in the aarch64 NEON kernels was 3-op (ushr+shl+orr; Blake3's rot12/rot7 were even 4-op through a copy). The 2-op insert forms (ushr+sli, shl+sri, add+sri for ror63) land the result in a temp, so the generators now thread a register map: the rotated row renames into the temp instead of copying back, and rows normalize to their home registers only before writebacks and loop back-edges. Blake3 hash4's G is restructured 26 -> 21 ops with zero move instructions (b ping-pongs v_b -> t13 -> v_b; d lands in the register whose message word is dead). Instruction counts: Blake2S 632->573, Blake2B 1377->1233, Blake3 compress 714->645, Blake3 hash4 1653->1373 (-17%, the multi-chunk throughput path), Argon2 -12 ops per round slice (x16 executed per FillBlock). tbl-rot8 deliberately not used: official BLAKE3 NEON uses shl+sri and there is no mask setup or extra register cost. * Fix XXH3 SIMD kernel bugs exposed by new long-input known-answer tests The XXH3 test vectors all stayed under 240 bytes, so the SIMD accumulate/scramble/initSecret paths were only ever checked for self-consistency - a wrong kernel agreed with itself and passed. Four known-answer tests (values cross-checked against the official xxHash implementation) now cover accumulate512 (299 B), scrambleAcc (2 KiB) and the seeded long path (299 B with MaxUInt64 and with an asymmetric key) on every target. They surfaced three shipped bugs: - aarch64 NEON Acc512/Scramble: five vector encoders carried a stray bit in the source-register field, so every emitted uzp1/uzp2/umlal/ umlal2/mul executed with source register 2|m. Acc512 mixed the raw secret into accumulator lanes 2-3/6-7; Scramble multiplied by uninitialized registers. The mnemonic comments were correct - the encoded words were not. - i386 InitSecret (SSE2 + AVX2): the 64-bit seed materialization pushed lo before hi, leaving the high dword at [esp], so movq loaded a dword-swapped qword (-seed became 2^32 instead of 1). - InitSecret's seed parameter itself: a by-value UInt64 third parameter never rides in ecx under the i386 register convention, so the shared Proc3 prologue handed the kernels an undefined register - one compiler worked only by caller-codegen accident. The seed now travels by pointer (ASeedPtr: PUInt64), the same pattern as the Blake2 counter/flags pointers, and every kernel dereferences it on entry ([edi] on i386, mov r8,[r8] on x86_64, ldr x2,[x2] on NEON). * Fix big-endian custom secret in scalar XXH3 and make the acc domain explicit XXH3_InitSecret_Scalar wrote the derived secret with native PUInt64 stores while every consumer reads the secret as little-endian wire bytes - on big-endian targets the custom secret came out byte-swapped, so seeded hashing of inputs over 240 bytes was wrong (caught by the seeded long-input known-answer tests on the big-endian CI; the unseeded ones passed since that path copies the default secret byte-for-byte). The custom-secret stores now go through WriteUInt64LittleEndian. XXH3_Accumulate512_Scalar / XXH3_ScrambleAcc_Scalar were already endian-correct (the accumulator is native value data, read and written natively everywhere including mergeAccs), but their raw PUInt64 pointer derefs looked identical to the buggy pattern. They now use TBinaryPrimitives.LoadUInt64/StoreUInt64 (native-order, alignment-safe) so wire accesses (Read/WriteUInt64LittleEndian) and value accesses (Load/StoreUInt64) are distinguishable at a glance. * Restructure X86 backends to single-wrap kernel declarations Each SIMD kernel wrapper was declared twice - once per architecture section - so signature changes had to be made in two places and could drift. Following the CryptoLib4Pascal backend style, every kernel now has ONE declaration with per-arch {$IFDEF} selecting the prologue and body includes (x86_64 first), and pure-Pascal wraps that were identical across architectures are shared. Genuinely per-arch code keeps grouped arch sections: SHA3 (different kernel sets per arch), the SHA-1/SHA-256 ShaNi pairs (i386 is a 4-param proc with the doubled-K table, x86_64 a 5-param proc with the byte-swap mask) and the i386 Avx / x86_64 Avx2 wrap pairs. --- HashLib.Tests/src/Hash64Tests.pas | 77 + HashLib/src/Hash64/HlpXXHash3.pas | 46 +- HashLib/src/Include/HashLib.inc | 2 +- .../Argon2/Argon2FillBlockNeon_aarch64.inc | 364 ++-- .../Blake2B/Blake2BCompressNeon_aarch64.inc | 1371 +++++++-------- ...2_i386.inc => Blake2SCompressAvx_i386.inc} | 4 +- ...6_64.inc => Blake2SCompressAvx_x86_64.inc} | 2 +- .../Blake2S/Blake2SCompressNeon_aarch64.inc | 544 +++--- ...86_64.inc => Blake3CompressAvx_x86_64.inc} | 2 +- .../Blake3/Blake3CompressNeon_aarch64.inc | 409 ++--- .../Simd/Blake3/Blake3Hash4Neon_aarch64.inc | 1515 +++++++---------- ...e2_i386.inc => CRCFoldForwardGpr_i386.inc} | 2 +- ...86_64.inc => CRCFoldForwardGpr_x86_64.inc} | 7 +- .../Simd/CRC/CRCFoldReflectedSse2_i386.inc | 2 + .../Simd/CRC/CRCFoldReflectedSse2_x86_64.inc | 2 + ...Avx2_i386.inc => SHA1CompressAvx_i386.inc} | 5 +- .../Simd/SHA1/SHA1CompressGpr_aarch64.inc | 1038 +++++++++++ ...x2_i386.inc => SHA256CompressAvx_i386.inc} | 5 +- .../Simd/SHA256/SHA256CompressGpr_aarch64.inc | 948 +++++++++++ .../SHA3/KeccakF1600GprAbsorb_aarch64.inc | 352 ++++ ...64.inc => KeccakF1600GprAbsorb_x86_64.inc} | 4 +- .../Simd/SHA3/KeccakF1600Gpr_aarch64.inc | 240 +++ ...2_x86_64.inc => KeccakF1600Gpr_x86_64.inc} | 4 +- .../Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc | 2 +- .../Simd/SHA512/SHA512CompressGpr_aarch64.inc | 949 +++++++++++ ...Avx2_i386.inc => ScryptSalsa8Avx_i386.inc} | 4 +- ..._x86_64.inc => ScryptSalsa8Avx_x86_64.inc} | 2 +- .../Simd/XXH3/XXH3Acc512Neon_aarch64.inc | 8 +- .../Simd/XXH3/XXH3InitSecretAvx2_i386.inc | 13 +- .../Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc | 4 +- .../Simd/XXH3/XXH3InitSecretNeon_aarch64.inc | 4 +- .../Simd/XXH3/XXH3InitSecretSse2_i386.inc | 15 +- .../Simd/XXH3/XXH3InitSecretSse2_x86_64.inc | 4 +- .../Simd/XXH3/XXH3ScrambleNeon_aarch64.inc | 16 +- .../src/Simd/Backend/HlpAdler32X86Backend.pas | 54 +- .../src/Simd/Backend/HlpArgon2X86Backend.pas | 39 +- .../src/Simd/Backend/HlpBlake2BX86Backend.pas | 67 +- .../src/Simd/Backend/HlpBlake2SX86Backend.pas | 77 +- .../src/Simd/Backend/HlpBlake3X86Backend.pas | 49 +- HashLib/src/Simd/Backend/HlpCRCX86Backend.pas | 106 +- .../src/Simd/Backend/HlpSHA1ArmBackend.pas | 14 +- .../src/Simd/Backend/HlpSHA1X86Backend.pas | 69 +- .../Simd/Backend/HlpSHA2_256ArmBackend.pas | 45 +- .../Simd/Backend/HlpSHA2_256X86Backend.pas | 69 +- .../Simd/Backend/HlpSHA2_512ArmBackend.pas | 69 +- .../Simd/Backend/HlpSHA2_512X86Backend.pas | 20 +- .../src/Simd/Backend/HlpSHA3ArmBackend.pas | 41 +- .../src/Simd/Backend/HlpSHA3X86Backend.pas | 68 +- .../src/Simd/Backend/HlpScryptX86Backend.pas | 40 +- .../src/Simd/Backend/HlpXXHash3ArmBackend.pas | 2 +- .../src/Simd/Backend/HlpXXHash3X86Backend.pas | 104 +- 51 files changed, 6026 insertions(+), 2873 deletions(-) rename HashLib/src/Include/Simd/Blake2S/{Blake2SCompressAvx2_i386.inc => Blake2SCompressAvx_i386.inc} (99%) rename HashLib/src/Include/Simd/Blake2S/{Blake2SCompressAvx2_x86_64.inc => Blake2SCompressAvx_x86_64.inc} (99%) rename HashLib/src/Include/Simd/Blake3/{Blake3CompressAvx2_x86_64.inc => Blake3CompressAvx_x86_64.inc} (99%) rename HashLib/src/Include/Simd/CRC/{CRCFoldForwardSse2_i386.inc => CRCFoldForwardGpr_i386.inc} (98%) rename HashLib/src/Include/Simd/CRC/{CRCFoldForwardSse2_x86_64.inc => CRCFoldForwardGpr_x86_64.inc} (87%) rename HashLib/src/Include/Simd/SHA1/{SHA1CompressAvx2_i386.inc => SHA1CompressAvx_i386.inc} (99%) create mode 100644 HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc rename HashLib/src/Include/Simd/SHA256/{SHA256CompressAvx2_i386.inc => SHA256CompressAvx_i386.inc} (99%) create mode 100644 HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc create mode 100644 HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc rename HashLib/src/Include/Simd/SHA3/{KeccakF1600Sse2Absorb_x86_64.inc => KeccakF1600GprAbsorb_x86_64.inc} (97%) create mode 100644 HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc rename HashLib/src/Include/Simd/SHA3/{KeccakF1600Sse2_x86_64.inc => KeccakF1600Gpr_x86_64.inc} (98%) create mode 100644 HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc rename HashLib/src/Include/Simd/Scrypt/{ScryptSalsa8Avx2_i386.inc => ScryptSalsa8Avx_i386.inc} (98%) rename HashLib/src/Include/Simd/Scrypt/{ScryptSalsa8Avx2_x86_64.inc => ScryptSalsa8Avx_x86_64.inc} (98%) diff --git a/HashLib.Tests/src/Hash64Tests.pas b/HashLib.Tests/src/Hash64Tests.pas index 265998c..0fe379a 100644 --- a/HashLib.Tests/src/Hash64Tests.pas +++ b/HashLib.Tests/src/Hash64Tests.pas @@ -3,6 +3,7 @@ interface uses + SysUtils, {$IFDEF FPC} fpcunit, testregistry, @@ -10,6 +11,7 @@ interface TestFramework, {$ENDIF FPC} HashLibTestBase, + HlpIHashInfo, HlpHashFactory; // Hash64 @@ -70,6 +72,18 @@ TTestXXHash3 = class(THashWithUInt64AsKeyAlgorithmTestCase) procedure SetUp; override; procedure TearDown; override; + published + // Known-answer tests for the long-input paths (values cross-checked + // against the official xxHash implementation): the self-consistency + // chunked tests alone cannot catch a wrong SIMD kernel because both + // sides run the same code. + procedure TestChunkedDataKnownAnswer; // 299 bytes: accumulate512 + procedure TestTwoKiBDataKnownAnswer; // 2048 bytes: scrambleAcc + procedure TestChunkedDataWithMaxUInt64AsKeyKnownAnswer; // seeded: initSecret + // An asymmetric key (lo32 <> hi32) - a symmetric one like MaxUInt64 + // cannot catch seed dword swaps or wrong hi/lo pickup in the kernels. + procedure TestChunkedDataWithAsymmetricKeyKnownAnswer; + end; implementation @@ -188,6 +202,69 @@ procedure TTestXXHash3.TearDown; inherited; end; +procedure TTestXXHash3.TestChunkedDataKnownAnswer; +begin + ExpectedString := '3D3D7245B763ACE8'; + ActualString := HashInstance.ComputeString(ChunkedData, TEncoding.UTF8) + .ToString(); + CheckEquals(ExpectedString, ActualString, Format('Expected %s but got %s.', + [ExpectedString, ActualString])); +end; + +procedure TTestXXHash3.TestTwoKiBDataKnownAnswer; +var + LData: TBytes; + LIdx: Int32; +begin + System.SetLength(LData, 2048); + for LIdx := 0 to 2047 do + begin + LData[LIdx] := Byte(LIdx and $FF); + end; + ExpectedString := 'DD420471FF96BD00'; + ActualString := HashInstance.ComputeBytes(LData).ToString(); + CheckEquals(ExpectedString, ActualString, Format('Expected %s but got %s.', + [ExpectedString, ActualString])); +end; + +procedure TTestXXHash3.TestChunkedDataWithAsymmetricKeyKnownAnswer; +var + LIHashWithKey: IHashWithKey; + LKey: TBytes; +begin + // key = $0123456789ABCDEF (little-endian bytes below) + ExpectedString := 'FBF9CD92890CC82A'; + CheckTrue(Supports(HashInstance, IHashWithKey, LIHashWithKey), + 'HashInstance must support IHashWithKey'); + LKey := TBytes.Create($EF, $CD, $AB, $89, $67, $45, $23, $01); + LIHashWithKey.Key := LKey; + ActualString := LIHashWithKey.ComputeString(ChunkedData, TEncoding.UTF8) + .ToString(); + CheckEquals(ExpectedString, ActualString, Format('Expected %s but got %s.', + [ExpectedString, ActualString])); +end; + +procedure TTestXXHash3.TestChunkedDataWithMaxUInt64AsKeyKnownAnswer; +var + LIHashWithKey: IHashWithKey; + LKey: TBytes; + LIdx: Int32; +begin + ExpectedString := '7DEFEE70FC854900'; + CheckTrue(Supports(HashInstance, IHashWithKey, LIHashWithKey), + 'HashInstance must support IHashWithKey'); + System.SetLength(LKey, System.SizeOf(UInt64)); + for LIdx := 0 to System.High(LKey) do + begin + LKey[LIdx] := $FF; + end; + LIHashWithKey.Key := LKey; + ActualString := LIHashWithKey.ComputeString(ChunkedData, TEncoding.UTF8) + .ToString(); + CheckEquals(ExpectedString, ActualString, Format('Expected %s but got %s.', + [ExpectedString, ActualString])); +end; + initialization // Register any test cases with the test runner diff --git a/HashLib/src/Hash64/HlpXXHash3.pas b/HashLib/src/Hash64/HlpXXHash3.pas index e6aaab6..b6ca698 100644 --- a/HashLib/src/Hash64/HlpXXHash3.pas +++ b/HashLib/src/Hash64/HlpXXHash3.pas @@ -21,7 +21,7 @@ interface ASecret: Pointer; ANbStripes: Int32); TXXH3ScrambleAccProc = procedure(AAcc: Pointer; ASecret: Pointer); TXXH3InitSecretProc = procedure(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); + ADefaultSecret: Pointer; ASeedPtr: PUInt64); var XXH3_Accumulate512: TXXH3Accumulate512Proc; @@ -208,60 +208,66 @@ implementation procedure XXH3_Accumulate512_Scalar(AAcc: Pointer; AInput: Pointer; ASecret: Pointer); var - LPAcc: PUInt64; - LPInput, LPSecret: PByte; + LPAcc, LPInput, LPSecret: PByte; + LPLane: PUInt64; I: Int32; LDataVal, LDataKey: UInt64; begin - LPAcc := PUInt64(AAcc); + LPAcc := PByte(AAcc); LPInput := PByte(AInput); LPSecret := PByte(ASecret); for I := 0 to XXH_ACC_NB - 1 do begin LDataVal := TBinaryPrimitives.ReadUInt64LittleEndian(LPInput, I * 8); LDataKey := LDataVal xor TBinaryPrimitives.ReadUInt64LittleEndian(LPSecret, I * 8); - PUInt64(PByte(LPAcc) + (I xor 1) * 8)^ := - PUInt64(PByte(LPAcc) + (I xor 1) * 8)^ + LDataVal; - PUInt64(PByte(LPAcc) + I * 8)^ := - PUInt64(PByte(LPAcc) + I * 8)^ + - UInt64(UInt32(LDataKey)) * UInt64(UInt32(LDataKey shr 32)); + LPLane := PUInt64(LPAcc + (I xor 1) * 8); + TBinaryPrimitives.StoreUInt64(LPLane, + TBinaryPrimitives.LoadUInt64(LPLane) + LDataVal); + LPLane := PUInt64(LPAcc + I * 8); + TBinaryPrimitives.StoreUInt64(LPLane, + TBinaryPrimitives.LoadUInt64(LPLane) + + UInt64(UInt32(LDataKey)) * UInt64(UInt32(LDataKey shr 32))); end; end; procedure XXH3_ScrambleAcc_Scalar(AAcc: Pointer; ASecret: Pointer); var - LPAcc: PUInt64; - LPSecret: PByte; + LPAcc, LPSecret: PByte; + LPLane: PUInt64; I: Int32; LKey64, LAcc64: UInt64; begin - LPAcc := PUInt64(AAcc); + LPAcc := PByte(AAcc); LPSecret := PByte(ASecret); for I := 0 to XXH_ACC_NB - 1 do begin LKey64 := TBinaryPrimitives.ReadUInt64LittleEndian(LPSecret, I * 8); - LAcc64 := PUInt64(PByte(LPAcc) + I * 8)^; + LPLane := PUInt64(LPAcc + I * 8); + LAcc64 := TBinaryPrimitives.LoadUInt64(LPLane); LAcc64 := LAcc64 xor (LAcc64 shr 47); LAcc64 := LAcc64 xor LKey64; LAcc64 := LAcc64 * XXH_PRIME32_1; - PUInt64(PByte(LPAcc) + I * 8)^ := LAcc64; + TBinaryPrimitives.StoreUInt64(LPLane, LAcc64); end; end; procedure XXH3_InitSecret_Scalar(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); + ADefaultSecret: Pointer; ASeedPtr: PUInt64); var I: Int32; LPSrc, LPDst: PByte; + ASeed: UInt64; begin + ASeed := ASeedPtr^; LPSrc := PByte(ADefaultSecret); LPDst := PByte(ACustomSecret); + for I := 0 to (192 div 16) - 1 do begin - PUInt64(LPDst + 16 * I)^ := - TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I) + ASeed; - PUInt64(LPDst + 16 * I + 8)^ := - TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I + 8) - ASeed; + TBinaryPrimitives.WriteUInt64LittleEndian(LPDst, 16 * I, + TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I) + ASeed); + TBinaryPrimitives.WriteUInt64LittleEndian(LPDst, 16 * I + 8, + TBinaryPrimitives.ReadUInt64LittleEndian(LPSrc, 16 * I + 8) - ASeed); end; end; @@ -448,7 +454,7 @@ class procedure TXXH3Core.XXH3_hashLong_internal_loop( class procedure TXXH3Core.XXH3_initCustomSecret(ACustomSecret: PByte; ASeed: UInt64); begin - HlpXXHash3.XXH3_InitSecret(ACustomSecret, @XXH3_SECRET[0], ASeed); + HlpXXHash3.XXH3_InitSecret(ACustomSecret, @XXH3_SECRET[0], @ASeed); end; class procedure TXXH3Core.XXH3_consumeStripes(var AAcc: TXXH3AccArray; diff --git a/HashLib/src/Include/HashLib.inc b/HashLib/src/Include/HashLib.inc index 2e90f93..ff32f55 100644 --- a/HashLib/src/Include/HashLib.inc +++ b/HashLib/src/Include/HashLib.inc @@ -173,7 +173,7 @@ {$IFDEF HASHLIB_ARM_SIMD} // Uncomment at most ONE to force a specific Arm SIMD dispatch level: -// {$DEFINE HASHLIB_FORCE_NEON} + {$DEFINE HASHLIB_FORCE_NEON} // {$DEFINE HASHLIB_FORCE_SVE} {$IF (DEFINED(HASHLIB_FORCE_SCALAR) AND DEFINED(HASHLIB_FORCE_NEON)) diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc index 7f6bc0a..a9ed74a 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc @@ -11,12 +11,14 @@ // v2-v3 = B0, B1 // v4-v5 = C0, C1 // v6-v7 = D0, D1 -// v16-v18 = fBlaMka / rotr temps +// v16-v18 = fBlaMka / rotate temps (2-op insert rotates rename B/D rows +// through v16/v17; rows return home before each slice store) // x9 = R_buf base ([sp+64]) // x10 = loop byte offset (steps 1-5) // x11 = Z_buf base ([sp+1088]) // x12 = Z slice pointer (column/row load/store) // w3 = WithXor (0 or 1) + sub sp, sp, #2128 add x9, sp, #64 mov x10, #0 @@ -78,138 +80,126 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680450 // ushr v16.2d, v2.2d, #24 - .long 0x4f685451 // shl v17.2d, v2.2d, #40 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x6f680470 // ushr v16.2d, v3.2d, #24 - .long 0x4f685471 // shl v17.2d, v3.2d, #40 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b - .long 0x0ea12810 // xtn v16.2s, v0.2d - .long 0x0ea12851 // xtn v17.2s, v2.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s - .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee28400 // add v0.2d, v0.2d, v2.2d + .long 0x6f685450 // sli v16.2d, v2.2d, #40 + .long 0x6f680471 // ushr v17.2d, v3.2d, #24 + .long 0x6f685471 // sli v17.2d, v3.2d, #40 + .long 0x0ea12802 // xtn v2.2s, v0.2d + .long 0x0ea12a03 // xtn v3.2s, v16.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s + .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d + .long 0x4ef08400 // add v0.2d, v0.2d, v16.2d .long 0x4ef28400 // add v0.2d, v0.2d, v18.2d - .long 0x0ea12830 // xtn v16.2s, v1.2d - .long 0x0ea12871 // xtn v17.2s, v3.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea12822 // xtn v2.2s, v1.2d + .long 0x0ea12a23 // xtn v3.2s, v17.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee38421 // add v1.2d, v1.2d, v3.2d + .long 0x4ef18421 // add v1.2d, v1.2d, v17.2d .long 0x4ef28421 // add v1.2d, v1.2d, v18.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d0 // ushr v16.2d, v6.2d, #16 - .long 0x4f7054d1 // shl v17.2d, v6.2d, #48 - .long 0x4eb11e06 // orr v6.16b, v16.16b, v17.16b - .long 0x6f7004f0 // ushr v16.2d, v7.2d, #16 - .long 0x4f7054f1 // shl v17.2d, v7.2d, #48 - .long 0x4eb11e07 // orr v7.16b, v16.16b, v17.16b - .long 0x0ea12890 // xtn v16.2s, v4.2d - .long 0x0ea128d1 // xtn v17.2s, v6.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s - .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x0ea12886 // xtn v6.2s, v4.2d + .long 0x0ea12847 // xtn v7.2s, v2.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s + .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d .long 0x4ef28484 // add v4.2d, v4.2d, v18.2d - .long 0x0ea128b0 // xtn v16.2s, v5.2d - .long 0x0ea128f1 // xtn v17.2s, v7.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea128a6 // xtn v6.2s, v5.2d + .long 0x0ea12867 // xtn v7.2s, v3.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d .long 0x4ef284a5 // add v5.2d, v5.2d, v18.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28450 // add v16.2d, v2.2d, v2.2d - .long 0x6f410451 // ushr v17.2d, v2.2d, #63 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x4ee38470 // add v16.2d, v3.2d, v3.2d - .long 0x6f410471 // ushr v17.2d, v3.2d, #63 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b - .long 0x6e034050 // ext v16.16b, v2.16b, v3.16b, #8 - .long 0x6e024071 // ext v17.16b, v3.16b, v2.16b, #8 - .long 0x4eb01e02 // orr v2.16b, v16.16b, v16.16b - .long 0x4eb11e23 // orr v3.16b, v17.16b, v17.16b + .long 0x6e241e10 // eor v16.16b, v16.16b, v4.16b + .long 0x6e251e31 // eor v17.16b, v17.16b, v5.16b + .long 0x4ef08606 // add v6.2d, v16.2d, v16.2d + .long 0x6f414606 // sri v6.2d, v16.2d, #63 + .long 0x4ef18627 // add v7.2d, v17.2d, v17.2d + .long 0x6f414627 // sri v7.2d, v17.2d, #63 + .long 0x6e0740d0 // ext v16.16b, v6.16b, v7.16b, #8 + .long 0x6e0640f1 // ext v17.16b, v7.16b, v6.16b, #8 + .long 0x4eb01e06 // orr v6.16b, v16.16b, v16.16b + .long 0x4eb11e27 // orr v7.16b, v17.16b, v17.16b .long 0x4ea41c90 // orr v16.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb01e05 // orr v5.16b, v16.16b, v16.16b - .long 0x6e0740d0 // ext v16.16b, v6.16b, v7.16b, #8 - .long 0x6e0640f1 // ext v17.16b, v7.16b, v6.16b, #8 - .long 0x4eb11e26 // orr v6.16b, v17.16b, v17.16b - .long 0x4eb01e07 // orr v7.16b, v16.16b, v16.16b + .long 0x6e034050 // ext v16.16b, v2.16b, v3.16b, #8 + .long 0x6e024071 // ext v17.16b, v3.16b, v2.16b, #8 + .long 0x4eb11e22 // orr v2.16b, v17.16b, v17.16b + .long 0x4eb01e03 // orr v3.16b, v16.16b, v16.16b .long 0x0ea12810 // xtn v16.2s, v0.2d - .long 0x0ea12851 // xtn v17.2s, v2.2d + .long 0x0ea128d1 // xtn v17.2s, v6.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee28400 // add v0.2d, v0.2d, v2.2d + .long 0x4ee68400 // add v0.2d, v0.2d, v6.2d .long 0x4ef28400 // add v0.2d, v0.2d, v18.2d .long 0x0ea12830 // xtn v16.2s, v1.2d - .long 0x0ea12871 // xtn v17.2s, v3.2d + .long 0x0ea128f1 // xtn v17.2s, v7.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee38421 // add v1.2d, v1.2d, v3.2d + .long 0x4ee78421 // add v1.2d, v1.2d, v7.2d .long 0x4ef28421 // add v1.2d, v1.2d, v18.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s .long 0x0ea12890 // xtn v16.2s, v4.2d - .long 0x0ea128d1 // xtn v17.2s, v6.2d + .long 0x0ea12851 // xtn v17.2s, v2.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d .long 0x4ef28484 // add v4.2d, v4.2d, v18.2d .long 0x0ea128b0 // xtn v16.2s, v5.2d - .long 0x0ea128f1 // xtn v17.2s, v7.2d + .long 0x0ea12871 // xtn v17.2s, v3.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d .long 0x4ef284a5 // add v5.2d, v5.2d, v18.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680450 // ushr v16.2d, v2.2d, #24 - .long 0x4f685451 // shl v17.2d, v2.2d, #40 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x6f680470 // ushr v16.2d, v3.2d, #24 - .long 0x4f685471 // shl v17.2d, v3.2d, #40 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b - .long 0x0ea12810 // xtn v16.2s, v0.2d - .long 0x0ea12851 // xtn v17.2s, v2.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s - .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee28400 // add v0.2d, v0.2d, v2.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d0 // ushr v16.2d, v6.2d, #24 + .long 0x6f6854d0 // sli v16.2d, v6.2d, #40 + .long 0x6f6804f1 // ushr v17.2d, v7.2d, #24 + .long 0x6f6854f1 // sli v17.2d, v7.2d, #40 + .long 0x0ea12806 // xtn v6.2s, v0.2d + .long 0x0ea12a07 // xtn v7.2s, v16.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s + .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d + .long 0x4ef08400 // add v0.2d, v0.2d, v16.2d .long 0x4ef28400 // add v0.2d, v0.2d, v18.2d - .long 0x0ea12830 // xtn v16.2s, v1.2d - .long 0x0ea12871 // xtn v17.2s, v3.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea12826 // xtn v6.2s, v1.2d + .long 0x0ea12a27 // xtn v7.2s, v17.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee38421 // add v1.2d, v1.2d, v3.2d + .long 0x4ef18421 // add v1.2d, v1.2d, v17.2d .long 0x4ef28421 // add v1.2d, v1.2d, v18.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d0 // ushr v16.2d, v6.2d, #16 - .long 0x4f7054d1 // shl v17.2d, v6.2d, #48 - .long 0x4eb11e06 // orr v6.16b, v16.16b, v17.16b - .long 0x6f7004f0 // ushr v16.2d, v7.2d, #16 - .long 0x4f7054f1 // shl v17.2d, v7.2d, #48 - .long 0x4eb11e07 // orr v7.16b, v16.16b, v17.16b - .long 0x0ea12890 // xtn v16.2s, v4.2d - .long 0x0ea128d1 // xtn v17.2s, v6.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 + .long 0x0ea12882 // xtn v2.2s, v4.2d + .long 0x0ea128c3 // xtn v3.2s, v6.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ef28484 // add v4.2d, v4.2d, v18.2d - .long 0x0ea128b0 // xtn v16.2s, v5.2d - .long 0x0ea128f1 // xtn v17.2s, v7.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea128a2 // xtn v2.2s, v5.2d + .long 0x0ea128e3 // xtn v3.2s, v7.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d .long 0x4ef284a5 // add v5.2d, v5.2d, v18.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28450 // add v16.2d, v2.2d, v2.2d - .long 0x6f410451 // ushr v17.2d, v2.2d, #63 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x4ee38470 // add v16.2d, v3.2d, v3.2d - .long 0x6f410471 // ushr v17.2d, v3.2d, #63 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b + .long 0x6e241e10 // eor v16.16b, v16.16b, v4.16b + .long 0x6e251e31 // eor v17.16b, v17.16b, v5.16b + .long 0x4ef08602 // add v2.2d, v16.2d, v16.2d + .long 0x6f414602 // sri v2.2d, v16.2d, #63 + .long 0x4ef18623 // add v3.2d, v17.2d, v17.2d + .long 0x6f414623 // sri v3.2d, v17.2d, #63 .long 0x6e024070 // ext v16.16b, v3.16b, v2.16b, #8 .long 0x6e034051 // ext v17.16b, v2.16b, v3.16b, #8 .long 0x4eb01e02 // orr v2.16b, v16.16b, v16.16b @@ -275,138 +265,126 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680450 // ushr v16.2d, v2.2d, #24 - .long 0x4f685451 // shl v17.2d, v2.2d, #40 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x6f680470 // ushr v16.2d, v3.2d, #24 - .long 0x4f685471 // shl v17.2d, v3.2d, #40 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b - .long 0x0ea12810 // xtn v16.2s, v0.2d - .long 0x0ea12851 // xtn v17.2s, v2.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s - .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee28400 // add v0.2d, v0.2d, v2.2d + .long 0x6f685450 // sli v16.2d, v2.2d, #40 + .long 0x6f680471 // ushr v17.2d, v3.2d, #24 + .long 0x6f685471 // sli v17.2d, v3.2d, #40 + .long 0x0ea12802 // xtn v2.2s, v0.2d + .long 0x0ea12a03 // xtn v3.2s, v16.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s + .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d + .long 0x4ef08400 // add v0.2d, v0.2d, v16.2d .long 0x4ef28400 // add v0.2d, v0.2d, v18.2d - .long 0x0ea12830 // xtn v16.2s, v1.2d - .long 0x0ea12871 // xtn v17.2s, v3.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea12822 // xtn v2.2s, v1.2d + .long 0x0ea12a23 // xtn v3.2s, v17.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee38421 // add v1.2d, v1.2d, v3.2d + .long 0x4ef18421 // add v1.2d, v1.2d, v17.2d .long 0x4ef28421 // add v1.2d, v1.2d, v18.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d0 // ushr v16.2d, v6.2d, #16 - .long 0x4f7054d1 // shl v17.2d, v6.2d, #48 - .long 0x4eb11e06 // orr v6.16b, v16.16b, v17.16b - .long 0x6f7004f0 // ushr v16.2d, v7.2d, #16 - .long 0x4f7054f1 // shl v17.2d, v7.2d, #48 - .long 0x4eb11e07 // orr v7.16b, v16.16b, v17.16b - .long 0x0ea12890 // xtn v16.2s, v4.2d - .long 0x0ea128d1 // xtn v17.2s, v6.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s - .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x0ea12886 // xtn v6.2s, v4.2d + .long 0x0ea12847 // xtn v7.2s, v2.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s + .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d .long 0x4ef28484 // add v4.2d, v4.2d, v18.2d - .long 0x0ea128b0 // xtn v16.2s, v5.2d - .long 0x0ea128f1 // xtn v17.2s, v7.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea128a6 // xtn v6.2s, v5.2d + .long 0x0ea12867 // xtn v7.2s, v3.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d .long 0x4ef284a5 // add v5.2d, v5.2d, v18.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28450 // add v16.2d, v2.2d, v2.2d - .long 0x6f410451 // ushr v17.2d, v2.2d, #63 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x4ee38470 // add v16.2d, v3.2d, v3.2d - .long 0x6f410471 // ushr v17.2d, v3.2d, #63 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b - .long 0x6e034050 // ext v16.16b, v2.16b, v3.16b, #8 - .long 0x6e024071 // ext v17.16b, v3.16b, v2.16b, #8 - .long 0x4eb01e02 // orr v2.16b, v16.16b, v16.16b - .long 0x4eb11e23 // orr v3.16b, v17.16b, v17.16b + .long 0x6e241e10 // eor v16.16b, v16.16b, v4.16b + .long 0x6e251e31 // eor v17.16b, v17.16b, v5.16b + .long 0x4ef08606 // add v6.2d, v16.2d, v16.2d + .long 0x6f414606 // sri v6.2d, v16.2d, #63 + .long 0x4ef18627 // add v7.2d, v17.2d, v17.2d + .long 0x6f414627 // sri v7.2d, v17.2d, #63 + .long 0x6e0740d0 // ext v16.16b, v6.16b, v7.16b, #8 + .long 0x6e0640f1 // ext v17.16b, v7.16b, v6.16b, #8 + .long 0x4eb01e06 // orr v6.16b, v16.16b, v16.16b + .long 0x4eb11e27 // orr v7.16b, v17.16b, v17.16b .long 0x4ea41c90 // orr v16.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb01e05 // orr v5.16b, v16.16b, v16.16b - .long 0x6e0740d0 // ext v16.16b, v6.16b, v7.16b, #8 - .long 0x6e0640f1 // ext v17.16b, v7.16b, v6.16b, #8 - .long 0x4eb11e26 // orr v6.16b, v17.16b, v17.16b - .long 0x4eb01e07 // orr v7.16b, v16.16b, v16.16b + .long 0x6e034050 // ext v16.16b, v2.16b, v3.16b, #8 + .long 0x6e024071 // ext v17.16b, v3.16b, v2.16b, #8 + .long 0x4eb11e22 // orr v2.16b, v17.16b, v17.16b + .long 0x4eb01e03 // orr v3.16b, v16.16b, v16.16b .long 0x0ea12810 // xtn v16.2s, v0.2d - .long 0x0ea12851 // xtn v17.2s, v2.2d + .long 0x0ea128d1 // xtn v17.2s, v6.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee28400 // add v0.2d, v0.2d, v2.2d + .long 0x4ee68400 // add v0.2d, v0.2d, v6.2d .long 0x4ef28400 // add v0.2d, v0.2d, v18.2d .long 0x0ea12830 // xtn v16.2s, v1.2d - .long 0x0ea12871 // xtn v17.2s, v3.2d + .long 0x0ea128f1 // xtn v17.2s, v7.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee38421 // add v1.2d, v1.2d, v3.2d + .long 0x4ee78421 // add v1.2d, v1.2d, v7.2d .long 0x4ef28421 // add v1.2d, v1.2d, v18.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s .long 0x0ea12890 // xtn v16.2s, v4.2d - .long 0x0ea128d1 // xtn v17.2s, v6.2d + .long 0x0ea12851 // xtn v17.2s, v2.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d .long 0x4ef28484 // add v4.2d, v4.2d, v18.2d .long 0x0ea128b0 // xtn v16.2s, v5.2d - .long 0x0ea128f1 // xtn v17.2s, v7.2d + .long 0x0ea12871 // xtn v17.2s, v3.2d .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d .long 0x4ef284a5 // add v5.2d, v5.2d, v18.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680450 // ushr v16.2d, v2.2d, #24 - .long 0x4f685451 // shl v17.2d, v2.2d, #40 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x6f680470 // ushr v16.2d, v3.2d, #24 - .long 0x4f685471 // shl v17.2d, v3.2d, #40 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b - .long 0x0ea12810 // xtn v16.2s, v0.2d - .long 0x0ea12851 // xtn v17.2s, v2.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s - .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee28400 // add v0.2d, v0.2d, v2.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d0 // ushr v16.2d, v6.2d, #24 + .long 0x6f6854d0 // sli v16.2d, v6.2d, #40 + .long 0x6f6804f1 // ushr v17.2d, v7.2d, #24 + .long 0x6f6854f1 // sli v17.2d, v7.2d, #40 + .long 0x0ea12806 // xtn v6.2s, v0.2d + .long 0x0ea12a07 // xtn v7.2s, v16.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s + .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d + .long 0x4ef08400 // add v0.2d, v0.2d, v16.2d .long 0x4ef28400 // add v0.2d, v0.2d, v18.2d - .long 0x0ea12830 // xtn v16.2s, v1.2d - .long 0x0ea12871 // xtn v17.2s, v3.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea12826 // xtn v6.2s, v1.2d + .long 0x0ea12a27 // xtn v7.2s, v17.2d + .long 0x2ea7c0d2 // umull v18.2d, v6.2s, v7.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d - .long 0x4ee38421 // add v1.2d, v1.2d, v3.2d + .long 0x4ef18421 // add v1.2d, v1.2d, v17.2d .long 0x4ef28421 // add v1.2d, v1.2d, v18.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d0 // ushr v16.2d, v6.2d, #16 - .long 0x4f7054d1 // shl v17.2d, v6.2d, #48 - .long 0x4eb11e06 // orr v6.16b, v16.16b, v17.16b - .long 0x6f7004f0 // ushr v16.2d, v7.2d, #16 - .long 0x4f7054f1 // shl v17.2d, v7.2d, #48 - .long 0x4eb11e07 // orr v7.16b, v16.16b, v17.16b - .long 0x0ea12890 // xtn v16.2s, v4.2d - .long 0x0ea128d1 // xtn v17.2s, v6.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 + .long 0x0ea12882 // xtn v2.2s, v4.2d + .long 0x0ea128c3 // xtn v3.2s, v6.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ef28484 // add v4.2d, v4.2d, v18.2d - .long 0x0ea128b0 // xtn v16.2s, v5.2d - .long 0x0ea128f1 // xtn v17.2s, v7.2d - .long 0x2eb1c212 // umull v18.2d, v16.2s, v17.2s + .long 0x0ea128a2 // xtn v2.2s, v5.2d + .long 0x0ea128e3 // xtn v3.2s, v7.2d + .long 0x2ea3c052 // umull v18.2d, v2.2s, v3.2s .long 0x4ef28652 // add v18.2d, v18.2d, v18.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d .long 0x4ef284a5 // add v5.2d, v5.2d, v18.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28450 // add v16.2d, v2.2d, v2.2d - .long 0x6f410451 // ushr v17.2d, v2.2d, #63 - .long 0x4eb11e02 // orr v2.16b, v16.16b, v17.16b - .long 0x4ee38470 // add v16.2d, v3.2d, v3.2d - .long 0x6f410471 // ushr v17.2d, v3.2d, #63 - .long 0x4eb11e03 // orr v3.16b, v16.16b, v17.16b + .long 0x6e241e10 // eor v16.16b, v16.16b, v4.16b + .long 0x6e251e31 // eor v17.16b, v17.16b, v5.16b + .long 0x4ef08602 // add v2.2d, v16.2d, v16.2d + .long 0x6f414602 // sri v2.2d, v16.2d, #63 + .long 0x4ef18623 // add v3.2d, v17.2d, v17.2d + .long 0x6f414623 // sri v3.2d, v17.2d, #63 .long 0x6e024070 // ext v16.16b, v3.16b, v2.16b, #8 .long 0x6e034051 // ext v17.16b, v2.16b, v3.16b, #8 .long 0x4eb01e02 // orr v2.16b, v16.16b, v16.16b diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc index 1eb793d..4c005c1 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc @@ -12,7 +12,8 @@ // v8-v15 = message block (16 x UInt64) // v16-v19 = saved initial row1l/h, row2l/h for the final feed-forward XOR // v20 = message gather temp b0 (G function) -// v21-v23 = rotate / diagonalize temps (b1 gather uses v23) +// v21-v23 = rotate / diagonalize temps (2-op insert rotates rename the +// rotated row halves through v21/v22; b1 gather uses v23) // u64 ror-by-32 uses rev64.4s (vrev64q_u32), not rev64.16b. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} @@ -49,94 +50,82 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e084514 // ins v20.d[0], v8.d[1] .long 0x6e184534 // ins v20.d[1], v9.d[1] .long 0x6e084557 // ins v23.d[0], v10.d[1] .long 0x6e184577 // ins v23.d[1], v11.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e080594 // ins v20.d[0], v12.d[0] .long 0x6e1805b4 // ins v20.d[1], v13.d[0] .long 0x6e0805d7 // ins v23.d[0], v14.d[0] .long 0x6e1805f7 // ins v23.d[1], v15.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e084594 // ins v20.d[0], v12.d[1] .long 0x6e1845b4 // ins v20.d[1], v13.d[1] .long 0x6e0845d7 // ins v23.d[0], v14.d[1] .long 0x6e1845f7 // ins v23.d[1], v15.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -163,92 +152,80 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e0805b4 // ins v20.d[0], v13.d[0] .long 0x6e180594 // ins v20.d[1], v12.d[0] .long 0x6e0b41f7 // ext v23.16b, v15.16b, v11.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e084114 // ext v20.16b, v8.16b, v8.16b, #8 .long 0x6e0845b7 // ins v23.d[0], v13.d[1] .long 0x6e184557 // ins v23.d[1], v10.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e0805d4 // ins v20.d[0], v14.d[0] .long 0x6e180534 // ins v20.d[1], v9.d[0] .long 0x6e084577 // ins v23.d[0], v11.d[1] .long 0x6e184537 // ins v23.d[1], v9.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -274,93 +251,81 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e080594 // ins v20.d[0], v12.d[0] .long 0x6e180514 // ins v20.d[1], v8.d[0] .long 0x6e080537 // ins v23.d[0], v9.d[0] .long 0x6e1845d7 // ins v23.d[1], v14.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e0805b4 // ins v20.d[0], v13.d[0] .long 0x6e184534 // ins v20.d[1], v9.d[1] .long 0x6e084577 // ins v23.d[0], v11.d[1] .long 0x6e184597 // ins v23.d[1], v12.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e0805f4 // ins v20.d[0], v15.d[0] .long 0x6e180574 // ins v20.d[1], v11.d[0] .long 0x6e0a4117 // ext v23.16b, v8.16b, v10.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -387,94 +352,82 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e084594 // ins v20.d[0], v12.d[1] .long 0x6e184514 // ins v20.d[1], v8.d[1] .long 0x6e0805d7 // ins v23.d[0], v14.d[0] .long 0x6e1805f7 // ins v23.d[1], v15.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e080534 // ins v20.d[0], v9.d[0] .long 0x6e184554 // ins v20.d[1], v10.d[1] .long 0x6e080557 // ins v23.d[0], v10.d[0] .long 0x6e1845f7 // ins v23.d[1], v15.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e080574 // ins v20.d[0], v11.d[0] .long 0x6e1805b4 // ins v20.d[1], v13.d[0] .long 0x6e080517 // ins v23.d[0], v8.d[0] .long 0x6e180597 // ins v23.d[1], v12.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -501,93 +454,81 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e080514 // ins v20.d[0], v8.d[0] .long 0x6e184574 // ins v20.d[1], v11.d[1] .long 0x6e080557 // ins v23.d[0], v10.d[0] .long 0x6e1845f7 // ins v23.d[1], v15.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e0805f4 // ins v20.d[0], v15.d[0] .long 0x6e1845b4 // ins v20.d[1], v13.d[1] .long 0x6e080577 // ins v23.d[0], v11.d[0] .long 0x6e184537 // ins v23.d[1], v9.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e0e4114 // ext v20.16b, v8.16b, v14.16b, #8 .long 0x6e080597 // ins v23.d[0], v12.d[0] .long 0x6e1845d7 // ins v23.d[1], v14.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -614,94 +555,82 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e0805d4 // ins v20.d[0], v14.d[0] .long 0x6e1805b4 // ins v20.d[1], v13.d[0] .long 0x6e0845b7 // ins v23.d[0], v13.d[1] .long 0x6e184537 // ins v23.d[1], v9.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e080554 // ins v20.d[0], v10.d[0] .long 0x6e184574 // ins v20.d[1], v11.d[1] .long 0x6e0845f7 // ins v23.d[0], v15.d[1] .long 0x6e184517 // ins v23.d[1], v8.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e0845d4 // ins v20.d[0], v14.d[1] .long 0x6e184554 // ins v20.d[1], v10.d[1] .long 0x6e0805f7 // ins v23.d[0], v15.d[0] .long 0x6e184597 // ins v23.d[1], v12.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -728,92 +657,80 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e084554 // ins v20.d[0], v10.d[1] .long 0x6e1845f4 // ins v20.d[1], v15.d[1] .long 0x6e0d41d7 // ext v23.16b, v14.16b, v13.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e080514 // ins v20.d[0], v8.d[0] .long 0x6e180574 // ins v20.d[1], v11.d[0] .long 0x6e0c4197 // ext v23.16b, v12.16b, v12.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e084574 // ins v20.d[0], v11.d[1] .long 0x6e184534 // ins v20.d[1], v9.d[1] .long 0x6e080537 // ins v23.d[0], v9.d[0] .long 0x6e1845b7 // ins v23.d[1], v13.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -840,93 +757,81 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e0f41b4 // ext v20.16b, v13.16b, v15.16b, #8 .long 0x6e084517 // ins v23.d[0], v8.d[1] .long 0x6e184597 // ins v23.d[1], v12.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e084554 // ins v20.d[0], v10.d[1] .long 0x6e1845f4 // ins v20.d[1], v15.d[1] .long 0x6e080597 // ins v23.d[0], v12.d[0] .long 0x6e180537 // ins v23.d[1], v9.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e080514 // ins v20.d[0], v8.d[0] .long 0x6e180554 // ins v20.d[1], v10.d[0] .long 0x6e080577 // ins v23.d[0], v11.d[0] .long 0x6e1805b7 // ins v23.d[1], v13.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -952,90 +857,78 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e0845f4 // ins v20.d[0], v15.d[1] .long 0x6e184594 // ins v20.d[1], v12.d[1] .long 0x6e0c4137 // ext v23.16b, v9.16b, v12.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x4eae1dd4 // orr v20.16b, v14.16b, v14.16b .long 0x6e0d4117 // ext v23.16b, v8.16b, v13.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e080534 // ins v20.d[0], v9.d[0] .long 0x6e184574 // ins v20.d[1], v11.d[1] .long 0x4eaa1d57 // orr v23.16b, v10.16b, v10.16b - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -1062,93 +955,81 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e080534 // ins v20.d[0], v9.d[0] .long 0x6e180554 // ins v20.d[1], v10.d[0] .long 0x6e080577 // ins v23.d[0], v11.d[0] .long 0x6e184557 // ins v23.d[1], v10.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e0845f4 // ins v20.d[0], v15.d[1] .long 0x6e184594 // ins v20.d[1], v12.d[1] .long 0x6e084537 // ins v23.d[0], v9.d[1] .long 0x6e1845d7 // ins v23.d[1], v14.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e0f41b4 // ext v20.16b, v13.16b, v15.16b, #8 .long 0x6e0805d7 // ins v23.d[0], v14.d[0] .long 0x6e180517 // ins v23.d[1], v8.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -1175,94 +1056,82 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e084514 // ins v20.d[0], v8.d[1] .long 0x6e184534 // ins v20.d[1], v9.d[1] .long 0x6e084557 // ins v23.d[0], v10.d[1] .long 0x6e184577 // ins v23.d[1], v11.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e080594 // ins v20.d[0], v12.d[0] .long 0x6e1805b4 // ins v20.d[1], v13.d[0] .long 0x6e0805d7 // ins v23.d[0], v14.d[0] .long 0x6e1805f7 // ins v23.d[1], v15.d[0] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e084594 // ins v20.d[0], v12.d[1] .long 0x6e1845b4 // ins v20.d[1], v13.d[1] .long 0x6e0845d7 // ins v23.d[0], v14.d[1] .long 0x6e1845f7 // ins v23.d[1], v15.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b @@ -1289,92 +1158,80 @@ .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6f685455 // sli v21.2d, v2.2d, #40 + .long 0x6f680476 // ushr v22.2d, v3.2d, #24 + .long 0x6f685476 // sli v22.2d, v3.2d, #40 .long 0x6e0805b4 // ins v20.d[0], v13.d[0] .long 0x6e180594 // ins v20.d[1], v12.d[0] .long 0x6e0b41f7 // ext v23.16b, v15.16b, v11.16b, #8 - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x6e034055 // ext v21.16b, v2.16b, v3.16b, #8 - .long 0x6e024063 // ext v3.16b, v3.16b, v2.16b, #8 - .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b + .long 0x6f7004c2 // ushr v2.2d, v6.2d, #16 + .long 0x6f7054c2 // sli v2.2d, v6.2d, #48 + .long 0x6f7004e3 // ushr v3.2d, v7.2d, #16 + .long 0x6f7054e3 // sli v3.2d, v7.2d, #48 + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a6 // add v6.2d, v21.2d, v21.2d + .long 0x6f4146a6 // sri v6.2d, v21.2d, #63 + .long 0x4ef686c7 // add v7.2d, v22.2d, v22.2d + .long 0x6f4146c7 // sri v7.2d, v22.2d, #63 + .long 0x6e0740d5 // ext v21.16b, v6.16b, v7.16b, #8 + .long 0x6e0640e7 // ext v7.16b, v7.16b, v6.16b, #8 + .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b .long 0x4ea41c95 // orr v21.16b, v4.16b, v4.16b .long 0x4ea51ca4 // orr v4.16b, v5.16b, v5.16b .long 0x4eb51ea5 // orr v5.16b, v21.16b, v21.16b - .long 0x6e0640f5 // ext v21.16b, v7.16b, v6.16b, #8 - .long 0x6e0740c7 // ext v7.16b, v6.16b, v7.16b, #8 - .long 0x4eb51ea6 // orr v6.16b, v21.16b, v21.16b + .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 + .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 + .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b .long 0x6e084114 // ext v20.16b, v8.16b, v8.16b, #8 .long 0x6e0845b7 // ins v23.d[0], v13.d[1] .long 0x6e184557 // ins v23.d[1], v10.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ee68694 // add v20.2d, v20.2d, v6.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ee786f7 // add v23.2d, v23.2d, v7.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x4ea008c6 // rev64 v6.4s, v6.4s - .long 0x4ea008e7 // rev64 v7.4s, v7.4s - .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d - .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x6f680455 // ushr v21.2d, v2.2d, #24 - .long 0x4f685456 // shl v22.2d, v2.2d, #40 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x6f680475 // ushr v21.2d, v3.2d, #24 - .long 0x4f685476 // shl v22.2d, v3.2d, #40 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x4ea00842 // rev64 v2.4s, v2.4s + .long 0x4ea00863 // rev64 v3.4s, v3.4s + .long 0x4ee28484 // add v4.2d, v4.2d, v2.2d + .long 0x4ee384a5 // add v5.2d, v5.2d, v3.2d + .long 0x6e241cc6 // eor v6.16b, v6.16b, v4.16b + .long 0x6e251ce7 // eor v7.16b, v7.16b, v5.16b + .long 0x6f6804d5 // ushr v21.2d, v6.2d, #24 + .long 0x6f6854d5 // sli v21.2d, v6.2d, #40 + .long 0x6f6804f6 // ushr v22.2d, v7.2d, #24 + .long 0x6f6854f6 // sli v22.2d, v7.2d, #40 .long 0x6e0805d4 // ins v20.d[0], v14.d[0] .long 0x6e180534 // ins v20.d[1], v9.d[0] .long 0x6e084577 // ins v23.d[0], v11.d[1] .long 0x6e184537 // ins v23.d[1], v9.d[1] - .long 0x4ee28694 // add v20.2d, v20.2d, v2.2d + .long 0x4ef58694 // add v20.2d, v20.2d, v21.2d .long 0x4ef48400 // add v0.2d, v0.2d, v20.2d - .long 0x4ee386f7 // add v23.2d, v23.2d, v3.2d + .long 0x4ef686f7 // add v23.2d, v23.2d, v22.2d .long 0x4ef78421 // add v1.2d, v1.2d, v23.2d - .long 0x6e201cc6 // eor v6.16b, v6.16b, v0.16b - .long 0x6e211ce7 // eor v7.16b, v7.16b, v1.16b - .long 0x6f7004d5 // ushr v21.2d, v6.2d, #16 - .long 0x4f7054d6 // shl v22.2d, v6.2d, #48 - .long 0x4eb61ea6 // orr v6.16b, v21.16b, v22.16b - .long 0x6f7004f5 // ushr v21.2d, v7.2d, #16 - .long 0x4f7054f6 // shl v22.2d, v7.2d, #48 - .long 0x4eb61ea7 // orr v7.16b, v21.16b, v22.16b + .long 0x6e201c42 // eor v2.16b, v2.16b, v0.16b + .long 0x6e211c63 // eor v3.16b, v3.16b, v1.16b + .long 0x6f700446 // ushr v6.2d, v2.2d, #16 + .long 0x6f705446 // sli v6.2d, v2.2d, #48 + .long 0x6f700467 // ushr v7.2d, v3.2d, #16 + .long 0x6f705467 // sli v7.2d, v3.2d, #48 .long 0x4ee68484 // add v4.2d, v4.2d, v6.2d .long 0x4ee784a5 // add v5.2d, v5.2d, v7.2d - .long 0x6e241c42 // eor v2.16b, v2.16b, v4.16b - .long 0x6e251c63 // eor v3.16b, v3.16b, v5.16b - .long 0x4ee28455 // add v21.2d, v2.2d, v2.2d - .long 0x6f410456 // ushr v22.2d, v2.2d, #63 - .long 0x4eb61ea2 // orr v2.16b, v21.16b, v22.16b - .long 0x4ee38475 // add v21.2d, v3.2d, v3.2d - .long 0x6f410476 // ushr v22.2d, v3.2d, #63 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e241eb5 // eor v21.16b, v21.16b, v4.16b + .long 0x6e251ed6 // eor v22.16b, v22.16b, v5.16b + .long 0x4ef586a2 // add v2.2d, v21.2d, v21.2d + .long 0x6f4146a2 // sri v2.2d, v21.2d, #63 + .long 0x4ef686c3 // add v3.2d, v22.2d, v22.2d + .long 0x6f4146c3 // sri v3.2d, v22.2d, #63 .long 0x6e024075 // ext v21.16b, v3.16b, v2.16b, #8 .long 0x6e034043 // ext v3.16b, v2.16b, v3.16b, #8 .long 0x4eb51ea2 // orr v2.16b, v21.16b, v21.16b diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc similarity index 99% rename from HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc rename to HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc index 09ea743..3e248c9 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_i386.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc @@ -1,5 +1,5 @@ -// AVX2 implementation of BLAKE2s compress (IA-32; VEX-encoded 128-bit, fully -// unrolled 10 rounds). Same structure as Blake2SCompressAvx2_x86_64.inc, +// AVX (VEX-128) implementation of BLAKE2s compress (IA-32; fully unrolled +// 10 rounds). Same structure as Blake2SCompressAvx_x86_64.inc, // with the rot8 mask read as a VEX memory operand per site (IA-32 has only // xmm0-7, so no register is free to keep it resident; VEX memory operands // are read unaligned, so the Pascal const needs no special alignment). diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc similarity index 99% rename from HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc rename to HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc index 93381de..e12d64e 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc @@ -1,4 +1,4 @@ -// AVX2 implementation of BLAKE2s compress (VEX-encoded 128-bit, fully unrolled 10 rounds). +// AVX (VEX-128) implementation of BLAKE2s compress (fully unrolled 10 rounds). // Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, // r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr // (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc index 6d024a8..d9045a6 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc @@ -12,7 +12,8 @@ // v4-v7 = message block (16 x UInt32) // v16, v17 = saved initial row1/row2 for the final feed-forward XOR // v20 = message gather temp (G function) -// v21-v23 = rotate temps (ushr/shl/orr) +// v21-v23 = rotate temps (2-op ushr+sli rotates rename the rotated row +// through them; rows return home before the final feed-forward) .long 0xad400400 // ldp q0, q1, [x0] .long 0x4ea01c10 // orr v16.16b, v0.16b, v0.16b @@ -32,85 +33,76 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e042494 // ins v20.s[0], v4.s[1] .long 0x6e0c6494 // ins v20.s[1], v4.s[3] .long 0x6e1424b4 // ins v20.s[2], v5.s[1] .long 0x6e1c64b4 // ins v20.s[3], v5.s[3] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1662d6 // ext v22.16b, v22.16b, v22.16b, #12 .long 0x6e0404d4 // ins v20.s[0], v6.s[0] .long 0x6e0c44d4 // ins v20.s[1], v6.s[2] .long 0x6e1404f4 // ins v20.s[2], v7.s[0] .long 0x6e1c44f4 // ins v20.s[3], v7.s[2] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0424d4 // ins v20.s[0], v6.s[1] .long 0x6e0c64d4 // ins v20.s[1], v6.s[3] .long 0x6e1424f4 // ins v20.s[2], v7.s[1] .long 0x6e1c64f4 // ins v20.s[3], v7.s[3] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1522b5 // ext v21.16b, v21.16b, v21.16b, #4 .long 0x6e0444f4 // ins v20.s[0], v7.s[2] .long 0x6e0c04b4 // ins v20.s[1], v5.s[0] .long 0x6e1424d4 // ins v20.s[2], v6.s[1] .long 0x6e1c24f4 // ins v20.s[3], v7.s[1] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6e600ab5 // rev32 v21.8h, v21.8h + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340436 // ushr v22.4s, v1.4s, #12 + .long 0x6f345436 // sli v22.4s, v1.4s, #20 .long 0x6e0444d4 // ins v20.s[0], v6.s[2] .long 0x6e0c04d4 // ins v20.s[1], v6.s[0] .long 0x6e1464f4 // ins v20.s[2], v7.s[3] .long 0x6e1c44b4 // ins v20.s[3], v5.s[2] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb68694 // add v20.4s, v20.4s, v22.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6f3806a3 // ushr v3.4s, v21.4s, #8 + .long 0x6f3856a3 // sli v3.4s, v21.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6e221ed6 // eor v22.16b, v22.16b, v2.16b + .long 0x6f3906c1 // ushr v1.4s, v22.4s, #7 + .long 0x6f3956c1 // sli v1.4s, v22.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 @@ -125,85 +117,76 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e0404f4 // ins v20.s[0], v7.s[0] .long 0x6e0c4494 // ins v20.s[1], v4.s[2] .long 0x6e1464b4 // ins v20.s[2], v5.s[3] .long 0x6e1c6494 // ins v20.s[3], v4.s[3] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1622d6 // ext v22.16b, v22.16b, v22.16b, #4 .long 0x6e0464d4 // ins v20.s[0], v6.s[3] .long 0x6e0c04f4 // ins v20.s[1], v7.s[0] .long 0x6e1424b4 // ins v20.s[2], v5.s[1] .long 0x6e1c64f4 // ins v20.s[3], v7.s[3] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0404d4 // ins v20.s[0], v6.s[0] .long 0x6e0c0494 // ins v20.s[1], v4.s[0] .long 0x6e144494 // ins v20.s[2], v4.s[2] .long 0x6e1c24f4 // ins v20.s[3], v7.s[1] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1562b5 // ext v21.16b, v21.16b, v21.16b, #12 .long 0x6e0444d4 // ins v20.s[0], v6.s[2] .long 0x6e0c6494 // ins v20.s[1], v4.s[3] .long 0x6e1464b4 // ins v20.s[2], v5.s[3] .long 0x6e1c24d4 // ins v20.s[3], v6.s[1] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6e600ab5 // rev32 v21.8h, v21.8h + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340436 // ushr v22.4s, v1.4s, #12 + .long 0x6f345436 // sli v22.4s, v1.4s, #20 .long 0x6e0444f4 // ins v20.s[0], v7.s[2] .long 0x6e0c44b4 // ins v20.s[1], v5.s[2] .long 0x6e142494 // ins v20.s[2], v4.s[1] .long 0x6e1c04b4 // ins v20.s[3], v5.s[0] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb68694 // add v20.4s, v20.4s, v22.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6f3806a3 // ushr v3.4s, v21.4s, #8 + .long 0x6f3856a3 // sli v3.4s, v21.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6e221ed6 // eor v22.16b, v22.16b, v2.16b + .long 0x6f3906c1 // ushr v1.4s, v22.4s, #7 + .long 0x6f3956c1 // sli v1.4s, v22.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 @@ -218,85 +201,76 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e0424d4 // ins v20.s[0], v6.s[1] .long 0x6e0c2494 // ins v20.s[1], v4.s[1] .long 0x6e1404f4 // ins v20.s[2], v7.s[0] .long 0x6e1c44f4 // ins v20.s[3], v7.s[2] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1662d6 // ext v22.16b, v22.16b, v22.16b, #12 .long 0x6e044494 // ins v20.s[0], v4.s[2] .long 0x6e0c24b4 // ins v20.s[1], v5.s[1] .long 0x6e1404b4 // ins v20.s[2], v5.s[0] .long 0x6e1c64f4 // ins v20.s[3], v7.s[3] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0444b4 // ins v20.s[0], v5.s[2] .long 0x6e0c44d4 // ins v20.s[1], v6.s[2] .long 0x6e140494 // ins v20.s[2], v4.s[0] .long 0x6e1c04d4 // ins v20.s[3], v6.s[0] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1522b5 // ext v21.16b, v21.16b, v21.16b, #4 .long 0x6e0424d4 // ins v20.s[0], v6.s[1] .long 0x6e0c24b4 // ins v20.s[1], v5.s[1] .long 0x6e144494 // ins v20.s[2], v4.s[2] .long 0x6e1c44d4 // ins v20.s[3], v6.s[2] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6e600ab5 // rev32 v21.8h, v21.8h + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340436 // ushr v22.4s, v1.4s, #12 + .long 0x6f345436 // sli v22.4s, v1.4s, #20 .long 0x6e040494 // ins v20.s[0], v4.s[0] .long 0x6e0c64b4 // ins v20.s[1], v5.s[3] .long 0x6e1404b4 // ins v20.s[2], v5.s[0] .long 0x6e1c64f4 // ins v20.s[3], v7.s[3] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb68694 // add v20.4s, v20.4s, v22.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6f3806a3 // ushr v3.4s, v21.4s, #8 + .long 0x6f3856a3 // sli v3.4s, v21.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6e221ed6 // eor v22.16b, v22.16b, v2.16b + .long 0x6f3906c1 // ushr v1.4s, v22.4s, #7 + .long 0x6f3956c1 // sli v1.4s, v22.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 @@ -311,85 +285,76 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e042494 // ins v20.s[0], v4.s[1] .long 0x6e0c04f4 // ins v20.s[1], v7.s[0] .long 0x6e1404d4 // ins v20.s[2], v6.s[0] .long 0x6e1c24f4 // ins v20.s[3], v7.s[1] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1622d6 // ext v22.16b, v22.16b, v22.16b, #4 .long 0x6e044494 // ins v20.s[0], v4.s[2] .long 0x6e0c44b4 // ins v20.s[1], v5.s[2] .long 0x6e140494 // ins v20.s[2], v4.s[0] .long 0x6e1c04d4 // ins v20.s[3], v6.s[0] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0404f4 // ins v20.s[0], v7.s[0] .long 0x6e0c44d4 // ins v20.s[1], v6.s[2] .long 0x6e1464d4 // ins v20.s[2], v6.s[3] .long 0x6e1c6494 // ins v20.s[3], v4.s[3] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1562b5 // ext v21.16b, v21.16b, v21.16b, #12 .long 0x6e0404b4 // ins v20.s[0], v5.s[0] .long 0x6e0c64b4 // ins v20.s[1], v5.s[3] .long 0x6e1464f4 // ins v20.s[2], v7.s[3] .long 0x6e1c2494 // ins v20.s[3], v4.s[1] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6e600ab5 // rev32 v21.8h, v21.8h + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340436 // ushr v22.4s, v1.4s, #12 + .long 0x6f345436 // sli v22.4s, v1.4s, #20 .long 0x6e0424f4 // ins v20.s[0], v7.s[1] .long 0x6e0c24b4 // ins v20.s[1], v5.s[1] .long 0x6e1444f4 // ins v20.s[2], v7.s[2] .long 0x6e1c24d4 // ins v20.s[3], v6.s[1] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb68694 // add v20.4s, v20.4s, v22.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6f3806a3 // ushr v3.4s, v21.4s, #8 + .long 0x6f3856a3 // sli v3.4s, v21.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6e221ed6 // eor v22.16b, v22.16b, v2.16b + .long 0x6f3906c1 // ushr v1.4s, v22.4s, #7 + .long 0x6f3956c1 // sli v1.4s, v22.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 @@ -404,85 +369,76 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e0424b4 // ins v20.s[0], v5.s[1] .long 0x6e0c64f4 // ins v20.s[1], v7.s[3] .long 0x6e1424f4 // ins v20.s[2], v7.s[1] .long 0x6e1c44d4 // ins v20.s[3], v6.s[2] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1662d6 // ext v22.16b, v22.16b, v22.16b, #12 .long 0x6e040494 // ins v20.s[0], v4.s[0] .long 0x6e0c44b4 // ins v20.s[1], v5.s[2] .long 0x6e1424d4 // ins v20.s[2], v6.s[1] .long 0x6e1c04d4 // ins v20.s[3], v6.s[0] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0464b4 // ins v20.s[0], v5.s[3] .long 0x6e0c6494 // ins v20.s[1], v4.s[3] .long 0x6e144494 // ins v20.s[2], v4.s[2] .long 0x6e1c64d4 // ins v20.s[3], v6.s[3] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1522b5 // ext v21.16b, v21.16b, v21.16b, #4 .long 0x6e0424f4 // ins v20.s[0], v7.s[1] .long 0x6e0c64b4 // ins v20.s[1], v5.s[3] .long 0x6e1404f4 // ins v20.s[2], v7.s[0] .long 0x6e1c6494 // ins v20.s[3], v4.s[3] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6e600ab5 // rev32 v21.8h, v21.8h + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340436 // ushr v22.4s, v1.4s, #12 + .long 0x6f345436 // sli v22.4s, v1.4s, #20 .long 0x6e0464d4 // ins v20.s[0], v6.s[3] .long 0x6e0c44f4 // ins v20.s[1], v7.s[2] .long 0x6e142494 // ins v20.s[2], v4.s[1] .long 0x6e1c24d4 // ins v20.s[3], v6.s[1] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb68694 // add v20.4s, v20.4s, v22.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6f3806a3 // ushr v3.4s, v21.4s, #8 + .long 0x6f3856a3 // sli v3.4s, v21.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6e221ed6 // eor v22.16b, v22.16b, v2.16b + .long 0x6f3906c1 // ushr v1.4s, v22.4s, #7 + .long 0x6f3956c1 // sli v1.4s, v22.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 @@ -497,85 +453,76 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e040494 // ins v20.s[0], v4.s[0] .long 0x6e0c04b4 // ins v20.s[1], v5.s[0] .long 0x6e1444b4 // ins v20.s[2], v5.s[2] .long 0x6e1c44d4 // ins v20.s[3], v6.s[2] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1622d6 // ext v22.16b, v22.16b, v22.16b, #4 .long 0x6e0444b4 // ins v20.s[0], v5.s[2] .long 0x6e0c44f4 // ins v20.s[1], v7.s[2] .long 0x6e1464d4 // ins v20.s[2], v6.s[3] .long 0x6e1c0494 // ins v20.s[3], v4.s[0] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0464f4 // ins v20.s[0], v7.s[3] .long 0x6e0c24d4 // ins v20.s[1], v6.s[1] .long 0x6e146494 // ins v20.s[2], v4.s[3] .long 0x6e1c04d4 // ins v20.s[3], v6.s[0] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1562b5 // ext v21.16b, v21.16b, v21.16b, #12 .long 0x6e0404f4 // ins v20.s[0], v7.s[0] .long 0x6e0c24f4 // ins v20.s[1], v7.s[1] .long 0x6e142494 // ins v20.s[2], v4.s[1] .long 0x6e1c44d4 // ins v20.s[3], v6.s[2] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6e600ab5 // rev32 v21.8h, v21.8h + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340436 // ushr v22.4s, v1.4s, #12 + .long 0x6f345436 // sli v22.4s, v1.4s, #20 .long 0x6e044494 // ins v20.s[0], v4.s[2] .long 0x6e0c64b4 // ins v20.s[1], v5.s[3] .long 0x6e1404b4 // ins v20.s[2], v5.s[0] .long 0x6e1c24b4 // ins v20.s[3], v5.s[1] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb68694 // add v20.4s, v20.4s, v22.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b + .long 0x6e201eb5 // eor v21.16b, v21.16b, v0.16b + .long 0x6f3806a3 // ushr v3.4s, v21.4s, #8 + .long 0x6f3856a3 // sli v3.4s, v21.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6e221ed6 // eor v22.16b, v22.16b, v2.16b + .long 0x6f3906c1 // ushr v1.4s, v22.4s, #7 + .long 0x6f3956c1 // sli v1.4s, v22.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 @@ -590,57 +537,52 @@ .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f345435 // sli v21.4s, v1.4s, #20 .long 0x6e044494 // ins v20.s[0], v4.s[2] .long 0x6e0c04b4 // ins v20.s[1], v5.s[0] .long 0x6e1444b4 // ins v20.s[2], v5.s[2] .long 0x6e1c24b4 // ins v20.s[3], v5.s[1] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s + .long 0x4eb58694 // add v20.4s, v20.4s, v21.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f380476 // ushr v22.4s, v3.4s, #8 + .long 0x6f385476 // sli v22.4s, v3.4s, #24 + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s + .long 0x6e221eb5 // eor v21.16b, v21.16b, v2.16b + .long 0x6f3906a1 // ushr v1.4s, v21.4s, #7 + .long 0x6f3956a1 // sli v1.4s, v21.4s, #25 .long 0x6e012021 // ext v1.16b, v1.16b, v1.16b, #4 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e036063 // ext v3.16b, v3.16b, v3.16b, #12 + .long 0x6e1662d6 // ext v22.16b, v22.16b, v22.16b, #12 .long 0x6e0464f4 // ins v20.s[0], v7.s[3] .long 0x6e0c24d4 // ins v20.s[1], v6.s[1] .long 0x6e146494 // ins v20.s[2], v4.s[3] .long 0x6e1c24f4 // ins v20.s[3], v7.s[1] .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6e600ad6 // rev32 v22.8h, v22.8h + .long 0x4eb68442 // add v2.4s, v2.4s, v22.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f340435 // ushr v21.4s, v1.4s, #12 - .long 0x4f345436 // shl v22.4s, v1.4s, #20 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x6e0464d4 // ins v20.s[0], v6.s[3] .long 0x6e0c44f4 // ins v20.s[1], v7.s[2] .long 0x6e1404f4 // ins v20.s[2], v7.s[0] .long 0x6e1c0494 // ins v20.s[3], v4.s[0] - .long 0x4ea18694 // add v20.4s, v20.4s, v1.4s - .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380475 // ushr v21.4s, v3.4s, #8 - .long 0x4f385476 // shl v22.4s, v3.4s, #24 - .long 0x4eb61ea3 // orr v3.16b, v21.16b, v22.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x6f390435 // ushr v21.4s, v1.4s, #7 - .long 0x4f395436 // shl v22.4s, v1.4s, #25 - .long 0x4eb61ea1 // orr v1.16b, v21.16b, v22.16b + .long 0x4ea38694 // add v20.4s, v20.4s, v3.4s + .long 0x4eb48400 // add v0.4s, v0.4s, v20.4s + .long 0x6e201ed6 // eor v22.16b, v22.16b, v0.16b + .long 0x6f3806d5 // ushr v21.4s, v22.4s, #8 + .long 0x6f3856d5 // sli v21.4s, v22.4s, #24 + .long 0x4eb58442 // add v2.4s, v2.4s, v21.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e016021 // ext v1.16b, v1.16b, v1.16b, #12 .long 0x6e024042 // ext v2.16b, v2.16b, v2.16b, #8 - .long 0x6e032063 // ext v3.16b, v3.16b, v3.16b, #4 + .long 0x6e1522b5 // ext v21.16b, v21.16b, v21.16b, #4 + .long 0x4eb51ea3 // orr v3.16b, v21.16b, v21.16b .long 0x6e221c00 // eor v0.16b, v0.16b, v2.16b .long 0x6e201e00 // eor v0.16b, v16.16b, v0.16b .long 0x6e231c21 // eor v1.16b, v1.16b, v3.16b diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc similarity index 99% rename from HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc rename to HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc index b622420..2ff5db8 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc @@ -1,4 +1,4 @@ -// AVX2 implementation of BLAKE3 compress (VEX-encoded 128-bit, 7 rounds with register-based +// AVX (VEX-128) implementation of BLAKE3 compress (7 rounds with register-based // message scheduling). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE3-team/BLAKE3 official SSE2/AVX2 implementation. diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc index 3a4e9b0..540b75e 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc @@ -12,7 +12,7 @@ // v4-v7 = message schedule registers m0..m3 // v16-v17 = permute temps t8/t9; v17 saved to stack mid-permute when shufps // needs v17 as scratch (see [sp, #0] spill below) -// v18-v19 = rotate temps (vsri path) +// v18-v19 = rotate temps (2-op ushr+sli rotates rename rows b/d through them) // v20 = shufps / non-cyclic pshufd scratch (t14); cyclic diagonalize // shuffles use in-place 'ext' instead // Stack (128 bytes): [sp, #0] transient t9 (v17) spill during inter-round permute; @@ -64,49 +64,39 @@ .long 0x6e600863 // rev32 v3.8h, v3.8h .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340432 // ushr v18.4s, v1.4s, #12 + .long 0x6f345432 // sli v18.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s + .long 0x4eb28400 // add v0.4s, v0.4s, v18.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f380473 // ushr v19.4s, v3.4s, #8 + .long 0x6f385473 // sli v19.4s, v3.4s, #24 + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s + .long 0x6e221e52 // eor v18.16b, v18.16b, v2.16b + .long 0x6f390641 // ushr v1.4s, v18.4s, #7 + .long 0x6f395641 // sli v1.4s, v18.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e134273 // ext v19.16b, v19.16b, v19.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 .long 0x4ea68400 // add v0.4s, v0.4s, v6.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6e600a73 // rev32 v19.8h, v19.8h + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x4ea38400 // add v0.4s, v0.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6f380672 // ushr v18.4s, v19.4s, #8 + .long 0x6f385672 // sli v18.4s, v19.4s, #24 + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e124252 // ext v18.16b, v18.16b, v18.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 .long 0x4ea41c90 // orr v16.16b, v4.16b, v4.16b .long 0x6e044614 // ins v20.s[0], v16.s[2] @@ -163,26 +153,21 @@ .long 0x4eb01e06 // orr v6.16b, v16.16b, v16.16b .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6e600a52 // rev32 v18.8h, v18.8h + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340433 // ushr v19.4s, v1.4s, #12 + .long 0x6f345433 // sli v19.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b + .long 0x4eb38400 // add v0.4s, v0.4s, v19.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6f380643 // ushr v3.4s, v18.4s, #8 + .long 0x6f385643 // sli v3.4s, v18.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6e221e73 // eor v19.16b, v19.16b, v2.16b + .long 0x6f390661 // ushr v1.4s, v19.4s, #7 + .long 0x6f395661 // sli v1.4s, v19.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 @@ -192,24 +177,19 @@ .long 0x6e600863 // rev32 v3.8h, v3.8h .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340432 // ushr v18.4s, v1.4s, #12 + .long 0x6f345432 // sli v18.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s + .long 0x4eb28400 // add v0.4s, v0.4s, v18.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f380473 // ushr v19.4s, v3.4s, #8 + .long 0x6f385473 // sli v19.4s, v3.4s, #24 + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s + .long 0x6e221e52 // eor v18.16b, v18.16b, v2.16b + .long 0x6f390641 // ushr v1.4s, v18.4s, #7 + .long 0x6f395641 // sli v1.4s, v18.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e134273 // ext v19.16b, v19.16b, v19.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 .long 0x4ea41c90 // orr v16.16b, v4.16b, v4.16b .long 0x6e044614 // ins v20.s[0], v16.s[2] @@ -266,51 +246,41 @@ .long 0x4eb01e06 // orr v6.16b, v16.16b, v16.16b .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6e600a73 // rev32 v19.8h, v19.8h + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x4ea38400 // add v0.4s, v0.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6f380672 // ushr v18.4s, v19.4s, #8 + .long 0x6f385672 // sli v18.4s, v19.4s, #24 + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e124252 // ext v18.16b, v18.16b, v18.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 .long 0x4ea68400 // add v0.4s, v0.4s, v6.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6e600a52 // rev32 v18.8h, v18.8h + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340433 // ushr v19.4s, v1.4s, #12 + .long 0x6f345433 // sli v19.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b + .long 0x4eb38400 // add v0.4s, v0.4s, v19.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6f380643 // ushr v3.4s, v18.4s, #8 + .long 0x6f385643 // sli v3.4s, v18.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6e221e73 // eor v19.16b, v19.16b, v2.16b + .long 0x6f390661 // ushr v1.4s, v19.4s, #7 + .long 0x6f395661 // sli v1.4s, v19.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 @@ -373,49 +343,39 @@ .long 0x6e600863 // rev32 v3.8h, v3.8h .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340432 // ushr v18.4s, v1.4s, #12 + .long 0x6f345432 // sli v18.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s + .long 0x4eb28400 // add v0.4s, v0.4s, v18.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f380473 // ushr v19.4s, v3.4s, #8 + .long 0x6f385473 // sli v19.4s, v3.4s, #24 + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s + .long 0x6e221e52 // eor v18.16b, v18.16b, v2.16b + .long 0x6f390641 // ushr v1.4s, v18.4s, #7 + .long 0x6f395641 // sli v1.4s, v18.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e134273 // ext v19.16b, v19.16b, v19.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 .long 0x4ea68400 // add v0.4s, v0.4s, v6.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6e600a73 // rev32 v19.8h, v19.8h + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x4ea38400 // add v0.4s, v0.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6f380672 // ushr v18.4s, v19.4s, #8 + .long 0x6f385672 // sli v18.4s, v19.4s, #24 + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e124252 // ext v18.16b, v18.16b, v18.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 .long 0x4ea41c90 // orr v16.16b, v4.16b, v4.16b .long 0x6e044614 // ins v20.s[0], v16.s[2] @@ -472,26 +432,21 @@ .long 0x4eb01e06 // orr v6.16b, v16.16b, v16.16b .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6e600a52 // rev32 v18.8h, v18.8h + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340433 // ushr v19.4s, v1.4s, #12 + .long 0x6f345433 // sli v19.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b + .long 0x4eb38400 // add v0.4s, v0.4s, v19.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6f380643 // ushr v3.4s, v18.4s, #8 + .long 0x6f385643 // sli v3.4s, v18.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6e221e73 // eor v19.16b, v19.16b, v2.16b + .long 0x6f390661 // ushr v1.4s, v19.4s, #7 + .long 0x6f395661 // sli v1.4s, v19.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 @@ -501,24 +456,19 @@ .long 0x6e600863 // rev32 v3.8h, v3.8h .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340432 // ushr v18.4s, v1.4s, #12 + .long 0x6f345432 // sli v18.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s + .long 0x4eb28400 // add v0.4s, v0.4s, v18.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f380473 // ushr v19.4s, v3.4s, #8 + .long 0x6f385473 // sli v19.4s, v3.4s, #24 + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s + .long 0x6e221e52 // eor v18.16b, v18.16b, v2.16b + .long 0x6f390641 // ushr v1.4s, v18.4s, #7 + .long 0x6f395641 // sli v1.4s, v18.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e134273 // ext v19.16b, v19.16b, v19.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 .long 0x4ea41c90 // orr v16.16b, v4.16b, v4.16b .long 0x6e044614 // ins v20.s[0], v16.s[2] @@ -575,51 +525,41 @@ .long 0x4eb01e06 // orr v6.16b, v16.16b, v16.16b .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6e600a73 // rev32 v19.8h, v19.8h + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x4ea38400 // add v0.4s, v0.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6f380672 // ushr v18.4s, v19.4s, #8 + .long 0x6f385672 // sli v18.4s, v19.4s, #24 + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e124252 // ext v18.16b, v18.16b, v18.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 .long 0x4ea68400 // add v0.4s, v0.4s, v6.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6e600a52 // rev32 v18.8h, v18.8h + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340433 // ushr v19.4s, v1.4s, #12 + .long 0x6f345433 // sli v19.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b + .long 0x4eb38400 // add v0.4s, v0.4s, v19.4s + .long 0x6e201e52 // eor v18.16b, v18.16b, v0.16b + .long 0x6f380643 // ushr v3.4s, v18.4s, #8 + .long 0x6f385643 // sli v3.4s, v18.4s, #24 .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6e221e73 // eor v19.16b, v19.16b, v2.16b + .long 0x6f390661 // ushr v1.4s, v19.4s, #7 + .long 0x6f395661 // sli v1.4s, v19.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 @@ -682,50 +622,41 @@ .long 0x6e600863 // rev32 v3.8h, v3.8h .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340432 // ushr v18.4s, v1.4s, #12 + .long 0x6f345432 // sli v18.4s, v1.4s, #20 .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s + .long 0x4eb28400 // add v0.4s, v0.4s, v18.4s .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f380473 // ushr v19.4s, v3.4s, #8 + .long 0x6f385473 // sli v19.4s, v3.4s, #24 + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s + .long 0x6e221e52 // eor v18.16b, v18.16b, v2.16b + .long 0x6f390641 // ushr v1.4s, v18.4s, #7 + .long 0x6f395641 // sli v1.4s, v18.4s, #25 .long 0x6e006000 // ext v0.16b, v0.16b, v0.16b, #12 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e134273 // ext v19.16b, v19.16b, v19.16b, #8 .long 0x6e022042 // ext v2.16b, v2.16b, v2.16b, #4 .long 0x4ea68400 // add v0.4s, v0.4s, v6.4s .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6e600863 // rev32 v3.8h, v3.8h - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6e600a73 // rev32 v19.8h, v19.8h + .long 0x4eb38442 // add v2.4s, v2.4s, v19.4s .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344432 // sri v18.4s, v1.4s, #12 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x6f340423 // ushr v3.4s, v1.4s, #12 + .long 0x6f345423 // sli v3.4s, v1.4s, #20 .long 0x4ea78400 // add v0.4s, v0.4s, v7.4s - .long 0x4ea18400 // add v0.4s, v0.4s, v1.4s - .long 0x6e201c63 // eor v3.16b, v3.16b, v0.16b - .long 0x6f380472 // ushr v18.4s, v3.4s, #8 - .long 0x4f385473 // shl v19.4s, v3.4s, #24 - .long 0x4eb31e43 // orr v3.16b, v18.16b, v19.16b - .long 0x4ea38442 // add v2.4s, v2.4s, v3.4s - .long 0x6e221c21 // eor v1.16b, v1.16b, v2.16b - .long 0x4ea11c32 // orr v18.16b, v1.16b, v1.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394432 // sri v18.4s, v1.4s, #7 - .long 0x4eb21e41 // orr v1.16b, v18.16b, v18.16b + .long 0x4ea38400 // add v0.4s, v0.4s, v3.4s + .long 0x6e201e73 // eor v19.16b, v19.16b, v0.16b + .long 0x6f380672 // ushr v18.4s, v19.4s, #8 + .long 0x6f385672 // sli v18.4s, v19.4s, #24 + .long 0x4eb28442 // add v2.4s, v2.4s, v18.4s + .long 0x6e221c63 // eor v3.16b, v3.16b, v2.16b + .long 0x6f390461 // ushr v1.4s, v3.4s, #7 + .long 0x6f395461 // sli v1.4s, v3.4s, #25 .long 0x6e002000 // ext v0.16b, v0.16b, v0.16b, #4 - .long 0x6e034063 // ext v3.16b, v3.16b, v3.16b, #8 + .long 0x6e124252 // ext v18.16b, v18.16b, v18.16b, #8 .long 0x6e026042 // ext v2.16b, v2.16b, v2.16b, #12 + .long 0x4eb21e43 // orr v3.16b, v18.16b, v18.16b .long 0x6e221c00 // eor v0.16b, v0.16b, v2.16b .long 0x6e231c21 // eor v1.16b, v1.16b, v3.16b .long 0xad404450 // ldp q16, q17, [x2] diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc index 2aec258..3763f14 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc @@ -9,7 +9,8 @@ // v0-v7 = state v0..v7 (CV rows, 4-wide) // v8-v11 = state v8..v11 (IV rows, updated each round) // v16-v17 = G temps (v12/v13 analog; d lane spilled via stack v12-v15 slots) -// v18-v19 = rotate temps (vsri path inside G) +// v16-v17 double as G temps; every rotate is the 2-op insert form and the +// rotating values (d and b) migrate v_b -> t13 -> v_b within each G // v20-v23 = transpose / block temps // x19 = block index (0..15), x20 = block byte offset within chunk // Stack frame 720 bytes (712B SSE2 layout + 8B align): @@ -203,24 +204,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc007f1 // ldr q17, [sp, #16] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc007e4 // ldr q4, [sp, #16] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc00bf1 // ldr q17, [sp, #32] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -229,24 +225,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc00ff1 // ldr q17, [sp, #48] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc00fe5 // ldr q5, [sp, #48] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc013f1 // ldr q17, [sp, #64] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -255,24 +246,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc017f1 // ldr q17, [sp, #80] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc017e6 // ldr q6, [sp, #80] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc01bf1 // ldr q17, [sp, #96] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -281,24 +267,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc01ff1 // ldr q17, [sp, #112] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc01fe7 // ldr q7, [sp, #112] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc023f1 // ldr q17, [sp, #128] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -307,24 +288,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc027f1 // ldr q17, [sp, #144] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc027e5 // ldr q5, [sp, #144] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc02bf1 // ldr q17, [sp, #160] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -333,24 +309,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc02ff1 // ldr q17, [sp, #176] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc02fe6 // ldr q6, [sp, #176] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc033f1 // ldr q17, [sp, #192] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -359,24 +330,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc037f1 // ldr q17, [sp, #208] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc037e7 // ldr q7, [sp, #208] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc03bf1 // ldr q17, [sp, #224] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -385,24 +351,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc03ff1 // ldr q17, [sp, #240] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc03fe4 // ldr q4, [sp, #240] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc00bf1 // ldr q17, [sp, #32] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -411,24 +372,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc01bf1 // ldr q17, [sp, #96] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc01be4 // ldr q4, [sp, #96] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc00ff1 // ldr q17, [sp, #48] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -437,24 +393,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc02bf1 // ldr q17, [sp, #160] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc02be5 // ldr q5, [sp, #160] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc01ff1 // ldr q17, [sp, #112] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -463,24 +414,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc003f1 // ldr q17, [sp, #0] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc003e6 // ldr q6, [sp, #0] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc013f1 // ldr q17, [sp, #64] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -489,24 +435,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc037f1 // ldr q17, [sp, #208] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc037e7 // ldr q7, [sp, #208] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc007f1 // ldr q17, [sp, #16] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -515,24 +456,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc02ff1 // ldr q17, [sp, #176] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc02fe5 // ldr q5, [sp, #176] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc033f1 // ldr q17, [sp, #192] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -541,24 +477,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc017f1 // ldr q17, [sp, #80] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc017e6 // ldr q6, [sp, #80] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc027f1 // ldr q17, [sp, #144] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -567,24 +498,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc03bf1 // ldr q17, [sp, #224] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc03be7 // ldr q7, [sp, #224] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc03ff1 // ldr q17, [sp, #240] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -593,24 +519,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc023f1 // ldr q17, [sp, #128] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc023e4 // ldr q4, [sp, #128] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc00ff1 // ldr q17, [sp, #48] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -619,24 +540,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc013f1 // ldr q17, [sp, #64] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc013e4 // ldr q4, [sp, #64] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc02bf1 // ldr q17, [sp, #160] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -645,24 +561,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc033f1 // ldr q17, [sp, #192] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc033e5 // ldr q5, [sp, #192] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc037f1 // ldr q17, [sp, #208] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -671,24 +582,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc00bf1 // ldr q17, [sp, #32] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc00be6 // ldr q6, [sp, #32] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc01ff1 // ldr q17, [sp, #112] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -697,24 +603,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc03bf1 // ldr q17, [sp, #224] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc03be7 // ldr q7, [sp, #224] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc01bf1 // ldr q17, [sp, #96] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -723,24 +624,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc017f1 // ldr q17, [sp, #80] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc017e5 // ldr q5, [sp, #80] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc027f1 // ldr q17, [sp, #144] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -749,24 +645,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc003f1 // ldr q17, [sp, #0] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc003e6 // ldr q6, [sp, #0] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc02ff1 // ldr q17, [sp, #176] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -775,24 +666,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc03ff1 // ldr q17, [sp, #240] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc03fe7 // ldr q7, [sp, #240] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc023f1 // ldr q17, [sp, #128] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -801,24 +687,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc007f1 // ldr q17, [sp, #16] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc007e4 // ldr q4, [sp, #16] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc02bf1 // ldr q17, [sp, #160] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -827,24 +708,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc01ff1 // ldr q17, [sp, #112] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc01fe4 // ldr q4, [sp, #112] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc033f1 // ldr q17, [sp, #192] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -853,24 +729,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc027f1 // ldr q17, [sp, #144] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc027e5 // ldr q5, [sp, #144] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc03bf1 // ldr q17, [sp, #224] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -879,24 +750,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc00ff1 // ldr q17, [sp, #48] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc00fe6 // ldr q6, [sp, #48] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc037f1 // ldr q17, [sp, #208] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -905,24 +771,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc03ff1 // ldr q17, [sp, #240] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc03fe7 // ldr q7, [sp, #240] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc013f1 // ldr q17, [sp, #64] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -931,24 +792,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc003f1 // ldr q17, [sp, #0] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc003e5 // ldr q5, [sp, #0] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc02ff1 // ldr q17, [sp, #176] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -957,24 +813,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc00bf1 // ldr q17, [sp, #32] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc00be6 // ldr q6, [sp, #32] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc017f1 // ldr q17, [sp, #80] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -983,24 +834,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc023f1 // ldr q17, [sp, #128] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc023e7 // ldr q7, [sp, #128] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc007f1 // ldr q17, [sp, #16] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1009,24 +855,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc01bf1 // ldr q17, [sp, #96] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc01be4 // ldr q4, [sp, #96] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc033f1 // ldr q17, [sp, #192] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -1035,24 +876,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc037f1 // ldr q17, [sp, #208] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc037e4 // ldr q4, [sp, #208] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc027f1 // ldr q17, [sp, #144] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -1061,24 +897,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc02ff1 // ldr q17, [sp, #176] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc02fe5 // ldr q5, [sp, #176] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc03ff1 // ldr q17, [sp, #240] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -1087,24 +918,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc02bf1 // ldr q17, [sp, #160] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc02be6 // ldr q6, [sp, #160] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc03bf1 // ldr q17, [sp, #224] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1113,24 +939,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc023f1 // ldr q17, [sp, #128] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc023e7 // ldr q7, [sp, #128] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc01ff1 // ldr q17, [sp, #112] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -1139,24 +960,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc00bf1 // ldr q17, [sp, #32] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc00be5 // ldr q5, [sp, #32] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc017f1 // ldr q17, [sp, #80] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -1165,24 +981,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc00ff1 // ldr q17, [sp, #48] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc00fe6 // ldr q6, [sp, #48] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc003f1 // ldr q17, [sp, #0] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -1191,24 +1002,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc007f1 // ldr q17, [sp, #16] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc007e7 // ldr q7, [sp, #16] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc01bf1 // ldr q17, [sp, #96] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1217,24 +1023,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc013f1 // ldr q17, [sp, #64] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc013e4 // ldr q4, [sp, #64] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc027f1 // ldr q17, [sp, #144] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -1243,24 +1044,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc03bf1 // ldr q17, [sp, #224] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc03be4 // ldr q4, [sp, #224] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc02ff1 // ldr q17, [sp, #176] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -1269,24 +1065,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc017f1 // ldr q17, [sp, #80] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc017e5 // ldr q5, [sp, #80] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc023f1 // ldr q17, [sp, #128] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -1295,24 +1086,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc033f1 // ldr q17, [sp, #192] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc033e6 // ldr q6, [sp, #192] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc03ff1 // ldr q17, [sp, #240] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1321,24 +1107,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc007f1 // ldr q17, [sp, #16] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc007e7 // ldr q7, [sp, #16] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc037f1 // ldr q17, [sp, #208] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -1347,24 +1128,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc00ff1 // ldr q17, [sp, #48] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc00fe5 // ldr q5, [sp, #48] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc003f1 // ldr q17, [sp, #0] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -1373,24 +1149,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc02bf1 // ldr q17, [sp, #160] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc02be6 // ldr q6, [sp, #160] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc00bf1 // ldr q17, [sp, #32] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -1399,24 +1170,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc01bf1 // ldr q17, [sp, #96] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc01be7 // ldr q7, [sp, #96] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc013f1 // ldr q17, [sp, #64] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1425,24 +1191,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc01ff1 // ldr q17, [sp, #112] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc01fe4 // ldr q4, [sp, #112] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc02ff1 // ldr q17, [sp, #176] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -1451,24 +1212,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc03ff1 // ldr q17, [sp, #240] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc03fe4 // ldr q4, [sp, #240] .long 0x4ea48400 // add v0.4s, v0.4s, v4.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281c84 // eor v4.16b, v4.16b, v8.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48508 // add v8.4s, v8.4s, v4.4s + .long 0x3d8043e4 // str q4, [sp, #256] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc017f1 // ldr q17, [sp, #80] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -1477,24 +1233,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc003f1 // ldr q17, [sp, #0] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc003e5 // ldr q5, [sp, #0] .long 0x4ea58421 // add v1.4s, v1.4s, v5.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291ca5 // eor v5.16b, v5.16b, v9.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea58529 // add v9.4s, v9.4s, v5.4s + .long 0x3d8047e5 // str q5, [sp, #272] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc007f1 // ldr q17, [sp, #16] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -1503,24 +1254,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc027f1 // ldr q17, [sp, #144] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc027e6 // ldr q6, [sp, #144] .long 0x4ea68442 // add v2.4s, v2.4s, v6.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1cc6 // eor v6.16b, v6.16b, v10.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6854a // add v10.4s, v10.4s, v6.4s + .long 0x3d804be6 // str q6, [sp, #288] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc023f1 // ldr q17, [sp, #128] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1529,24 +1275,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc01bf1 // ldr q17, [sp, #96] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc01be7 // ldr q7, [sp, #96] .long 0x4ea78463 // add v3.4s, v3.4s, v7.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1ce7 // eor v7.16b, v7.16b, v11.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea7856b // add v11.4s, v11.4s, v7.4s + .long 0x3d804fe7 // str q7, [sp, #304] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04ff0 // ldr q16, [sp, #304] .long 0x3dc03bf1 // ldr q17, [sp, #224] .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s @@ -1555,24 +1296,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444b2 // sri v18.4s, v5.4s, #12 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3dc02bf1 // ldr q17, [sp, #160] - .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s + .long 0x4f3454b1 // shl v17.4s, v5.4s, #20 + .long 0x6f3444b1 // sri v17.4s, v5.4s, #12 + .long 0x3dc02be5 // ldr q5, [sp, #160] .long 0x4ea58400 // add v0.4s, v0.4s, v5.4s + .long 0x4eb18400 // add v0.4s, v0.4s, v17.4s .long 0x6e201e10 // eor v16.16b, v16.16b, v0.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0854a // add v10.4s, v10.4s, v16.4s - .long 0x6e2a1ca5 // eor v5.16b, v5.16b, v10.16b - .long 0x4ea51cb2 // orr v18.16b, v5.16b, v5.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944b2 // sri v18.4s, v5.4s, #7 - .long 0x4eb21e45 // orr v5.16b, v18.16b, v18.16b - .long 0x3d804ff0 // str q16, [sp, #304] + .long 0x6f380605 // ushr v5.4s, v16.4s, #8 + .long 0x6f385605 // sli v5.4s, v16.4s, #24 + .long 0x4ea5854a // add v10.4s, v10.4s, v5.4s + .long 0x3d804fe5 // str q5, [sp, #304] + .long 0x6e2a1e31 // eor v17.16b, v17.16b, v10.16b + .long 0x4f395625 // shl v5.4s, v17.4s, #25 + .long 0x6f394625 // sri v5.4s, v17.4s, #7 .long 0x3dc043f0 // ldr q16, [sp, #256] .long 0x3dc00bf1 // ldr q17, [sp, #32] .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s @@ -1581,24 +1317,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444d2 // sri v18.4s, v6.4s, #12 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3dc033f1 // ldr q17, [sp, #192] - .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s + .long 0x4f3454d1 // shl v17.4s, v6.4s, #20 + .long 0x6f3444d1 // sri v17.4s, v6.4s, #12 + .long 0x3dc033e6 // ldr q6, [sp, #192] .long 0x4ea68421 // add v1.4s, v1.4s, v6.4s + .long 0x4eb18421 // add v1.4s, v1.4s, v17.4s .long 0x6e211e10 // eor v16.16b, v16.16b, v1.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb0856b // add v11.4s, v11.4s, v16.4s - .long 0x6e2b1cc6 // eor v6.16b, v6.16b, v11.16b - .long 0x4ea61cd2 // orr v18.16b, v6.16b, v6.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944d2 // sri v18.4s, v6.4s, #7 - .long 0x4eb21e46 // orr v6.16b, v18.16b, v18.16b - .long 0x3d8043f0 // str q16, [sp, #256] + .long 0x6f380606 // ushr v6.4s, v16.4s, #8 + .long 0x6f385606 // sli v6.4s, v16.4s, #24 + .long 0x4ea6856b // add v11.4s, v11.4s, v6.4s + .long 0x3d8043e6 // str q6, [sp, #256] + .long 0x6e2b1e31 // eor v17.16b, v17.16b, v11.16b + .long 0x4f395626 // shl v6.4s, v17.4s, #25 + .long 0x6f394626 // sri v6.4s, v17.4s, #7 .long 0x3dc047f0 // ldr q16, [sp, #272] .long 0x3dc00ff1 // ldr q17, [sp, #48] .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s @@ -1607,24 +1338,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f3444f2 // sri v18.4s, v7.4s, #12 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3dc013f1 // ldr q17, [sp, #64] - .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s + .long 0x4f3454f1 // shl v17.4s, v7.4s, #20 + .long 0x6f3444f1 // sri v17.4s, v7.4s, #12 + .long 0x3dc013e7 // ldr q7, [sp, #64] .long 0x4ea78442 // add v2.4s, v2.4s, v7.4s + .long 0x4eb18442 // add v2.4s, v2.4s, v17.4s .long 0x6e221e10 // eor v16.16b, v16.16b, v2.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08508 // add v8.4s, v8.4s, v16.4s - .long 0x6e281ce7 // eor v7.16b, v7.16b, v8.16b - .long 0x4ea71cf2 // orr v18.16b, v7.16b, v7.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f3944f2 // sri v18.4s, v7.4s, #7 - .long 0x4eb21e47 // orr v7.16b, v18.16b, v18.16b - .long 0x3d8047f0 // str q16, [sp, #272] + .long 0x6f380607 // ushr v7.4s, v16.4s, #8 + .long 0x6f385607 // sli v7.4s, v16.4s, #24 + .long 0x4ea78508 // add v8.4s, v8.4s, v7.4s + .long 0x3d8047e7 // str q7, [sp, #272] + .long 0x6e281e31 // eor v17.16b, v17.16b, v8.16b + .long 0x4f395627 // shl v7.4s, v17.4s, #25 + .long 0x6f394627 // sri v7.4s, v17.4s, #7 .long 0x3dc04bf0 // ldr q16, [sp, #288] .long 0x3dc01ff1 // ldr q17, [sp, #112] .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s @@ -1633,24 +1359,19 @@ .long 0x6e600a10 // rev32 v16.8h, v16.8h .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f345652 // shl v18.4s, v18.4s, #20 - .long 0x6f344492 // sri v18.4s, v4.4s, #12 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3dc037f1 // ldr q17, [sp, #208] - .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s + .long 0x4f345491 // shl v17.4s, v4.4s, #20 + .long 0x6f344491 // sri v17.4s, v4.4s, #12 + .long 0x3dc037e4 // ldr q4, [sp, #208] .long 0x4ea48463 // add v3.4s, v3.4s, v4.4s + .long 0x4eb18463 // add v3.4s, v3.4s, v17.4s .long 0x6e231e10 // eor v16.16b, v16.16b, v3.16b - .long 0x6f380612 // ushr v18.4s, v16.4s, #8 - .long 0x4f385613 // shl v19.4s, v16.4s, #24 - .long 0x4eb31e50 // orr v16.16b, v18.16b, v19.16b - .long 0x4eb08529 // add v9.4s, v9.4s, v16.4s - .long 0x6e291c84 // eor v4.16b, v4.16b, v9.16b - .long 0x4ea41c92 // orr v18.16b, v4.16b, v4.16b - .long 0x4f395652 // shl v18.4s, v18.4s, #25 - .long 0x6f394492 // sri v18.4s, v4.4s, #7 - .long 0x4eb21e44 // orr v4.16b, v18.16b, v18.16b - .long 0x3d804bf0 // str q16, [sp, #288] + .long 0x6f380604 // ushr v4.4s, v16.4s, #8 + .long 0x6f385604 // sli v4.4s, v16.4s, #24 + .long 0x4ea48529 // add v9.4s, v9.4s, v4.4s + .long 0x3d804be4 // str q4, [sp, #288] + .long 0x6e291e31 // eor v17.16b, v17.16b, v9.16b + .long 0x4f395624 // shl v4.4s, v17.4s, #25 + .long 0x6f394624 // sri v4.4s, v17.4s, #7 .long 0x6e281c00 // eor v0.16b, v0.16b, v8.16b .long 0x6e291c21 // eor v1.16b, v1.16b, v9.16b .long 0x6e2a1c42 // eor v2.16b, v2.16b, v10.16b diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc similarity index 98% rename from HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc rename to HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc index 5128fb1..ce9d58c 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc @@ -1,5 +1,5 @@ // MSB-first 64-bit CRC: 16-byte slice (IA-32; SSE2 not required — same as x64 MSB path). -// x64 counterpart: CRCFoldForwardSse2_x86_64.inc. +// x64 counterpart: CRCFoldForwardGpr_x86_64.inc. // After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength, edi = AState, eax = Ctx. // Ctx: FoldConstants.CrcBits at +80, TableRow at +96. CrcMask derived from width. // Result UInt64 in edx:eax. diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc similarity index 87% rename from HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc rename to HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc index 80aef2a..391c552 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc @@ -1,7 +1,8 @@ -// MSB-first 64-bit CRC: 16-byte slice (slicing-by-16) using SSE2 for load only. -// IA-32 counterpart: CRCFoldForwardSse2_i386.inc. +// MSB-first 64-bit CRC: 16-byte slice (slicing-by-16), pure GPR - no vector +// instructions (the Gpr name states the ISA requirement: none beyond base x86-64). +// IA-32 counterpart: CRCFoldForwardGpr_i386.inc. // Signature (after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; +// function CRC_Fold_Forward_Gpr(AData: PByte; ALength: UInt32; // AState: Pointer; AConstants: Pointer): UInt64; // MS x64: rcx=AData, edx=ALength, r8=AState, r9=Ctx. // Callee-saved: rsi/rdi must be preserved (used as LTempCopy / LBIdx scratch). diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc index e8612d1..9e1efac 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc @@ -1,4 +1,6 @@ // Reflected (LSB-first) 64-bit CRC: 16-byte slice (IA-32 SSE2 + GPR table XOR). +// GPR slicing core; SSE2 is genuinely required for the 128-bit loads and the +// CRC state shuttle - the Sse2 name states the ISA requirement. // After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength, edi = AState, eax = Ctx. // TableRow[i] at Ctx + 96; each entry is a 32-bit (untyped) Pointer. // Result UInt64 in edx:eax (high:low). Preserves Delphi/FPC i386 frame via push/pop ebp. diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc index 3aa4034..47cd99d 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc @@ -1,4 +1,6 @@ // Reflected (LSB-first) 64-bit CRC: 16-byte slice using SSE2 loads + GPR table XOR. +// GPR slicing core; SSE2 is genuinely required for the 128-bit loads and the +// CRC state shuttle - the Sse2 name states the ISA requirement. // Signature (after HlpSimdProc4Begin_x86_64.inc): // function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; // AState: Pointer; AConstants: Pointer): UInt64; diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc similarity index 99% rename from HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc rename to HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc index 10a8b4d..9a98708 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_i386.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc @@ -1,7 +1,6 @@ // SHA-1 AVX SIMD-schedule implementation (IA-32). VEX-128 (AVX1) -// instructions only - there is no i386 AVX2 SHA-1 upstream - dispatched at -// the AVX2 tier (every AVX2 CPU has AVX1; AVX1-only CPUs fall to the SSSE3 -// tier). The 3-operand VEX forms eliminate the SSSE3 kernel's register-copy +// instructions only - there is no i386 AVX2 SHA-1 upstream. The 3-operand +// VEX forms eliminate the SSSE3 kernel's register-copy // movdqa traffic in the interleaved message schedule. All VEX instructions // are db-encoded for broad assembler compatibility. // The four round constants and the byte-swap mask are read from diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc new file mode 100644 index 0000000..e5617ff --- /dev/null +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc @@ -0,0 +1,1038 @@ +// SHA-1 pure-GPR implementation (AArch64) for cores without the SHA-1 +// crypto extension; the Gpr name states the ISA requirement: none beyond +// base AArch64. Serial SHA maps better onto the 31 GPRs than onto NEON +// lanes (single dependency chain, 1-op ror, rotate-folded eor operands). +// The four round constants are materialized as movz/movk immediates - no +// K table is read. +// Expects AAPCS64 (after HlpSimdProc3Begin_aarch64): x0 = state ptr +// (5 x UInt32), x1 = data ptr, w2 = numblocks. +// Frame: 96-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved). +// AArch64 instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha1-armv8.pl (sha1_block_data_order, the +// plain path). + + .long 0x2a0203e2 // mov w2,w2 // zero-extend ANumBlocks (AAPCS64 leaves x2's top half undefined) + + .long 0xa9ba7bfd // stp x29,x30,[sp,#-96]! + .long 0x910003fd // add x29,sp,#0 + .long 0xa90153f3 // stp x19,x20,[sp,#16] + .long 0xa9025bf5 // stp x21,x22,[sp,#32] + .long 0xa90363f7 // stp x23,x24,[sp,#48] + .long 0xa9046bf9 // stp x25,x26,[sp,#64] + .long 0xa90573fb // stp x27,x28,[sp,#80] + + .long 0x29405414 // ldp w20,w21,[x0] + .long 0x29415c16 // ldp w22,w23,[x0,#8] + .long 0xb9401018 // ldr w24,[x0,#16] + + +.Lsha1_gpr_loop: + .long 0xf8440423 // ldr x3,[x1],#64 + .long 0x528f333c // movz w28,#0x7999 + .long 0xd1000442 // sub x2,x2,#1 + .long 0x72ab505c // movk w28,#0x5a82, lsl #16 + .long 0xdac00863 // rev32 x3,x3 + .long 0x0b1c0318 // add w24,w24,w28 // warm it up + .long 0x0b030318 // add w24,w24,w3 + .long 0xd360fc64 // lsr x4,x3,#32 + .long 0xf85c8025 // ldr x5,[x1,#-56] + .long 0x0a3502f9 // bic w25,w23,w21 + .long 0x0a1502da // and w26,w22,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x0b0402f7 // add w23,w23,w4 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0xdac008a5 // rev32 x5,x5 + .long 0x0a3402d9 // bic w25,w22,w20 + .long 0x0a1402ba // and w26,w21,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x0b0502d6 // add w22,w22,w5 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0xd360fca6 // lsr x6,x5,#32 + .long 0xf85d0027 // ldr x7,[x1,#-48] + .long 0x0a3802b9 // bic w25,w21,w24 + .long 0x0a18029a // and w26,w20,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x0b0602b5 // add w21,w21,w6 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0xdac008e7 // rev32 x7,x7 + .long 0x0a370299 // bic w25,w20,w23 + .long 0x0a17031a // and w26,w24,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x0b070294 // add w20,w20,w7 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0xd360fce8 // lsr x8,x7,#32 + .long 0xf85d8029 // ldr x9,[x1,#-40] + .long 0x0a360319 // bic w25,w24,w22 + .long 0x0a1602fa // and w26,w23,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x0b080318 // add w24,w24,w8 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0xdac00929 // rev32 x9,x9 + .long 0x0a3502f9 // bic w25,w23,w21 + .long 0x0a1502da // and w26,w22,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x0b0902f7 // add w23,w23,w9 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0xd360fd2a // lsr x10,x9,#32 + .long 0xf85e002b // ldr x11,[x1,#-32] + .long 0x0a3402d9 // bic w25,w22,w20 + .long 0x0a1402ba // and w26,w21,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x0b0a02d6 // add w22,w22,w10 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0xdac0096b // rev32 x11,x11 + .long 0x0a3802b9 // bic w25,w21,w24 + .long 0x0a18029a // and w26,w20,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x0b0b02b5 // add w21,w21,w11 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0xd360fd6c // lsr x12,x11,#32 + .long 0xf85e802d // ldr x13,[x1,#-24] + .long 0x0a370299 // bic w25,w20,w23 + .long 0x0a17031a // and w26,w24,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x0b0c0294 // add w20,w20,w12 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0xdac009ad // rev32 x13,x13 + .long 0x0a360319 // bic w25,w24,w22 + .long 0x0a1602fa // and w26,w23,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x0b0d0318 // add w24,w24,w13 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0xd360fdae // lsr x14,x13,#32 + .long 0xf85f002f // ldr x15,[x1,#-16] + .long 0x0a3502f9 // bic w25,w23,w21 + .long 0x0a1502da // and w26,w22,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x0b0e02f7 // add w23,w23,w14 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0xdac009ef // rev32 x15,x15 + .long 0x0a3402d9 // bic w25,w22,w20 + .long 0x0a1402ba // and w26,w21,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x0b0f02d6 // add w22,w22,w15 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0xd360fdf0 // lsr x16,x15,#32 + .long 0xf85f8031 // ldr x17,[x1,#-8] + .long 0x0a3802b9 // bic w25,w21,w24 + .long 0x0a18029a // and w26,w20,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x0b1002b5 // add w21,w21,w16 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0xdac00a31 // rev32 x17,x17 + .long 0x0a370299 // bic w25,w20,w23 + .long 0x0a17031a // and w26,w24,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x0b110294 // add w20,w20,w17 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0xd360fe33 // lsr x19,x17,#32 + .long 0x4a050063 // eor w3,w3,w5 + .long 0x0a360319 // bic w25,w24,w22 + .long 0x0a1602fa // and w26,w23,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x4a0b0063 // eor w3,w3,w11 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x4a100063 // eor w3,w3,w16 + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x0b130318 // add w24,w24,w19 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13837c63 // ror w3,w3,#31 + .long 0x4a060084 // eor w4,w4,w6 + .long 0x0a3502f9 // bic w25,w23,w21 + .long 0x0a1502da // and w26,w22,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x4a0c0084 // eor w4,w4,w12 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x4a110084 // eor w4,w4,w17 + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x0b0302f7 // add w23,w23,w3 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13847c84 // ror w4,w4,#31 + .long 0x4a0700a5 // eor w5,w5,w7 + .long 0x0a3402d9 // bic w25,w22,w20 + .long 0x0a1402ba // and w26,w21,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x4a0d00a5 // eor w5,w5,w13 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x4a1300a5 // eor w5,w5,w19 + .long 0x13940a94 // ror w20,w20,#2 + .long 0x0b0402d6 // add w22,w22,w4 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13857ca5 // ror w5,w5,#31 + .long 0x4a0800c6 // eor w6,w6,w8 + .long 0x0a3802b9 // bic w25,w21,w24 + .long 0x0a18029a // and w26,w20,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x4a0e00c6 // eor w6,w6,w14 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x4a0300c6 // eor w6,w6,w3 + .long 0x13980b18 // ror w24,w24,#2 + .long 0x0b0502b5 // add w21,w21,w5 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13867cc6 // ror w6,w6,#31 + .long 0x4a0900e7 // eor w7,w7,w9 + .long 0x0a370299 // bic w25,w20,w23 + .long 0x0a17031a // and w26,w24,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x4a0f00e7 // eor w7,w7,w15 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x4a0400e7 // eor w7,w7,w4 + .long 0x13970af7 // ror w23,w23,#2 + .long 0x0b060294 // add w20,w20,w6 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13877ce7 // ror w7,w7,#31 + .long 0x529d743c // movz w28,#0xeba1 + .long 0x72addb3c // movk w28,#0x6ed9, lsl #16 + .long 0x4a0a0108 // eor w8,w8,w10 + .long 0x0a360319 // bic w25,w24,w22 + .long 0x0a1602fa // and w26,w23,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x4a100108 // eor w8,w8,w16 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x4a050108 // eor w8,w8,w5 + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x0b070318 // add w24,w24,w7 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13887d08 // ror w8,w8,#31 + .long 0x4a0b0129 // eor w9,w9,w11 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a110129 // eor w9,w9,w17 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a060129 // eor w9,w9,w6 + .long 0x0b0802f7 // add w23,w23,w8 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13897d29 // ror w9,w9,#31 + .long 0x4a0c014a // eor w10,w10,w12 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a13014a // eor w10,w10,w19 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a07014a // eor w10,w10,w7 + .long 0x0b0902d6 // add w22,w22,w9 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x138a7d4a // ror w10,w10,#31 + .long 0x4a0d016b // eor w11,w11,w13 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a03016b // eor w11,w11,w3 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a08016b // eor w11,w11,w8 + .long 0x0b0a02b5 // add w21,w21,w10 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x138b7d6b // ror w11,w11,#31 + .long 0x4a0e018c // eor w12,w12,w14 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a04018c // eor w12,w12,w4 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a09018c // eor w12,w12,w9 + .long 0x0b0b0294 // add w20,w20,w11 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x138c7d8c // ror w12,w12,#31 + .long 0x4a0f01ad // eor w13,w13,w15 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a0501ad // eor w13,w13,w5 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0a01ad // eor w13,w13,w10 + .long 0x0b0c0318 // add w24,w24,w12 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x138d7dad // ror w13,w13,#31 + .long 0x4a1001ce // eor w14,w14,w16 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a0601ce // eor w14,w14,w6 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0b01ce // eor w14,w14,w11 + .long 0x0b0d02f7 // add w23,w23,w13 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x138e7dce // ror w14,w14,#31 + .long 0x4a1101ef // eor w15,w15,w17 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0701ef // eor w15,w15,w7 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a0c01ef // eor w15,w15,w12 + .long 0x0b0e02d6 // add w22,w22,w14 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x138f7def // ror w15,w15,#31 + .long 0x4a130210 // eor w16,w16,w19 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a080210 // eor w16,w16,w8 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a0d0210 // eor w16,w16,w13 + .long 0x0b0f02b5 // add w21,w21,w15 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13907e10 // ror w16,w16,#31 + .long 0x4a030231 // eor w17,w17,w3 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a090231 // eor w17,w17,w9 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a0e0231 // eor w17,w17,w14 + .long 0x0b100294 // add w20,w20,w16 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13917e31 // ror w17,w17,#31 + .long 0x4a040273 // eor w19,w19,w4 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a0a0273 // eor w19,w19,w10 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0f0273 // eor w19,w19,w15 + .long 0x0b110318 // add w24,w24,w17 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13937e73 // ror w19,w19,#31 + .long 0x4a050063 // eor w3,w3,w5 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a0b0063 // eor w3,w3,w11 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a100063 // eor w3,w3,w16 + .long 0x0b1302f7 // add w23,w23,w19 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13837c63 // ror w3,w3,#31 + .long 0x4a060084 // eor w4,w4,w6 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0c0084 // eor w4,w4,w12 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a110084 // eor w4,w4,w17 + .long 0x0b0302d6 // add w22,w22,w3 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13847c84 // ror w4,w4,#31 + .long 0x4a0700a5 // eor w5,w5,w7 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0d00a5 // eor w5,w5,w13 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a1300a5 // eor w5,w5,w19 + .long 0x0b0402b5 // add w21,w21,w4 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13857ca5 // ror w5,w5,#31 + .long 0x4a0800c6 // eor w6,w6,w8 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a0e00c6 // eor w6,w6,w14 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a0300c6 // eor w6,w6,w3 + .long 0x0b050294 // add w20,w20,w5 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13867cc6 // ror w6,w6,#31 + .long 0x4a0900e7 // eor w7,w7,w9 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a0f00e7 // eor w7,w7,w15 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0400e7 // eor w7,w7,w4 + .long 0x0b060318 // add w24,w24,w6 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13877ce7 // ror w7,w7,#31 + .long 0x4a0a0108 // eor w8,w8,w10 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a100108 // eor w8,w8,w16 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a050108 // eor w8,w8,w5 + .long 0x0b0702f7 // add w23,w23,w7 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13887d08 // ror w8,w8,#31 + .long 0x4a0b0129 // eor w9,w9,w11 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a110129 // eor w9,w9,w17 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a060129 // eor w9,w9,w6 + .long 0x0b0802d6 // add w22,w22,w8 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13897d29 // ror w9,w9,#31 + .long 0x4a0c014a // eor w10,w10,w12 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a13014a // eor w10,w10,w19 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a07014a // eor w10,w10,w7 + .long 0x0b0902b5 // add w21,w21,w9 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x138a7d4a // ror w10,w10,#31 + .long 0x4a0d016b // eor w11,w11,w13 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a03016b // eor w11,w11,w3 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a08016b // eor w11,w11,w8 + .long 0x0b0a0294 // add w20,w20,w10 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x138b7d6b // ror w11,w11,#31 + .long 0x52979b9c // movz w28,#0xbcdc + .long 0x72b1e37c // movk w28,#0x8f1b, lsl #16 + .long 0x4a0e018c // eor w12,w12,w14 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a04018c // eor w12,w12,w4 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a09018c // eor w12,w12,w9 + .long 0x0b0b0318 // add w24,w24,w11 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x138c7d8c // ror w12,w12,#31 + .long 0x2a1602b9 // orr w25,w21,w22 + .long 0x0a1602ba // and w26,w21,w22 + .long 0x4a0f01ad // eor w13,w13,w15 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0a170339 // and w25,w25,w23 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a0501ad // eor w13,w13,w5 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0a01ad // eor w13,w13,w10 + .long 0x0b0c02f7 // add w23,w23,w12 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x138d7dad // ror w13,w13,#31 + .long 0x2a150299 // orr w25,w20,w21 + .long 0x0a15029a // and w26,w20,w21 + .long 0x4a1001ce // eor w14,w14,w16 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0a160339 // and w25,w25,w22 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0601ce // eor w14,w14,w6 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a0b01ce // eor w14,w14,w11 + .long 0x0b0d02d6 // add w22,w22,w13 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x138e7dce // ror w14,w14,#31 + .long 0x2a140319 // orr w25,w24,w20 + .long 0x0a14031a // and w26,w24,w20 + .long 0x4a1101ef // eor w15,w15,w17 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0a150339 // and w25,w25,w21 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0701ef // eor w15,w15,w7 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a0c01ef // eor w15,w15,w12 + .long 0x0b0e02b5 // add w21,w21,w14 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x138f7def // ror w15,w15,#31 + .long 0x2a1802f9 // orr w25,w23,w24 + .long 0x0a1802fa // and w26,w23,w24 + .long 0x4a130210 // eor w16,w16,w19 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0a140339 // and w25,w25,w20 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a080210 // eor w16,w16,w8 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a0d0210 // eor w16,w16,w13 + .long 0x0b0f0294 // add w20,w20,w15 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13907e10 // ror w16,w16,#31 + .long 0x2a1702d9 // orr w25,w22,w23 + .long 0x0a1702da // and w26,w22,w23 + .long 0x4a030231 // eor w17,w17,w3 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0a180339 // and w25,w25,w24 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a090231 // eor w17,w17,w9 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0e0231 // eor w17,w17,w14 + .long 0x0b100318 // add w24,w24,w16 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13917e31 // ror w17,w17,#31 + .long 0x2a1602b9 // orr w25,w21,w22 + .long 0x0a1602ba // and w26,w21,w22 + .long 0x4a040273 // eor w19,w19,w4 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0a170339 // and w25,w25,w23 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a0a0273 // eor w19,w19,w10 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0f0273 // eor w19,w19,w15 + .long 0x0b1102f7 // add w23,w23,w17 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13937e73 // ror w19,w19,#31 + .long 0x2a150299 // orr w25,w20,w21 + .long 0x0a15029a // and w26,w20,w21 + .long 0x4a050063 // eor w3,w3,w5 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0a160339 // and w25,w25,w22 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0b0063 // eor w3,w3,w11 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a100063 // eor w3,w3,w16 + .long 0x0b1302d6 // add w22,w22,w19 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13837c63 // ror w3,w3,#31 + .long 0x2a140319 // orr w25,w24,w20 + .long 0x0a14031a // and w26,w24,w20 + .long 0x4a060084 // eor w4,w4,w6 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0a150339 // and w25,w25,w21 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0c0084 // eor w4,w4,w12 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a110084 // eor w4,w4,w17 + .long 0x0b0302b5 // add w21,w21,w3 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13847c84 // ror w4,w4,#31 + .long 0x2a1802f9 // orr w25,w23,w24 + .long 0x0a1802fa // and w26,w23,w24 + .long 0x4a0700a5 // eor w5,w5,w7 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0a140339 // and w25,w25,w20 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a0d00a5 // eor w5,w5,w13 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a1300a5 // eor w5,w5,w19 + .long 0x0b040294 // add w20,w20,w4 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13857ca5 // ror w5,w5,#31 + .long 0x2a1702d9 // orr w25,w22,w23 + .long 0x0a1702da // and w26,w22,w23 + .long 0x4a0800c6 // eor w6,w6,w8 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0a180339 // and w25,w25,w24 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a0e00c6 // eor w6,w6,w14 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0300c6 // eor w6,w6,w3 + .long 0x0b050318 // add w24,w24,w5 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13867cc6 // ror w6,w6,#31 + .long 0x2a1602b9 // orr w25,w21,w22 + .long 0x0a1602ba // and w26,w21,w22 + .long 0x4a0900e7 // eor w7,w7,w9 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0a170339 // and w25,w25,w23 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a0f00e7 // eor w7,w7,w15 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0400e7 // eor w7,w7,w4 + .long 0x0b0602f7 // add w23,w23,w6 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13877ce7 // ror w7,w7,#31 + .long 0x2a150299 // orr w25,w20,w21 + .long 0x0a15029a // and w26,w20,w21 + .long 0x4a0a0108 // eor w8,w8,w10 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0a160339 // and w25,w25,w22 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a100108 // eor w8,w8,w16 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a050108 // eor w8,w8,w5 + .long 0x0b0702d6 // add w22,w22,w7 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13887d08 // ror w8,w8,#31 + .long 0x2a140319 // orr w25,w24,w20 + .long 0x0a14031a // and w26,w24,w20 + .long 0x4a0b0129 // eor w9,w9,w11 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0a150339 // and w25,w25,w21 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a110129 // eor w9,w9,w17 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a060129 // eor w9,w9,w6 + .long 0x0b0802b5 // add w21,w21,w8 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13897d29 // ror w9,w9,#31 + .long 0x2a1802f9 // orr w25,w23,w24 + .long 0x0a1802fa // and w26,w23,w24 + .long 0x4a0c014a // eor w10,w10,w12 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0a140339 // and w25,w25,w20 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a13014a // eor w10,w10,w19 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a07014a // eor w10,w10,w7 + .long 0x0b090294 // add w20,w20,w9 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x138a7d4a // ror w10,w10,#31 + .long 0x2a1702d9 // orr w25,w22,w23 + .long 0x0a1702da // and w26,w22,w23 + .long 0x4a0d016b // eor w11,w11,w13 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0a180339 // and w25,w25,w24 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a03016b // eor w11,w11,w3 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a08016b // eor w11,w11,w8 + .long 0x0b0a0318 // add w24,w24,w10 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x138b7d6b // ror w11,w11,#31 + .long 0x2a1602b9 // orr w25,w21,w22 + .long 0x0a1602ba // and w26,w21,w22 + .long 0x4a0e018c // eor w12,w12,w14 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0a170339 // and w25,w25,w23 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a04018c // eor w12,w12,w4 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a09018c // eor w12,w12,w9 + .long 0x0b0b02f7 // add w23,w23,w11 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x138c7d8c // ror w12,w12,#31 + .long 0x2a150299 // orr w25,w20,w21 + .long 0x0a15029a // and w26,w20,w21 + .long 0x4a0f01ad // eor w13,w13,w15 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0a160339 // and w25,w25,w22 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0501ad // eor w13,w13,w5 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a0a01ad // eor w13,w13,w10 + .long 0x0b0c02d6 // add w22,w22,w12 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x138d7dad // ror w13,w13,#31 + .long 0x2a140319 // orr w25,w24,w20 + .long 0x0a14031a // and w26,w24,w20 + .long 0x4a1001ce // eor w14,w14,w16 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0a150339 // and w25,w25,w21 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0601ce // eor w14,w14,w6 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a0b01ce // eor w14,w14,w11 + .long 0x0b0d02b5 // add w21,w21,w13 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x138e7dce // ror w14,w14,#31 + .long 0x2a1802f9 // orr w25,w23,w24 + .long 0x0a1802fa // and w26,w23,w24 + .long 0x4a1101ef // eor w15,w15,w17 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0a140339 // and w25,w25,w20 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a0701ef // eor w15,w15,w7 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a0c01ef // eor w15,w15,w12 + .long 0x0b0e0294 // add w20,w20,w14 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x138f7def // ror w15,w15,#31 + .long 0x52983adc // movz w28,#0xc1d6 + .long 0x72b94c5c // movk w28,#0xca62, lsl #16 + .long 0x2a1702d9 // orr w25,w22,w23 + .long 0x0a1702da // and w26,w22,w23 + .long 0x4a130210 // eor w16,w16,w19 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0a180339 // and w25,w25,w24 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a080210 // eor w16,w16,w8 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x2a1a0339 // orr w25,w25,w26 + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0d0210 // eor w16,w16,w13 + .long 0x0b0f0318 // add w24,w24,w15 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13907e10 // ror w16,w16,#31 + .long 0x4a030231 // eor w17,w17,w3 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a090231 // eor w17,w17,w9 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0e0231 // eor w17,w17,w14 + .long 0x0b1002f7 // add w23,w23,w16 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13917e31 // ror w17,w17,#31 + .long 0x4a040273 // eor w19,w19,w4 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0a0273 // eor w19,w19,w10 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a0f0273 // eor w19,w19,w15 + .long 0x0b1102d6 // add w22,w22,w17 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13937e73 // ror w19,w19,#31 + .long 0x4a050063 // eor w3,w3,w5 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0b0063 // eor w3,w3,w11 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a100063 // eor w3,w3,w16 + .long 0x0b1302b5 // add w21,w21,w19 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13837c63 // ror w3,w3,#31 + .long 0x4a060084 // eor w4,w4,w6 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a0c0084 // eor w4,w4,w12 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a110084 // eor w4,w4,w17 + .long 0x0b030294 // add w20,w20,w3 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13847c84 // ror w4,w4,#31 + .long 0x4a0700a5 // eor w5,w5,w7 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a0d00a5 // eor w5,w5,w13 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a1300a5 // eor w5,w5,w19 + .long 0x0b040318 // add w24,w24,w4 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x13857ca5 // ror w5,w5,#31 + .long 0x4a0800c6 // eor w6,w6,w8 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a0e00c6 // eor w6,w6,w14 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0300c6 // eor w6,w6,w3 + .long 0x0b0502f7 // add w23,w23,w5 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13867cc6 // ror w6,w6,#31 + .long 0x4a0900e7 // eor w7,w7,w9 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a0f00e7 // eor w7,w7,w15 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a0400e7 // eor w7,w7,w4 + .long 0x0b0602d6 // add w22,w22,w6 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13877ce7 // ror w7,w7,#31 + .long 0x4a0a0108 // eor w8,w8,w10 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a100108 // eor w8,w8,w16 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a050108 // eor w8,w8,w5 + .long 0x0b0702b5 // add w21,w21,w7 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13887d08 // ror w8,w8,#31 + .long 0x4a0b0129 // eor w9,w9,w11 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a110129 // eor w9,w9,w17 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a060129 // eor w9,w9,w6 + .long 0x0b080294 // add w20,w20,w8 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x13897d29 // ror w9,w9,#31 + .long 0x4a0c014a // eor w10,w10,w12 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a13014a // eor w10,w10,w19 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a07014a // eor w10,w10,w7 + .long 0x0b090318 // add w24,w24,w9 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x138a7d4a // ror w10,w10,#31 + .long 0x4a0d016b // eor w11,w11,w13 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a03016b // eor w11,w11,w3 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a08016b // eor w11,w11,w8 + .long 0x0b0a02f7 // add w23,w23,w10 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x138b7d6b // ror w11,w11,#31 + .long 0x4a0e018c // eor w12,w12,w14 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a04018c // eor w12,w12,w4 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a09018c // eor w12,w12,w9 + .long 0x0b0b02d6 // add w22,w22,w11 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x138c7d8c // ror w12,w12,#31 + .long 0x4a0f01ad // eor w13,w13,w15 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0501ad // eor w13,w13,w5 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a0a01ad // eor w13,w13,w10 + .long 0x0b0c02b5 // add w21,w21,w12 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x138d7dad // ror w13,w13,#31 + .long 0x4a1001ce // eor w14,w14,w16 + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a0601ce // eor w14,w14,w6 + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x4a0b01ce // eor w14,w14,w11 + .long 0x0b0d0294 // add w20,w20,w13 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x138e7dce // ror w14,w14,#31 + .long 0x4a1101ef // eor w15,w15,w17 + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x0b1c0318 // add w24,w24,w28 // future e+=K + .long 0x4a0701ef // eor w15,w15,w7 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0x4a0c01ef // eor w15,w15,w12 + .long 0x0b0e0318 // add w24,w24,w14 // future e+=X[i] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x138f7def // ror w15,w15,#31 + .long 0x4a130210 // eor w16,w16,w19 + .long 0x4a1502f9 // eor w25,w23,w21 + .long 0x13946e9b // ror w27,w20,#27 + .long 0x0b1c02f7 // add w23,w23,w28 // future e+=K + .long 0x4a080210 // eor w16,w16,w8 + .long 0x4a160339 // eor w25,w25,w22 + .long 0x0b1b0318 // add w24,w24,w27 // e+=rot(a,5) + .long 0x13950ab5 // ror w21,w21,#2 + .long 0x4a0d0210 // eor w16,w16,w13 + .long 0x0b0f02f7 // add w23,w23,w15 // future e+=X[i] + .long 0x0b190318 // add w24,w24,w25 // e+=F(b,c,d) + .long 0x13907e10 // ror w16,w16,#31 + .long 0x4a030231 // eor w17,w17,w3 + .long 0x4a1402d9 // eor w25,w22,w20 + .long 0x13986f1b // ror w27,w24,#27 + .long 0x0b1c02d6 // add w22,w22,w28 // future e+=K + .long 0x4a090231 // eor w17,w17,w9 + .long 0x4a150339 // eor w25,w25,w21 + .long 0x0b1b02f7 // add w23,w23,w27 // e+=rot(a,5) + .long 0x13940a94 // ror w20,w20,#2 + .long 0x4a0e0231 // eor w17,w17,w14 + .long 0x0b1002d6 // add w22,w22,w16 // future e+=X[i] + .long 0x0b1902f7 // add w23,w23,w25 // e+=F(b,c,d) + .long 0x13917e31 // ror w17,w17,#31 + .long 0x4a040273 // eor w19,w19,w4 + .long 0x4a1802b9 // eor w25,w21,w24 + .long 0x13976efb // ror w27,w23,#27 + .long 0x0b1c02b5 // add w21,w21,w28 // future e+=K + .long 0x4a0a0273 // eor w19,w19,w10 + .long 0x4a140339 // eor w25,w25,w20 + .long 0x0b1b02d6 // add w22,w22,w27 // e+=rot(a,5) + .long 0x13980b18 // ror w24,w24,#2 + .long 0x4a0f0273 // eor w19,w19,w15 + .long 0x0b1102b5 // add w21,w21,w17 // future e+=X[i] + .long 0x0b1902d6 // add w22,w22,w25 // e+=F(b,c,d) + .long 0x13937e73 // ror w19,w19,#31 + .long 0x29401404 // ldp w4,w5,[x0] + .long 0x4a170299 // eor w25,w20,w23 + .long 0x13966edb // ror w27,w22,#27 + .long 0x0b1c0294 // add w20,w20,w28 // future e+=K + .long 0x4a180339 // eor w25,w25,w24 + .long 0x0b1b02b5 // add w21,w21,w27 // e+=rot(a,5) + .long 0x13970af7 // ror w23,w23,#2 + .long 0x0b130294 // add w20,w20,w19 // future e+=X[i] + .long 0x0b1902b5 // add w21,w21,w25 // e+=F(b,c,d) + .long 0x29411c06 // ldp w6,w7,[x0,#8] + .long 0x4a160319 // eor w25,w24,w22 + .long 0x13956ebb // ror w27,w21,#27 + .long 0x4a170339 // eor w25,w25,w23 + .long 0x0b1b0294 // add w20,w20,w27 // e+=rot(a,5) + .long 0x13960ad6 // ror w22,w22,#2 + .long 0xb9401008 // ldr w8,[x0,#16] + .long 0x0b190294 // add w20,w20,w25 // e+=F(b,c,d) + .long 0x0b0502b5 // add w21,w21,w5 + .long 0x0b0602d6 // add w22,w22,w6 + .long 0x0b040294 // add w20,w20,w4 + .long 0x0b0702f7 // add w23,w23,w7 + .long 0x0b080318 // add w24,w24,w8 + .long 0x29005414 // stp w20,w21,[x0] + .long 0x29015c16 // stp w22,w23,[x0,#8] + .long 0xb9001018 // str w24,[x0,#16] + cbnz x2,.Lsha1_gpr_loop + + .long 0xa94153f3 // ldp x19,x20,[sp,#16] + .long 0xa9425bf5 // ldp x21,x22,[sp,#32] + .long 0xa94363f7 // ldp x23,x24,[sp,#48] + .long 0xa9446bf9 // ldp x25,x26,[sp,#64] + .long 0xa94573fb // ldp x27,x28,[sp,#80] + .long 0xf84607fd // ldr x29,[sp],#96 + ret diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc similarity index 99% rename from HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc rename to HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc index 6f198cb..ffce73e 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc @@ -1,7 +1,6 @@ // SHA-256 AVX SIMD-schedule implementation (IA-32). VEX-128 (AVX1) -// instructions only - there is no i386 AVX2 SHA-256 upstream - dispatched at -// the AVX2 tier (every AVX2 CPU has AVX1; AVX1-only CPUs fall to the SSSE3 -// tier). The 3-operand VEX forms eliminate the SSSE3 kernel's register-copy +// instructions only - there is no i386 AVX2 SHA-256 upstream. The 3-operand +// VEX forms eliminate the SSSE3 kernel's register-copy // movdqa traffic; the byte-swap mask stays resident in xmm7. All VEX // instructions are db-encoded for broad assembler compatibility. // K256 is read from K256_Doubled at a 32-byte stride (the walk and offsets diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc new file mode 100644 index 0000000..7217099 --- /dev/null +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc @@ -0,0 +1,948 @@ +// SHA-256 pure-GPR implementation (AArch64) for cores without the SHA-256 +// crypto extension; the Gpr name states the ISA requirement: none beyond +// base AArch64. Serial SHA maps better onto the 31 GPRs than onto NEON +// lanes (single dependency chain, 1-op ror, rotate-folded eor operands). +// Expects AAPCS64 (after HlpSimdProc4Begin_aarch64): x0 = state ptr +// (8 x UInt32), x1 = data ptr, w2 = numblocks, x3 = K256_Gpr ptr. +// K256_Gpr carries the 64 round constants PLUS a zero terminator word - the +// message-schedule loop ends when the loaded K word is zero (cbnz), exactly +// like the original's sentinel-terminated table; a plain K256 const cannot +// drive this loop. +// Frame: 128-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved) + 16 bytes +// schedule scratch; x30 (LR) is repurposed as the K walk pointer between the +// save and the restore, as in the original. +// AArch64 instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha512-armv8.pl (sha256_block_data_order, +// the plain path; the generator emits both SHA-256 and SHA-512). + + .long 0x2a0203e2 // mov w2,w2 // zero-extend ANumBlocks (AAPCS64 leaves x2's top half undefined) + .long 0xa9b87bfd // stp x29,x30,[sp,#-128]! + .long 0x910003fd // add x29,sp,#0 + + .long 0xa90153f3 // stp x19,x20,[sp,#16] + .long 0xa9025bf5 // stp x21,x22,[sp,#32] + .long 0xa90363f7 // stp x23,x24,[sp,#48] + .long 0xa9046bf9 // stp x25,x26,[sp,#64] + .long 0xa90573fb // stp x27,x28,[sp,#80] + .long 0xd10043ff // sub sp,sp,#4*4 + + .long 0x29405414 // ldp w20,w21,[x0] // load context + .long 0x29415c16 // ldp w22,w23,[x0,#2*4] + .long 0x29426418 // ldp w24,w25,[x0,#4*4] + .long 0x8b021822 // add x2,x1,x2, lsl #6 // end of input + .long 0x29436c1a // ldp w26,w27,[x0,#6*4] + .long 0xaa0303fe // mov x30,x3 // K256_Gpr (param 4; x3 is reused for message words below) + .long 0xa9060ba0 // stp x0,x2,[x29,#96] + + +.Lsha256_gpr_loop: + .long 0x28c11023 // ldp w3,w4,[x1],#2*4 + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++ + .long 0x4a1602bc // eor w28,w21,w22 // magic seed + .long 0xf9003ba1 // str x1,[x29,#112] + .long 0x5ac00863 // rev w3,w3 // 0 + .long 0x13981b10 // ror w16,w24,#6 + .long 0x0b13037b // add w27,w27,w19 // h+=K[i] + .long 0x4ad83b06 // eor w6,w24,w24, ror #14 + .long 0x0a180331 // and w17,w25,w24 + .long 0x0a380353 // bic w19,w26,w24 + .long 0x0b03037b // add w27,w27,w3 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a150293 // eor w19,w20,w21 // a^b, b^c in next round + .long 0x4ac62e10 // eor w16,w16,w6, ror #11 // Sigma1(e) + .long 0x13940a86 // ror w6,w20,#2 + .long 0x0b11037b // add w27,w27,w17 // h+=Ch(e,f,g) + .long 0x4ad42691 // eor w17,w20,w20, ror #9 + .long 0x0b10037b // add w27,w27,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b1b02f7 // add w23,w23,w27 // d+=h + .long 0x4a15039c // eor w28,w28,w21 // Maj(a,b,c) + .long 0x4ad134d1 // eor w17,w6,w17, ror #13 // Sigma0(a) + .long 0x0b1c037b // add w27,w27,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) + .long 0x5ac00884 // rev w4,w4 // 1 + .long 0x28c11825 // ldp w5,w6,[x1],#2*4 + .long 0x0b11037b // add w27,w27,w17 // h+=Sigma0(a) + .long 0x13971af0 // ror w16,w23,#6 + .long 0x0b1c035a // add w26,w26,w28 // h+=K[i] + .long 0x4ad73ae7 // eor w7,w23,w23, ror #14 + .long 0x0a170311 // and w17,w24,w23 + .long 0x0a37033c // bic w28,w25,w23 + .long 0x0b04035a // add w26,w26,w4 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a14037c // eor w28,w27,w20 // a^b, b^c in next round + .long 0x4ac72e10 // eor w16,w16,w7, ror #11 // Sigma1(e) + .long 0x139b0b67 // ror w7,w27,#2 + .long 0x0b11035a // add w26,w26,w17 // h+=Ch(e,f,g) + .long 0x4adb2771 // eor w17,w27,w27, ror #9 + .long 0x0b10035a // add w26,w26,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b1a02d6 // add w22,w22,w26 // d+=h + .long 0x4a140273 // eor w19,w19,w20 // Maj(a,b,c) + .long 0x4ad134f1 // eor w17,w7,w17, ror #13 // Sigma0(a) + .long 0x0b13035a // add w26,w26,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) + .long 0x5ac008a5 // rev w5,w5 // 2 + .long 0x0b11035a // add w26,w26,w17 // h+=Sigma0(a) + .long 0x13961ad0 // ror w16,w22,#6 + .long 0x0b130339 // add w25,w25,w19 // h+=K[i] + .long 0x4ad63ac8 // eor w8,w22,w22, ror #14 + .long 0x0a1602f1 // and w17,w23,w22 + .long 0x0a360313 // bic w19,w24,w22 + .long 0x0b050339 // add w25,w25,w5 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1b0353 // eor w19,w26,w27 // a^b, b^c in next round + .long 0x4ac82e10 // eor w16,w16,w8, ror #11 // Sigma1(e) + .long 0x139a0b48 // ror w8,w26,#2 + .long 0x0b110339 // add w25,w25,w17 // h+=Ch(e,f,g) + .long 0x4ada2751 // eor w17,w26,w26, ror #9 + .long 0x0b100339 // add w25,w25,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b1902b5 // add w21,w21,w25 // d+=h + .long 0x4a1b039c // eor w28,w28,w27 // Maj(a,b,c) + .long 0x4ad13511 // eor w17,w8,w17, ror #13 // Sigma0(a) + .long 0x0b1c0339 // add w25,w25,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) + .long 0x5ac008c6 // rev w6,w6 // 3 + .long 0x28c12027 // ldp w7,w8,[x1],#2*4 + .long 0x0b110339 // add w25,w25,w17 // h+=Sigma0(a) + .long 0x13951ab0 // ror w16,w21,#6 + .long 0x0b1c0318 // add w24,w24,w28 // h+=K[i] + .long 0x4ad53aa9 // eor w9,w21,w21, ror #14 + .long 0x0a1502d1 // and w17,w22,w21 + .long 0x0a3502fc // bic w28,w23,w21 + .long 0x0b060318 // add w24,w24,w6 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1a033c // eor w28,w25,w26 // a^b, b^c in next round + .long 0x4ac92e10 // eor w16,w16,w9, ror #11 // Sigma1(e) + .long 0x13990b29 // ror w9,w25,#2 + .long 0x0b110318 // add w24,w24,w17 // h+=Ch(e,f,g) + .long 0x4ad92731 // eor w17,w25,w25, ror #9 + .long 0x0b100318 // add w24,w24,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b180294 // add w20,w20,w24 // d+=h + .long 0x4a1a0273 // eor w19,w19,w26 // Maj(a,b,c) + .long 0x4ad13531 // eor w17,w9,w17, ror #13 // Sigma0(a) + .long 0x0b130318 // add w24,w24,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) + .long 0x5ac008e7 // rev w7,w7 // 4 + .long 0x0b110318 // add w24,w24,w17 // h+=Sigma0(a) + .long 0x13941a90 // ror w16,w20,#6 + .long 0x0b1302f7 // add w23,w23,w19 // h+=K[i] + .long 0x4ad43a8a // eor w10,w20,w20, ror #14 + .long 0x0a1402b1 // and w17,w21,w20 + .long 0x0a3402d3 // bic w19,w22,w20 + .long 0x0b0702f7 // add w23,w23,w7 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a190313 // eor w19,w24,w25 // a^b, b^c in next round + .long 0x4aca2e10 // eor w16,w16,w10, ror #11 // Sigma1(e) + .long 0x13980b0a // ror w10,w24,#2 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Ch(e,f,g) + .long 0x4ad82711 // eor w17,w24,w24, ror #9 + .long 0x0b1002f7 // add w23,w23,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b17037b // add w27,w27,w23 // d+=h + .long 0x4a19039c // eor w28,w28,w25 // Maj(a,b,c) + .long 0x4ad13551 // eor w17,w10,w17, ror #13 // Sigma0(a) + .long 0x0b1c02f7 // add w23,w23,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) + .long 0x5ac00908 // rev w8,w8 // 5 + .long 0x28c12829 // ldp w9,w10,[x1],#2*4 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Sigma0(a) + .long 0x139b1b70 // ror w16,w27,#6 + .long 0x0b1c02d6 // add w22,w22,w28 // h+=K[i] + .long 0x4adb3b6b // eor w11,w27,w27, ror #14 + .long 0x0a1b0291 // and w17,w20,w27 + .long 0x0a3b02bc // bic w28,w21,w27 + .long 0x0b0802d6 // add w22,w22,w8 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1802fc // eor w28,w23,w24 // a^b, b^c in next round + .long 0x4acb2e10 // eor w16,w16,w11, ror #11 // Sigma1(e) + .long 0x13970aeb // ror w11,w23,#2 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Ch(e,f,g) + .long 0x4ad726f1 // eor w17,w23,w23, ror #9 + .long 0x0b1002d6 // add w22,w22,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b16035a // add w26,w26,w22 // d+=h + .long 0x4a180273 // eor w19,w19,w24 // Maj(a,b,c) + .long 0x4ad13571 // eor w17,w11,w17, ror #13 // Sigma0(a) + .long 0x0b1302d6 // add w22,w22,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) + .long 0x5ac00929 // rev w9,w9 // 6 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Sigma0(a) + .long 0x139a1b50 // ror w16,w26,#6 + .long 0x0b1302b5 // add w21,w21,w19 // h+=K[i] + .long 0x4ada3b4c // eor w12,w26,w26, ror #14 + .long 0x0a1a0371 // and w17,w27,w26 + .long 0x0a3a0293 // bic w19,w20,w26 + .long 0x0b0902b5 // add w21,w21,w9 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1702d3 // eor w19,w22,w23 // a^b, b^c in next round + .long 0x4acc2e10 // eor w16,w16,w12, ror #11 // Sigma1(e) + .long 0x13960acc // ror w12,w22,#2 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Ch(e,f,g) + .long 0x4ad626d1 // eor w17,w22,w22, ror #9 + .long 0x0b1002b5 // add w21,w21,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b150339 // add w25,w25,w21 // d+=h + .long 0x4a17039c // eor w28,w28,w23 // Maj(a,b,c) + .long 0x4ad13591 // eor w17,w12,w17, ror #13 // Sigma0(a) + .long 0x0b1c02b5 // add w21,w21,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) + .long 0x5ac0094a // rev w10,w10 // 7 + .long 0x28c1302b // ldp w11,w12,[x1],#2*4 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Sigma0(a) + .long 0x13991b30 // ror w16,w25,#6 + .long 0x0b1c0294 // add w20,w20,w28 // h+=K[i] + .long 0x4ad93b2d // eor w13,w25,w25, ror #14 + .long 0x0a190351 // and w17,w26,w25 + .long 0x0a39037c // bic w28,w27,w25 + .long 0x0b0a0294 // add w20,w20,w10 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1602bc // eor w28,w21,w22 // a^b, b^c in next round + .long 0x4acd2e10 // eor w16,w16,w13, ror #11 // Sigma1(e) + .long 0x13950aad // ror w13,w21,#2 + .long 0x0b110294 // add w20,w20,w17 // h+=Ch(e,f,g) + .long 0x4ad526b1 // eor w17,w21,w21, ror #9 + .long 0x0b100294 // add w20,w20,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b140318 // add w24,w24,w20 // d+=h + .long 0x4a160273 // eor w19,w19,w22 // Maj(a,b,c) + .long 0x4ad135b1 // eor w17,w13,w17, ror #13 // Sigma0(a) + .long 0x0b130294 // add w20,w20,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w20,w20,w17 // h+=Sigma0(a) + .long 0x5ac0096b // rev w11,w11 // 8 + .long 0x0b110294 // add w20,w20,w17 // h+=Sigma0(a) + .long 0x13981b10 // ror w16,w24,#6 + .long 0x0b13037b // add w27,w27,w19 // h+=K[i] + .long 0x4ad83b0e // eor w14,w24,w24, ror #14 + .long 0x0a180331 // and w17,w25,w24 + .long 0x0a380353 // bic w19,w26,w24 + .long 0x0b0b037b // add w27,w27,w11 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a150293 // eor w19,w20,w21 // a^b, b^c in next round + .long 0x4ace2e10 // eor w16,w16,w14, ror #11 // Sigma1(e) + .long 0x13940a8e // ror w14,w20,#2 + .long 0x0b11037b // add w27,w27,w17 // h+=Ch(e,f,g) + .long 0x4ad42691 // eor w17,w20,w20, ror #9 + .long 0x0b10037b // add w27,w27,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b1b02f7 // add w23,w23,w27 // d+=h + .long 0x4a15039c // eor w28,w28,w21 // Maj(a,b,c) + .long 0x4ad135d1 // eor w17,w14,w17, ror #13 // Sigma0(a) + .long 0x0b1c037b // add w27,w27,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) + .long 0x5ac0098c // rev w12,w12 // 9 + .long 0x28c1382d // ldp w13,w14,[x1],#2*4 + .long 0x0b11037b // add w27,w27,w17 // h+=Sigma0(a) + .long 0x13971af0 // ror w16,w23,#6 + .long 0x0b1c035a // add w26,w26,w28 // h+=K[i] + .long 0x4ad73aef // eor w15,w23,w23, ror #14 + .long 0x0a170311 // and w17,w24,w23 + .long 0x0a37033c // bic w28,w25,w23 + .long 0x0b0c035a // add w26,w26,w12 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a14037c // eor w28,w27,w20 // a^b, b^c in next round + .long 0x4acf2e10 // eor w16,w16,w15, ror #11 // Sigma1(e) + .long 0x139b0b6f // ror w15,w27,#2 + .long 0x0b11035a // add w26,w26,w17 // h+=Ch(e,f,g) + .long 0x4adb2771 // eor w17,w27,w27, ror #9 + .long 0x0b10035a // add w26,w26,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b1a02d6 // add w22,w22,w26 // d+=h + .long 0x4a140273 // eor w19,w19,w20 // Maj(a,b,c) + .long 0x4ad135f1 // eor w17,w15,w17, ror #13 // Sigma0(a) + .long 0x0b13035a // add w26,w26,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) + .long 0x5ac009ad // rev w13,w13 // 10 + .long 0x0b11035a // add w26,w26,w17 // h+=Sigma0(a) + .long 0x13961ad0 // ror w16,w22,#6 + .long 0x0b130339 // add w25,w25,w19 // h+=K[i] + .long 0x4ad63ac0 // eor w0,w22,w22, ror #14 + .long 0x0a1602f1 // and w17,w23,w22 + .long 0x0a360313 // bic w19,w24,w22 + .long 0x0b0d0339 // add w25,w25,w13 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1b0353 // eor w19,w26,w27 // a^b, b^c in next round + .long 0x4ac02e10 // eor w16,w16,w0, ror #11 // Sigma1(e) + .long 0x139a0b40 // ror w0,w26,#2 + .long 0x0b110339 // add w25,w25,w17 // h+=Ch(e,f,g) + .long 0x4ada2751 // eor w17,w26,w26, ror #9 + .long 0x0b100339 // add w25,w25,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b1902b5 // add w21,w21,w25 // d+=h + .long 0x4a1b039c // eor w28,w28,w27 // Maj(a,b,c) + .long 0x4ad13411 // eor w17,w0,w17, ror #13 // Sigma0(a) + .long 0x0b1c0339 // add w25,w25,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) + .long 0x5ac009ce // rev w14,w14 // 11 + .long 0x28c1002f // ldp w15,w0,[x1],#2*4 + .long 0x0b110339 // add w25,w25,w17 // h+=Sigma0(a) + .long 0xb9000fe6 // str w6,[sp,#12] + .long 0x13951ab0 // ror w16,w21,#6 + .long 0x0b1c0318 // add w24,w24,w28 // h+=K[i] + .long 0x4ad53aa6 // eor w6,w21,w21, ror #14 + .long 0x0a1502d1 // and w17,w22,w21 + .long 0x0a3502fc // bic w28,w23,w21 + .long 0x0b0e0318 // add w24,w24,w14 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1a033c // eor w28,w25,w26 // a^b, b^c in next round + .long 0x4ac62e10 // eor w16,w16,w6, ror #11 // Sigma1(e) + .long 0x13990b26 // ror w6,w25,#2 + .long 0x0b110318 // add w24,w24,w17 // h+=Ch(e,f,g) + .long 0x4ad92731 // eor w17,w25,w25, ror #9 + .long 0x0b100318 // add w24,w24,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b180294 // add w20,w20,w24 // d+=h + .long 0x4a1a0273 // eor w19,w19,w26 // Maj(a,b,c) + .long 0x4ad134d1 // eor w17,w6,w17, ror #13 // Sigma0(a) + .long 0x0b130318 // add w24,w24,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) + .long 0x5ac009ef // rev w15,w15 // 12 + .long 0x0b110318 // add w24,w24,w17 // h+=Sigma0(a) + .long 0xb90003e7 // str w7,[sp,#0] + .long 0x13941a90 // ror w16,w20,#6 + .long 0x0b1302f7 // add w23,w23,w19 // h+=K[i] + .long 0x4ad43a87 // eor w7,w20,w20, ror #14 + .long 0x0a1402b1 // and w17,w21,w20 + .long 0x0a3402d3 // bic w19,w22,w20 + .long 0x0b0f02f7 // add w23,w23,w15 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a190313 // eor w19,w24,w25 // a^b, b^c in next round + .long 0x4ac72e10 // eor w16,w16,w7, ror #11 // Sigma1(e) + .long 0x13980b07 // ror w7,w24,#2 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Ch(e,f,g) + .long 0x4ad82711 // eor w17,w24,w24, ror #9 + .long 0x0b1002f7 // add w23,w23,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b17037b // add w27,w27,w23 // d+=h + .long 0x4a19039c // eor w28,w28,w25 // Maj(a,b,c) + .long 0x4ad134f1 // eor w17,w7,w17, ror #13 // Sigma0(a) + .long 0x0b1c02f7 // add w23,w23,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) + .long 0x5ac00800 // rev w0,w0 // 13 + .long 0x29400821 // ldp w1,w2,[x1] + .long 0x0b1102f7 // add w23,w23,w17 // h+=Sigma0(a) + .long 0xb90007e8 // str w8,[sp,#4] + .long 0x139b1b70 // ror w16,w27,#6 + .long 0x0b1c02d6 // add w22,w22,w28 // h+=K[i] + .long 0x4adb3b68 // eor w8,w27,w27, ror #14 + .long 0x0a1b0291 // and w17,w20,w27 + .long 0x0a3b02bc // bic w28,w21,w27 + .long 0x0b0002d6 // add w22,w22,w0 // h+=X[i] + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1802fc // eor w28,w23,w24 // a^b, b^c in next round + .long 0x4ac82e10 // eor w16,w16,w8, ror #11 // Sigma1(e) + .long 0x13970ae8 // ror w8,w23,#2 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Ch(e,f,g) + .long 0x4ad726f1 // eor w17,w23,w23, ror #9 + .long 0x0b1002d6 // add w22,w22,w16 // h+=Sigma1(e) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x0b16035a // add w26,w26,w22 // d+=h + .long 0x4a180273 // eor w19,w19,w24 // Maj(a,b,c) + .long 0x4ad13511 // eor w17,w8,w17, ror #13 // Sigma0(a) + .long 0x0b1302d6 // add w22,w22,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) + .long 0x5ac00821 // rev w1,w1 // 14 + .long 0xb9400fe6 // ldr w6,[sp,#12] + .long 0x0b1102d6 // add w22,w22,w17 // h+=Sigma0(a) + .long 0xb9000be9 // str w9,[sp,#8] + .long 0x139a1b50 // ror w16,w26,#6 + .long 0x0b1302b5 // add w21,w21,w19 // h+=K[i] + .long 0x4ada3b49 // eor w9,w26,w26, ror #14 + .long 0x0a1a0371 // and w17,w27,w26 + .long 0x0a3a0293 // bic w19,w20,w26 + .long 0x0b0102b5 // add w21,w21,w1 // h+=X[i] + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1702d3 // eor w19,w22,w23 // a^b, b^c in next round + .long 0x4ac92e10 // eor w16,w16,w9, ror #11 // Sigma1(e) + .long 0x13960ac9 // ror w9,w22,#2 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Ch(e,f,g) + .long 0x4ad626d1 // eor w17,w22,w22, ror #9 + .long 0x0b1002b5 // add w21,w21,w16 // h+=Sigma1(e) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x0b150339 // add w25,w25,w21 // d+=h + .long 0x4a17039c // eor w28,w28,w23 // Maj(a,b,c) + .long 0x4ad13531 // eor w17,w9,w17, ror #13 // Sigma0(a) + .long 0x0b1c02b5 // add w21,w21,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) + .long 0x5ac00842 // rev w2,w2 // 15 + .long 0xb94003e7 // ldr w7,[sp,#0] + .long 0x0b1102b5 // add w21,w21,w17 // h+=Sigma0(a) + .long 0xb9000fea // str w10,[sp,#12] + .long 0x13991b30 // ror w16,w25,#6 + .long 0x0b1c0294 // add w20,w20,w28 // h+=K[i] + .long 0x13841c89 // ror w9,w4,#7 + .long 0x0a190351 // and w17,w26,w25 + .long 0x13814428 // ror w8,w1,#17 + .long 0x0a39037c // bic w28,w27,w25 + .long 0x13950aaa // ror w10,w21,#2 + .long 0x0b020294 // add w20,w20,w2 // h+=X[i] + .long 0x4ad92e10 // eor w16,w16,w25, ror #11 + .long 0x4ac44929 // eor w9,w9,w4, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1602bc // eor w28,w21,w22 // a^b, b^c in next round + .long 0x4ad96610 // eor w16,w16,w25, ror #25 // Sigma1(e) + .long 0x4ad5354a // eor w10,w10,w21, ror #13 + .long 0x0b110294 // add w20,w20,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4ac14d08 // eor w8,w8,w1, ror #19 + .long 0x4a440d29 // eor w9,w9,w4, lsr #3 // sigma0(X[i+1]) + .long 0x0b100294 // add w20,w20,w16 // h+=Sigma1(e) + .long 0x4a160273 // eor w19,w19,w22 // Maj(a,b,c) + .long 0x4ad55951 // eor w17,w10,w21, ror #22 // Sigma0(a) + .long 0x4a412908 // eor w8,w8,w1, lsr #10 // sigma1(X[i+14]) + .long 0x0b0c0063 // add w3,w3,w12 + .long 0x0b140318 // add w24,w24,w20 // d+=h + .long 0x0b130294 // add w20,w20,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b090063 // add w3,w3,w9 + .long 0x0b110294 // add w20,w20,w17 // h+=Sigma0(a) + .long 0x0b080063 // add w3,w3,w8 + +.Lsha256_gpr_loop_16_xx: + .long 0xb94007e8 // ldr w8,[sp,#4] + .long 0xb90003eb // str w11,[sp,#0] + .long 0x13981b10 // ror w16,w24,#6 + .long 0x0b13037b // add w27,w27,w19 // h+=K[i] + .long 0x13851caa // ror w10,w5,#7 + .long 0x0a180331 // and w17,w25,w24 + .long 0x13824449 // ror w9,w2,#17 + .long 0x0a380353 // bic w19,w26,w24 + .long 0x13940a8b // ror w11,w20,#2 + .long 0x0b03037b // add w27,w27,w3 // h+=X[i] + .long 0x4ad82e10 // eor w16,w16,w24, ror #11 + .long 0x4ac5494a // eor w10,w10,w5, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a150293 // eor w19,w20,w21 // a^b, b^c in next round + .long 0x4ad86610 // eor w16,w16,w24, ror #25 // Sigma1(e) + .long 0x4ad4356b // eor w11,w11,w20, ror #13 + .long 0x0b11037b // add w27,w27,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4ac24d29 // eor w9,w9,w2, ror #19 + .long 0x4a450d4a // eor w10,w10,w5, lsr #3 // sigma0(X[i+1]) + .long 0x0b10037b // add w27,w27,w16 // h+=Sigma1(e) + .long 0x4a15039c // eor w28,w28,w21 // Maj(a,b,c) + .long 0x4ad45971 // eor w17,w11,w20, ror #22 // Sigma0(a) + .long 0x4a422929 // eor w9,w9,w2, lsr #10 // sigma1(X[i+14]) + .long 0x0b0d0084 // add w4,w4,w13 + .long 0x0b1b02f7 // add w23,w23,w27 // d+=h + .long 0x0b1c037b // add w27,w27,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b0a0084 // add w4,w4,w10 + .long 0x0b11037b // add w27,w27,w17 // h+=Sigma0(a) + .long 0x0b090084 // add w4,w4,w9 + .long 0xb9400be9 // ldr w9,[sp,#8] + .long 0xb90007ec // str w12,[sp,#4] + .long 0x13971af0 // ror w16,w23,#6 + .long 0x0b1c035a // add w26,w26,w28 // h+=K[i] + .long 0x13861ccb // ror w11,w6,#7 + .long 0x0a170311 // and w17,w24,w23 + .long 0x1383446a // ror w10,w3,#17 + .long 0x0a37033c // bic w28,w25,w23 + .long 0x139b0b6c // ror w12,w27,#2 + .long 0x0b04035a // add w26,w26,w4 // h+=X[i] + .long 0x4ad72e10 // eor w16,w16,w23, ror #11 + .long 0x4ac6496b // eor w11,w11,w6, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a14037c // eor w28,w27,w20 // a^b, b^c in next round + .long 0x4ad76610 // eor w16,w16,w23, ror #25 // Sigma1(e) + .long 0x4adb358c // eor w12,w12,w27, ror #13 + .long 0x0b11035a // add w26,w26,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4ac34d4a // eor w10,w10,w3, ror #19 + .long 0x4a460d6b // eor w11,w11,w6, lsr #3 // sigma0(X[i+1]) + .long 0x0b10035a // add w26,w26,w16 // h+=Sigma1(e) + .long 0x4a140273 // eor w19,w19,w20 // Maj(a,b,c) + .long 0x4adb5991 // eor w17,w12,w27, ror #22 // Sigma0(a) + .long 0x4a43294a // eor w10,w10,w3, lsr #10 // sigma1(X[i+14]) + .long 0x0b0e00a5 // add w5,w5,w14 + .long 0x0b1a02d6 // add w22,w22,w26 // d+=h + .long 0x0b13035a // add w26,w26,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b0b00a5 // add w5,w5,w11 + .long 0x0b11035a // add w26,w26,w17 // h+=Sigma0(a) + .long 0x0b0a00a5 // add w5,w5,w10 + .long 0xb9400fea // ldr w10,[sp,#12] + .long 0xb9000bed // str w13,[sp,#8] + .long 0x13961ad0 // ror w16,w22,#6 + .long 0x0b130339 // add w25,w25,w19 // h+=K[i] + .long 0x13871cec // ror w12,w7,#7 + .long 0x0a1602f1 // and w17,w23,w22 + .long 0x1384448b // ror w11,w4,#17 + .long 0x0a360313 // bic w19,w24,w22 + .long 0x139a0b4d // ror w13,w26,#2 + .long 0x0b050339 // add w25,w25,w5 // h+=X[i] + .long 0x4ad62e10 // eor w16,w16,w22, ror #11 + .long 0x4ac7498c // eor w12,w12,w7, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1b0353 // eor w19,w26,w27 // a^b, b^c in next round + .long 0x4ad66610 // eor w16,w16,w22, ror #25 // Sigma1(e) + .long 0x4ada35ad // eor w13,w13,w26, ror #13 + .long 0x0b110339 // add w25,w25,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4ac44d6b // eor w11,w11,w4, ror #19 + .long 0x4a470d8c // eor w12,w12,w7, lsr #3 // sigma0(X[i+1]) + .long 0x0b100339 // add w25,w25,w16 // h+=Sigma1(e) + .long 0x4a1b039c // eor w28,w28,w27 // Maj(a,b,c) + .long 0x4ada59b1 // eor w17,w13,w26, ror #22 // Sigma0(a) + .long 0x4a44296b // eor w11,w11,w4, lsr #10 // sigma1(X[i+14]) + .long 0x0b0f00c6 // add w6,w6,w15 + .long 0x0b1902b5 // add w21,w21,w25 // d+=h + .long 0x0b1c0339 // add w25,w25,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b0c00c6 // add w6,w6,w12 + .long 0x0b110339 // add w25,w25,w17 // h+=Sigma0(a) + .long 0x0b0b00c6 // add w6,w6,w11 + .long 0xb94003eb // ldr w11,[sp,#0] + .long 0xb9000fee // str w14,[sp,#12] + .long 0x13951ab0 // ror w16,w21,#6 + .long 0x0b1c0318 // add w24,w24,w28 // h+=K[i] + .long 0x13881d0d // ror w13,w8,#7 + .long 0x0a1502d1 // and w17,w22,w21 + .long 0x138544ac // ror w12,w5,#17 + .long 0x0a3502fc // bic w28,w23,w21 + .long 0x13990b2e // ror w14,w25,#2 + .long 0x0b060318 // add w24,w24,w6 // h+=X[i] + .long 0x4ad52e10 // eor w16,w16,w21, ror #11 + .long 0x4ac849ad // eor w13,w13,w8, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1a033c // eor w28,w25,w26 // a^b, b^c in next round + .long 0x4ad56610 // eor w16,w16,w21, ror #25 // Sigma1(e) + .long 0x4ad935ce // eor w14,w14,w25, ror #13 + .long 0x0b110318 // add w24,w24,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4ac54d8c // eor w12,w12,w5, ror #19 + .long 0x4a480dad // eor w13,w13,w8, lsr #3 // sigma0(X[i+1]) + .long 0x0b100318 // add w24,w24,w16 // h+=Sigma1(e) + .long 0x4a1a0273 // eor w19,w19,w26 // Maj(a,b,c) + .long 0x4ad959d1 // eor w17,w14,w25, ror #22 // Sigma0(a) + .long 0x4a45298c // eor w12,w12,w5, lsr #10 // sigma1(X[i+14]) + .long 0x0b0000e7 // add w7,w7,w0 + .long 0x0b180294 // add w20,w20,w24 // d+=h + .long 0x0b130318 // add w24,w24,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b0d00e7 // add w7,w7,w13 + .long 0x0b110318 // add w24,w24,w17 // h+=Sigma0(a) + .long 0x0b0c00e7 // add w7,w7,w12 + .long 0xb94007ec // ldr w12,[sp,#4] + .long 0xb90003ef // str w15,[sp,#0] + .long 0x13941a90 // ror w16,w20,#6 + .long 0x0b1302f7 // add w23,w23,w19 // h+=K[i] + .long 0x13891d2e // ror w14,w9,#7 + .long 0x0a1402b1 // and w17,w21,w20 + .long 0x138644cd // ror w13,w6,#17 + .long 0x0a3402d3 // bic w19,w22,w20 + .long 0x13980b0f // ror w15,w24,#2 + .long 0x0b0702f7 // add w23,w23,w7 // h+=X[i] + .long 0x4ad42e10 // eor w16,w16,w20, ror #11 + .long 0x4ac949ce // eor w14,w14,w9, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a190313 // eor w19,w24,w25 // a^b, b^c in next round + .long 0x4ad46610 // eor w16,w16,w20, ror #25 // Sigma1(e) + .long 0x4ad835ef // eor w15,w15,w24, ror #13 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4ac64dad // eor w13,w13,w6, ror #19 + .long 0x4a490dce // eor w14,w14,w9, lsr #3 // sigma0(X[i+1]) + .long 0x0b1002f7 // add w23,w23,w16 // h+=Sigma1(e) + .long 0x4a19039c // eor w28,w28,w25 // Maj(a,b,c) + .long 0x4ad859f1 // eor w17,w15,w24, ror #22 // Sigma0(a) + .long 0x4a4629ad // eor w13,w13,w6, lsr #10 // sigma1(X[i+14]) + .long 0x0b010108 // add w8,w8,w1 + .long 0x0b17037b // add w27,w27,w23 // d+=h + .long 0x0b1c02f7 // add w23,w23,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b0e0108 // add w8,w8,w14 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Sigma0(a) + .long 0x0b0d0108 // add w8,w8,w13 + .long 0xb9400bed // ldr w13,[sp,#8] + .long 0xb90007e0 // str w0,[sp,#4] + .long 0x139b1b70 // ror w16,w27,#6 + .long 0x0b1c02d6 // add w22,w22,w28 // h+=K[i] + .long 0x138a1d4f // ror w15,w10,#7 + .long 0x0a1b0291 // and w17,w20,w27 + .long 0x138744ee // ror w14,w7,#17 + .long 0x0a3b02bc // bic w28,w21,w27 + .long 0x13970ae0 // ror w0,w23,#2 + .long 0x0b0802d6 // add w22,w22,w8 // h+=X[i] + .long 0x4adb2e10 // eor w16,w16,w27, ror #11 + .long 0x4aca49ef // eor w15,w15,w10, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1802fc // eor w28,w23,w24 // a^b, b^c in next round + .long 0x4adb6610 // eor w16,w16,w27, ror #25 // Sigma1(e) + .long 0x4ad73400 // eor w0,w0,w23, ror #13 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4ac74dce // eor w14,w14,w7, ror #19 + .long 0x4a4a0def // eor w15,w15,w10, lsr #3 // sigma0(X[i+1]) + .long 0x0b1002d6 // add w22,w22,w16 // h+=Sigma1(e) + .long 0x4a180273 // eor w19,w19,w24 // Maj(a,b,c) + .long 0x4ad75811 // eor w17,w0,w23, ror #22 // Sigma0(a) + .long 0x4a4729ce // eor w14,w14,w7, lsr #10 // sigma1(X[i+14]) + .long 0x0b020129 // add w9,w9,w2 + .long 0x0b16035a // add w26,w26,w22 // d+=h + .long 0x0b1302d6 // add w22,w22,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b0f0129 // add w9,w9,w15 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Sigma0(a) + .long 0x0b0e0129 // add w9,w9,w14 + .long 0xb9400fee // ldr w14,[sp,#12] + .long 0xb9000be1 // str w1,[sp,#8] + .long 0x139a1b50 // ror w16,w26,#6 + .long 0x0b1302b5 // add w21,w21,w19 // h+=K[i] + .long 0x138b1d60 // ror w0,w11,#7 + .long 0x0a1a0371 // and w17,w27,w26 + .long 0x1388450f // ror w15,w8,#17 + .long 0x0a3a0293 // bic w19,w20,w26 + .long 0x13960ac1 // ror w1,w22,#2 + .long 0x0b0902b5 // add w21,w21,w9 // h+=X[i] + .long 0x4ada2e10 // eor w16,w16,w26, ror #11 + .long 0x4acb4800 // eor w0,w0,w11, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1702d3 // eor w19,w22,w23 // a^b, b^c in next round + .long 0x4ada6610 // eor w16,w16,w26, ror #25 // Sigma1(e) + .long 0x4ad63421 // eor w1,w1,w22, ror #13 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4ac84def // eor w15,w15,w8, ror #19 + .long 0x4a4b0c00 // eor w0,w0,w11, lsr #3 // sigma0(X[i+1]) + .long 0x0b1002b5 // add w21,w21,w16 // h+=Sigma1(e) + .long 0x4a17039c // eor w28,w28,w23 // Maj(a,b,c) + .long 0x4ad65831 // eor w17,w1,w22, ror #22 // Sigma0(a) + .long 0x4a4829ef // eor w15,w15,w8, lsr #10 // sigma1(X[i+14]) + .long 0x0b03014a // add w10,w10,w3 + .long 0x0b150339 // add w25,w25,w21 // d+=h + .long 0x0b1c02b5 // add w21,w21,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b00014a // add w10,w10,w0 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Sigma0(a) + .long 0x0b0f014a // add w10,w10,w15 + .long 0xb94003ef // ldr w15,[sp,#0] + .long 0xb9000fe2 // str w2,[sp,#12] + .long 0x13991b30 // ror w16,w25,#6 + .long 0x0b1c0294 // add w20,w20,w28 // h+=K[i] + .long 0x138c1d81 // ror w1,w12,#7 + .long 0x0a190351 // and w17,w26,w25 + .long 0x13894520 // ror w0,w9,#17 + .long 0x0a39037c // bic w28,w27,w25 + .long 0x13950aa2 // ror w2,w21,#2 + .long 0x0b0a0294 // add w20,w20,w10 // h+=X[i] + .long 0x4ad92e10 // eor w16,w16,w25, ror #11 + .long 0x4acc4821 // eor w1,w1,w12, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1602bc // eor w28,w21,w22 // a^b, b^c in next round + .long 0x4ad96610 // eor w16,w16,w25, ror #25 // Sigma1(e) + .long 0x4ad53442 // eor w2,w2,w21, ror #13 + .long 0x0b110294 // add w20,w20,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4ac94c00 // eor w0,w0,w9, ror #19 + .long 0x4a4c0c21 // eor w1,w1,w12, lsr #3 // sigma0(X[i+1]) + .long 0x0b100294 // add w20,w20,w16 // h+=Sigma1(e) + .long 0x4a160273 // eor w19,w19,w22 // Maj(a,b,c) + .long 0x4ad55851 // eor w17,w2,w21, ror #22 // Sigma0(a) + .long 0x4a492800 // eor w0,w0,w9, lsr #10 // sigma1(X[i+14]) + .long 0x0b04016b // add w11,w11,w4 + .long 0x0b140318 // add w24,w24,w20 // d+=h + .long 0x0b130294 // add w20,w20,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b01016b // add w11,w11,w1 + .long 0x0b110294 // add w20,w20,w17 // h+=Sigma0(a) + .long 0x0b00016b // add w11,w11,w0 + .long 0xb94007e0 // ldr w0,[sp,#4] + .long 0xb90003e3 // str w3,[sp,#0] + .long 0x13981b10 // ror w16,w24,#6 + .long 0x0b13037b // add w27,w27,w19 // h+=K[i] + .long 0x138d1da2 // ror w2,w13,#7 + .long 0x0a180331 // and w17,w25,w24 + .long 0x138a4541 // ror w1,w10,#17 + .long 0x0a380353 // bic w19,w26,w24 + .long 0x13940a83 // ror w3,w20,#2 + .long 0x0b0b037b // add w27,w27,w11 // h+=X[i] + .long 0x4ad82e10 // eor w16,w16,w24, ror #11 + .long 0x4acd4842 // eor w2,w2,w13, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a150293 // eor w19,w20,w21 // a^b, b^c in next round + .long 0x4ad86610 // eor w16,w16,w24, ror #25 // Sigma1(e) + .long 0x4ad43463 // eor w3,w3,w20, ror #13 + .long 0x0b11037b // add w27,w27,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4aca4c21 // eor w1,w1,w10, ror #19 + .long 0x4a4d0c42 // eor w2,w2,w13, lsr #3 // sigma0(X[i+1]) + .long 0x0b10037b // add w27,w27,w16 // h+=Sigma1(e) + .long 0x4a15039c // eor w28,w28,w21 // Maj(a,b,c) + .long 0x4ad45871 // eor w17,w3,w20, ror #22 // Sigma0(a) + .long 0x4a4a2821 // eor w1,w1,w10, lsr #10 // sigma1(X[i+14]) + .long 0x0b05018c // add w12,w12,w5 + .long 0x0b1b02f7 // add w23,w23,w27 // d+=h + .long 0x0b1c037b // add w27,w27,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b02018c // add w12,w12,w2 + .long 0x0b11037b // add w27,w27,w17 // h+=Sigma0(a) + .long 0x0b01018c // add w12,w12,w1 + .long 0xb9400be1 // ldr w1,[sp,#8] + .long 0xb90007e4 // str w4,[sp,#4] + .long 0x13971af0 // ror w16,w23,#6 + .long 0x0b1c035a // add w26,w26,w28 // h+=K[i] + .long 0x138e1dc3 // ror w3,w14,#7 + .long 0x0a170311 // and w17,w24,w23 + .long 0x138b4562 // ror w2,w11,#17 + .long 0x0a37033c // bic w28,w25,w23 + .long 0x139b0b64 // ror w4,w27,#2 + .long 0x0b0c035a // add w26,w26,w12 // h+=X[i] + .long 0x4ad72e10 // eor w16,w16,w23, ror #11 + .long 0x4ace4863 // eor w3,w3,w14, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a14037c // eor w28,w27,w20 // a^b, b^c in next round + .long 0x4ad76610 // eor w16,w16,w23, ror #25 // Sigma1(e) + .long 0x4adb3484 // eor w4,w4,w27, ror #13 + .long 0x0b11035a // add w26,w26,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4acb4c42 // eor w2,w2,w11, ror #19 + .long 0x4a4e0c63 // eor w3,w3,w14, lsr #3 // sigma0(X[i+1]) + .long 0x0b10035a // add w26,w26,w16 // h+=Sigma1(e) + .long 0x4a140273 // eor w19,w19,w20 // Maj(a,b,c) + .long 0x4adb5891 // eor w17,w4,w27, ror #22 // Sigma0(a) + .long 0x4a4b2842 // eor w2,w2,w11, lsr #10 // sigma1(X[i+14]) + .long 0x0b0601ad // add w13,w13,w6 + .long 0x0b1a02d6 // add w22,w22,w26 // d+=h + .long 0x0b13035a // add w26,w26,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b0301ad // add w13,w13,w3 + .long 0x0b11035a // add w26,w26,w17 // h+=Sigma0(a) + .long 0x0b0201ad // add w13,w13,w2 + .long 0xb9400fe2 // ldr w2,[sp,#12] + .long 0xb9000be5 // str w5,[sp,#8] + .long 0x13961ad0 // ror w16,w22,#6 + .long 0x0b130339 // add w25,w25,w19 // h+=K[i] + .long 0x138f1de4 // ror w4,w15,#7 + .long 0x0a1602f1 // and w17,w23,w22 + .long 0x138c4583 // ror w3,w12,#17 + .long 0x0a360313 // bic w19,w24,w22 + .long 0x139a0b45 // ror w5,w26,#2 + .long 0x0b0d0339 // add w25,w25,w13 // h+=X[i] + .long 0x4ad62e10 // eor w16,w16,w22, ror #11 + .long 0x4acf4884 // eor w4,w4,w15, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1b0353 // eor w19,w26,w27 // a^b, b^c in next round + .long 0x4ad66610 // eor w16,w16,w22, ror #25 // Sigma1(e) + .long 0x4ada34a5 // eor w5,w5,w26, ror #13 + .long 0x0b110339 // add w25,w25,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4acc4c63 // eor w3,w3,w12, ror #19 + .long 0x4a4f0c84 // eor w4,w4,w15, lsr #3 // sigma0(X[i+1]) + .long 0x0b100339 // add w25,w25,w16 // h+=Sigma1(e) + .long 0x4a1b039c // eor w28,w28,w27 // Maj(a,b,c) + .long 0x4ada58b1 // eor w17,w5,w26, ror #22 // Sigma0(a) + .long 0x4a4c2863 // eor w3,w3,w12, lsr #10 // sigma1(X[i+14]) + .long 0x0b0701ce // add w14,w14,w7 + .long 0x0b1902b5 // add w21,w21,w25 // d+=h + .long 0x0b1c0339 // add w25,w25,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b0401ce // add w14,w14,w4 + .long 0x0b110339 // add w25,w25,w17 // h+=Sigma0(a) + .long 0x0b0301ce // add w14,w14,w3 + .long 0xb94003e3 // ldr w3,[sp,#0] + .long 0xb9000fe6 // str w6,[sp,#12] + .long 0x13951ab0 // ror w16,w21,#6 + .long 0x0b1c0318 // add w24,w24,w28 // h+=K[i] + .long 0x13801c05 // ror w5,w0,#7 + .long 0x0a1502d1 // and w17,w22,w21 + .long 0x138d45a4 // ror w4,w13,#17 + .long 0x0a3502fc // bic w28,w23,w21 + .long 0x13990b26 // ror w6,w25,#2 + .long 0x0b0e0318 // add w24,w24,w14 // h+=X[i] + .long 0x4ad52e10 // eor w16,w16,w21, ror #11 + .long 0x4ac048a5 // eor w5,w5,w0, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1a033c // eor w28,w25,w26 // a^b, b^c in next round + .long 0x4ad56610 // eor w16,w16,w21, ror #25 // Sigma1(e) + .long 0x4ad934c6 // eor w6,w6,w25, ror #13 + .long 0x0b110318 // add w24,w24,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4acd4c84 // eor w4,w4,w13, ror #19 + .long 0x4a400ca5 // eor w5,w5,w0, lsr #3 // sigma0(X[i+1]) + .long 0x0b100318 // add w24,w24,w16 // h+=Sigma1(e) + .long 0x4a1a0273 // eor w19,w19,w26 // Maj(a,b,c) + .long 0x4ad958d1 // eor w17,w6,w25, ror #22 // Sigma0(a) + .long 0x4a4d2884 // eor w4,w4,w13, lsr #10 // sigma1(X[i+14]) + .long 0x0b0801ef // add w15,w15,w8 + .long 0x0b180294 // add w20,w20,w24 // d+=h + .long 0x0b130318 // add w24,w24,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b0501ef // add w15,w15,w5 + .long 0x0b110318 // add w24,w24,w17 // h+=Sigma0(a) + .long 0x0b0401ef // add w15,w15,w4 + .long 0xb94007e4 // ldr w4,[sp,#4] + .long 0xb90003e7 // str w7,[sp,#0] + .long 0x13941a90 // ror w16,w20,#6 + .long 0x0b1302f7 // add w23,w23,w19 // h+=K[i] + .long 0x13811c26 // ror w6,w1,#7 + .long 0x0a1402b1 // and w17,w21,w20 + .long 0x138e45c5 // ror w5,w14,#17 + .long 0x0a3402d3 // bic w19,w22,w20 + .long 0x13980b07 // ror w7,w24,#2 + .long 0x0b0f02f7 // add w23,w23,w15 // h+=X[i] + .long 0x4ad42e10 // eor w16,w16,w20, ror #11 + .long 0x4ac148c6 // eor w6,w6,w1, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a190313 // eor w19,w24,w25 // a^b, b^c in next round + .long 0x4ad46610 // eor w16,w16,w20, ror #25 // Sigma1(e) + .long 0x4ad834e7 // eor w7,w7,w24, ror #13 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4ace4ca5 // eor w5,w5,w14, ror #19 + .long 0x4a410cc6 // eor w6,w6,w1, lsr #3 // sigma0(X[i+1]) + .long 0x0b1002f7 // add w23,w23,w16 // h+=Sigma1(e) + .long 0x4a19039c // eor w28,w28,w25 // Maj(a,b,c) + .long 0x4ad858f1 // eor w17,w7,w24, ror #22 // Sigma0(a) + .long 0x4a4e28a5 // eor w5,w5,w14, lsr #10 // sigma1(X[i+14]) + .long 0x0b090000 // add w0,w0,w9 + .long 0x0b17037b // add w27,w27,w23 // d+=h + .long 0x0b1c02f7 // add w23,w23,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b060000 // add w0,w0,w6 + .long 0x0b1102f7 // add w23,w23,w17 // h+=Sigma0(a) + .long 0x0b050000 // add w0,w0,w5 + .long 0xb9400be5 // ldr w5,[sp,#8] + .long 0xb90007e8 // str w8,[sp,#4] + .long 0x139b1b70 // ror w16,w27,#6 + .long 0x0b1c02d6 // add w22,w22,w28 // h+=K[i] + .long 0x13821c47 // ror w7,w2,#7 + .long 0x0a1b0291 // and w17,w20,w27 + .long 0x138f45e6 // ror w6,w15,#17 + .long 0x0a3b02bc // bic w28,w21,w27 + .long 0x13970ae8 // ror w8,w23,#2 + .long 0x0b0002d6 // add w22,w22,w0 // h+=X[i] + .long 0x4adb2e10 // eor w16,w16,w27, ror #11 + .long 0x4ac248e7 // eor w7,w7,w2, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1802fc // eor w28,w23,w24 // a^b, b^c in next round + .long 0x4adb6610 // eor w16,w16,w27, ror #25 // Sigma1(e) + .long 0x4ad73508 // eor w8,w8,w23, ror #13 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4acf4cc6 // eor w6,w6,w15, ror #19 + .long 0x4a420ce7 // eor w7,w7,w2, lsr #3 // sigma0(X[i+1]) + .long 0x0b1002d6 // add w22,w22,w16 // h+=Sigma1(e) + .long 0x4a180273 // eor w19,w19,w24 // Maj(a,b,c) + .long 0x4ad75911 // eor w17,w8,w23, ror #22 // Sigma0(a) + .long 0x4a4f28c6 // eor w6,w6,w15, lsr #10 // sigma1(X[i+14]) + .long 0x0b0a0021 // add w1,w1,w10 + .long 0x0b16035a // add w26,w26,w22 // d+=h + .long 0x0b1302d6 // add w22,w22,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b070021 // add w1,w1,w7 + .long 0x0b1102d6 // add w22,w22,w17 // h+=Sigma0(a) + .long 0x0b060021 // add w1,w1,w6 + .long 0xb9400fe6 // ldr w6,[sp,#12] + .long 0xb9000be9 // str w9,[sp,#8] + .long 0x139a1b50 // ror w16,w26,#6 + .long 0x0b1302b5 // add w21,w21,w19 // h+=K[i] + .long 0x13831c68 // ror w8,w3,#7 + .long 0x0a1a0371 // and w17,w27,w26 + .long 0x13804407 // ror w7,w0,#17 + .long 0x0a3a0293 // bic w19,w20,w26 + .long 0x13960ac9 // ror w9,w22,#2 + .long 0x0b0102b5 // add w21,w21,w1 // h+=X[i] + .long 0x4ada2e10 // eor w16,w16,w26, ror #11 + .long 0x4ac34908 // eor w8,w8,w3, ror #18 + .long 0x2a130231 // orr w17,w17,w19 // Ch(e,f,g) + .long 0x4a1702d3 // eor w19,w22,w23 // a^b, b^c in next round + .long 0x4ada6610 // eor w16,w16,w26, ror #25 // Sigma1(e) + .long 0x4ad63529 // eor w9,w9,w22, ror #13 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Ch(e,f,g) + .long 0x0a13039c // and w28,w28,w19 // (b^c)&=(a^b) + .long 0x4ac04ce7 // eor w7,w7,w0, ror #19 + .long 0x4a430d08 // eor w8,w8,w3, lsr #3 // sigma0(X[i+1]) + .long 0x0b1002b5 // add w21,w21,w16 // h+=Sigma1(e) + .long 0x4a17039c // eor w28,w28,w23 // Maj(a,b,c) + .long 0x4ad65931 // eor w17,w9,w22, ror #22 // Sigma0(a) + .long 0x4a4028e7 // eor w7,w7,w0, lsr #10 // sigma1(X[i+14]) + .long 0x0b0b0042 // add w2,w2,w11 + .long 0x0b150339 // add w25,w25,w21 // d+=h + .long 0x0b1c02b5 // add w21,w21,w28 // h+=Maj(a,b,c) + .long 0xb84047dc // ldr w28,[x30],#4 // *K++, w19 in next round + .long 0x0b080042 // add w2,w2,w8 + .long 0x0b1102b5 // add w21,w21,w17 // h+=Sigma0(a) + .long 0x0b070042 // add w2,w2,w7 + .long 0xb94003e7 // ldr w7,[sp,#0] + .long 0xb9000fea // str w10,[sp,#12] + .long 0x13991b30 // ror w16,w25,#6 + .long 0x0b1c0294 // add w20,w20,w28 // h+=K[i] + .long 0x13841c89 // ror w9,w4,#7 + .long 0x0a190351 // and w17,w26,w25 + .long 0x13814428 // ror w8,w1,#17 + .long 0x0a39037c // bic w28,w27,w25 + .long 0x13950aaa // ror w10,w21,#2 + .long 0x0b020294 // add w20,w20,w2 // h+=X[i] + .long 0x4ad92e10 // eor w16,w16,w25, ror #11 + .long 0x4ac44929 // eor w9,w9,w4, ror #18 + .long 0x2a1c0231 // orr w17,w17,w28 // Ch(e,f,g) + .long 0x4a1602bc // eor w28,w21,w22 // a^b, b^c in next round + .long 0x4ad96610 // eor w16,w16,w25, ror #25 // Sigma1(e) + .long 0x4ad5354a // eor w10,w10,w21, ror #13 + .long 0x0b110294 // add w20,w20,w17 // h+=Ch(e,f,g) + .long 0x0a1c0273 // and w19,w19,w28 // (b^c)&=(a^b) + .long 0x4ac14d08 // eor w8,w8,w1, ror #19 + .long 0x4a440d29 // eor w9,w9,w4, lsr #3 // sigma0(X[i+1]) + .long 0x0b100294 // add w20,w20,w16 // h+=Sigma1(e) + .long 0x4a160273 // eor w19,w19,w22 // Maj(a,b,c) + .long 0x4ad55951 // eor w17,w10,w21, ror #22 // Sigma0(a) + .long 0x4a412908 // eor w8,w8,w1, lsr #10 // sigma1(X[i+14]) + .long 0x0b0c0063 // add w3,w3,w12 + .long 0x0b140318 // add w24,w24,w20 // d+=h + .long 0x0b130294 // add w20,w20,w19 // h+=Maj(a,b,c) + .long 0xb84047d3 // ldr w19,[x30],#4 // *K++, w28 in next round + .long 0x0b090063 // add w3,w3,w9 + .long 0x0b110294 // add w20,w20,w17 // h+=Sigma0(a) + .long 0x0b080063 // add w3,w3,w8 + cbnz w19,.Lsha256_gpr_loop_16_xx + + .long 0xa9460ba0 // ldp x0,x2,[x29,#96] + .long 0xf9403ba1 // ldr x1,[x29,#112] + .long 0xd10413de // sub x30,x30,#260 // rewind + + .long 0x29401003 // ldp w3,w4,[x0] + .long 0x29411805 // ldp w5,w6,[x0,#2*4] + .long 0x9100e021 // add x1,x1,#14*4 // advance input pointer + .long 0x29422007 // ldp w7,w8,[x0,#4*4] + .long 0x0b030294 // add w20,w20,w3 + .long 0x29432809 // ldp w9,w10,[x0,#6*4] + .long 0x0b0402b5 // add w21,w21,w4 + .long 0x0b0502d6 // add w22,w22,w5 + .long 0x0b0602f7 // add w23,w23,w6 + .long 0x29005414 // stp w20,w21,[x0] + .long 0x0b070318 // add w24,w24,w7 + .long 0x0b080339 // add w25,w25,w8 + .long 0x29015c16 // stp w22,w23,[x0,#2*4] + .long 0x0b09035a // add w26,w26,w9 + .long 0x0b0a037b // add w27,w27,w10 + .long 0xeb02003f // cmp x1,x2 + .long 0x29026418 // stp w24,w25,[x0,#4*4] + .long 0x29036c1a // stp w26,w27,[x0,#6*4] + b.ne .Lsha256_gpr_loop + + .long 0xa94153b3 // ldp x19,x20,[x29,#16] + .long 0x910043ff // add sp,sp,#4*4 + .long 0xa9425bb5 // ldp x21,x22,[x29,#32] + .long 0xa94363b7 // ldp x23,x24,[x29,#48] + .long 0xa9446bb9 // ldp x25,x26,[x29,#64] + .long 0xa94573bb // ldp x27,x28,[x29,#80] + .long 0xa8c87bfd // ldp x29,x30,[sp],#128 + ret diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc new file mode 100644 index 0000000..c575f0b --- /dev/null +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc @@ -0,0 +1,352 @@ +// Keccak-f[1600] pure-GPR multi-block absorb (AArch64) for cores without +// FEAT_SHA3; the Gpr name states the ISA requirement: none beyond base +// AArch64. XORs each rate-sized block into the state (unrolled per-lane +// ladder driven by the block size), then runs the same GPR permutation as +// KeccakF1600Gpr_aarch64.inc - the inner is this file's own copy. +// Expects AAPCS64 (after HlpSimdProc5Begin_aarch64): x0 = AState +// (25 x UInt64, standard layout), x1 = AData, w2 = ABlockCount, +// w3 = ABlockSize (bytes), x4 = AConstants (iotas: 24 x UInt64). +// The reference takes a byte length; it is computed as +// ABlockCount * ABlockSize on entry. The reference frame grows 64 -> 80 +// because its own slots occupy [sp,#32..63] - the iotas end pointer for the +// permutation's end-pointer termination (see the permute kernel's header) +// lives at [sp,#64]. +// AArch64 instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.pl (SHA3_absorb + +// KeccakF1600_int, the plain path) by Andy Polyakov. + + .long 0xa9b87bfd // stp x29,x30,[sp,#-128]! + .long 0x910003fd // add x29,sp,#0 + .long 0xa90153f3 // stp x19,x20,[sp,#16] + .long 0xa9025bf5 // stp x21,x22,[sp,#32] + .long 0xa90363f7 // stp x23,x24,[sp,#48] + .long 0xa9046bf9 // stp x25,x26,[sp,#64] + .long 0xa90573fb // stp x27,x28,[sp,#80] + .long 0xd10143ff // sub sp,sp,#80 // reference frame + 16 for the iotas end slot + .long 0x91030084 // add x4,x4,#192 // iotas end = AConstants + 24*8 + .long 0xf90023e4 // str x4,[sp,#64] // stashed for the inner + .long 0x9ba37c42 // umull x2,w2,w3 // len = ABlockCount * ABlockSize bytes + .long 0x2a0303e3 // mov w3,w3 // zero-extend ABlockSize (AAPCS64 leaves x3's top half undefined) + + .long 0xa90207e0 // stp x0,x1,[sp,#32] // offload arguments + .long 0xa9030fe2 // stp x2,x3,[sp,#48] + + .long 0xaa0003fa // mov x26,x0 // uint64_t A[5][5] + .long 0xaa0103fb // mov x27,x1 // const void *inp + .long 0xaa0203fc // mov x28,x2 // size_t len + .long 0xaa0303fe // mov x30,x3 // size_t bsz + .long 0xa9400740 // ldp x0,x1,[x26,#16*0] + .long 0xa9410f42 // ldp x2,x3,[x26,#16*1] + .long 0xa9421744 // ldp x4,x5,[x26,#16*2] + .long 0xa9431f46 // ldp x6,x7,[x26,#16*3] + .long 0xa9442748 // ldp x8,x9,[x26,#16*4] + .long 0xa9452f4a // ldp x10,x11,[x26,#16*5] + .long 0xa946374c // ldp x12,x13,[x26,#16*6] + .long 0xa9473f4e // ldp x14,x15,[x26,#16*7] + .long 0xa9484750 // ldp x16,x17,[x26,#16*8] + .long 0xa9494f59 // ldp x25,x19,[x26,#16*9] + .long 0xa94a5754 // ldp x20,x21,[x26,#16*10] + .long 0xa94b5f56 // ldp x22,x23,[x26,#16*11] + .long 0xf9406358 // ldr x24,[x26,#16*12] + b .Lkeccak_gpr_absorb_loop_absorb + + +.Lkeccak_gpr_absorb_loop_absorb: + .long 0xeb1e039a // subs x26,x28,x30 // len - bsz + b.lo .Lkeccak_gpr_absorb_absorbed + + .long 0xf9001bfa // str x26,[sp,#48] // save len - bsz + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0000 // eor x0,x0,x26 + .long 0xf10043df // cmp x30,#8*(0+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0021 // eor x1,x1,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0042 // eor x2,x2,x26 + .long 0xf10083df // cmp x30,#8*(2+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0063 // eor x3,x3,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0084 // eor x4,x4,x26 + .long 0xf100c3df // cmp x30,#8*(4+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a00a5 // eor x5,x5,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a00c6 // eor x6,x6,x26 + .long 0xf10103df // cmp x30,#8*(6+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a00e7 // eor x7,x7,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0108 // eor x8,x8,x26 + .long 0xf10143df // cmp x30,#8*(8+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0129 // eor x9,x9,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a014a // eor x10,x10,x26 + .long 0xf10183df // cmp x30,#8*(10+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a016b // eor x11,x11,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a018c // eor x12,x12,x26 + .long 0xf101c3df // cmp x30,#8*(12+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a01ad // eor x13,x13,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a01ce // eor x14,x14,x26 + .long 0xf10203df // cmp x30,#8*(14+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a01ef // eor x15,x15,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0210 // eor x16,x16,x26 + .long 0xf10243df // cmp x30,#8*(16+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0231 // eor x17,x17,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0339 // eor x25,x25,x26 + .long 0xf10283df // cmp x30,#8*(18+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0273 // eor x19,x19,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0294 // eor x20,x20,x26 + .long 0xf102c3df // cmp x30,#8*(20+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a02b5 // eor x21,x21,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a02d6 // eor x22,x22,x26 + .long 0xf10303df // cmp x30,#8*(22+2) + b.lo .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a02f7 // eor x23,x23,x26 + b.eq .Lkeccak_gpr_absorb_process_block + .long 0xf840877a // ldr x26,[x27],#8 // *inp++ + .long 0xca1a0318 // eor x24,x24,x26 + + +.Lkeccak_gpr_absorb_process_block: + .long 0xf90017fb // str x27,[sp,#40] // save inp + + bl .Lkeccak_gpr_absorb_int + + .long 0xf94017fb // ldr x27,[sp,#40] // restore arguments + .long 0xa9437bfc // ldp x28,x30,[sp,#48] + b .Lkeccak_gpr_absorb_loop_absorb + + +.Lkeccak_gpr_absorb_absorbed: + .long 0xf94013fb // ldr x27,[sp,#32] + .long 0xa9000760 // stp x0,x1,[x27,#16*0] + .long 0xa9010f62 // stp x2,x3,[x27,#16*1] + .long 0xa9021764 // stp x4,x5,[x27,#16*2] + .long 0xa9031f66 // stp x6,x7,[x27,#16*3] + .long 0xa9042768 // stp x8,x9,[x27,#16*4] + .long 0xa9052f6a // stp x10,x11,[x27,#16*5] + .long 0xa906376c // stp x12,x13,[x27,#16*6] + .long 0xa9073f6e // stp x14,x15,[x27,#16*7] + .long 0xa9084770 // stp x16,x17,[x27,#16*8] + .long 0xa9094f79 // stp x25,x19,[x27,#16*9] + .long 0xa90a5774 // stp x20,x21,[x27,#16*10] + .long 0xa90b5f76 // stp x22,x23,[x27,#16*11] + .long 0xf9006378 // str x24,[x27,#16*12] + + .long 0xaa1c03e0 // mov x0,x28 // return value + .long 0xa94153b3 // ldp x19,x20,[x29,#16] + .long 0x910143ff // add sp,sp,#80 + .long 0xa9425bb5 // ldp x21,x22,[x29,#32] + .long 0xa94363b7 // ldp x23,x24,[x29,#48] + .long 0xa9446bb9 // ldp x25,x26,[x29,#64] + .long 0xa94573bb // ldp x27,x28,[x29,#80] + .long 0xa8c87bfd // ldp x29,x30,[sp],#128 + ret + + +.Lkeccak_gpr_absorb_int: + .long 0xf94023fc // ldr x28,[sp,#64] // iotas end (stashed by the absorb) + .long 0xd103039c // sub x28,x28,#192 // iotas base (24 x 8) + .long 0xa9017bfc // stp x28,x30,[sp,#16] // 32 bytes on top are mine + b .Lkeccak_gpr_absorb_loop + +.Lkeccak_gpr_absorb_loop: + ////////////////////////////////////////// Theta + .long 0xca05001a // eor x26,x0,x5 + .long 0xa90027e4 // stp x4,x9,[sp,#0] // offload pair... + .long 0xca06003b // eor x27,x1,x6 + .long 0xca07005c // eor x28,x2,x7 + .long 0xca08007e // eor x30,x3,x8 + .long 0xca090084 // eor x4,x4,x9 + .long 0xca0a035a // eor x26,x26,x10 + .long 0xca0b037b // eor x27,x27,x11 + .long 0xca0c039c // eor x28,x28,x12 + .long 0xca0d03de // eor x30,x30,x13 + .long 0xca0e0084 // eor x4,x4,x14 + .long 0xca0f035a // eor x26,x26,x15 + .long 0xca10037b // eor x27,x27,x16 + .long 0xca11039c // eor x28,x28,x17 + .long 0xca1903de // eor x30,x30,x25 + .long 0xca130084 // eor x4,x4,x19 + .long 0xca14035a // eor x26,x26,x20 + .long 0xca16039c // eor x28,x28,x22 + .long 0xca15037b // eor x27,x27,x21 + .long 0xca1703de // eor x30,x30,x23 + .long 0xca180084 // eor x4,x4,x24 + + .long 0xcadcff49 // eor x9,x26,x28, ror #63 + + .long 0xca090021 // eor x1,x1,x9 + .long 0xca0900c6 // eor x6,x6,x9 + .long 0xca09016b // eor x11,x11,x9 + .long 0xca090210 // eor x16,x16,x9 + .long 0xca0902b5 // eor x21,x21,x9 + + .long 0xcadeff69 // eor x9,x27,x30, ror #63 + .long 0xcac4ff9c // eor x28,x28,x4, ror #63 + .long 0xcadaffde // eor x30,x30,x26, ror #63 + .long 0xcadbfc84 // eor x4,x4,x27, ror #63 + + .long 0xca09005b // eor x27, x2,x9 // mov x27,x2 + .long 0xca0900e7 // eor x7,x7,x9 + .long 0xca09018c // eor x12,x12,x9 + .long 0xca090231 // eor x17,x17,x9 + .long 0xca0902d6 // eor x22,x22,x9 + + .long 0xca040000 // eor x0,x0,x4 + .long 0xca0400a5 // eor x5,x5,x4 + .long 0xca04014a // eor x10,x10,x4 + .long 0xca0401ef // eor x15,x15,x4 + .long 0xca040294 // eor x20,x20,x4 + .long 0xa94027e4 // ldp x4,x9,[sp,#0] // re-load offloaded data + .long 0xca1c007a // eor x26, x3,x28 // mov x26,x3 + .long 0xca1c0108 // eor x8,x8,x28 + .long 0xca1c01ad // eor x13,x13,x28 + .long 0xca1c0339 // eor x25,x25,x28 + .long 0xca1c02f7 // eor x23,x23,x28 + + .long 0xca1e009c // eor x28, x4,x30 // mov x28,x4 + .long 0xca1e0129 // eor x9,x9,x30 + .long 0xca1e01ce // eor x14,x14,x30 + .long 0xca1e0273 // eor x19,x19,x30 + .long 0xca1e0318 // eor x24,x24,x30 + + ////////////////////////////////////////// Rho+Pi + .long 0xaa0103fe // mov x30,x1 + .long 0x93c650c1 // ror x1,x6,#64-44 + //mov x27,x2 + .long 0x93cc5582 // ror x2,x12,#64-43 + //mov x26,x3 + .long 0x93d9af23 // ror x3,x25,#64-21 + //mov x28,x4 + .long 0x93d8cb04 // ror x4,x24,#64-14 + + .long 0x93c9b126 // ror x6,x9,#64-20 + .long 0x93cd9dac // ror x12,x13,#64-25 + .long 0x93d1c639 // ror x25,x17,#64-15 + .long 0x93d5fab8 // ror x24,x21,#64-2 + + .long 0x93d60ec9 // ror x9,x22,#64-61 + .long 0x93d3e26d // ror x13,x19,#64-8 + .long 0x93cbd971 // ror x17,x11,#64-10 + .long 0x93c82515 // ror x21,x8,#64-55 + + .long 0x93ce65d6 // ror x22,x14,#64-39 + .long 0x93d722f3 // ror x19,x23,#64-56 + .long 0x93c7e8eb // ror x11,x7,#64-6 + .long 0x93d04e08 // ror x8,x16,#64-45 + + .long 0x93d4ba8e // ror x14,x20,#64-18 + .long 0x93cf5df7 // ror x23,x15,#64-41 + .long 0x93caf547 // ror x7,x10,#64-3 + .long 0x93c570b0 // ror x16,x5,#64-36 + + .long 0x93da9345 // ror x5,x26,#64-28 + .long 0x93deffca // ror x10,x30,#64-1 + .long 0x93dc978f // ror x15,x28,#64-27 + .long 0x93db0b74 // ror x20,x27,#64-62 + + ////////////////////////////////////////// Chi+Iota + .long 0x8a21005a // bic x26,x2,x1 + .long 0x8a22007b // bic x27,x3,x2 + .long 0x8a24001c // bic x28,x0,x4 + .long 0x8a20003e // bic x30,x1,x0 + .long 0xca1a0000 // eor x0,x0,x26 + .long 0x8a23009a // bic x26,x4,x3 + .long 0xca1b0021 // eor x1,x1,x27 + .long 0xf9400bfb // ldr x27,[sp,#16] + .long 0xca1c0063 // eor x3,x3,x28 + .long 0xca1e0084 // eor x4,x4,x30 + .long 0xca1a0042 // eor x2,x2,x26 + .long 0xf840877e // ldr x30,[x27],#8 // Iota[i++] + .long 0xca1e0000 // eor x0,x0,x30 // A[0][0] ^= Iota (hoisted - frees x30 for the end test) + + .long 0x8a2600fa // bic x26,x7,x6 + .long 0xf94023fe // ldr x30,[sp,#64] // iotas end + .long 0xeb1e037f // cmp x27,x30 // are we done? (end-pointer test; a Pascal const + // cannot provide the original's 256-aligned table) + .long 0xf9000bfb // str x27,[sp,#16] + .long 0x8a27011b // bic x27,x8,x7 + .long 0x8a2900bc // bic x28,x5,x9 + .long 0x8a2500de // bic x30,x6,x5 + .long 0xca1a00a5 // eor x5,x5,x26 + .long 0x8a28013a // bic x26,x9,x8 + .long 0xca1b00c6 // eor x6,x6,x27 + .long 0xca1c0108 // eor x8,x8,x28 + .long 0xca1e0129 // eor x9,x9,x30 + .long 0xca1a00e7 // eor x7,x7,x26 + + .long 0x8a2b019a // bic x26,x12,x11 + .long 0x8a2c01bb // bic x27,x13,x12 + .long 0x8a2e015c // bic x28,x10,x14 + .long 0x8a2a017e // bic x30,x11,x10 + .long 0xca1a014a // eor x10,x10,x26 + .long 0x8a2d01da // bic x26,x14,x13 + .long 0xca1b016b // eor x11,x11,x27 + .long 0xca1c01ad // eor x13,x13,x28 + .long 0xca1e01ce // eor x14,x14,x30 + .long 0xca1a018c // eor x12,x12,x26 + + .long 0x8a30023a // bic x26,x17,x16 + .long 0x8a31033b // bic x27,x25,x17 + .long 0x8a3301fc // bic x28,x15,x19 + .long 0x8a2f021e // bic x30,x16,x15 + .long 0xca1a01ef // eor x15,x15,x26 + .long 0x8a39027a // bic x26,x19,x25 + .long 0xca1b0210 // eor x16,x16,x27 + .long 0xca1c0339 // eor x25,x25,x28 + .long 0xca1e0273 // eor x19,x19,x30 + .long 0xca1a0231 // eor x17,x17,x26 + + .long 0x8a3502da // bic x26,x22,x21 + .long 0x8a3602fb // bic x27,x23,x22 + .long 0x8a38029c // bic x28,x20,x24 + .long 0x8a3402be // bic x30,x21,x20 + .long 0xca1a0294 // eor x20,x20,x26 + .long 0x8a37031a // bic x26,x24,x23 + .long 0xca1b02b5 // eor x21,x21,x27 + .long 0xca1c02f7 // eor x23,x23,x28 + .long 0xca1e0318 // eor x24,x24,x30 + .long 0xca1a02d6 // eor x22,x22,x26 + + b.ne .Lkeccak_gpr_absorb_loop + + .long 0xf9400ffe // ldr x30,[sp,#24] + ret diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc similarity index 97% rename from HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc rename to HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc index cac5aa3..ee600e0 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc @@ -1,9 +1,9 @@ // Keccak-f[1600] sponge absorb for x86-64, pure 64-bit GPR code - the -// asm twin of the AVX2 absorb for the SSE2 dispatch slot: XORs whole blocks +// asm twin of the AVX2 absorb: XORs whole blocks // into the state and permutes, keeping the state in the lane-complemented // domain across the entire batch (the NOT conversion is hoisted out of the // block loop - the standalone permute pays it per call). -// The permutation body is the same inner as KeccakF1600Sse2_x86_64.inc +// The permutation body is the same inner as KeccakF1600Gpr_x86_64.inc // (embedded again because local labels cannot cross include files), with the // same end-pointer loop termination via the sentinel at [rsp]. // Reference: OpenSSL CRYPTOGAMS keccak1600-x86_64.pl (SHA3_absorb) by diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc new file mode 100644 index 0000000..401834c --- /dev/null +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc @@ -0,0 +1,240 @@ +// Keccak-f[1600] pure-GPR permutation (AArch64) for cores without FEAT_SHA3; +// the Gpr name states the ISA requirement: none beyond base AArch64. The 25 +// lanes live in x0-x17/x19-x25 with x26-x28/x30 as temps; chi is computed +// directly with bic, so no lane complementing exists in this lineage. +// Expects AAPCS64 (after HlpSimdProc2Begin_aarch64): x0 = AState +// (25 x UInt64, standard layout), x1 = AConstants (iotas: 24 x UInt64). +// The original round loop ended on a 256-ALIGNED iotas table (tst #255), +// which a Pascal const cannot guarantee - the termination is patched to an +// end-pointer compare (iotas end stashed at [sp,#40]; the Iota xor is +// hoisted to free x30 for the test; the intervening bic/eor stream writes +// no flags, so the b.ne polarity is unchanged). +// The inner keeps the original called shape (bl/ret); x30 (LR) doubles as a +// temp inside the rounds, as in the original. +// AArch64 instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.pl (KeccakF1600 + +// KeccakF1600_int, the plain path) by Andy Polyakov. + + .long 0xa9b87bfd // stp x29,x30,[sp,#-128]! + .long 0x910003fd // add x29,sp,#0 + .long 0xa90153f3 // stp x19,x20,[sp,#16] + .long 0xa9025bf5 // stp x21,x22,[sp,#32] + .long 0xa90363f7 // stp x23,x24,[sp,#48] + .long 0xa9046bf9 // stp x25,x26,[sp,#64] + .long 0xa90573fb // stp x27,x28,[sp,#80] + .long 0xd100c3ff // sub sp,sp,#48 + .long 0x91030021 // add x1,x1,#192 // iotas end = AConstants + 24*8 + .long 0xf90017e1 // str x1,[sp,#40] // stashed for the inner (frame slot is free) + + .long 0xf90013e0 // str x0,[sp,#32] // offload argument + .long 0xaa0003fa // mov x26,x0 + .long 0xa9400400 // ldp x0,x1,[x0,#16*0] + .long 0xa9410f42 // ldp x2,x3,[x26,#16*1] + .long 0xa9421744 // ldp x4,x5,[x26,#16*2] + .long 0xa9431f46 // ldp x6,x7,[x26,#16*3] + .long 0xa9442748 // ldp x8,x9,[x26,#16*4] + .long 0xa9452f4a // ldp x10,x11,[x26,#16*5] + .long 0xa946374c // ldp x12,x13,[x26,#16*6] + .long 0xa9473f4e // ldp x14,x15,[x26,#16*7] + .long 0xa9484750 // ldp x16,x17,[x26,#16*8] + .long 0xa9494f59 // ldp x25,x19,[x26,#16*9] + .long 0xa94a5754 // ldp x20,x21,[x26,#16*10] + .long 0xa94b5f56 // ldp x22,x23,[x26,#16*11] + .long 0xf9406358 // ldr x24,[x26,#16*12] + + bl .Lkeccak_gpr_int + + .long 0xf94013fa // ldr x26,[sp,#32] + .long 0xa9000740 // stp x0,x1,[x26,#16*0] + .long 0xa9010f42 // stp x2,x3,[x26,#16*1] + .long 0xa9021744 // stp x4,x5,[x26,#16*2] + .long 0xa9031f46 // stp x6,x7,[x26,#16*3] + .long 0xa9042748 // stp x8,x9,[x26,#16*4] + .long 0xa9052f4a // stp x10,x11,[x26,#16*5] + .long 0xa906374c // stp x12,x13,[x26,#16*6] + .long 0xa9073f4e // stp x14,x15,[x26,#16*7] + .long 0xa9084750 // stp x16,x17,[x26,#16*8] + .long 0xa9094f59 // stp x25,x19,[x26,#16*9] + .long 0xa90a5754 // stp x20,x21,[x26,#16*10] + .long 0xa90b5f56 // stp x22,x23,[x26,#16*11] + .long 0xf9006358 // str x24,[x26,#16*12] + + .long 0xa94153b3 // ldp x19,x20,[x29,#16] + .long 0x9100c3ff // add sp,sp,#48 + .long 0xa9425bb5 // ldp x21,x22,[x29,#32] + .long 0xa94363b7 // ldp x23,x24,[x29,#48] + .long 0xa9446bb9 // ldp x25,x26,[x29,#64] + .long 0xa94573bb // ldp x27,x28,[x29,#80] + .long 0xa8c87bfd // ldp x29,x30,[sp],#128 + ret + + +.Lkeccak_gpr_int: + .long 0xf94017fc // ldr x28,[sp,#40] // iotas end (stashed by the wrapper) + .long 0xd103039c // sub x28,x28,#192 // iotas base (24 x 8) + .long 0xa9017bfc // stp x28,x30,[sp,#16] // 32 bytes on top are mine + b .Lkeccak_gpr_loop + +.Lkeccak_gpr_loop: + ////////////////////////////////////////// Theta + .long 0xca05001a // eor x26,x0,x5 + .long 0xa90027e4 // stp x4,x9,[sp,#0] // offload pair... + .long 0xca06003b // eor x27,x1,x6 + .long 0xca07005c // eor x28,x2,x7 + .long 0xca08007e // eor x30,x3,x8 + .long 0xca090084 // eor x4,x4,x9 + .long 0xca0a035a // eor x26,x26,x10 + .long 0xca0b037b // eor x27,x27,x11 + .long 0xca0c039c // eor x28,x28,x12 + .long 0xca0d03de // eor x30,x30,x13 + .long 0xca0e0084 // eor x4,x4,x14 + .long 0xca0f035a // eor x26,x26,x15 + .long 0xca10037b // eor x27,x27,x16 + .long 0xca11039c // eor x28,x28,x17 + .long 0xca1903de // eor x30,x30,x25 + .long 0xca130084 // eor x4,x4,x19 + .long 0xca14035a // eor x26,x26,x20 + .long 0xca16039c // eor x28,x28,x22 + .long 0xca15037b // eor x27,x27,x21 + .long 0xca1703de // eor x30,x30,x23 + .long 0xca180084 // eor x4,x4,x24 + + .long 0xcadcff49 // eor x9,x26,x28, ror #63 + + .long 0xca090021 // eor x1,x1,x9 + .long 0xca0900c6 // eor x6,x6,x9 + .long 0xca09016b // eor x11,x11,x9 + .long 0xca090210 // eor x16,x16,x9 + .long 0xca0902b5 // eor x21,x21,x9 + + .long 0xcadeff69 // eor x9,x27,x30, ror #63 + .long 0xcac4ff9c // eor x28,x28,x4, ror #63 + .long 0xcadaffde // eor x30,x30,x26, ror #63 + .long 0xcadbfc84 // eor x4,x4,x27, ror #63 + + .long 0xca09005b // eor x27, x2,x9 // mov x27,x2 + .long 0xca0900e7 // eor x7,x7,x9 + .long 0xca09018c // eor x12,x12,x9 + .long 0xca090231 // eor x17,x17,x9 + .long 0xca0902d6 // eor x22,x22,x9 + + .long 0xca040000 // eor x0,x0,x4 + .long 0xca0400a5 // eor x5,x5,x4 + .long 0xca04014a // eor x10,x10,x4 + .long 0xca0401ef // eor x15,x15,x4 + .long 0xca040294 // eor x20,x20,x4 + .long 0xa94027e4 // ldp x4,x9,[sp,#0] // re-load offloaded data + .long 0xca1c007a // eor x26, x3,x28 // mov x26,x3 + .long 0xca1c0108 // eor x8,x8,x28 + .long 0xca1c01ad // eor x13,x13,x28 + .long 0xca1c0339 // eor x25,x25,x28 + .long 0xca1c02f7 // eor x23,x23,x28 + + .long 0xca1e009c // eor x28, x4,x30 // mov x28,x4 + .long 0xca1e0129 // eor x9,x9,x30 + .long 0xca1e01ce // eor x14,x14,x30 + .long 0xca1e0273 // eor x19,x19,x30 + .long 0xca1e0318 // eor x24,x24,x30 + + ////////////////////////////////////////// Rho+Pi + .long 0xaa0103fe // mov x30,x1 + .long 0x93c650c1 // ror x1,x6,#64-44 + //mov x27,x2 + .long 0x93cc5582 // ror x2,x12,#64-43 + //mov x26,x3 + .long 0x93d9af23 // ror x3,x25,#64-21 + //mov x28,x4 + .long 0x93d8cb04 // ror x4,x24,#64-14 + + .long 0x93c9b126 // ror x6,x9,#64-20 + .long 0x93cd9dac // ror x12,x13,#64-25 + .long 0x93d1c639 // ror x25,x17,#64-15 + .long 0x93d5fab8 // ror x24,x21,#64-2 + + .long 0x93d60ec9 // ror x9,x22,#64-61 + .long 0x93d3e26d // ror x13,x19,#64-8 + .long 0x93cbd971 // ror x17,x11,#64-10 + .long 0x93c82515 // ror x21,x8,#64-55 + + .long 0x93ce65d6 // ror x22,x14,#64-39 + .long 0x93d722f3 // ror x19,x23,#64-56 + .long 0x93c7e8eb // ror x11,x7,#64-6 + .long 0x93d04e08 // ror x8,x16,#64-45 + + .long 0x93d4ba8e // ror x14,x20,#64-18 + .long 0x93cf5df7 // ror x23,x15,#64-41 + .long 0x93caf547 // ror x7,x10,#64-3 + .long 0x93c570b0 // ror x16,x5,#64-36 + + .long 0x93da9345 // ror x5,x26,#64-28 + .long 0x93deffca // ror x10,x30,#64-1 + .long 0x93dc978f // ror x15,x28,#64-27 + .long 0x93db0b74 // ror x20,x27,#64-62 + + ////////////////////////////////////////// Chi+Iota + .long 0x8a21005a // bic x26,x2,x1 + .long 0x8a22007b // bic x27,x3,x2 + .long 0x8a24001c // bic x28,x0,x4 + .long 0x8a20003e // bic x30,x1,x0 + .long 0xca1a0000 // eor x0,x0,x26 + .long 0x8a23009a // bic x26,x4,x3 + .long 0xca1b0021 // eor x1,x1,x27 + .long 0xf9400bfb // ldr x27,[sp,#16] + .long 0xca1c0063 // eor x3,x3,x28 + .long 0xca1e0084 // eor x4,x4,x30 + .long 0xca1a0042 // eor x2,x2,x26 + .long 0xf840877e // ldr x30,[x27],#8 // Iota[i++] + .long 0xca1e0000 // eor x0,x0,x30 // A[0][0] ^= Iota (hoisted - frees x30 for the end test) + + .long 0x8a2600fa // bic x26,x7,x6 + .long 0xf94017fe // ldr x30,[sp,#40] // iotas end + .long 0xeb1e037f // cmp x27,x30 // are we done? (end-pointer test; a Pascal const + // cannot provide the original's 256-aligned table) + .long 0xf9000bfb // str x27,[sp,#16] + .long 0x8a27011b // bic x27,x8,x7 + .long 0x8a2900bc // bic x28,x5,x9 + .long 0x8a2500de // bic x30,x6,x5 + .long 0xca1a00a5 // eor x5,x5,x26 + .long 0x8a28013a // bic x26,x9,x8 + .long 0xca1b00c6 // eor x6,x6,x27 + .long 0xca1c0108 // eor x8,x8,x28 + .long 0xca1e0129 // eor x9,x9,x30 + .long 0xca1a00e7 // eor x7,x7,x26 + + .long 0x8a2b019a // bic x26,x12,x11 + .long 0x8a2c01bb // bic x27,x13,x12 + .long 0x8a2e015c // bic x28,x10,x14 + .long 0x8a2a017e // bic x30,x11,x10 + .long 0xca1a014a // eor x10,x10,x26 + .long 0x8a2d01da // bic x26,x14,x13 + .long 0xca1b016b // eor x11,x11,x27 + .long 0xca1c01ad // eor x13,x13,x28 + .long 0xca1e01ce // eor x14,x14,x30 + .long 0xca1a018c // eor x12,x12,x26 + + .long 0x8a30023a // bic x26,x17,x16 + .long 0x8a31033b // bic x27,x25,x17 + .long 0x8a3301fc // bic x28,x15,x19 + .long 0x8a2f021e // bic x30,x16,x15 + .long 0xca1a01ef // eor x15,x15,x26 + .long 0x8a39027a // bic x26,x19,x25 + .long 0xca1b0210 // eor x16,x16,x27 + .long 0xca1c0339 // eor x25,x25,x28 + .long 0xca1e0273 // eor x19,x19,x30 + .long 0xca1a0231 // eor x17,x17,x26 + + .long 0x8a3502da // bic x26,x22,x21 + .long 0x8a3602fb // bic x27,x23,x22 + .long 0x8a38029c // bic x28,x20,x24 + .long 0x8a3402be // bic x30,x21,x20 + .long 0xca1a0294 // eor x20,x20,x26 + .long 0x8a37031a // bic x26,x24,x23 + .long 0xca1b02b5 // eor x21,x21,x27 + .long 0xca1c02f7 // eor x23,x23,x28 + .long 0xca1e0318 // eor x24,x24,x30 + .long 0xca1a02d6 // eor x22,x22,x26 + + b.ne .Lkeccak_gpr_loop + + .long 0xf9400ffe // ldr x30,[sp,#24] + ret diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc similarity index 98% rename from HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc rename to HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc index 3fc19e5..5ace1b4 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc @@ -1,7 +1,5 @@ // Keccak-f[1600] permutation for x86-64, pure 64-bit GPR code (no SIMD -// registers at all) - the fastest non-AVX2 form of Keccak on x86-64, so it -// fills the SSE2 dispatch slot for pre-AVX2 CPUs (house precedent: the CRC -// "SSE2" slicing kernels are GPR too). +// registers at all) - the fastest non-AVX2 form of Keccak on x86-64. // Reference: OpenSSL CRYPTOGAMS keccak1600-x86_64.pl by Andy Polyakov. // // The inner routine works in the LANE-COMPLEMENTED domain (lanes 1, 2, 8, diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc index a9ba75a..2dcc604 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc @@ -1,5 +1,5 @@ // Keccak-f[1600] sponge absorb for IA-32, pure SSE2 - the asm twin of the -// x86-64 absorb for the SSE2 dispatch slot: XORs whole blocks into the state +// x86-64 absorb: XORs whole blocks into the state // and permutes. MMX converted to SSE2 like the permute. // The permutation body is the same inner as KeccakF1600Sse2_i386.inc // (embedded again because local labels cannot cross include files). diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc new file mode 100644 index 0000000..2b0329a --- /dev/null +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc @@ -0,0 +1,949 @@ +// SHA-512 pure-GPR implementation (AArch64) for cores without FEAT_SHA512 +// (absent on most consumer Cortex-A7x); the Gpr name states the ISA +// requirement: none beyond base AArch64. Serial SHA maps better onto the +// 31 GPRs than onto NEON lanes (single dependency chain, 1-op ror, +// rotate-folded eor operands). +// Expects AAPCS64 (after HlpSimdProc4Begin_aarch64): x0 = state ptr +// (8 x UInt64), x1 = data ptr, w2 = numblocks, x3 = K512_Gpr ptr. +// K512_Gpr carries the 80 round constants PLUS a zero terminator quad - the +// message-schedule loop ends when the loaded K word is zero (cbnz), exactly +// like the original's sentinel-terminated table; a plain K512 const cannot +// drive this loop. +// Frame: 128-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved) + 32 bytes +// schedule scratch; x30 (LR) is repurposed as the K walk pointer between the +// save and the restore, as in the original. +// AArch64 instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha512-armv8.pl (sha512_block_data_order, +// the plain path). + + .long 0x2a0203e2 // mov w2,w2 // zero-extend ANumBlocks (AAPCS64 leaves x2's top half undefined) + .long 0xa9b87bfd // stp x29,x30,[sp,#-128]! + .long 0x910003fd // add x29,sp,#0 + + .long 0xa90153f3 // stp x19,x20,[sp,#16] + .long 0xa9025bf5 // stp x21,x22,[sp,#32] + .long 0xa90363f7 // stp x23,x24,[sp,#48] + .long 0xa9046bf9 // stp x25,x26,[sp,#64] + .long 0xa90573fb // stp x27,x28,[sp,#80] + .long 0xd10083ff // sub sp,sp,#4*8 + + .long 0xa9405414 // ldp x20,x21,[x0] // load context + .long 0xa9415c16 // ldp x22,x23,[x0,#2*8] + .long 0xa9426418 // ldp x24,x25,[x0,#4*8] + .long 0x8b021c22 // add x2,x1,x2, lsl #7 // end of input + .long 0xa9436c1a // ldp x26,x27,[x0,#6*8] + .long 0xaa0303fe // mov x30,x3 // K512_Gpr (param 4; x3 is reused for message words below) + .long 0xa9060ba0 // stp x0,x2,[x29,#96] + + +.Lsha512_gpr_loop: + .long 0xa8c11023 // ldp x3,x4,[x1],#2*8 + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++ + .long 0xca1602bc // eor x28,x21,x22 // magic seed + .long 0xf9003ba1 // str x1,[x29,#112] + .long 0xdac00c63 // rev x3,x3 // 0 + .long 0x93d83b10 // ror x16,x24,#14 + .long 0x8b13037b // add x27,x27,x19 // h+=K[i] + .long 0xcad85f06 // eor x6,x24,x24, ror #23 + .long 0x8a180331 // and x17,x25,x24 + .long 0x8a380353 // bic x19,x26,x24 + .long 0x8b03037b // add x27,x27,x3 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca150293 // eor x19,x20,x21 // a^b, b^c in next round + .long 0xcac64a10 // eor x16,x16,x6, ror #18 // Sigma1(e) + .long 0x93d47286 // ror x6,x20,#28 + .long 0x8b11037b // add x27,x27,x17 // h+=Ch(e,f,g) + .long 0xcad41691 // eor x17,x20,x20, ror #5 + .long 0x8b10037b // add x27,x27,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b1b02f7 // add x23,x23,x27 // d+=h + .long 0xca15039c // eor x28,x28,x21 // Maj(a,b,c) + .long 0xcad188d1 // eor x17,x6,x17, ror #34 // Sigma0(a) + .long 0x8b1c037b // add x27,x27,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) + .long 0xdac00c84 // rev x4,x4 // 1 + .long 0xa8c11825 // ldp x5,x6,[x1],#2*8 + .long 0x8b11037b // add x27,x27,x17 // h+=Sigma0(a) + .long 0x93d73af0 // ror x16,x23,#14 + .long 0x8b1c035a // add x26,x26,x28 // h+=K[i] + .long 0xcad75ee7 // eor x7,x23,x23, ror #23 + .long 0x8a170311 // and x17,x24,x23 + .long 0x8a37033c // bic x28,x25,x23 + .long 0x8b04035a // add x26,x26,x4 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca14037c // eor x28,x27,x20 // a^b, b^c in next round + .long 0xcac74a10 // eor x16,x16,x7, ror #18 // Sigma1(e) + .long 0x93db7367 // ror x7,x27,#28 + .long 0x8b11035a // add x26,x26,x17 // h+=Ch(e,f,g) + .long 0xcadb1771 // eor x17,x27,x27, ror #5 + .long 0x8b10035a // add x26,x26,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b1a02d6 // add x22,x22,x26 // d+=h + .long 0xca140273 // eor x19,x19,x20 // Maj(a,b,c) + .long 0xcad188f1 // eor x17,x7,x17, ror #34 // Sigma0(a) + .long 0x8b13035a // add x26,x26,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) + .long 0xdac00ca5 // rev x5,x5 // 2 + .long 0x8b11035a // add x26,x26,x17 // h+=Sigma0(a) + .long 0x93d63ad0 // ror x16,x22,#14 + .long 0x8b130339 // add x25,x25,x19 // h+=K[i] + .long 0xcad65ec8 // eor x8,x22,x22, ror #23 + .long 0x8a1602f1 // and x17,x23,x22 + .long 0x8a360313 // bic x19,x24,x22 + .long 0x8b050339 // add x25,x25,x5 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1b0353 // eor x19,x26,x27 // a^b, b^c in next round + .long 0xcac84a10 // eor x16,x16,x8, ror #18 // Sigma1(e) + .long 0x93da7348 // ror x8,x26,#28 + .long 0x8b110339 // add x25,x25,x17 // h+=Ch(e,f,g) + .long 0xcada1751 // eor x17,x26,x26, ror #5 + .long 0x8b100339 // add x25,x25,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b1902b5 // add x21,x21,x25 // d+=h + .long 0xca1b039c // eor x28,x28,x27 // Maj(a,b,c) + .long 0xcad18911 // eor x17,x8,x17, ror #34 // Sigma0(a) + .long 0x8b1c0339 // add x25,x25,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) + .long 0xdac00cc6 // rev x6,x6 // 3 + .long 0xa8c12027 // ldp x7,x8,[x1],#2*8 + .long 0x8b110339 // add x25,x25,x17 // h+=Sigma0(a) + .long 0x93d53ab0 // ror x16,x21,#14 + .long 0x8b1c0318 // add x24,x24,x28 // h+=K[i] + .long 0xcad55ea9 // eor x9,x21,x21, ror #23 + .long 0x8a1502d1 // and x17,x22,x21 + .long 0x8a3502fc // bic x28,x23,x21 + .long 0x8b060318 // add x24,x24,x6 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1a033c // eor x28,x25,x26 // a^b, b^c in next round + .long 0xcac94a10 // eor x16,x16,x9, ror #18 // Sigma1(e) + .long 0x93d97329 // ror x9,x25,#28 + .long 0x8b110318 // add x24,x24,x17 // h+=Ch(e,f,g) + .long 0xcad91731 // eor x17,x25,x25, ror #5 + .long 0x8b100318 // add x24,x24,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b180294 // add x20,x20,x24 // d+=h + .long 0xca1a0273 // eor x19,x19,x26 // Maj(a,b,c) + .long 0xcad18931 // eor x17,x9,x17, ror #34 // Sigma0(a) + .long 0x8b130318 // add x24,x24,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) + .long 0xdac00ce7 // rev x7,x7 // 4 + .long 0x8b110318 // add x24,x24,x17 // h+=Sigma0(a) + .long 0x93d43a90 // ror x16,x20,#14 + .long 0x8b1302f7 // add x23,x23,x19 // h+=K[i] + .long 0xcad45e8a // eor x10,x20,x20, ror #23 + .long 0x8a1402b1 // and x17,x21,x20 + .long 0x8a3402d3 // bic x19,x22,x20 + .long 0x8b0702f7 // add x23,x23,x7 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca190313 // eor x19,x24,x25 // a^b, b^c in next round + .long 0xcaca4a10 // eor x16,x16,x10, ror #18 // Sigma1(e) + .long 0x93d8730a // ror x10,x24,#28 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Ch(e,f,g) + .long 0xcad81711 // eor x17,x24,x24, ror #5 + .long 0x8b1002f7 // add x23,x23,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b17037b // add x27,x27,x23 // d+=h + .long 0xca19039c // eor x28,x28,x25 // Maj(a,b,c) + .long 0xcad18951 // eor x17,x10,x17, ror #34 // Sigma0(a) + .long 0x8b1c02f7 // add x23,x23,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) + .long 0xdac00d08 // rev x8,x8 // 5 + .long 0xa8c12829 // ldp x9,x10,[x1],#2*8 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Sigma0(a) + .long 0x93db3b70 // ror x16,x27,#14 + .long 0x8b1c02d6 // add x22,x22,x28 // h+=K[i] + .long 0xcadb5f6b // eor x11,x27,x27, ror #23 + .long 0x8a1b0291 // and x17,x20,x27 + .long 0x8a3b02bc // bic x28,x21,x27 + .long 0x8b0802d6 // add x22,x22,x8 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1802fc // eor x28,x23,x24 // a^b, b^c in next round + .long 0xcacb4a10 // eor x16,x16,x11, ror #18 // Sigma1(e) + .long 0x93d772eb // ror x11,x23,#28 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Ch(e,f,g) + .long 0xcad716f1 // eor x17,x23,x23, ror #5 + .long 0x8b1002d6 // add x22,x22,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b16035a // add x26,x26,x22 // d+=h + .long 0xca180273 // eor x19,x19,x24 // Maj(a,b,c) + .long 0xcad18971 // eor x17,x11,x17, ror #34 // Sigma0(a) + .long 0x8b1302d6 // add x22,x22,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) + .long 0xdac00d29 // rev x9,x9 // 6 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Sigma0(a) + .long 0x93da3b50 // ror x16,x26,#14 + .long 0x8b1302b5 // add x21,x21,x19 // h+=K[i] + .long 0xcada5f4c // eor x12,x26,x26, ror #23 + .long 0x8a1a0371 // and x17,x27,x26 + .long 0x8a3a0293 // bic x19,x20,x26 + .long 0x8b0902b5 // add x21,x21,x9 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1702d3 // eor x19,x22,x23 // a^b, b^c in next round + .long 0xcacc4a10 // eor x16,x16,x12, ror #18 // Sigma1(e) + .long 0x93d672cc // ror x12,x22,#28 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Ch(e,f,g) + .long 0xcad616d1 // eor x17,x22,x22, ror #5 + .long 0x8b1002b5 // add x21,x21,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b150339 // add x25,x25,x21 // d+=h + .long 0xca17039c // eor x28,x28,x23 // Maj(a,b,c) + .long 0xcad18991 // eor x17,x12,x17, ror #34 // Sigma0(a) + .long 0x8b1c02b5 // add x21,x21,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) + .long 0xdac00d4a // rev x10,x10 // 7 + .long 0xa8c1302b // ldp x11,x12,[x1],#2*8 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Sigma0(a) + .long 0x93d93b30 // ror x16,x25,#14 + .long 0x8b1c0294 // add x20,x20,x28 // h+=K[i] + .long 0xcad95f2d // eor x13,x25,x25, ror #23 + .long 0x8a190351 // and x17,x26,x25 + .long 0x8a39037c // bic x28,x27,x25 + .long 0x8b0a0294 // add x20,x20,x10 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1602bc // eor x28,x21,x22 // a^b, b^c in next round + .long 0xcacd4a10 // eor x16,x16,x13, ror #18 // Sigma1(e) + .long 0x93d572ad // ror x13,x21,#28 + .long 0x8b110294 // add x20,x20,x17 // h+=Ch(e,f,g) + .long 0xcad516b1 // eor x17,x21,x21, ror #5 + .long 0x8b100294 // add x20,x20,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b140318 // add x24,x24,x20 // d+=h + .long 0xca160273 // eor x19,x19,x22 // Maj(a,b,c) + .long 0xcad189b1 // eor x17,x13,x17, ror #34 // Sigma0(a) + .long 0x8b130294 // add x20,x20,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x20,x20,x17 // h+=Sigma0(a) + .long 0xdac00d6b // rev x11,x11 // 8 + .long 0x8b110294 // add x20,x20,x17 // h+=Sigma0(a) + .long 0x93d83b10 // ror x16,x24,#14 + .long 0x8b13037b // add x27,x27,x19 // h+=K[i] + .long 0xcad85f0e // eor x14,x24,x24, ror #23 + .long 0x8a180331 // and x17,x25,x24 + .long 0x8a380353 // bic x19,x26,x24 + .long 0x8b0b037b // add x27,x27,x11 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca150293 // eor x19,x20,x21 // a^b, b^c in next round + .long 0xcace4a10 // eor x16,x16,x14, ror #18 // Sigma1(e) + .long 0x93d4728e // ror x14,x20,#28 + .long 0x8b11037b // add x27,x27,x17 // h+=Ch(e,f,g) + .long 0xcad41691 // eor x17,x20,x20, ror #5 + .long 0x8b10037b // add x27,x27,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b1b02f7 // add x23,x23,x27 // d+=h + .long 0xca15039c // eor x28,x28,x21 // Maj(a,b,c) + .long 0xcad189d1 // eor x17,x14,x17, ror #34 // Sigma0(a) + .long 0x8b1c037b // add x27,x27,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) + .long 0xdac00d8c // rev x12,x12 // 9 + .long 0xa8c1382d // ldp x13,x14,[x1],#2*8 + .long 0x8b11037b // add x27,x27,x17 // h+=Sigma0(a) + .long 0x93d73af0 // ror x16,x23,#14 + .long 0x8b1c035a // add x26,x26,x28 // h+=K[i] + .long 0xcad75eef // eor x15,x23,x23, ror #23 + .long 0x8a170311 // and x17,x24,x23 + .long 0x8a37033c // bic x28,x25,x23 + .long 0x8b0c035a // add x26,x26,x12 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca14037c // eor x28,x27,x20 // a^b, b^c in next round + .long 0xcacf4a10 // eor x16,x16,x15, ror #18 // Sigma1(e) + .long 0x93db736f // ror x15,x27,#28 + .long 0x8b11035a // add x26,x26,x17 // h+=Ch(e,f,g) + .long 0xcadb1771 // eor x17,x27,x27, ror #5 + .long 0x8b10035a // add x26,x26,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b1a02d6 // add x22,x22,x26 // d+=h + .long 0xca140273 // eor x19,x19,x20 // Maj(a,b,c) + .long 0xcad189f1 // eor x17,x15,x17, ror #34 // Sigma0(a) + .long 0x8b13035a // add x26,x26,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) + .long 0xdac00dad // rev x13,x13 // 10 + .long 0x8b11035a // add x26,x26,x17 // h+=Sigma0(a) + .long 0x93d63ad0 // ror x16,x22,#14 + .long 0x8b130339 // add x25,x25,x19 // h+=K[i] + .long 0xcad65ec0 // eor x0,x22,x22, ror #23 + .long 0x8a1602f1 // and x17,x23,x22 + .long 0x8a360313 // bic x19,x24,x22 + .long 0x8b0d0339 // add x25,x25,x13 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1b0353 // eor x19,x26,x27 // a^b, b^c in next round + .long 0xcac04a10 // eor x16,x16,x0, ror #18 // Sigma1(e) + .long 0x93da7340 // ror x0,x26,#28 + .long 0x8b110339 // add x25,x25,x17 // h+=Ch(e,f,g) + .long 0xcada1751 // eor x17,x26,x26, ror #5 + .long 0x8b100339 // add x25,x25,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b1902b5 // add x21,x21,x25 // d+=h + .long 0xca1b039c // eor x28,x28,x27 // Maj(a,b,c) + .long 0xcad18811 // eor x17,x0,x17, ror #34 // Sigma0(a) + .long 0x8b1c0339 // add x25,x25,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) + .long 0xdac00dce // rev x14,x14 // 11 + .long 0xa8c1002f // ldp x15,x0,[x1],#2*8 + .long 0x8b110339 // add x25,x25,x17 // h+=Sigma0(a) + .long 0xf9000fe6 // str x6,[sp,#24] + .long 0x93d53ab0 // ror x16,x21,#14 + .long 0x8b1c0318 // add x24,x24,x28 // h+=K[i] + .long 0xcad55ea6 // eor x6,x21,x21, ror #23 + .long 0x8a1502d1 // and x17,x22,x21 + .long 0x8a3502fc // bic x28,x23,x21 + .long 0x8b0e0318 // add x24,x24,x14 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1a033c // eor x28,x25,x26 // a^b, b^c in next round + .long 0xcac64a10 // eor x16,x16,x6, ror #18 // Sigma1(e) + .long 0x93d97326 // ror x6,x25,#28 + .long 0x8b110318 // add x24,x24,x17 // h+=Ch(e,f,g) + .long 0xcad91731 // eor x17,x25,x25, ror #5 + .long 0x8b100318 // add x24,x24,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b180294 // add x20,x20,x24 // d+=h + .long 0xca1a0273 // eor x19,x19,x26 // Maj(a,b,c) + .long 0xcad188d1 // eor x17,x6,x17, ror #34 // Sigma0(a) + .long 0x8b130318 // add x24,x24,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) + .long 0xdac00def // rev x15,x15 // 12 + .long 0x8b110318 // add x24,x24,x17 // h+=Sigma0(a) + .long 0xf90003e7 // str x7,[sp,#0] + .long 0x93d43a90 // ror x16,x20,#14 + .long 0x8b1302f7 // add x23,x23,x19 // h+=K[i] + .long 0xcad45e87 // eor x7,x20,x20, ror #23 + .long 0x8a1402b1 // and x17,x21,x20 + .long 0x8a3402d3 // bic x19,x22,x20 + .long 0x8b0f02f7 // add x23,x23,x15 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca190313 // eor x19,x24,x25 // a^b, b^c in next round + .long 0xcac74a10 // eor x16,x16,x7, ror #18 // Sigma1(e) + .long 0x93d87307 // ror x7,x24,#28 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Ch(e,f,g) + .long 0xcad81711 // eor x17,x24,x24, ror #5 + .long 0x8b1002f7 // add x23,x23,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b17037b // add x27,x27,x23 // d+=h + .long 0xca19039c // eor x28,x28,x25 // Maj(a,b,c) + .long 0xcad188f1 // eor x17,x7,x17, ror #34 // Sigma0(a) + .long 0x8b1c02f7 // add x23,x23,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) + .long 0xdac00c00 // rev x0,x0 // 13 + .long 0xa9400821 // ldp x1,x2,[x1] + .long 0x8b1102f7 // add x23,x23,x17 // h+=Sigma0(a) + .long 0xf90007e8 // str x8,[sp,#8] + .long 0x93db3b70 // ror x16,x27,#14 + .long 0x8b1c02d6 // add x22,x22,x28 // h+=K[i] + .long 0xcadb5f68 // eor x8,x27,x27, ror #23 + .long 0x8a1b0291 // and x17,x20,x27 + .long 0x8a3b02bc // bic x28,x21,x27 + .long 0x8b0002d6 // add x22,x22,x0 // h+=X[i] + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1802fc // eor x28,x23,x24 // a^b, b^c in next round + .long 0xcac84a10 // eor x16,x16,x8, ror #18 // Sigma1(e) + .long 0x93d772e8 // ror x8,x23,#28 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Ch(e,f,g) + .long 0xcad716f1 // eor x17,x23,x23, ror #5 + .long 0x8b1002d6 // add x22,x22,x16 // h+=Sigma1(e) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0x8b16035a // add x26,x26,x22 // d+=h + .long 0xca180273 // eor x19,x19,x24 // Maj(a,b,c) + .long 0xcad18911 // eor x17,x8,x17, ror #34 // Sigma0(a) + .long 0x8b1302d6 // add x22,x22,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) + .long 0xdac00c21 // rev x1,x1 // 14 + .long 0xf9400fe6 // ldr x6,[sp,#24] + .long 0x8b1102d6 // add x22,x22,x17 // h+=Sigma0(a) + .long 0xf9000be9 // str x9,[sp,#16] + .long 0x93da3b50 // ror x16,x26,#14 + .long 0x8b1302b5 // add x21,x21,x19 // h+=K[i] + .long 0xcada5f49 // eor x9,x26,x26, ror #23 + .long 0x8a1a0371 // and x17,x27,x26 + .long 0x8a3a0293 // bic x19,x20,x26 + .long 0x8b0102b5 // add x21,x21,x1 // h+=X[i] + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1702d3 // eor x19,x22,x23 // a^b, b^c in next round + .long 0xcac94a10 // eor x16,x16,x9, ror #18 // Sigma1(e) + .long 0x93d672c9 // ror x9,x22,#28 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Ch(e,f,g) + .long 0xcad616d1 // eor x17,x22,x22, ror #5 + .long 0x8b1002b5 // add x21,x21,x16 // h+=Sigma1(e) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0x8b150339 // add x25,x25,x21 // d+=h + .long 0xca17039c // eor x28,x28,x23 // Maj(a,b,c) + .long 0xcad18931 // eor x17,x9,x17, ror #34 // Sigma0(a) + .long 0x8b1c02b5 // add x21,x21,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) + .long 0xdac00c42 // rev x2,x2 // 15 + .long 0xf94003e7 // ldr x7,[sp,#0] + .long 0x8b1102b5 // add x21,x21,x17 // h+=Sigma0(a) + .long 0xf9000fea // str x10,[sp,#24] + .long 0x93d93b30 // ror x16,x25,#14 + .long 0x8b1c0294 // add x20,x20,x28 // h+=K[i] + .long 0x93c40489 // ror x9,x4,#1 + .long 0x8a190351 // and x17,x26,x25 + .long 0x93c14c28 // ror x8,x1,#19 + .long 0x8a39037c // bic x28,x27,x25 + .long 0x93d572aa // ror x10,x21,#28 + .long 0x8b020294 // add x20,x20,x2 // h+=X[i] + .long 0xcad94a10 // eor x16,x16,x25, ror #18 + .long 0xcac42129 // eor x9,x9,x4, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1602bc // eor x28,x21,x22 // a^b, b^c in next round + .long 0xcad9a610 // eor x16,x16,x25, ror #41 // Sigma1(e) + .long 0xcad5894a // eor x10,x10,x21, ror #34 + .long 0x8b110294 // add x20,x20,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcac1f508 // eor x8,x8,x1, ror #61 + .long 0xca441d29 // eor x9,x9,x4, lsr #7 // sigma0(X[i+1]) + .long 0x8b100294 // add x20,x20,x16 // h+=Sigma1(e) + .long 0xca160273 // eor x19,x19,x22 // Maj(a,b,c) + .long 0xcad59d51 // eor x17,x10,x21, ror #39 // Sigma0(a) + .long 0xca411908 // eor x8,x8,x1, lsr #6 // sigma1(X[i+14]) + .long 0x8b0c0063 // add x3,x3,x12 + .long 0x8b140318 // add x24,x24,x20 // d+=h + .long 0x8b130294 // add x20,x20,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b090063 // add x3,x3,x9 + .long 0x8b110294 // add x20,x20,x17 // h+=Sigma0(a) + .long 0x8b080063 // add x3,x3,x8 + +.Lsha512_gpr_loop_16_xx: + .long 0xf94007e8 // ldr x8,[sp,#8] + .long 0xf90003eb // str x11,[sp,#0] + .long 0x93d83b10 // ror x16,x24,#14 + .long 0x8b13037b // add x27,x27,x19 // h+=K[i] + .long 0x93c504aa // ror x10,x5,#1 + .long 0x8a180331 // and x17,x25,x24 + .long 0x93c24c49 // ror x9,x2,#19 + .long 0x8a380353 // bic x19,x26,x24 + .long 0x93d4728b // ror x11,x20,#28 + .long 0x8b03037b // add x27,x27,x3 // h+=X[i] + .long 0xcad84a10 // eor x16,x16,x24, ror #18 + .long 0xcac5214a // eor x10,x10,x5, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca150293 // eor x19,x20,x21 // a^b, b^c in next round + .long 0xcad8a610 // eor x16,x16,x24, ror #41 // Sigma1(e) + .long 0xcad4896b // eor x11,x11,x20, ror #34 + .long 0x8b11037b // add x27,x27,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcac2f529 // eor x9,x9,x2, ror #61 + .long 0xca451d4a // eor x10,x10,x5, lsr #7 // sigma0(X[i+1]) + .long 0x8b10037b // add x27,x27,x16 // h+=Sigma1(e) + .long 0xca15039c // eor x28,x28,x21 // Maj(a,b,c) + .long 0xcad49d71 // eor x17,x11,x20, ror #39 // Sigma0(a) + .long 0xca421929 // eor x9,x9,x2, lsr #6 // sigma1(X[i+14]) + .long 0x8b0d0084 // add x4,x4,x13 + .long 0x8b1b02f7 // add x23,x23,x27 // d+=h + .long 0x8b1c037b // add x27,x27,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b0a0084 // add x4,x4,x10 + .long 0x8b11037b // add x27,x27,x17 // h+=Sigma0(a) + .long 0x8b090084 // add x4,x4,x9 + .long 0xf9400be9 // ldr x9,[sp,#16] + .long 0xf90007ec // str x12,[sp,#8] + .long 0x93d73af0 // ror x16,x23,#14 + .long 0x8b1c035a // add x26,x26,x28 // h+=K[i] + .long 0x93c604cb // ror x11,x6,#1 + .long 0x8a170311 // and x17,x24,x23 + .long 0x93c34c6a // ror x10,x3,#19 + .long 0x8a37033c // bic x28,x25,x23 + .long 0x93db736c // ror x12,x27,#28 + .long 0x8b04035a // add x26,x26,x4 // h+=X[i] + .long 0xcad74a10 // eor x16,x16,x23, ror #18 + .long 0xcac6216b // eor x11,x11,x6, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca14037c // eor x28,x27,x20 // a^b, b^c in next round + .long 0xcad7a610 // eor x16,x16,x23, ror #41 // Sigma1(e) + .long 0xcadb898c // eor x12,x12,x27, ror #34 + .long 0x8b11035a // add x26,x26,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcac3f54a // eor x10,x10,x3, ror #61 + .long 0xca461d6b // eor x11,x11,x6, lsr #7 // sigma0(X[i+1]) + .long 0x8b10035a // add x26,x26,x16 // h+=Sigma1(e) + .long 0xca140273 // eor x19,x19,x20 // Maj(a,b,c) + .long 0xcadb9d91 // eor x17,x12,x27, ror #39 // Sigma0(a) + .long 0xca43194a // eor x10,x10,x3, lsr #6 // sigma1(X[i+14]) + .long 0x8b0e00a5 // add x5,x5,x14 + .long 0x8b1a02d6 // add x22,x22,x26 // d+=h + .long 0x8b13035a // add x26,x26,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b0b00a5 // add x5,x5,x11 + .long 0x8b11035a // add x26,x26,x17 // h+=Sigma0(a) + .long 0x8b0a00a5 // add x5,x5,x10 + .long 0xf9400fea // ldr x10,[sp,#24] + .long 0xf9000bed // str x13,[sp,#16] + .long 0x93d63ad0 // ror x16,x22,#14 + .long 0x8b130339 // add x25,x25,x19 // h+=K[i] + .long 0x93c704ec // ror x12,x7,#1 + .long 0x8a1602f1 // and x17,x23,x22 + .long 0x93c44c8b // ror x11,x4,#19 + .long 0x8a360313 // bic x19,x24,x22 + .long 0x93da734d // ror x13,x26,#28 + .long 0x8b050339 // add x25,x25,x5 // h+=X[i] + .long 0xcad64a10 // eor x16,x16,x22, ror #18 + .long 0xcac7218c // eor x12,x12,x7, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1b0353 // eor x19,x26,x27 // a^b, b^c in next round + .long 0xcad6a610 // eor x16,x16,x22, ror #41 // Sigma1(e) + .long 0xcada89ad // eor x13,x13,x26, ror #34 + .long 0x8b110339 // add x25,x25,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcac4f56b // eor x11,x11,x4, ror #61 + .long 0xca471d8c // eor x12,x12,x7, lsr #7 // sigma0(X[i+1]) + .long 0x8b100339 // add x25,x25,x16 // h+=Sigma1(e) + .long 0xca1b039c // eor x28,x28,x27 // Maj(a,b,c) + .long 0xcada9db1 // eor x17,x13,x26, ror #39 // Sigma0(a) + .long 0xca44196b // eor x11,x11,x4, lsr #6 // sigma1(X[i+14]) + .long 0x8b0f00c6 // add x6,x6,x15 + .long 0x8b1902b5 // add x21,x21,x25 // d+=h + .long 0x8b1c0339 // add x25,x25,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b0c00c6 // add x6,x6,x12 + .long 0x8b110339 // add x25,x25,x17 // h+=Sigma0(a) + .long 0x8b0b00c6 // add x6,x6,x11 + .long 0xf94003eb // ldr x11,[sp,#0] + .long 0xf9000fee // str x14,[sp,#24] + .long 0x93d53ab0 // ror x16,x21,#14 + .long 0x8b1c0318 // add x24,x24,x28 // h+=K[i] + .long 0x93c8050d // ror x13,x8,#1 + .long 0x8a1502d1 // and x17,x22,x21 + .long 0x93c54cac // ror x12,x5,#19 + .long 0x8a3502fc // bic x28,x23,x21 + .long 0x93d9732e // ror x14,x25,#28 + .long 0x8b060318 // add x24,x24,x6 // h+=X[i] + .long 0xcad54a10 // eor x16,x16,x21, ror #18 + .long 0xcac821ad // eor x13,x13,x8, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1a033c // eor x28,x25,x26 // a^b, b^c in next round + .long 0xcad5a610 // eor x16,x16,x21, ror #41 // Sigma1(e) + .long 0xcad989ce // eor x14,x14,x25, ror #34 + .long 0x8b110318 // add x24,x24,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcac5f58c // eor x12,x12,x5, ror #61 + .long 0xca481dad // eor x13,x13,x8, lsr #7 // sigma0(X[i+1]) + .long 0x8b100318 // add x24,x24,x16 // h+=Sigma1(e) + .long 0xca1a0273 // eor x19,x19,x26 // Maj(a,b,c) + .long 0xcad99dd1 // eor x17,x14,x25, ror #39 // Sigma0(a) + .long 0xca45198c // eor x12,x12,x5, lsr #6 // sigma1(X[i+14]) + .long 0x8b0000e7 // add x7,x7,x0 + .long 0x8b180294 // add x20,x20,x24 // d+=h + .long 0x8b130318 // add x24,x24,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b0d00e7 // add x7,x7,x13 + .long 0x8b110318 // add x24,x24,x17 // h+=Sigma0(a) + .long 0x8b0c00e7 // add x7,x7,x12 + .long 0xf94007ec // ldr x12,[sp,#8] + .long 0xf90003ef // str x15,[sp,#0] + .long 0x93d43a90 // ror x16,x20,#14 + .long 0x8b1302f7 // add x23,x23,x19 // h+=K[i] + .long 0x93c9052e // ror x14,x9,#1 + .long 0x8a1402b1 // and x17,x21,x20 + .long 0x93c64ccd // ror x13,x6,#19 + .long 0x8a3402d3 // bic x19,x22,x20 + .long 0x93d8730f // ror x15,x24,#28 + .long 0x8b0702f7 // add x23,x23,x7 // h+=X[i] + .long 0xcad44a10 // eor x16,x16,x20, ror #18 + .long 0xcac921ce // eor x14,x14,x9, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca190313 // eor x19,x24,x25 // a^b, b^c in next round + .long 0xcad4a610 // eor x16,x16,x20, ror #41 // Sigma1(e) + .long 0xcad889ef // eor x15,x15,x24, ror #34 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcac6f5ad // eor x13,x13,x6, ror #61 + .long 0xca491dce // eor x14,x14,x9, lsr #7 // sigma0(X[i+1]) + .long 0x8b1002f7 // add x23,x23,x16 // h+=Sigma1(e) + .long 0xca19039c // eor x28,x28,x25 // Maj(a,b,c) + .long 0xcad89df1 // eor x17,x15,x24, ror #39 // Sigma0(a) + .long 0xca4619ad // eor x13,x13,x6, lsr #6 // sigma1(X[i+14]) + .long 0x8b010108 // add x8,x8,x1 + .long 0x8b17037b // add x27,x27,x23 // d+=h + .long 0x8b1c02f7 // add x23,x23,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b0e0108 // add x8,x8,x14 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Sigma0(a) + .long 0x8b0d0108 // add x8,x8,x13 + .long 0xf9400bed // ldr x13,[sp,#16] + .long 0xf90007e0 // str x0,[sp,#8] + .long 0x93db3b70 // ror x16,x27,#14 + .long 0x8b1c02d6 // add x22,x22,x28 // h+=K[i] + .long 0x93ca054f // ror x15,x10,#1 + .long 0x8a1b0291 // and x17,x20,x27 + .long 0x93c74cee // ror x14,x7,#19 + .long 0x8a3b02bc // bic x28,x21,x27 + .long 0x93d772e0 // ror x0,x23,#28 + .long 0x8b0802d6 // add x22,x22,x8 // h+=X[i] + .long 0xcadb4a10 // eor x16,x16,x27, ror #18 + .long 0xcaca21ef // eor x15,x15,x10, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1802fc // eor x28,x23,x24 // a^b, b^c in next round + .long 0xcadba610 // eor x16,x16,x27, ror #41 // Sigma1(e) + .long 0xcad78800 // eor x0,x0,x23, ror #34 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcac7f5ce // eor x14,x14,x7, ror #61 + .long 0xca4a1def // eor x15,x15,x10, lsr #7 // sigma0(X[i+1]) + .long 0x8b1002d6 // add x22,x22,x16 // h+=Sigma1(e) + .long 0xca180273 // eor x19,x19,x24 // Maj(a,b,c) + .long 0xcad79c11 // eor x17,x0,x23, ror #39 // Sigma0(a) + .long 0xca4719ce // eor x14,x14,x7, lsr #6 // sigma1(X[i+14]) + .long 0x8b020129 // add x9,x9,x2 + .long 0x8b16035a // add x26,x26,x22 // d+=h + .long 0x8b1302d6 // add x22,x22,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b0f0129 // add x9,x9,x15 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Sigma0(a) + .long 0x8b0e0129 // add x9,x9,x14 + .long 0xf9400fee // ldr x14,[sp,#24] + .long 0xf9000be1 // str x1,[sp,#16] + .long 0x93da3b50 // ror x16,x26,#14 + .long 0x8b1302b5 // add x21,x21,x19 // h+=K[i] + .long 0x93cb0560 // ror x0,x11,#1 + .long 0x8a1a0371 // and x17,x27,x26 + .long 0x93c84d0f // ror x15,x8,#19 + .long 0x8a3a0293 // bic x19,x20,x26 + .long 0x93d672c1 // ror x1,x22,#28 + .long 0x8b0902b5 // add x21,x21,x9 // h+=X[i] + .long 0xcada4a10 // eor x16,x16,x26, ror #18 + .long 0xcacb2000 // eor x0,x0,x11, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1702d3 // eor x19,x22,x23 // a^b, b^c in next round + .long 0xcadaa610 // eor x16,x16,x26, ror #41 // Sigma1(e) + .long 0xcad68821 // eor x1,x1,x22, ror #34 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcac8f5ef // eor x15,x15,x8, ror #61 + .long 0xca4b1c00 // eor x0,x0,x11, lsr #7 // sigma0(X[i+1]) + .long 0x8b1002b5 // add x21,x21,x16 // h+=Sigma1(e) + .long 0xca17039c // eor x28,x28,x23 // Maj(a,b,c) + .long 0xcad69c31 // eor x17,x1,x22, ror #39 // Sigma0(a) + .long 0xca4819ef // eor x15,x15,x8, lsr #6 // sigma1(X[i+14]) + .long 0x8b03014a // add x10,x10,x3 + .long 0x8b150339 // add x25,x25,x21 // d+=h + .long 0x8b1c02b5 // add x21,x21,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b00014a // add x10,x10,x0 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Sigma0(a) + .long 0x8b0f014a // add x10,x10,x15 + .long 0xf94003ef // ldr x15,[sp,#0] + .long 0xf9000fe2 // str x2,[sp,#24] + .long 0x93d93b30 // ror x16,x25,#14 + .long 0x8b1c0294 // add x20,x20,x28 // h+=K[i] + .long 0x93cc0581 // ror x1,x12,#1 + .long 0x8a190351 // and x17,x26,x25 + .long 0x93c94d20 // ror x0,x9,#19 + .long 0x8a39037c // bic x28,x27,x25 + .long 0x93d572a2 // ror x2,x21,#28 + .long 0x8b0a0294 // add x20,x20,x10 // h+=X[i] + .long 0xcad94a10 // eor x16,x16,x25, ror #18 + .long 0xcacc2021 // eor x1,x1,x12, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1602bc // eor x28,x21,x22 // a^b, b^c in next round + .long 0xcad9a610 // eor x16,x16,x25, ror #41 // Sigma1(e) + .long 0xcad58842 // eor x2,x2,x21, ror #34 + .long 0x8b110294 // add x20,x20,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcac9f400 // eor x0,x0,x9, ror #61 + .long 0xca4c1c21 // eor x1,x1,x12, lsr #7 // sigma0(X[i+1]) + .long 0x8b100294 // add x20,x20,x16 // h+=Sigma1(e) + .long 0xca160273 // eor x19,x19,x22 // Maj(a,b,c) + .long 0xcad59c51 // eor x17,x2,x21, ror #39 // Sigma0(a) + .long 0xca491800 // eor x0,x0,x9, lsr #6 // sigma1(X[i+14]) + .long 0x8b04016b // add x11,x11,x4 + .long 0x8b140318 // add x24,x24,x20 // d+=h + .long 0x8b130294 // add x20,x20,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b01016b // add x11,x11,x1 + .long 0x8b110294 // add x20,x20,x17 // h+=Sigma0(a) + .long 0x8b00016b // add x11,x11,x0 + .long 0xf94007e0 // ldr x0,[sp,#8] + .long 0xf90003e3 // str x3,[sp,#0] + .long 0x93d83b10 // ror x16,x24,#14 + .long 0x8b13037b // add x27,x27,x19 // h+=K[i] + .long 0x93cd05a2 // ror x2,x13,#1 + .long 0x8a180331 // and x17,x25,x24 + .long 0x93ca4d41 // ror x1,x10,#19 + .long 0x8a380353 // bic x19,x26,x24 + .long 0x93d47283 // ror x3,x20,#28 + .long 0x8b0b037b // add x27,x27,x11 // h+=X[i] + .long 0xcad84a10 // eor x16,x16,x24, ror #18 + .long 0xcacd2042 // eor x2,x2,x13, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca150293 // eor x19,x20,x21 // a^b, b^c in next round + .long 0xcad8a610 // eor x16,x16,x24, ror #41 // Sigma1(e) + .long 0xcad48863 // eor x3,x3,x20, ror #34 + .long 0x8b11037b // add x27,x27,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcacaf421 // eor x1,x1,x10, ror #61 + .long 0xca4d1c42 // eor x2,x2,x13, lsr #7 // sigma0(X[i+1]) + .long 0x8b10037b // add x27,x27,x16 // h+=Sigma1(e) + .long 0xca15039c // eor x28,x28,x21 // Maj(a,b,c) + .long 0xcad49c71 // eor x17,x3,x20, ror #39 // Sigma0(a) + .long 0xca4a1821 // eor x1,x1,x10, lsr #6 // sigma1(X[i+14]) + .long 0x8b05018c // add x12,x12,x5 + .long 0x8b1b02f7 // add x23,x23,x27 // d+=h + .long 0x8b1c037b // add x27,x27,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b02018c // add x12,x12,x2 + .long 0x8b11037b // add x27,x27,x17 // h+=Sigma0(a) + .long 0x8b01018c // add x12,x12,x1 + .long 0xf9400be1 // ldr x1,[sp,#16] + .long 0xf90007e4 // str x4,[sp,#8] + .long 0x93d73af0 // ror x16,x23,#14 + .long 0x8b1c035a // add x26,x26,x28 // h+=K[i] + .long 0x93ce05c3 // ror x3,x14,#1 + .long 0x8a170311 // and x17,x24,x23 + .long 0x93cb4d62 // ror x2,x11,#19 + .long 0x8a37033c // bic x28,x25,x23 + .long 0x93db7364 // ror x4,x27,#28 + .long 0x8b0c035a // add x26,x26,x12 // h+=X[i] + .long 0xcad74a10 // eor x16,x16,x23, ror #18 + .long 0xcace2063 // eor x3,x3,x14, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca14037c // eor x28,x27,x20 // a^b, b^c in next round + .long 0xcad7a610 // eor x16,x16,x23, ror #41 // Sigma1(e) + .long 0xcadb8884 // eor x4,x4,x27, ror #34 + .long 0x8b11035a // add x26,x26,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcacbf442 // eor x2,x2,x11, ror #61 + .long 0xca4e1c63 // eor x3,x3,x14, lsr #7 // sigma0(X[i+1]) + .long 0x8b10035a // add x26,x26,x16 // h+=Sigma1(e) + .long 0xca140273 // eor x19,x19,x20 // Maj(a,b,c) + .long 0xcadb9c91 // eor x17,x4,x27, ror #39 // Sigma0(a) + .long 0xca4b1842 // eor x2,x2,x11, lsr #6 // sigma1(X[i+14]) + .long 0x8b0601ad // add x13,x13,x6 + .long 0x8b1a02d6 // add x22,x22,x26 // d+=h + .long 0x8b13035a // add x26,x26,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b0301ad // add x13,x13,x3 + .long 0x8b11035a // add x26,x26,x17 // h+=Sigma0(a) + .long 0x8b0201ad // add x13,x13,x2 + .long 0xf9400fe2 // ldr x2,[sp,#24] + .long 0xf9000be5 // str x5,[sp,#16] + .long 0x93d63ad0 // ror x16,x22,#14 + .long 0x8b130339 // add x25,x25,x19 // h+=K[i] + .long 0x93cf05e4 // ror x4,x15,#1 + .long 0x8a1602f1 // and x17,x23,x22 + .long 0x93cc4d83 // ror x3,x12,#19 + .long 0x8a360313 // bic x19,x24,x22 + .long 0x93da7345 // ror x5,x26,#28 + .long 0x8b0d0339 // add x25,x25,x13 // h+=X[i] + .long 0xcad64a10 // eor x16,x16,x22, ror #18 + .long 0xcacf2084 // eor x4,x4,x15, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1b0353 // eor x19,x26,x27 // a^b, b^c in next round + .long 0xcad6a610 // eor x16,x16,x22, ror #41 // Sigma1(e) + .long 0xcada88a5 // eor x5,x5,x26, ror #34 + .long 0x8b110339 // add x25,x25,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcaccf463 // eor x3,x3,x12, ror #61 + .long 0xca4f1c84 // eor x4,x4,x15, lsr #7 // sigma0(X[i+1]) + .long 0x8b100339 // add x25,x25,x16 // h+=Sigma1(e) + .long 0xca1b039c // eor x28,x28,x27 // Maj(a,b,c) + .long 0xcada9cb1 // eor x17,x5,x26, ror #39 // Sigma0(a) + .long 0xca4c1863 // eor x3,x3,x12, lsr #6 // sigma1(X[i+14]) + .long 0x8b0701ce // add x14,x14,x7 + .long 0x8b1902b5 // add x21,x21,x25 // d+=h + .long 0x8b1c0339 // add x25,x25,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b0401ce // add x14,x14,x4 + .long 0x8b110339 // add x25,x25,x17 // h+=Sigma0(a) + .long 0x8b0301ce // add x14,x14,x3 + .long 0xf94003e3 // ldr x3,[sp,#0] + .long 0xf9000fe6 // str x6,[sp,#24] + .long 0x93d53ab0 // ror x16,x21,#14 + .long 0x8b1c0318 // add x24,x24,x28 // h+=K[i] + .long 0x93c00405 // ror x5,x0,#1 + .long 0x8a1502d1 // and x17,x22,x21 + .long 0x93cd4da4 // ror x4,x13,#19 + .long 0x8a3502fc // bic x28,x23,x21 + .long 0x93d97326 // ror x6,x25,#28 + .long 0x8b0e0318 // add x24,x24,x14 // h+=X[i] + .long 0xcad54a10 // eor x16,x16,x21, ror #18 + .long 0xcac020a5 // eor x5,x5,x0, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1a033c // eor x28,x25,x26 // a^b, b^c in next round + .long 0xcad5a610 // eor x16,x16,x21, ror #41 // Sigma1(e) + .long 0xcad988c6 // eor x6,x6,x25, ror #34 + .long 0x8b110318 // add x24,x24,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcacdf484 // eor x4,x4,x13, ror #61 + .long 0xca401ca5 // eor x5,x5,x0, lsr #7 // sigma0(X[i+1]) + .long 0x8b100318 // add x24,x24,x16 // h+=Sigma1(e) + .long 0xca1a0273 // eor x19,x19,x26 // Maj(a,b,c) + .long 0xcad99cd1 // eor x17,x6,x25, ror #39 // Sigma0(a) + .long 0xca4d1884 // eor x4,x4,x13, lsr #6 // sigma1(X[i+14]) + .long 0x8b0801ef // add x15,x15,x8 + .long 0x8b180294 // add x20,x20,x24 // d+=h + .long 0x8b130318 // add x24,x24,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b0501ef // add x15,x15,x5 + .long 0x8b110318 // add x24,x24,x17 // h+=Sigma0(a) + .long 0x8b0401ef // add x15,x15,x4 + .long 0xf94007e4 // ldr x4,[sp,#8] + .long 0xf90003e7 // str x7,[sp,#0] + .long 0x93d43a90 // ror x16,x20,#14 + .long 0x8b1302f7 // add x23,x23,x19 // h+=K[i] + .long 0x93c10426 // ror x6,x1,#1 + .long 0x8a1402b1 // and x17,x21,x20 + .long 0x93ce4dc5 // ror x5,x14,#19 + .long 0x8a3402d3 // bic x19,x22,x20 + .long 0x93d87307 // ror x7,x24,#28 + .long 0x8b0f02f7 // add x23,x23,x15 // h+=X[i] + .long 0xcad44a10 // eor x16,x16,x20, ror #18 + .long 0xcac120c6 // eor x6,x6,x1, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca190313 // eor x19,x24,x25 // a^b, b^c in next round + .long 0xcad4a610 // eor x16,x16,x20, ror #41 // Sigma1(e) + .long 0xcad888e7 // eor x7,x7,x24, ror #34 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcacef4a5 // eor x5,x5,x14, ror #61 + .long 0xca411cc6 // eor x6,x6,x1, lsr #7 // sigma0(X[i+1]) + .long 0x8b1002f7 // add x23,x23,x16 // h+=Sigma1(e) + .long 0xca19039c // eor x28,x28,x25 // Maj(a,b,c) + .long 0xcad89cf1 // eor x17,x7,x24, ror #39 // Sigma0(a) + .long 0xca4e18a5 // eor x5,x5,x14, lsr #6 // sigma1(X[i+14]) + .long 0x8b090000 // add x0,x0,x9 + .long 0x8b17037b // add x27,x27,x23 // d+=h + .long 0x8b1c02f7 // add x23,x23,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b060000 // add x0,x0,x6 + .long 0x8b1102f7 // add x23,x23,x17 // h+=Sigma0(a) + .long 0x8b050000 // add x0,x0,x5 + .long 0xf9400be5 // ldr x5,[sp,#16] + .long 0xf90007e8 // str x8,[sp,#8] + .long 0x93db3b70 // ror x16,x27,#14 + .long 0x8b1c02d6 // add x22,x22,x28 // h+=K[i] + .long 0x93c20447 // ror x7,x2,#1 + .long 0x8a1b0291 // and x17,x20,x27 + .long 0x93cf4de6 // ror x6,x15,#19 + .long 0x8a3b02bc // bic x28,x21,x27 + .long 0x93d772e8 // ror x8,x23,#28 + .long 0x8b0002d6 // add x22,x22,x0 // h+=X[i] + .long 0xcadb4a10 // eor x16,x16,x27, ror #18 + .long 0xcac220e7 // eor x7,x7,x2, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1802fc // eor x28,x23,x24 // a^b, b^c in next round + .long 0xcadba610 // eor x16,x16,x27, ror #41 // Sigma1(e) + .long 0xcad78908 // eor x8,x8,x23, ror #34 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcacff4c6 // eor x6,x6,x15, ror #61 + .long 0xca421ce7 // eor x7,x7,x2, lsr #7 // sigma0(X[i+1]) + .long 0x8b1002d6 // add x22,x22,x16 // h+=Sigma1(e) + .long 0xca180273 // eor x19,x19,x24 // Maj(a,b,c) + .long 0xcad79d11 // eor x17,x8,x23, ror #39 // Sigma0(a) + .long 0xca4f18c6 // eor x6,x6,x15, lsr #6 // sigma1(X[i+14]) + .long 0x8b0a0021 // add x1,x1,x10 + .long 0x8b16035a // add x26,x26,x22 // d+=h + .long 0x8b1302d6 // add x22,x22,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b070021 // add x1,x1,x7 + .long 0x8b1102d6 // add x22,x22,x17 // h+=Sigma0(a) + .long 0x8b060021 // add x1,x1,x6 + .long 0xf9400fe6 // ldr x6,[sp,#24] + .long 0xf9000be9 // str x9,[sp,#16] + .long 0x93da3b50 // ror x16,x26,#14 + .long 0x8b1302b5 // add x21,x21,x19 // h+=K[i] + .long 0x93c30468 // ror x8,x3,#1 + .long 0x8a1a0371 // and x17,x27,x26 + .long 0x93c04c07 // ror x7,x0,#19 + .long 0x8a3a0293 // bic x19,x20,x26 + .long 0x93d672c9 // ror x9,x22,#28 + .long 0x8b0102b5 // add x21,x21,x1 // h+=X[i] + .long 0xcada4a10 // eor x16,x16,x26, ror #18 + .long 0xcac32108 // eor x8,x8,x3, ror #8 + .long 0xaa130231 // orr x17,x17,x19 // Ch(e,f,g) + .long 0xca1702d3 // eor x19,x22,x23 // a^b, b^c in next round + .long 0xcadaa610 // eor x16,x16,x26, ror #41 // Sigma1(e) + .long 0xcad68929 // eor x9,x9,x22, ror #34 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Ch(e,f,g) + .long 0x8a13039c // and x28,x28,x19 // (b^c)&=(a^b) + .long 0xcac0f4e7 // eor x7,x7,x0, ror #61 + .long 0xca431d08 // eor x8,x8,x3, lsr #7 // sigma0(X[i+1]) + .long 0x8b1002b5 // add x21,x21,x16 // h+=Sigma1(e) + .long 0xca17039c // eor x28,x28,x23 // Maj(a,b,c) + .long 0xcad69d31 // eor x17,x9,x22, ror #39 // Sigma0(a) + .long 0xca4018e7 // eor x7,x7,x0, lsr #6 // sigma1(X[i+14]) + .long 0x8b0b0042 // add x2,x2,x11 + .long 0x8b150339 // add x25,x25,x21 // d+=h + .long 0x8b1c02b5 // add x21,x21,x28 // h+=Maj(a,b,c) + .long 0xf84087dc // ldr x28,[x30],#8 // *K++, x19 in next round + .long 0x8b080042 // add x2,x2,x8 + .long 0x8b1102b5 // add x21,x21,x17 // h+=Sigma0(a) + .long 0x8b070042 // add x2,x2,x7 + .long 0xf94003e7 // ldr x7,[sp,#0] + .long 0xf9000fea // str x10,[sp,#24] + .long 0x93d93b30 // ror x16,x25,#14 + .long 0x8b1c0294 // add x20,x20,x28 // h+=K[i] + .long 0x93c40489 // ror x9,x4,#1 + .long 0x8a190351 // and x17,x26,x25 + .long 0x93c14c28 // ror x8,x1,#19 + .long 0x8a39037c // bic x28,x27,x25 + .long 0x93d572aa // ror x10,x21,#28 + .long 0x8b020294 // add x20,x20,x2 // h+=X[i] + .long 0xcad94a10 // eor x16,x16,x25, ror #18 + .long 0xcac42129 // eor x9,x9,x4, ror #8 + .long 0xaa1c0231 // orr x17,x17,x28 // Ch(e,f,g) + .long 0xca1602bc // eor x28,x21,x22 // a^b, b^c in next round + .long 0xcad9a610 // eor x16,x16,x25, ror #41 // Sigma1(e) + .long 0xcad5894a // eor x10,x10,x21, ror #34 + .long 0x8b110294 // add x20,x20,x17 // h+=Ch(e,f,g) + .long 0x8a1c0273 // and x19,x19,x28 // (b^c)&=(a^b) + .long 0xcac1f508 // eor x8,x8,x1, ror #61 + .long 0xca441d29 // eor x9,x9,x4, lsr #7 // sigma0(X[i+1]) + .long 0x8b100294 // add x20,x20,x16 // h+=Sigma1(e) + .long 0xca160273 // eor x19,x19,x22 // Maj(a,b,c) + .long 0xcad59d51 // eor x17,x10,x21, ror #39 // Sigma0(a) + .long 0xca411908 // eor x8,x8,x1, lsr #6 // sigma1(X[i+14]) + .long 0x8b0c0063 // add x3,x3,x12 + .long 0x8b140318 // add x24,x24,x20 // d+=h + .long 0x8b130294 // add x20,x20,x19 // h+=Maj(a,b,c) + .long 0xf84087d3 // ldr x19,[x30],#8 // *K++, x28 in next round + .long 0x8b090063 // add x3,x3,x9 + .long 0x8b110294 // add x20,x20,x17 // h+=Sigma0(a) + .long 0x8b080063 // add x3,x3,x8 + cbnz x19,.Lsha512_gpr_loop_16_xx + + .long 0xa9460ba0 // ldp x0,x2,[x29,#96] + .long 0xf9403ba1 // ldr x1,[x29,#112] + .long 0xd10a23de // sub x30,x30,#648 // rewind + + .long 0xa9401003 // ldp x3,x4,[x0] + .long 0xa9411805 // ldp x5,x6,[x0,#2*8] + .long 0x9101c021 // add x1,x1,#14*8 // advance input pointer + .long 0xa9422007 // ldp x7,x8,[x0,#4*8] + .long 0x8b030294 // add x20,x20,x3 + .long 0xa9432809 // ldp x9,x10,[x0,#6*8] + .long 0x8b0402b5 // add x21,x21,x4 + .long 0x8b0502d6 // add x22,x22,x5 + .long 0x8b0602f7 // add x23,x23,x6 + .long 0xa9005414 // stp x20,x21,[x0] + .long 0x8b070318 // add x24,x24,x7 + .long 0x8b080339 // add x25,x25,x8 + .long 0xa9015c16 // stp x22,x23,[x0,#2*8] + .long 0x8b09035a // add x26,x26,x9 + .long 0x8b0a037b // add x27,x27,x10 + .long 0xeb02003f // cmp x1,x2 + .long 0xa9026418 // stp x24,x25,[x0,#4*8] + .long 0xa9036c1a // stp x26,x27,[x0,#6*8] + b.ne .Lsha512_gpr_loop + + .long 0xa94153b3 // ldp x19,x20,[x29,#16] + .long 0x910083ff // add sp,sp,#4*8 + .long 0xa9425bb5 // ldp x21,x22,[x29,#32] + .long 0xa94363b7 // ldp x23,x24,[x29,#48] + .long 0xa9446bb9 // ldp x25,x26,[x29,#64] + .long 0xa94573bb // ldp x27,x28,[x29,#80] + .long 0xa8c87bfd // ldp x29,x30,[sp],#128 + ret diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc similarity index 98% rename from HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc rename to HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc index 0966dfa..72d06f5 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_i386.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc @@ -1,5 +1,5 @@ -// AVX2 (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted -// data (IA-32). Same structure as ScryptSalsa8Avx2_x86_64.inc; the state +// AVX (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted +// data (IA-32). Same structure as ScryptSalsa8Avx_x86_64.inc; the state // save/reload uses vmovdqu (IA-32 stacks are only 4-aligned), so the frame is // 64 bytes with no alignment padding. // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_x86_64.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc similarity index 98% rename from HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_x86_64.inc rename to HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc index 6ce81ab..ad8192b 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc @@ -1,4 +1,4 @@ -// AVX2 (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted data. +// AVX (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted data. // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // // Reference: Colin Percival, "Stronger Key Derivation via Sequential diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc index fdd58f6..d98d523 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc @@ -19,8 +19,8 @@ .long 0x6e0540b1 // ext v17.16b, v5.16b, v5.16b, #8 .long 0x6e261c84 // eor v4.16b, v4.16b, v6.16b .long 0x6e271ca5 // eor v5.16b, v5.16b, v7.16b - .long 0x4e871886 // uzp1 v6.4s, v4.4s, v5.4s - .long 0x4e875887 // uzp2 v7.4s, v4.4s, v5.4s + .long 0x4e851886 // uzp1 v6.4s, v4.4s, v5.4s + .long 0x4e855887 // uzp2 v7.4s, v4.4s, v5.4s .long 0x2ea780d0 // umlal v16.2d, v6.2s, v7.2s .long 0x6ea780d1 // umlal2 v17.2d, v6.4s, v7.4s .long 0x3dc00000 // ldr q0, [x0, #0x0] @@ -38,8 +38,8 @@ .long 0x6e0540b1 // ext v17.16b, v5.16b, v5.16b, #8 .long 0x6e261c84 // eor v4.16b, v4.16b, v6.16b .long 0x6e271ca5 // eor v5.16b, v5.16b, v7.16b - .long 0x4e871886 // uzp1 v6.4s, v4.4s, v5.4s - .long 0x4e875887 // uzp2 v7.4s, v4.4s, v5.4s + .long 0x4e851886 // uzp1 v6.4s, v4.4s, v5.4s + .long 0x4e855887 // uzp2 v7.4s, v4.4s, v5.4s .long 0x2ea780d0 // umlal v16.2d, v6.2s, v7.2s .long 0x6ea780d1 // umlal2 v17.2d, v6.4s, v7.4s .long 0x3dc00802 // ldr q2, [x0, #0x20] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc index 220699d..54cc778 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc @@ -3,20 +3,19 @@ // x86_64 version's vmovq xmm, r64 seed transfers (not encodable in 32-bit // mode) become the SSE2 i386 sibling's push/vmovq-from-stack pattern, with // the negation done in 32-bit halves (not/not + add/adc carry). -// IA-32: after HlpSimdProc3Begin_i386 - ebx = customSecret, -// esi = defaultSecret, edi = seed.lo32, dword [esp+16] = seed.hi32 -// (UInt64 third parameter; high dword on stack). +// IA-32: after HlpSimdProc3Begin_i386 - ebx = customSecret, esi = defaultSecret, +// edi = seed ptr (PUInt64). // Uses only volatile registers: ymm0-ymm1, eax, ecx, edx (edi reused). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: official xxHash C - XXH3_initCustomSecret_avx2 in xxhash.h, // HashLib XXH3InitSecretAvx2_x86_64.inc. // Build seed vector ymm0 = [seed, -seed, seed, -seed] - mov eax, edi - mov edx, dword ptr [esp + $10] + mov eax, dword ptr [edi] + mov edx, dword ptr [edi + $4] - push eax push edx + push eax db $C5, $FA, $7E, $04, $24 // vmovq xmm0, qword [esp] add esp, $8 @@ -26,8 +25,8 @@ not edi add ecx, $1 adc edi, $0 - push ecx push edi + push ecx db $C5, $FA, $7E, $0C, $24 // vmovq xmm1, qword [esp] add esp, $8 db $C5, $F9, $6C, $C1 // vpunpcklqdq xmm0, xmm0, xmm1 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc index a8bde0b..8937c16 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc @@ -1,10 +1,12 @@ // AVX2 implementation of XXH3_initCustomSecret (fully unrolled, 6 x 32-byte chunks). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI: rcx = customSecret ptr, rdx = defaultSecret ptr, r8 = seed (UInt64). +// Expects MS x64 ABI: rcx = customSecret ptr, rdx = defaultSecret ptr, +// r8 = seed ptr (PUInt64). // Uses only volatile registers: ymm0-ymm2, rax. // Reference: official xxHash C - XXH3_initCustomSecret_avx2 in xxhash.h // Build seed vector ymm0 = [seed, -seed, seed, -seed] + mov r8, qword [r8] db $C4, $C1, $F9, $6E, $C0 // vmovq xmm0, r8 mov rax, r8 neg rax diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc index 5be2728..c210f94 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc @@ -1,5 +1,6 @@ // XXH3 initCustomSecret AArch64 NEON implementation (192-byte custom secret). -// Expects AAPCS64: x0 = customSecret ptr, x1 = defaultSecret ptr, x2 = seed (UInt64). +// Expects AAPCS64: x0 = customSecret ptr, x1 = defaultSecret ptr, +// x2 = seed ptr (PUInt64). // Leaf nostackframe; caller-saved GPR/vector only. // Reference: HashLib XXH3InitSecretSse2_x86_64.inc. // AArch64 vector instructions are .long-encoded for broad assembler compatibility. @@ -8,6 +9,7 @@ // v0 = vSeed broadcast vector [seed, -seed] // v16-v17 = fmov staging for zip1 pack // v2 = defaultSecret block load / add temp + ldr x2, [x2] neg x3, x2 .long 0x9e670050 // fmov d16, x2 .long 0x9e670071 // fmov d17, x3 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc index cad3d2e..eeee84d 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc @@ -1,15 +1,14 @@ // SSE2 implementation of XXH3_initCustomSecret (fully unrolled, 12 x 16-byte chunks). -// IA-32: after HlpSimdProc3Begin_i386 — ebx = customSecret, esi = defaultSecret, edi = seed.lo32, -// dword [esp+16] = seed.hi32 (UInt64 third parameter; high dword on stack). -// (parallel to MS x64 ABI: rcx, rdx, r8). -// Uses only volatile XMM: xmm0–xmm2. +// IA-32: after HlpSimdProc3Begin_i386 - ebx = customSecret, esi = defaultSecret, +// edi = seed ptr (PUInt64). +// Uses only volatile XMM: xmm0-xmm2. // Reference: official xxHash C - XXH3_initCustomSecret_sse2 in xxhash.h - mov eax, edi - mov edx, dword ptr [esp + 16] + mov eax, dword ptr [edi] + mov edx, dword ptr [edi + 4] - push eax push edx + push eax movq xmm0, qword ptr [esp] add esp, 8 @@ -19,8 +18,8 @@ not edi add ecx, 1 adc edi, 0 - push ecx push edi + push ecx movq xmm1, qword ptr [esp] add esp, 8 punpcklqdq xmm0, xmm1 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc index 8b1306f..d39de63 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc @@ -1,10 +1,12 @@ // SSE2 implementation of XXH3_initCustomSecret (fully unrolled, 12 x 16-byte chunks). -// Expects MS x64 ABI: rcx = customSecret ptr, rdx = defaultSecret ptr, r8 = seed (UInt64). +// Expects MS x64 ABI: rcx = customSecret ptr, rdx = defaultSecret ptr, +// r8 = seed ptr (PUInt64). // Uses only volatile registers: xmm0-xmm2. // Algorithm: for each 16-byte block, lo_qword += seed, hi_qword -= seed. // Reference: official xxHash C - XXH3_initCustomSecret_sse2 in xxhash.h // Build seed vector xmm0 = [seed, -seed] + mov r8, qword [r8] movq xmm0, r8 mov rax, r8 neg rax diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc index 9dfc0e4..7bf9f56 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc @@ -21,9 +21,9 @@ .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b .long 0x3dc00021 // ldr q1, [x1, #0x0] .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b - .long 0x4ea69c03 // mul v3.4s, v0.4s, v4.4s + .long 0x4ea49c03 // mul v3.4s, v0.4s, v4.4s .long 0x0ea12801 // xtn v1.2s, v0.2d - .long 0x2ea78023 // umlal v3.2d, v1.2s, v5.2s + .long 0x2ea58023 // umlal v3.2d, v1.2s, v5.2s .long 0x3d800003 // str q3, [x0, #0x0] // --- chunk 1: acc[2..3], secret[0x10..] --- .long 0x3dc00400 // ldr q0, [x0, #0x10] @@ -31,9 +31,9 @@ .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b .long 0x3dc00421 // ldr q1, [x1, #0x10] .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b - .long 0x4ea69c03 // mul v3.4s, v0.4s, v4.4s + .long 0x4ea49c03 // mul v3.4s, v0.4s, v4.4s .long 0x0ea12801 // xtn v1.2s, v0.2d - .long 0x2ea78023 // umlal v3.2d, v1.2s, v5.2s + .long 0x2ea58023 // umlal v3.2d, v1.2s, v5.2s .long 0x3d800403 // str q3, [x0, #0x10] // --- chunk 2: acc[4..5], secret[0x20..] --- .long 0x3dc00800 // ldr q0, [x0, #0x20] @@ -41,9 +41,9 @@ .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b .long 0x3dc00821 // ldr q1, [x1, #0x20] .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b - .long 0x4ea69c03 // mul v3.4s, v0.4s, v4.4s + .long 0x4ea49c03 // mul v3.4s, v0.4s, v4.4s .long 0x0ea12801 // xtn v1.2s, v0.2d - .long 0x2ea78023 // umlal v3.2d, v1.2s, v5.2s + .long 0x2ea58023 // umlal v3.2d, v1.2s, v5.2s .long 0x3d800803 // str q3, [x0, #0x20] // --- chunk 3: acc[6..7], secret[0x30..] --- .long 0x3dc00c00 // ldr q0, [x0, #0x30] @@ -51,8 +51,8 @@ .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b .long 0x3dc00c21 // ldr q1, [x1, #0x30] .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b - .long 0x4ea69c03 // mul v3.4s, v0.4s, v4.4s + .long 0x4ea49c03 // mul v3.4s, v0.4s, v4.4s .long 0x0ea12801 // xtn v1.2s, v0.2d - .long 0x2ea78023 // umlal v3.2d, v1.2s, v5.2s + .long 0x2ea58023 // umlal v3.2d, v1.2s, v5.2s .long 0x3d800c03 // str q3, [x0, #0x30] ret diff --git a/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas b/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas index 883f76a..4e41cba 100644 --- a/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpAdler32X86Backend.pas @@ -34,50 +34,42 @@ implementation // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure Adler32_ProcessBlocks_Sse2(AData: PByte; ANumBlocks: UInt32; ASums, AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Adler32\Adler32BlocksSse2_i386.inc} -end; - -procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_i386.inc} -end; - -procedure Adler32_ProcessBlocks_Avx2(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Adler32\Adler32BlocksAvx2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} - -procedure Adler32_ProcessBlocks_Sse2(AData: PByte; ANumBlocks: UInt32; - ASums, AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Adler32\Adler32BlocksSse2_x86_64.inc} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Adler32\Adler32BlocksSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Adler32\Adler32BlocksSse2_i386.inc} +{$ENDIF} end; procedure Adler32_ProcessBlocks_Ssse3(AData: PByte; ANumBlocks: UInt32; ASums, AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Adler32\Adler32BlocksSsse3_i386.inc} +{$ENDIF} end; procedure Adler32_ProcessBlocks_Avx2(AData: PByte; ANumBlocks: UInt32; ASums, AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Adler32\Adler32BlocksAvx2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Adler32\Adler32BlocksAvx2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Adler32\Adler32BlocksAvx2_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_X86_64_ASM} - procedure Adler32_Update_Sse2(AData: PByte; ALength: UInt32; ASums: Pointer); begin Adler32_Update_Simd(AData, ALength, ASums, @Adler32_ProcessBlocks_Sse2); diff --git a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas index 715e7cd..e7733e6 100644 --- a/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpArgon2X86Backend.pas @@ -46,28 +46,19 @@ implementation // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_i386.inc} -end; - -procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; - AWithXor: Int32; AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} - {$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_i386.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} -procedure Argon2_FillBlock_Sse2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Argon2\Argon2FillBlockSse2_x86_64.inc} -end; - procedure Argon2_FillBlock_Ssse3(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32; AMasks: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} @@ -81,14 +72,20 @@ procedure Argon2_FillBlock_Ssse3_Wrap(ALeft, ARight, ACurrent: Pointer; @ARGON2_ROT_MASKS); end; +{$ENDIF HASHLIB_X86_64_ASM} + procedure Argon2_FillBlock_Avx2(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32; AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} +{$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} +{$I ..\..\Include\Simd\Argon2\Argon2FillBlockAvx2_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_X86_64_ASM} - procedure Argon2_FillBlock_Avx2_Wrap(ALeft, ARight, ACurrent: Pointer; AWithXor: Int32); begin diff --git a/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas index 56b558b..13687b4 100644 --- a/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpBlake2BX86Backend.pas @@ -45,52 +45,27 @@ implementation // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_i386.inc} -end; - -procedure Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, - AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} - {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSsse3_i386.inc} -end; - -procedure Blake2B_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, - AIV: Pointer); -begin - Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, - @BLAKE2B_ROT_MASKS); -end; - -procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, - AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} - {$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_i386.inc} -end; - -procedure Blake2B_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, - AIV: Pointer); -begin - Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, - @BLAKE2B_ROT_MASKS); -end; - -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} - -procedure Blake2B_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_x86_64.inc} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Blake2B\Blake2BCompressSse2_i386.inc} +{$ENDIF} end; procedure Blake2B_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake2B\Blake2BCompressSsse3_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake2B\Blake2BCompressSsse3_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} +{$I ..\..\Include\Simd\Blake2B\Blake2BCompressSsse3_i386.inc} +{$ENDIF} end; procedure Blake2B_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, @@ -102,8 +77,14 @@ procedure Blake2B_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, procedure Blake2B_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} +{$I ..\..\Include\Simd\Blake2B\Blake2BCompressAvx2_i386.inc} +{$ENDIF} end; procedure Blake2B_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, @@ -113,8 +94,6 @@ procedure Blake2B_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, @BLAKE2B_ROT_MASKS); end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TBlake2BX86Backend } diff --git a/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas index 07af353..5072787 100644 --- a/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpBlake2SX86Backend.pas @@ -28,7 +28,7 @@ implementation HlpSimdLevels; const - // pshufb byte-rotation masks for the AVX2 kernel: rotr32 by 16 (at +0) and + // pshufb byte-rotation masks for the AVX and SSSE3 kernels: rotr32 by 16 (at +0) and // by 8 (at +16) as single byte shuffles. Matches the official BLAKE2 SSSE3+ // implementation's r16/r8 shuffle constants. BLAKE2S_ROT_MASKS: array [0 .. 3] of UInt64 = ( @@ -42,52 +42,27 @@ implementation // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_i386.inc} -end; - -procedure Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, - AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} - {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSsse3_i386.inc} -end; - -procedure Blake2S_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, - AIV: Pointer); -begin - Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, - @BLAKE2S_ROT_MASKS); -end; - -procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, - AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} - {$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx2_i386.inc} -end; - -procedure Blake2S_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, - AIV: Pointer); -begin - Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, - @BLAKE2S_ROT_MASKS); -end; - -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} - -procedure Blake2S_Compress_Sse2(AState, AMsg, ACounterFlags, AIV: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_x86_64.inc} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Blake2S\Blake2SCompressSse2_i386.inc} +{$ENDIF} end; procedure Blake2S_Compress_Ssse3(AState, AMsg, ACounterFlags, AIV, AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake2S\Blake2SCompressSsse3_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake2S\Blake2SCompressSsse3_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} +{$I ..\..\Include\Simd\Blake2S\Blake2SCompressSsse3_i386.inc} +{$ENDIF} end; procedure Blake2S_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, @@ -97,21 +72,25 @@ procedure Blake2S_Compress_Ssse3_Wrap(AState, AMsg, ACounterFlags, @BLAKE2S_ROT_MASKS); end; -procedure Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, +procedure Blake2S_Compress_Avx(AState, AMsg, ACounterFlags, AIV, AMasks: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} +{$I ..\..\Include\Simd\Blake2S\Blake2SCompressAvx_i386.inc} +{$ENDIF} end; -procedure Blake2S_Compress_Avx2_Wrap(AState, AMsg, ACounterFlags, +procedure Blake2S_Compress_Avx_Wrap(AState, AMsg, ACounterFlags, AIV: Pointer); begin - Blake2S_Compress_Avx2(AState, AMsg, ACounterFlags, AIV, + Blake2S_Compress_Avx(AState, AMsg, ACounterFlags, AIV, @BLAKE2S_ROT_MASKS); end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TBlake2SX86Backend } @@ -122,7 +101,7 @@ class function TBlake2SX86Backend.Select(AScalar: TBlake2SCompressProc): TBlake2 case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@Blake2S_Compress_Avx2_Wrap); + Exit(@Blake2S_Compress_Avx_Wrap); TX86SimdLevel.SSSE3: Exit(@Blake2S_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: diff --git a/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas b/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas index c24c86d..efde87e 100644 --- a/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpBlake3X86Backend.pas @@ -50,28 +50,19 @@ implementation // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_i386.inc} -end; - -procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; - ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_i386.inc} - {$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_i386.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} -procedure Blake3_Compress_Sse2(AState, AMsg, ACV, ACounterFlags: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake3\Blake3CompressSse2_x86_64.inc} -end; - procedure Blake3_Compress_Ssse3(AState, AMsg, ACV, ACounterFlags, AMasks: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} @@ -85,25 +76,35 @@ procedure Blake3_Compress_Ssse3_Wrap(AState, AMsg, ACV, @BLAKE3_ROT_MASKS); end; -procedure Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags, +procedure Blake3_Compress_Avx(AState, AMsg, ACV, ACounterFlags, AMasks: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake3\Blake3CompressAvx2_x86_64.inc} + {$I ..\..\Include\Simd\Blake3\Blake3CompressAvx_x86_64.inc} end; -procedure Blake3_Compress_Avx2_Wrap(AState, AMsg, ACV, +procedure Blake3_Compress_Avx_Wrap(AState, AMsg, ACV, ACounterFlags: Pointer); begin - Blake3_Compress_Avx2(AState, AMsg, ACV, ACounterFlags, + Blake3_Compress_Avx(AState, AMsg, ACV, ACounterFlags, @BLAKE3_ROT_MASKS); end; +{$ENDIF HASHLIB_X86_64_ASM} + procedure Blake3_Hash4_Sse2(AInput, AKey, AOut: Pointer; ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32); - {$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} - {$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_x86_64.inc} +{$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc6Begin_i386.inc} +{$I ..\..\Include\Simd\Blake3\Blake3Hash4Sse2_i386.inc} +{$ENDIF} end; +{$IFDEF HASHLIB_X86_64_ASM} + procedure Blake3_Hash4_Ssse3(AInput, AKey, AOut: Pointer; ANumChunks: Int32; ACounter: UInt64; AFlags: UInt32; AMasks: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc7Begin_x86_64.inc} @@ -200,7 +201,7 @@ class function TBlake3X86Backend.SelectCompress(AScalar: TBlake3CompressProc): T case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@Blake3_Compress_Avx2_Wrap); + Exit(@Blake3_Compress_Avx_Wrap); TX86SimdLevel.SSSE3: Exit(@Blake3_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: diff --git a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas index f83163f..554b076 100644 --- a/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpCRCX86Backend.pas @@ -34,86 +34,78 @@ implementation // x86_64: VPCLMULQDQ, PCLMULQDQ, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflectedSse2_i386.inc} -end; - -function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_i386.inc} -end; - -function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflectedPclmul_i386.inc} -end; - -function CRC_Fold_Forward_Pclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldForwardPclmul_i386.inc} -end; - -function CRC_Fold_Reflected_Vpclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflectedVpclmul_i386.inc} -end; - -function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldForwardVpclmul_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} - -function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; - AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflectedSse2_x86_64.inc} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldReflectedSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldReflectedSse2_i386.inc} +{$ENDIF} end; -function CRC_Fold_Forward_Sse2(AData: PByte; ALength: UInt32; +function CRC_Fold_Forward_Gpr(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldForwardSse2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldForwardGpr_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldForwardGpr_i386.inc} +{$ENDIF} end; function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflectedPclmul_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldReflectedPclmul_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldReflectedPclmul_i386.inc} +{$ENDIF} end; function CRC_Fold_Reflected_Vpclmul(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldReflectedVpclmul_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldReflectedVpclmul_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldReflectedVpclmul_i386.inc} +{$ENDIF} end; function CRC_Fold_Forward_Pclmul(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldForwardPclmul_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldForwardPclmul_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldForwardPclmul_i386.inc} +{$ENDIF} end; function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; AState: Pointer; AConstants: Pointer): UInt64; - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\CRC\CRCFoldForwardVpclmul_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldForwardVpclmul_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\CRC\CRCFoldForwardVpclmul_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TCRCX86Backend } @@ -146,7 +138,7 @@ class function TCRCX86Backend.Select(AReflectedScalar, TX86SimdLevel.SSE2: begin Result.Reflected := @CRC_Fold_Reflected_Sse2; - Result.Fwd := @CRC_Fold_Forward_Sse2; + Result.Fwd := @CRC_Fold_Forward_Gpr; end; end; {$ENDIF HASHLIB_X86_SIMD} diff --git a/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas index 62e5c2b..cf40f21 100644 --- a/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA1ArmBackend.pas @@ -24,11 +24,12 @@ implementation {$IFDEF HASHLIB_AARCH64_ASM} uses - HlpCpuFeatures; + HlpCpuFeatures, + HlpSimdLevels; // ============================================================================= // SIMD kernels -// aarch64: SHA1 Crypto Extensions +// aarch64: SHA1 Crypto Extensions, NEON // ============================================================================= procedure SHA1_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; @@ -42,6 +43,11 @@ procedure SHA1_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UInt3 SHA1_Compress_CryptoExt(AState, AData, ANumBlocks, @K_SHA1); end; +procedure SHA1_Compress_Gpr(AState, AData: Pointer; ANumBlocks: UInt32); + {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressGpr_aarch64.inc} +end; + {$ENDIF HASHLIB_AARCH64_ASM} { TSHA1ArmBackend } @@ -51,6 +57,10 @@ class function TSHA1ArmBackend.Select(AScalar: TSHA1CompressProc): TSHA1Compress {$IFDEF HASHLIB_AARCH64_ASM} if TCpuFeatures.Arm.HasSHA1() then Exit(@SHA1_Compress_CryptoExt_Wrap); + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@SHA1_Compress_Gpr); + end; {$ENDIF} Result := AScalar; end; diff --git a/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas index 5cf4c38..4728b77 100644 --- a/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA1X86Backend.pas @@ -75,24 +75,6 @@ procedure SHA1_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); SHA1_Compress_ShaNi(AState, AData, ANumBlocks, @K_SHA1_Doubled); end; -procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_i386.inc} -end; - -procedure SHA1_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA1\SHA1CompressSsse3_i386.inc} -end; - -procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx2_i386.inc} -end; - {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -108,24 +90,60 @@ procedure SHA1_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); SHA1_Compress_ShaNi(AState, AData, ANumBlocks, @K_SHA1, @BSWAP32_MASK); end; +{$ENDIF HASHLIB_X86_64_ASM} + procedure SHA1_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\SHA1\SHA1CompressSse2_i386.inc} +{$ENDIF} end; procedure SHA1_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA1\SHA1CompressSsse3_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\SHA1\SHA1CompressSsse3_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\SHA1\SHA1CompressSsse3_i386.inc} +{$ENDIF} +end; + +{$IFDEF HASHLIB_I386_ASM} + +procedure SHA1_Compress_Avx(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx_i386.inc} end; +procedure SHA1_Compress_Avx_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_Avx(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + procedure SHA1_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} {$I ..\..\Include\Simd\SHA1\SHA1CompressAvx2_x86_64.inc} end; +procedure SHA1_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA1_Compress_Avx2(AState, AData, ANumBlocks, @K_SHA1_Doubled); +end; + {$ENDIF HASHLIB_X86_64_ASM} procedure SHA1_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); @@ -138,11 +156,6 @@ procedure SHA1_Compress_Ssse3_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); SHA1_Compress_Ssse3(AState, AData, ANumBlocks, @K_SHA1_Doubled); end; -procedure SHA1_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA1_Compress_Avx2(AState, AData, ANumBlocks, @K_SHA1_Doubled); -end; - {$ENDIF HASHLIB_X86_SIMD} { TSHA1X86Backend } @@ -155,7 +168,7 @@ class function TSHA1X86Backend.Select(AScalar: TSHA1CompressProc): TSHA1Compress case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@SHA1_Compress_Avx2_Wrap); + Exit(@SHA1_Compress_Avx_Wrap); TX86SimdLevel.SSSE3: Exit(@SHA1_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: diff --git a/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas index 6e56321..6b2c407 100644 --- a/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_256ArmBackend.pas @@ -24,11 +24,37 @@ implementation {$IFDEF HASHLIB_AARCH64_ASM} uses - HlpCpuFeatures; + HlpCpuFeatures, + HlpSimdLevels; + +const + // K256 with a trailing zero terminator for the pure-GPR kernel: its + // message-schedule loop ends when the loaded K word is zero (cbnz), like + // the original's sentinel-terminated table - the plain K256 const cannot + // drive that loop. The crypto-extension kernel keeps using K256. + K256_Gpr: array [0 .. 64] of UInt32 = ( + $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, + $D807AA98, $12835B01, $243185BE, $550C7DC3, + $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, + $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, + $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, + $983E5152, $A831C66D, $B00327C8, $BF597FC7, + $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, + $650A7354, $766A0ABB, $81C2C92E, $92722C85, + $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, + $D192E819, $D6990624, $F40E3585, $106AA070, + $19A4C116, $1E376C08, $2748774C, $34B0BCB5, + $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, + $748F82EE, $78A5636F, $84C87814, $8CC70208, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2, + 0 // terminator - the schedule loop ends on a zero K word + ); // ============================================================================= // SIMD kernels -// aarch64: SHA256 Crypto Extensions +// aarch64: SHA256 Crypto Extensions, NEON // ============================================================================= procedure SHA256_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; @@ -42,6 +68,17 @@ procedure SHA256_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UIn SHA256_Compress_CryptoExt(AState, AData, ANumBlocks, @K256); end; +procedure SHA256_Compress_Gpr(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressGpr_aarch64.inc} +end; + +procedure SHA256_Compress_Gpr_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_Gpr(AState, AData, ANumBlocks, @K256_Gpr); +end; + {$ENDIF HASHLIB_AARCH64_ASM} { TSHA2_256ArmBackend } @@ -51,6 +88,10 @@ class function TSHA2_256ArmBackend.Select(AScalar: TSHA256CompressProc): TSHA256 {$IFDEF HASHLIB_AARCH64_ASM} if TCpuFeatures.Arm.HasSHA256() then Exit(@SHA256_Compress_CryptoExt_Wrap); + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@SHA256_Compress_Gpr_Wrap); + end; {$ENDIF} Result := AScalar; end; diff --git a/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas index c81baf2..ad0ee0c 100644 --- a/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_256X86Backend.pas @@ -102,24 +102,6 @@ procedure SHA256_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32) SHA256_Compress_ShaNi(AState, AData, ANumBlocks, @K256_Doubled); end; -procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_i386.inc} -end; - -procedure SHA256_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA256\SHA256CompressSsse3_i386.inc} -end; - -procedure SHA256_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA256\SHA256CompressAvx2_i386.inc} -end; - {$ENDIF HASHLIB_I386_ASM} {$IFDEF HASHLIB_X86_64_ASM} @@ -135,24 +117,60 @@ procedure SHA256_Compress_ShaNi_Wrap(AState, AData: Pointer; ANumBlocks: UInt32) SHA256_Compress_ShaNi(AState, AData, ANumBlocks, @K256, @BSWAP32_MASK); end; +{$ENDIF HASHLIB_X86_64_ASM} + procedure SHA256_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\SHA256\SHA256CompressSse2_i386.inc} +{$ENDIF} end; procedure SHA256_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA256\SHA256CompressSsse3_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\SHA256\SHA256CompressSsse3_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\SHA256\SHA256CompressSsse3_i386.inc} +{$ENDIF} +end; + +{$IFDEF HASHLIB_I386_ASM} + +procedure SHA256_Compress_Avx(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} + {$I ..\..\Include\Simd\SHA256\SHA256CompressAvx_i386.inc} end; +procedure SHA256_Compress_Avx_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_Avx(AState, AData, ANumBlocks, @K256_Doubled); +end; + +{$ENDIF HASHLIB_I386_ASM} + +{$IFDEF HASHLIB_X86_64_ASM} + procedure SHA256_Compress_Avx2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} {$I ..\..\Include\Simd\SHA256\SHA256CompressAvx2_x86_64.inc} end; +procedure SHA256_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA256_Compress_Avx2(AState, AData, ANumBlocks, @K256_Doubled); +end; + {$ENDIF HASHLIB_X86_64_ASM} procedure SHA256_Compress_Ssse3_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); @@ -160,11 +178,6 @@ procedure SHA256_Compress_Ssse3_Wrap(AState, AData: Pointer; ANumBlocks: UInt32) SHA256_Compress_Ssse3(AState, AData, ANumBlocks, @K256_Doubled); end; -procedure SHA256_Compress_Avx2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); -begin - SHA256_Compress_Avx2(AState, AData, ANumBlocks, @K256_Doubled); -end; - procedure SHA256_Compress_Sse2_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); begin SHA256_Compress_Sse2(AState, AData, ANumBlocks, @K256_Doubled); @@ -182,7 +195,7 @@ class function TSHA2_256X86Backend.Select(AScalar: TSHA256CompressProc): TSHA256 case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSSE3, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@SHA256_Compress_Avx2_Wrap); + Exit(@SHA256_Compress_Avx_Wrap); TX86SimdLevel.SSSE3: Exit(@SHA256_Compress_Ssse3_Wrap); TX86SimdLevel.SSE2: diff --git a/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas index 0800d22..1c64277 100644 --- a/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_512ArmBackend.pas @@ -24,11 +24,61 @@ implementation {$IFDEF HASHLIB_AARCH64_ASM} uses - HlpCpuFeatures; + HlpCpuFeatures, + HlpSimdLevels; + +const + // K512 with a trailing zero terminator for the plain-GPR kernel: its + // message-schedule loop ends when the loaded K word is zero (cbnz), like + // the original's sentinel-terminated table - the plain K512 const cannot + // drive that loop. The crypto-extension kernel keeps using K512. + K512_Gpr: array [0 .. 80] of UInt64 = ( + UInt64($428A2F98D728AE22), UInt64($7137449123EF65CD), + UInt64($B5C0FBCFEC4D3B2F), UInt64($E9B5DBA58189DBBC), + UInt64($3956C25BF348B538), UInt64($59F111F1B605D019), + UInt64($923F82A4AF194F9B), UInt64($AB1C5ED5DA6D8118), + UInt64($D807AA98A3030242), UInt64($12835B0145706FBE), + UInt64($243185BE4EE4B28C), UInt64($550C7DC3D5FFB4E2), + UInt64($72BE5D74F27B896F), UInt64($80DEB1FE3B1696B1), + UInt64($9BDC06A725C71235), UInt64($C19BF174CF692694), + UInt64($E49B69C19EF14AD2), UInt64($EFBE4786384F25E3), + UInt64($0FC19DC68B8CD5B5), UInt64($240CA1CC77AC9C65), + UInt64($2DE92C6F592B0275), UInt64($4A7484AA6EA6E483), + UInt64($5CB0A9DCBD41FBD4), UInt64($76F988DA831153B5), + UInt64($983E5152EE66DFAB), UInt64($A831C66D2DB43210), + UInt64($B00327C898FB213F), UInt64($BF597FC7BEEF0EE4), + UInt64($C6E00BF33DA88FC2), UInt64($D5A79147930AA725), + UInt64($06CA6351E003826F), UInt64($142929670A0E6E70), + UInt64($27B70A8546D22FFC), UInt64($2E1B21385C26C926), + UInt64($4D2C6DFC5AC42AED), UInt64($53380D139D95B3DF), + UInt64($650A73548BAF63DE), UInt64($766A0ABB3C77B2A8), + UInt64($81C2C92E47EDAEE6), UInt64($92722C851482353B), + UInt64($A2BFE8A14CF10364), UInt64($A81A664BBC423001), + UInt64($C24B8B70D0F89791), UInt64($C76C51A30654BE30), + UInt64($D192E819D6EF5218), UInt64($D69906245565A910), + UInt64($F40E35855771202A), UInt64($106AA07032BBD1B8), + UInt64($19A4C116B8D2D0C8), UInt64($1E376C085141AB53), + UInt64($2748774CDF8EEB99), UInt64($34B0BCB5E19B48A8), + UInt64($391C0CB3C5C95A63), UInt64($4ED8AA4AE3418ACB), + UInt64($5B9CCA4F7763E373), UInt64($682E6FF3D6B2B8A3), + UInt64($748F82EE5DEFB2FC), UInt64($78A5636F43172F60), + UInt64($84C87814A1F0AB72), UInt64($8CC702081A6439EC), + UInt64($90BEFFFA23631E28), UInt64($A4506CEBDE82BDE9), + UInt64($BEF9A3F7B2C67915), UInt64($C67178F2E372532B), + UInt64($CA273ECEEA26619C), UInt64($D186B8C721C0C207), + UInt64($EADA7DD6CDE0EB1E), UInt64($F57D4F7FEE6ED178), + UInt64($06F067AA72176FBA), UInt64($0A637DC5A2C898A6), + UInt64($113F9804BEF90DAE), UInt64($1B710B35131C471B), + UInt64($28DB77F523047D84), UInt64($32CAAB7B40C72493), + UInt64($3C9EBE0A15C9BEBC), UInt64($431D67C49C100D4C), + UInt64($4CC5D4BECB3E42B6), UInt64($597F299CFC657E2A), + UInt64($5FCB6FAB3AD6FAEC), UInt64($6C44198C4A475817), + UInt64(0) // terminator - the schedule loop ends on a zero K word + ); // ============================================================================= // SIMD kernels -// aarch64: SHA512 Crypto Extensions +// aarch64: SHA512 Crypto Extensions, NEON // ============================================================================= procedure SHA512_Compress_CryptoExt(AState, AData: Pointer; ANumBlocks: UInt32; @@ -42,6 +92,17 @@ procedure SHA512_Compress_CryptoExt_Wrap(AState, AData: Pointer; ANumBlocks: UIn SHA512_Compress_CryptoExt(AState, AData, ANumBlocks, @K512); end; +procedure SHA512_Compress_Gpr(AState, AData: Pointer; ANumBlocks: UInt32; + AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA512\SHA512CompressGpr_aarch64.inc} +end; + +procedure SHA512_Compress_Gpr_Wrap(AState, AData: Pointer; ANumBlocks: UInt32); +begin + SHA512_Compress_Gpr(AState, AData, ANumBlocks, @K512_Gpr); +end; + {$ENDIF HASHLIB_AARCH64_ASM} { TSHA2_512ArmBackend } @@ -51,6 +112,10 @@ class function TSHA2_512ArmBackend.Select(AScalar: TSHA512CompressProc): TSHA512 {$IFDEF HASHLIB_AARCH64_ASM} if TCpuFeatures.Arm.HasSHA512() then Exit(@SHA512_Compress_CryptoExt_Wrap); + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@SHA512_Compress_Gpr_Wrap); + end; {$ENDIF} Result := AScalar; end; diff --git a/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas index 486621f..6ce14d9 100644 --- a/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA2_512X86Backend.pas @@ -125,24 +125,20 @@ implementation // x86_64: AVX2, SSSE3, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure SHA512_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} - {$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_i386.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} +{$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_i386.inc} +{$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} -procedure SHA512_Compress_Sse2(AState, AData: Pointer; ANumBlocks: UInt32; - AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA512\SHA512CompressSse2_x86_64.inc} -end; - procedure SHA512_Compress_Ssse3(AState, AData: Pointer; ANumBlocks: UInt32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc4Begin_x86_64.inc} diff --git a/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas b/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas index 22c3000..84f6f4b 100644 --- a/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA3ArmBackend.pas @@ -25,15 +25,16 @@ implementation {$IFDEF HASHLIB_AARCH64_ASM} uses - HlpCpuFeatures; + HlpCpuFeatures, + HlpSimdLevels; // ============================================================================= // SIMD kernels -// aarch64: SHA3 Crypto Extensions +// aarch64: SHA3 Crypto Extensions, NEON // -// The FEAT_SHA3 kernels reuse the plain RC round-constant table directly (the -// asm broadcasts each 64-bit iota with ld1r), so no packed constant block is -// needed. +// Both kernels reuse the plain RC round-constant table directly (the +// FEAT_SHA3 asm broadcasts each 64-bit iota with ld1r; the GPR permute walks +// it behind an end-pointer), so no packed constant block is needed. // ============================================================================= procedure KeccakF1600_CryptoExt(AState: Pointer; AConstants: Pointer); @@ -58,6 +59,28 @@ procedure KeccakF1600_CryptoExt_Absorb_Wrap(AState: Pointer; AData: PByte; KeccakF1600_CryptoExt_Absorb(AState, AData, ABlockCount, ABlockSize, @RC); end; +procedure KeccakF1600_Gpr(AState: Pointer; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Gpr_aarch64.inc} +end; + +procedure KeccakF1600_Gpr_Wrap(AState: Pointer); +begin + KeccakF1600_Gpr(AState, @RC); +end; + +procedure KeccakF1600_Gpr_Absorb(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_aarch64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600GprAbsorb_aarch64.inc} +end; + +procedure KeccakF1600_Gpr_Absorb_Wrap(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); +begin + KeccakF1600_Gpr_Absorb(AState, AData, ABlockCount, ABlockSize, @RC); +end; + {$ENDIF HASHLIB_AARCH64_ASM} { TSHA3ArmBackend } @@ -67,6 +90,10 @@ class function TSHA3ArmBackend.SelectPermute(AScalar: TKeccakF1600Proc): TKeccak {$IFDEF HASHLIB_AARCH64_ASM} if TCpuFeatures.Arm.HasSHA3() then Exit(@KeccakF1600_CryptoExt_Wrap); + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@KeccakF1600_Gpr_Wrap); + end; {$ENDIF} Result := AScalar; end; @@ -76,6 +103,10 @@ class function TSHA3ArmBackend.SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TK {$IFDEF HASHLIB_AARCH64_ASM} if TCpuFeatures.Arm.HasSHA3() then Exit(@KeccakF1600_CryptoExt_Absorb_Wrap); + case TCpuFeatures.Arm.SelectSlot([TArmSimdLevel.NEON]) of + TArmSimdLevel.NEON: + Exit(@KeccakF1600_Gpr_Absorb_Wrap); + end; {$ENDIF} Result := AScalar; end; diff --git a/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas b/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas index 8fce55a..d7c8492 100644 --- a/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpSHA3X86Backend.pas @@ -31,7 +31,7 @@ implementation const // Plain 24-entry iota round constants (stride 8) for the scalar-layout - // kernels (i386 + x86_64 SSE2; the AVX2 kernel uses the x4-broadcast + // kernels (i386 SSE2 + x86_64 GPR; the AVX2 kernel uses the x4-broadcast // table below). K_KECCAK_IOTAS: array [0 .. 23] of UInt64 = ( UInt64($0000000000000001), UInt64($0000000000008082), @@ -104,6 +104,33 @@ implementation // x86_64: AVX2, SSE2 // ============================================================================= +{$IFDEF HASHLIB_I386_ASM} + +procedure KeccakF1600_Sse2(AState: Pointer; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2_i386.inc} +end; + +procedure KeccakF1600_Sse2_Absorb(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); + {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2Absorb_i386.inc} +end; + +procedure KeccakF1600_Sse2_Wrap(AState: Pointer); +begin + KeccakF1600_Sse2(AState, @K_KECCAK_IOTAS); +end; + +procedure KeccakF1600_Sse2_Absorb_Wrap(AState: Pointer; AData: PByte; + ABlockCount: Int32; ABlockSize: Int32); +begin + KeccakF1600_Sse2_Absorb(AState, AData, ABlockCount, ABlockSize, + @K_KECCAK_IOTAS); +end; + +{$ENDIF HASHLIB_I386_ASM} + {$IFDEF HASHLIB_X86_64_ASM} procedure KeccakF1600_Avx2(AState: Pointer; AConstants: Pointer); @@ -117,15 +144,15 @@ procedure KeccakF1600_Avx2_Absorb(AState: Pointer; AData: PByte; {$I ..\..\Include\Simd\SHA3\KeccakF1600Avx2Absorb_x86_64.inc} end; -procedure KeccakF1600_Sse2(AState: Pointer; AConstants: Pointer); +procedure KeccakF1600_Gpr(AState: Pointer; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2_x86_64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600Gpr_x86_64.inc} end; -procedure KeccakF1600_Sse2_Absorb(AState: Pointer; AData: PByte; +procedure KeccakF1600_Gpr_Absorb(AState: Pointer; AData: PByte; ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_x86_64.inc} - {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2Absorb_x86_64.inc} + {$I ..\..\Include\Simd\SHA3\KeccakF1600GprAbsorb_x86_64.inc} end; procedure KeccakF1600_Avx2_Wrap(AState: Pointer); @@ -139,35 +166,20 @@ procedure KeccakF1600_Avx2_Absorb_Wrap(AState: Pointer; AData: PByte; KeccakF1600_Avx2_Absorb(AState, AData, ABlockCount, ABlockSize, @K_KECCAK); end; -{$ENDIF HASHLIB_X86_64_ASM} - -{$IFDEF HASHLIB_I386_ASM} - -procedure KeccakF1600_Sse2(AState: Pointer; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2_i386.inc} -end; - -procedure KeccakF1600_Sse2_Absorb(AState: Pointer; AData: PByte; - ABlockCount: Int32; ABlockSize: Int32; AConstants: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc5Begin_i386.inc} - {$I ..\..\Include\Simd\SHA3\KeccakF1600Sse2Absorb_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - -procedure KeccakF1600_Sse2_Wrap(AState: Pointer); +procedure KeccakF1600_Gpr_Wrap(AState: Pointer); begin - KeccakF1600_Sse2(AState, @K_KECCAK_IOTAS); + KeccakF1600_Gpr(AState, @K_KECCAK_IOTAS); end; -procedure KeccakF1600_Sse2_Absorb_Wrap(AState: Pointer; AData: PByte; +procedure KeccakF1600_Gpr_Absorb_Wrap(AState: Pointer; AData: PByte; ABlockCount: Int32; ABlockSize: Int32); begin - KeccakF1600_Sse2_Absorb(AState, AData, ABlockCount, ABlockSize, + KeccakF1600_Gpr_Absorb(AState, AData, ABlockCount, ABlockSize, @K_KECCAK_IOTAS); end; +{$ENDIF HASHLIB_X86_64_ASM} + {$ENDIF HASHLIB_X86_SIMD} { TSHA3X86Backend } @@ -179,7 +191,7 @@ class function TSHA3X86Backend.SelectPermute(AScalar: TKeccakF1600Proc): TKeccak TX86SimdLevel.AVX2: Exit(@KeccakF1600_Avx2_Wrap); TX86SimdLevel.SSE2: - Exit(@KeccakF1600_Sse2_Wrap); + Exit(@KeccakF1600_Gpr_Wrap); end; {$ENDIF} {$IFDEF HASHLIB_I386_ASM} @@ -198,7 +210,7 @@ class function TSHA3X86Backend.SelectAbsorb(AScalar: TKeccakF1600AbsorbProc): TK TX86SimdLevel.AVX2: Exit(@KeccakF1600_Avx2_Absorb_Wrap); TX86SimdLevel.SSE2: - Exit(@KeccakF1600_Sse2_Absorb_Wrap); + Exit(@KeccakF1600_Gpr_Absorb_Wrap); end; {$ENDIF} {$IFDEF HASHLIB_I386_ASM} diff --git a/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas b/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas index 117a7a0..e2e26b9 100644 --- a/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpScryptX86Backend.pas @@ -33,34 +33,28 @@ implementation // x86_64: AVX2, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_i386.inc} -end; - -procedure Scrypt_SalsaXor_Avx2(AState, AInput: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Avx2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} - -procedure Scrypt_SalsaXor_Sse2(AState, AInput: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_x86_64.inc} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} +{$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} +{$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Sse2_i386.inc} +{$ENDIF} end; -procedure Scrypt_SalsaXor_Avx2(AState, AInput: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Avx2_x86_64.inc} +procedure Scrypt_SalsaXor_Avx(AState, AInput: Pointer); +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} +{$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Avx_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} +{$I ..\..\Include\Simd\Scrypt\ScryptSalsa8Avx_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_X86_64_ASM} - {$ENDIF HASHLIB_X86_SIMD} { TScryptX86Backend } @@ -70,7 +64,7 @@ class function TScryptX86Backend.Select(AScalar: TScryptSalsaXorProc): TScryptSa {$IFDEF HASHLIB_X86_SIMD} case TCpuFeatures.X86.SelectSlot([TX86SimdLevel.AVX2, TX86SimdLevel.SSE2]) of TX86SimdLevel.AVX2: - Exit(@Scrypt_SalsaXor_Avx2); + Exit(@Scrypt_SalsaXor_Avx); TX86SimdLevel.SSE2: Exit(@Scrypt_SalsaXor_Sse2); end; diff --git a/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas b/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas index f252f92..4ee5437 100644 --- a/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas +++ b/HashLib/src/Simd/Backend/HlpXXHash3ArmBackend.pas @@ -47,7 +47,7 @@ procedure XXH3_ScrambleAcc_Neon(AAcc: Pointer; ASecret: Pointer); end; procedure XXH3_InitSecret_Neon(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); + ADefaultSecret: Pointer; ASeedPtr: PUInt64); {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_aarch64.inc} {$I ..\..\Include\Simd\XXH3\XXH3InitSecretNeon_aarch64.inc} end; diff --git a/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas b/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas index 383875f..b31d318 100644 --- a/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas +++ b/HashLib/src/Simd/Backend/HlpXXHash3X86Backend.pas @@ -36,82 +36,76 @@ implementation // x86_64: AVX2, SSE2 // ============================================================================= -{$IFDEF HASHLIB_I386_ASM} - procedure XXH3_Accumulate512_Sse2(AAcc: Pointer; AInput: Pointer; ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} - {$I ..\..\Include\Simd\XXH3\XXH3Acc512Sse2_i386.inc} -end; - -procedure XXH3_ScrambleAcc_Sse2(AAcc: Pointer; ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\..\Include\Simd\XXH3\XXH3ScrambleSse2_i386.inc} -end; - -procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} - {$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_i386.inc} -end; - -procedure XXH3_Accumulate512_Avx2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} - {$I ..\..\Include\Simd\XXH3\XXH3Acc512Avx2_i386.inc} -end; - -procedure XXH3_ScrambleAcc_Avx2(AAcc: Pointer; ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} - {$I ..\..\Include\Simd\XXH3\XXH3ScrambleAvx2_i386.inc} -end; - -procedure XXH3_InitSecret_Avx2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} - {$I ..\..\Include\Simd\XXH3\XXH3InitSecretAvx2_i386.inc} -end; - -{$ENDIF HASHLIB_I386_ASM} - {$IFDEF HASHLIB_X86_64_ASM} - -procedure XXH3_Accumulate512_Sse2(AAcc: Pointer; AInput: Pointer; - ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\..\Include\Simd\XXH3\XXH3Acc512Sse2_x86_64.inc} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} +{$I ..\..\Include\Simd\XXH3\XXH3Acc512Sse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} +{$I ..\..\Include\Simd\XXH3\XXH3Acc512Sse2_i386.inc} +{$ENDIF} end; procedure XXH3_ScrambleAcc_Sse2(AAcc: Pointer; ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\..\Include\Simd\XXH3\XXH3ScrambleSse2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} +{$I ..\..\Include\Simd\XXH3\XXH3ScrambleSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} +{$I ..\..\Include\Simd\XXH3\XXH3ScrambleSse2_i386.inc} +{$ENDIF} end; procedure XXH3_InitSecret_Sse2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_x86_64.inc} + ADefaultSecret: Pointer; ASeedPtr: PUInt64); +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} +{$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} +{$I ..\..\Include\Simd\XXH3\XXH3InitSecretSse2_i386.inc} +{$ENDIF} end; procedure XXH3_Accumulate512_Avx2(AAcc: Pointer; AInput: Pointer; ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\..\Include\Simd\XXH3\XXH3Acc512Avx2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} +{$I ..\..\Include\Simd\XXH3\XXH3Acc512Avx2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} +{$I ..\..\Include\Simd\XXH3\XXH3Acc512Avx2_i386.inc} +{$ENDIF} end; procedure XXH3_ScrambleAcc_Avx2(AAcc: Pointer; ASecret: Pointer); - {$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} - {$I ..\..\Include\Simd\XXH3\XXH3ScrambleAvx2_x86_64.inc} +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_x86_64.inc} +{$I ..\..\Include\Simd\XXH3\XXH3ScrambleAvx2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc2Begin_i386.inc} +{$I ..\..\Include\Simd\XXH3\XXH3ScrambleAvx2_i386.inc} +{$ENDIF} end; procedure XXH3_InitSecret_Avx2(ACustomSecret: Pointer; - ADefaultSecret: Pointer; ASeed: UInt64); - {$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} - {$I ..\..\Include\Simd\XXH3\XXH3InitSecretAvx2_x86_64.inc} + ADefaultSecret: Pointer; ASeedPtr: PUInt64); +{$IFDEF HASHLIB_X86_64_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_x86_64.inc} +{$I ..\..\Include\Simd\XXH3\XXH3InitSecretAvx2_x86_64.inc} +{$ENDIF} +{$IFDEF HASHLIB_I386_ASM} +{$I ..\..\Include\Simd\Common\HlpSimdProc3Begin_i386.inc} +{$I ..\..\Include\Simd\XXH3\XXH3InitSecretAvx2_i386.inc} +{$ENDIF} end; -{$ENDIF HASHLIB_X86_64_ASM} - procedure XXH3_Accumulate_Sse2(AAcc: Pointer; AInput: Pointer; ASecret: Pointer; ANbStripes: Int32); begin From ad5febf5046a8b82c2655287061d85311a1a4d93 Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 12:14:58 +0100 Subject: [PATCH 08/10] Enforce file format checks and normalize SIMD kernel headers (#99) * enforce file format at commit time A new scripts/maintenance/check-file-format.ps1 verifies CRLF, strict UTF-8 and no BOM across the source/text tree. * Normalize source file format and unify the SIMD kernel headers Phase A - format: 74 files converted to CRLF (10 x86_64 kernel includes, 29 library units, one test unit, the scripts tree). The repo encoding rule is valid UTF-8 without BOM; a new scripts/maintenance/check-file-format.ps1 enforces CRLF + strict UTF-8 + no BOM and the pre-commit hook chains it after the duplicate-GUID check. Phase B - headers: all 107 kernel .inc headers now follow one canonical shape: title, strategy notes, "ABI (after HlpSimdProcNBegin_.inc): ..." with layout sub-lines, register map, frame/saves, the encoding one-liner, and "Reference:" always last. Typographic punctuation in the Simd tree normalized to ASCII (BOM-less sources render non-ASCII as mojibake in the IDEs). The Common/CpuFeatures prologue includes keep their structure - per- compiler adaptation is their purpose - with punctuation normalized. Every aarch64 header was changed through its generator constant, so regeneration stays byte-idempotent (asm-check passes for all 15 generated kernels). Two stale headers were corrected: Blake2B NEON now documents its d8-d15 save/restore via the shared include, and Blake3 hash4 NEON's duplicated G-temps map lines are merged. * Silence FPC's below-esp warning in the SHA-256 i386 kernels FPC flags "lea esp, [esp - $60]" with "Use of -offset(%esp), access may cause a crash or value may be lost" in the SSE2/SSSE3/AVX SHA-256 i386 kernels. The warning is a false positive - lea is address arithmetic, not a memory access; the line is the CRYPTOGAMS flag-neutral spelling of a stack allocation and nothing ever dereferences below esp. Spelled it "sub esp, $60" instead: no flag consumer lives between the allocation and the next flag-setting instruction at any of the three sites, so the forms are equivalent - and the recurring build noise is gone. --- .../Simd/Adler32/Adler32BlocksAvx2_i386.inc | 16 ++--- .../Simd/Adler32/Adler32BlocksAvx2_x86_64.inc | 17 ++--- .../Adler32/Adler32BlocksNeon_aarch64.inc | 17 +++-- .../Simd/Adler32/Adler32BlocksSse2_i386.inc | 32 ++++----- .../Simd/Adler32/Adler32BlocksSse2_x86_64.inc | 22 +++--- .../Simd/Adler32/Adler32BlocksSsse3_i386.inc | 17 +++-- .../Adler32/Adler32BlocksSsse3_x86_64.inc | 14 ++-- .../Simd/Argon2/Argon2FillBlockAvx2_i386.inc | 24 +++---- .../Argon2/Argon2FillBlockAvx2_x86_64.inc | 39 ++++++----- .../Argon2/Argon2FillBlockNeon_aarch64.inc | 19 +++--- .../Simd/Argon2/Argon2FillBlockSse2_i386.inc | 30 ++++---- .../Argon2/Argon2FillBlockSse2_x86_64.inc | 32 ++++----- .../Argon2/Argon2FillBlockSsse3_x86_64.inc | 44 ++++++------ .../Simd/Blake2B/Blake2BCompressAvx2_i386.inc | 25 +++---- .../Blake2B/Blake2BCompressAvx2_x86_64.inc | 20 +++--- .../Blake2B/Blake2BCompressNeon_aarch64.inc | 17 +++-- .../Simd/Blake2B/Blake2BCompressSse2_i386.inc | 17 +++-- .../Blake2B/Blake2BCompressSse2_x86_64.inc | 5 +- .../Blake2B/Blake2BCompressSsse3_i386.inc | 27 ++++---- .../Blake2B/Blake2BCompressSsse3_x86_64.inc | 14 ++-- .../Simd/Blake2S/Blake2SCompressAvx_i386.inc | 31 +++++---- .../Blake2S/Blake2SCompressAvx_x86_64.inc | 22 +++--- .../Blake2S/Blake2SCompressNeon_aarch64.inc | 14 ++-- .../Simd/Blake2S/Blake2SCompressSse2_i386.inc | 18 ++--- .../Blake2S/Blake2SCompressSse2_x86_64.inc | 15 ++-- .../Blake2S/Blake2SCompressSsse3_i386.inc | 28 ++++---- .../Blake2S/Blake2SCompressSsse3_x86_64.inc | 22 +++--- .../Simd/Blake3/Blake3CompressAvx_x86_64.inc | 43 ++++++------ .../Blake3/Blake3CompressNeon_aarch64.inc | 19 +++--- .../Simd/Blake3/Blake3CompressSse2_i386.inc | 20 +++--- .../Simd/Blake3/Blake3CompressSse2_x86_64.inc | 36 +++++----- .../Blake3/Blake3CompressSsse3_x86_64.inc | 34 +++++----- .../Simd/Blake3/Blake3Hash4Neon_aarch64.inc | 34 ++++++---- .../Simd/Blake3/Blake3Hash4Sse2_i386.inc | 46 +++++++------ .../Simd/Blake3/Blake3Hash4Sse2_x86_64.inc | 27 ++++---- .../Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc | 36 +++++----- .../Simd/Blake3/Blake3Hash8Avx2_x86_64.inc | 43 ++++++------ .../Simd/CRC/CRCFoldForwardGpr_i386.inc | 13 ++-- .../Simd/CRC/CRCFoldForwardGpr_x86_64.inc | 20 +++--- .../Simd/CRC/CRCFoldForwardPclmul_i386.inc | 34 +++++----- .../Simd/CRC/CRCFoldForwardPclmul_x86_64.inc | 43 ++++-------- .../Simd/CRC/CRCFoldForwardPmull_aarch64.inc | 23 ++++--- .../Simd/CRC/CRCFoldForwardVpclmul_i386.inc | 31 +++++---- .../Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc | 38 ++++------- .../Simd/CRC/CRCFoldReflectedPclmul_i386.inc | 33 +++++---- .../CRC/CRCFoldReflectedPclmul_x86_64.inc | 37 ++++------ .../CRC/CRCFoldReflectedPmull_aarch64.inc | 25 ++++--- .../Simd/CRC/CRCFoldReflectedSse2_i386.inc | 16 +++-- .../Simd/CRC/CRCFoldReflectedSse2_x86_64.inc | 20 +++--- .../Simd/CRC/CRCFoldReflectedVpclmul_i386.inc | 33 +++++---- .../CRC/CRCFoldReflectedVpclmul_x86_64.inc | 40 ++++------- .../Simd/Common/HlpSimdProc4Begin_aarch64.inc | 2 +- .../Simd/Common/HlpSimdProc5Begin_i386.inc | 2 +- .../Simd/Common/HlpSimdProc6Begin_i386.inc | 2 +- .../Simd/SHA1/SHA1CompressAvx2_x86_64.inc | 27 ++++---- .../Simd/SHA1/SHA1CompressAvx_i386.inc | 24 +++---- .../SHA1/SHA1CompressCryptoExt_aarch64.inc | 13 ++-- .../Simd/SHA1/SHA1CompressGpr_aarch64.inc | 16 ++--- .../Simd/SHA1/SHA1CompressShaNi_i386.inc | 25 +++---- .../Simd/SHA1/SHA1CompressShaNi_x86_64.inc | 58 +++++++--------- .../Simd/SHA1/SHA1CompressSse2_i386.inc | 22 +++--- .../Simd/SHA1/SHA1CompressSse2_x86_64.inc | 27 ++++---- .../Simd/SHA1/SHA1CompressSsse3_i386.inc | 22 +++--- .../Simd/SHA1/SHA1CompressSsse3_x86_64.inc | 28 ++++---- .../Simd/SHA256/SHA256CompressAvx2_x86_64.inc | 31 ++++----- .../Simd/SHA256/SHA256CompressAvx_i386.inc | 29 ++++---- .../SHA256CompressCryptoExt_aarch64.inc | 14 ++-- .../Simd/SHA256/SHA256CompressGpr_aarch64.inc | 27 ++++---- .../Simd/SHA256/SHA256CompressShaNi_i386.inc | 24 ++++--- .../SHA256/SHA256CompressShaNi_x86_64.inc | 51 ++++++-------- .../Simd/SHA256/SHA256CompressSse2_i386.inc | 24 ++++--- .../Simd/SHA256/SHA256CompressSse2_x86_64.inc | 25 ++++--- .../Simd/SHA256/SHA256CompressSsse3_i386.inc | 28 ++++---- .../SHA256/SHA256CompressSsse3_x86_64.inc | 19 +++--- .../SHA3/KeccakF1600Avx2Absorb_x86_64.inc | 59 +++++++--------- .../Simd/SHA3/KeccakF1600Avx2_x86_64.inc | 33 ++++----- .../KeccakF1600CryptoExtAbsorb_aarch64.inc | 15 ++-- .../SHA3/KeccakF1600CryptoExt_aarch64.inc | 15 ++-- .../SHA3/KeccakF1600GprAbsorb_aarch64.inc | 26 +++---- .../Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc | 31 ++++----- .../Simd/SHA3/KeccakF1600Gpr_aarch64.inc | 26 +++---- .../Simd/SHA3/KeccakF1600Gpr_x86_64.inc | 32 ++++----- .../Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc | 26 +++---- .../Simd/SHA3/KeccakF1600Sse2_i386.inc | 31 +++++---- .../Simd/SHA512/SHA512CompressAvx2_x86_64.inc | 27 ++++---- .../SHA512CompressCryptoExt_aarch64.inc | 15 ++-- .../Simd/SHA512/SHA512CompressGpr_aarch64.inc | 28 ++++---- .../Simd/SHA512/SHA512CompressSse2_i386.inc | 15 ++-- .../Simd/SHA512/SHA512CompressSse2_x86_64.inc | 23 +++---- .../SHA512/SHA512CompressSsse3_x86_64.inc | 25 +++---- .../Simd/Scrypt/ScryptSalsa8Avx_i386.inc | 38 +++++------ .../Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc | 36 +++++----- .../Simd/Scrypt/ScryptSalsa8Neon_aarch64.inc | 21 +++--- .../Simd/Scrypt/ScryptSalsa8Sse2_i386.inc | 33 +++++---- .../Simd/Scrypt/ScryptSalsa8Sse2_x86_64.inc | 29 ++++---- .../Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc | 10 +-- .../Simd/XXH3/XXH3Acc512Avx2_x86_64.inc | 10 +-- .../Simd/XXH3/XXH3Acc512Neon_aarch64.inc | 14 ++-- .../Include/Simd/XXH3/XXH3Acc512Sse2_i386.inc | 11 +-- .../Simd/XXH3/XXH3Acc512Sse2_x86_64.inc | 10 +-- .../Simd/XXH3/XXH3InitSecretAvx2_i386.inc | 18 ++--- .../Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc | 11 +-- .../Simd/XXH3/XXH3InitSecretNeon_aarch64.inc | 13 ++-- .../Simd/XXH3/XXH3InitSecretSse2_i386.inc | 12 ++-- .../Simd/XXH3/XXH3InitSecretSse2_x86_64.inc | 13 ++-- .../Simd/XXH3/XXH3ScrambleAvx2_i386.inc | 9 ++- .../Simd/XXH3/XXH3ScrambleAvx2_x86_64.inc | 9 +-- .../Simd/XXH3/XXH3ScrambleNeon_aarch64.inc | 13 ++-- .../Simd/XXH3/XXH3ScrambleSse2_i386.inc | 15 ++-- .../Simd/XXH3/XXH3ScrambleSse2_x86_64.inc | 14 ++-- scripts/maintenance/check-file-format.ps1 | 68 +++++++++++++++++++ 111 files changed, 1396 insertions(+), 1320 deletions(-) create mode 100644 scripts/maintenance/check-file-format.ps1 diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc index fe5d598..36e8f9f 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_i386.inc @@ -1,13 +1,13 @@ -// AVX2 implementation of Adler-32 block processing (IA-32; 256-bit ymm -// integer ops work in 32-bit mode - only ymm0-7 exist, which this kernel -// fits). Same structure as Adler32BlocksAvx2_x86_64.inc. -// IA-32: after HlpSimdProc4Begin_i386 - ebx = data ptr, esi = num_blocks, +// AVX2 implementation of Adler-32 block processing (num_blocks x 32-byte blocks; +// IA-32: 256-bit ymm integer ops work in 32-bit mode and only ymm0-ymm7 exist, +// which this kernel fits). Same structure as Adler32BlocksAvx2_x86_64.inc. +// Does NOT apply mod 65521 (the caller does). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = data ptr, esi = num_blocks, // edi = sums ptr, eax = constants ptr (moved to ecx at entry; eax then // accumulates SumA). SumB rides xmm1 end-to-end via vmovd memory forms. -// ASums layout: [SumA: UInt32, SumB: UInt32]. -// Constants layout: [weights: 32B, ones_16: 32B] at offsets 0 and 32. -// Processes num_blocks x 32-byte blocks. Does NOT apply mod 65521 (caller does it). -// Uses ymm0-ymm5 only (all volatile on IA-32; no saves needed). +// Sums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout: [weights: 32B, ones_16: 32B] at offsets 0 and 32. +// Saves: none (uses ymm0-ymm5 only; all volatile on IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: Chromium zlib adler32_simd.c, HashLib Adler32BlocksAvx2_x86_64.inc. diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_x86_64.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_x86_64.inc index aeff0cc..ecb750b 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksAvx2_x86_64.inc @@ -1,12 +1,13 @@ -// AVX2 implementation of Adler-32 block processing. -// Expects MS x64 ABI: rcx = data ptr, edx = num_blocks, r8 = sums ptr, r9 = constants ptr. -// ASums layout: [SumA: UInt32, SumB: UInt32]. -// Constants layout: [weights: 32B, ones_16: 32B] at offsets 0 and 32. -// Processes num_blocks x 32-byte blocks. Does NOT apply mod 65521 (caller does it). -// Uses ymm0-ymm5 only (volatile under both ABIs; no saves needed). -// Weights and ones are reloaded from memory each iteration to avoid -// using non-volatile ymm registers. +// AVX2 implementation of Adler-32 block processing (num_blocks x 32-byte blocks). +// Does NOT apply mod 65521 (the caller does). Weights and ones are reloaded +// from memory each iteration so no non-volatile ymm register is needed. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = data ptr, edx = num_blocks, +// r8 = sums ptr, r9 = constants ptr. +// Sums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout: [weights: 32B, ones_16: 32B] at offsets 0 and 32. +// Saves: none (uses ymm0-ymm5 only; volatile under both ABIs). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: Chromium zlib adler32_simd.c. // Zero register db $C5, $E5, $EF, $DB // vpxor ymm3, ymm3, ymm3 diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksNeon_aarch64.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksNeon_aarch64.inc index 1fc83e4..e346dfe 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksNeon_aarch64.inc @@ -1,10 +1,9 @@ -// Adler-32 ProcessBlocks AArch64 NEON implementation (32-byte blocks). -// Expects AAPCS64: x0 = AData, w1 = ANumBlocks, x2 = ASums, x3 = AConstants. -// ASums layout: [SumA: UInt32, SumB: UInt32]. Does NOT apply mod 65521. -// Constants layout matches Adler32Constants: bytes [32..1] at offset 0..31. -// Leaf nostackframe; caller-saved GPR/vector only. -// Reference: Chromium zlib adler32_simd.c, HashLib Adler32BlocksSsse3_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of Adler-32 block processing (num_blocks x 32-byte blocks). +// Does NOT apply mod 65521 (the caller does). +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = data ptr, w1 = num_blocks, +// x2 = sums ptr, x3 = constants ptr. +// Sums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout matches Adler32Constants: bytes [32..1] at offsets 0..31. // Register map: // w9 = block counter (from w1) // w10 = SumA in / SumA out @@ -20,6 +19,10 @@ // v24-v27 = widened weight vectors for vmlal // v28-v29 = weight byte loads from AConstants // v30 = ext scratch for weight / reduce halves +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: Chromium zlib adler32_simd.c, HashLib Adler32BlocksSsse3_x86_64.inc. + .long 0xb940004a // ldr w10, [x2] .long 0xb940044b // ldr w11, [x2, #4] .long 0x1b017d4c // mul w12, w10, w1 diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_i386.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_i386.inc index 7691003..8053714 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_i386.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_i386.inc @@ -1,20 +1,18 @@ -// SSE2 implementation of Adler-32 block processing (IA-32). -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ANumBlocks, edi = ASums, eax = AConstants. -// ASums: [SumA: UInt32, SumB: UInt32]. Constants: [weights_hi: 16B, weights_lo: 16B] (32 bytes). -// Processes num_blocks x 32-byte blocks; caller applies mod 65521. -// -// x64 uses xmm6-xmm9 for widened weights; IA-32 only has xmm0-xmm7, so widened weights -// live on stack (4 x 16 bytes). xmm6–xmm7 saved/restored defensively (volatile on i386). -// -// Same SSE2 emulation as Adler32BlocksSse2_x86_64.inc (punpcklbw/hbw + pmaddwd). -// -// Stack layout (sub esp, 96): -// [esp + 0..15]: xmm6 save -// [esp + 16..31]: xmm7 save -// [esp + 32..47]: w0 (weights_hi low) -// [esp + 48..63]: w1 (weights_hi high) -// [esp + 64..79]: w2 (weights_lo low) -// [esp + 80..95]: w3 (weights_lo high) +// SSE2 implementation of Adler-32 block processing (num_blocks x 32-byte blocks; +// IA-32). Does NOT apply mod 65521 (the caller does). Same SSE2 pmaddubsw +// emulation as Adler32BlocksSse2_x86_64.inc (punpcklbw/hbw + pmaddwd); x64 +// keeps the widened weights in xmm6-xmm9, IA-32 only has xmm0-xmm7 so they +// live on the stack (4 x 16 bytes). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = data ptr, esi = num_blocks, +// edi = sums ptr, eax = constants ptr. +// Sums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout: [weights_hi: 16B, weights_lo: 16B] (32 bytes). +// Frame (sub esp, 96): +// [esp + 0..15] = xmm6 save [esp + 48..63] = w1 (weights_hi high) +// [esp + 16..31] = xmm7 save [esp + 64..79] = w2 (weights_lo low) +// [esp + 32..47] = w0 (weights_hi low) [esp + 80..95] = w3 (weights_lo high) +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). +// Reference: Chromium zlib adler32_simd.c, HashLib Adler32BlocksSse2_x86_64.inc. // Preserve constants pointer (eax) before GPR reloads from ASums push eax diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc index a65ed9a..5b470d6 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSse2_x86_64.inc @@ -1,14 +1,14 @@ -// SSE2 implementation of Adler-32 block processing. -// Expects MS x64 ABI: rcx = data ptr, edx = num_blocks, r8 = sums ptr, r9 = constants ptr. -// ASums layout: [SumA: UInt32, SumB: UInt32]. -// Constants layout: [weights_hi: 16B, weights_lo: 16B] (only first 32 bytes used). -// Processes num_blocks x 32-byte blocks. Does NOT apply mod 65521 (caller does it). -// Uses xmm0-xmm9; xmm6-xmm9 are MS x64 non-volatile (saved/restored). -// -// Emulates SSSE3 pmaddubsw via punpcklbw/punpckhbw + pmaddwd: -// data bytes are zero-extended to i16, then multiplied with pre-widened -// weight bytes via pmaddwd (SSE2), producing the same 4 x i32 weighted -// sums per 16-byte half that pmaddubsw + pmaddwd would yield. +// SSE2 implementation of Adler-32 block processing (num_blocks x 32-byte blocks). +// Does NOT apply mod 65521 (the caller does). Emulates SSSE3 pmaddubsw via +// punpcklbw/punpckhbw + pmaddwd: data bytes are zero-extended to i16, then +// multiplied with pre-widened weight bytes via pmaddwd (SSE2), producing the +// same 4 x i32 weighted sums per 16-byte half that pmaddubsw + pmaddwd yield. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = data ptr, edx = num_blocks, +// r8 = sums ptr, r9 = constants ptr. +// Sums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout: [weights_hi: 16B, weights_lo: 16B] (first 32 bytes used). +// Saves: xmm6-xmm9 (MS x64 non-volatile) in the local frame; uses xmm0-xmm9. +// Reference: Chromium zlib adler32_simd.c. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_i386.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_i386.inc index 2fc07bd..7392e92 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_i386.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_i386.inc @@ -1,10 +1,13 @@ -// SSSE3 Adler-32 block processing (IA-32). -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ANumBlocks, edi = ASums, eax = AConstants. -// Constants: [weights_hi: 16B, weights_lo: 16B, ones_16: 16B] (48 bytes; same as x64 SSSE3). -// No xmm8 on IA-32: psadbw uses a copy in xmm5 (first half) or xmm4 (second half), then reload weights. -// Caller applies mod 65521. -// -// xmm6–xmm7 saved/restored defensively (volatile on i386). +// SSSE3 implementation of Adler-32 block processing (num_blocks x 32-byte blocks; +// IA-32). Does NOT apply mod 65521 (the caller does). No xmm8 on IA-32: +// psadbw uses a copy in xmm5 (first half) or xmm4 (second half), then the +// weights are reloaded. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = data ptr, esi = num_blocks, +// edi = sums ptr, eax = constants ptr. +// Constants layout: [weights_hi: 16B, weights_lo: 16B, ones_16: 16B] +// (48 bytes; same as the x64 SSSE3 kernel). +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). +// Reference: Chromium zlib adler32_simd.c, HashLib Adler32BlocksSsse3_x86_64.inc. push eax diff --git a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc index a9e486a..61ebf40 100644 --- a/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Adler32/Adler32BlocksSsse3_x86_64.inc @@ -1,9 +1,11 @@ -// SSSE3 implementation of Adler-32 block processing. -// Expects MS x64 ABI: rcx = data ptr, edx = num_blocks, r8 = sums ptr, r9 = constants ptr. -// ASums layout: [SumA: UInt32, SumB: UInt32]. -// Constants layout: [weights_hi: 16B, weights_lo: 16B, ones_16: 16B]. -// Processes num_blocks x 32-byte blocks. Does NOT apply mod 65521 (caller does it). -// Uses xmm0-xmm8; xmm6-xmm8 are MS x64 non-volatile (saved/restored). +// SSSE3 implementation of Adler-32 block processing (num_blocks x 32-byte blocks). +// Does NOT apply mod 65521 (the caller does). +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = data ptr, edx = num_blocks, +// r8 = sums ptr, r9 = constants ptr. +// Sums layout: [SumA: UInt32, SumB: UInt32]. +// Constants layout: [weights_hi: 16B, weights_lo: 16B, ones_16: 16B]. +// Saves: xmm6-xmm8 (MS x64 non-volatile) in the local frame; uses xmm0-xmm8. +// Reference: Chromium zlib adler32_simd.c. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc index 0745ef5..de78c4c 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_i386.inc @@ -1,22 +1,22 @@ -// AVX2 implementation of Argon2 FillBlock (IA-32). 256-bit ymm integer ops -// work in 32-bit mode; same algorithm and buffer layout as -// Argon2FillBlockAvx2_x86_64.inc, redesigned for the IA-32 register budget: +// AVX2 implementation of Argon2 FillBlock (BlaMka round function; IA-32). +// 256-bit ymm integer ops work in 32-bit mode; same algorithm and buffer +// layout as Argon2FillBlockAvx2_x86_64.inc, redesigned for the IA-32 +// register budget: // - the byte-rotation masks are VEX memory operands (rot24 at [masks], // rot16 at [masks+$20]; read unaligned, so the Pascal const needs no -// special alignment) - the kernel touches only ymm0-ymm4, all volatile, -// so nothing is saved; +// special alignment) - the kernel touches only ymm0-ymm4; // - R_buf/Z_buf sit at [esp]/[esp+1024] and are addressed [esp+edx+disp] // (edx = loop offset) - no buffer pointer registers are needed; // - Left/Right are dead after step 1's XOR. -// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// IA-32: after HlpSimdProc5Begin_i386 - ebx = Left ptr, esi = Right ptr, +// Diagonalize/Undiagonalize via vpermq. vzeroupper required before return. +// ABI (after HlpSimdProc5Begin_i386.inc): ebx = Left ptr, esi = Right ptr, // edi = Current ptr, eax = WithXor (0 or 1; live until the final step), // ecx = byte-rotation masks ptr (ARGON2_ROT_MASKS; live throughout). -// Each pointer addresses 128 QWords (1024 bytes). -// Stack layout (sub esp, 2048): [esp+0..1023] R_buf, [esp+1024..2047] Z_buf. -// ARight and ACurrent may alias; R_buf buffering handles this. -// Diagonalize/Undiagonalize via vpermq (cross-lane 64-bit permute). -// vzeroupper required before return. +// Each pointer addresses 128 QWords (1024 bytes). ARight and ACurrent may +// alias; R_buf buffering handles this. +// Frame (sub esp, 2048): [esp+0..1023] R_buf, [esp+1024..2047] Z_buf. +// Saves: none (uses ymm0-ymm4 only; all volatile on IA-32). +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: official Argon2 AVX2 (blamka-round-opt.h), HashLib // Argon2FillBlockAvx2_x86_64.inc. diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc index 4968b07..cafc467 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockAvx2_x86_64.inc @@ -1,26 +1,25 @@ -// AVX2 implementation of Argon2 FillBlock. -// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = Left ptr, rdx = Right ptr, +// AVX2 implementation of Argon2 FillBlock (BlaMka round function). +// Rotations: rot32 via vpshufd, rot24/16 via vpshufb against the resident +// masks, rot63 via shift+or (not byte-aligned). Diagonalize/Undiagonalize +// via vpermq (cross-lane 64-bit permute). vzeroupper required before return. +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = Left ptr, rdx = Right ptr, // r8 = Current ptr, r9 = WithXor (0 or 1), r10 = byte-rotation masks ptr -// (see ARGON2_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the -// Pascal const needs no special alignment; consumed by the entry mask loads, -// r10 is scratch afterwards). -// Each pointer addresses 128 QWords (1024 bytes). -// Uses ymm0-ymm11; ymm6-ymm11 are MS x64 non-volatile (saved/restored). -// Register map during G rounds: ymm0 = A(v0..v3), ymm1 = B(v4..v7), +// (ARGON2_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment; consumed by the entry mask +// loads, r10 is scratch afterwards). +// Each pointer addresses 128 QWords (1024 bytes). ARight and ACurrent may +// alias; R_buf buffering handles this. r8/r9 survive all loops. +// Register map (G rounds): ymm0 = A(v0..v3), ymm1 = B(v4..v7), // ymm2 = C(v8..v11), ymm3 = D(v12..v15), ymm4-ymm5 = temps, // ymm10 = rot24 mask, ymm11 = rot16 mask. -// Rotations: rot32 via vpshufd, rot24/16 via vpshufb against the resident -// masks, rot63 via shift+or (not byte-aligned). -// Stack layout (sub rsp, 2184): -// [rsp+0..127] ymm6-9 save area (4 * 32 = 128 bytes) -// [rsp+128..1151] R_buf (1024 bytes) -// [rsp+1152..2175] Z_buf (1024 bytes) -// [rsp+2176..2183] alignment padding -// r8 (Current) and r9 (WithXor) survive all loops (not clobbered). -// ARight and ACurrent may alias; R_buf buffering handles this. -// Diagonalize/Undiagonalize via vpermq (cross-lane 64-bit permute). -// vzeroupper required before return. +// Frame (sub rsp, 2184): +// [rsp+0..127] = ymm6-ymm9 save area (4 x 32 bytes) +// [rsp+128..1151] = R_buf (1024 bytes) +// [rsp+1152..2175] = Z_buf (1024 bytes) +// [rsp+2176..2183] = alignment padding +// Saves: ymm6-ymm11 (MS x64 non-volatile); uses ymm0-ymm11. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: official Argon2 AVX2 (blamka-round-opt.h). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc index a9ed74a..476e408 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockNeon_aarch64.inc @@ -1,11 +1,9 @@ -// Argon2 FillBlock AArch64 NEON implementation (BlaMka round function). -// Expects AAPCS64: x0 = Left ptr, x1 = Right ptr, x2 = Current ptr, w3 = WithXor. -// Each pointer addresses 128 UInt64 (1024 bytes). -// Stack frame 2128 bytes; see register map. -// Steps: R=Left XOR Right; Z=copy(R); 8 column + 8 row BlaMka rounds on Z; -// Current = R XOR Z [XOR Current if WithXor]. Diagonalize via vext #8. -// Reference: jedisct1/libsodium argon2-fill-block-neon.c, HashLib Argon2FillBlockSse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of Argon2 FillBlock (BlaMka round function). +// Steps: R = Left XOR Right; Z = copy(R); 8 column + 8 row BlaMka rounds on +// Z; Current = R XOR Z [XOR Current if WithXor]. Diagonalize via vext #8. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = Left ptr, x1 = Right ptr, +// x2 = Current ptr, w3 = WithXor (0 or 1). +// Each pointer addresses 128 QWords (1024 bytes). // Register map: // v0-v1 = A0, A1 // v2-v3 = B0, B1 @@ -18,6 +16,11 @@ // x11 = Z_buf base ([sp+1088]) // x12 = Z slice pointer (column/row load/store) // w3 = WithXor (0 or 1) +// Frame: 2128 bytes (R_buf at [sp+64], Z_buf at [sp+1088], 16-byte SP pad). +// Saves: none (caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: jedisct1/libsodium argon2-fill-block-neon.c, HashLib +// Argon2FillBlockSse2_x86_64.inc. sub sp, sp, #2128 add x9, sp, #64 diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_i386.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_i386.inc index ee688b4..e68ca3c 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_i386.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_i386.inc @@ -1,15 +1,19 @@ -// SSE2 implementation of Argon2 FillBlock. -// IA-32: after HlpSimdProc4Begin_i386 — ebx, esi, edi, eax = Left, Right, Current, WithXor -// (parallel to MS x64 ABI: rcx, rdx, r8, r9). -// Each pointer addresses 128 QWords (1024 bytes). -// Uses xmm0–xmm7; xmm6–xmm7 saved/restored defensively (volatile on i386). -// Register map during G rounds: xmm0-1 = A(0..3), xmm2-3 = B(4..7), -// xmm4-5 = C(8..11), xmm6-7 = D(12..15) / temps (same roles as x64, fewer XMM). -// IA-32 stack (sub esp, 2132): WithXor at [esp+2128]; spill slots [esp+2080],[esp+2096],[esp+2112]; -// R_buf at lea eax,[esp+32]; ECX = loop offset; EBX = Z_buf base after copy; EDI = Current. -// r8/r9 analogues (Current, WithXor) are not clobbered across loops. ARight and ACurrent may alias. -// -// Diagonalize/Undiagonalize use shufpd (see x64 header in Argon2FillBlockSse2_x86_64.inc). +// SSE2 implementation of Argon2 FillBlock (BlaMka round function; IA-32). +// Same roles as Argon2FillBlockSse2_x86_64.inc with fewer XMM registers; +// Diagonalize/Undiagonalize use shufpd (see the x64 sibling's header). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = Left ptr, esi = Right ptr, +// edi = Current ptr, eax = WithXor (0 or 1). +// Each pointer addresses 128 QWords (1024 bytes). ARight and ACurrent may +// alias; R_buf buffering handles this. Current/WithXor analogues are not +// clobbered across loops. +// Register map (G rounds): xmm0-1 = A(0..3), xmm2-3 = B(4..7), +// xmm4-5 = C(8..11), xmm6-7 = D(12..15) / temps. +// Frame (sub esp, 2132): WithXor at [esp+2128]; spill slots [esp+2080], +// [esp+2096], [esp+2112]; R_buf at lea eax,[esp+32]; ecx = loop offset; +// ebx = Z_buf base after the copy; edi = Current. +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). +// Reference: official Argon2 SSE2 (blamka-round-ref/opt), HashLib +// Argon2FillBlockSse2_x86_64.inc. sub esp, 2132 @@ -697,7 +701,7 @@ jb @row_loop // ========================================================================= - // Step 5: Final XOR — Current = R_buf XOR Z_buf [XOR Current] + // Step 5: Final XOR - Current = R_buf XOR Z_buf [XOR Current] // ========================================================================= cmp dword ptr [esp + 2128], 0 jnz @final_with_xor diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc index b529766..85db639 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSse2_x86_64.inc @@ -1,20 +1,20 @@ -// SSE2 implementation of Argon2 FillBlock. -// Expects MS x64 ABI: rcx = Left ptr, rdx = Right ptr, r8 = Current ptr, r9 = WithXor (0 or 1). -// Each pointer addresses 128 QWords (1024 bytes). -// Uses xmm0-xmm9; xmm6-xmm9 are MS x64 non-volatile (saved/restored). -// Register map during G rounds: xmm0-1 = A(0..3), xmm2-3 = B(4..7), -// xmm4-5 = C(8..11), xmm6-7 = D(12..15), xmm8-9 = temps. -// Stack layout (sub rsp, 2120): -// [rsp+0..63] xmm6-9 save area -// [rsp+64..1087] R_buf (1024 bytes) -// [rsp+1088..2111] Z_buf (1024 bytes) -// [rsp+2112..2119] alignment padding -// r8 (Current) and r9 (WithXor) survive all loops (not clobbered). -// ARight and ACurrent may alias; R_buf buffering handles this. -// +// SSE2 implementation of Argon2 FillBlock (BlaMka round function). // Diagonalize/Undiagonalize use shufpd to rotate QWord positions within -// register pairs. Right-rotates require a 3-movdqa swap since shufpd +// register pairs; right-rotates require a 3-movdqa swap since shufpd // naturally places results in the opposite register for that direction. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = Left ptr, rdx = Right ptr, +// r8 = Current ptr, r9 = WithXor (0 or 1). +// Each pointer addresses 128 QWords (1024 bytes). ARight and ACurrent may +// alias; R_buf buffering handles this. r8/r9 survive all loops. +// Register map (G rounds): xmm0-1 = A(0..3), xmm2-3 = B(4..7), +// xmm4-5 = C(8..11), xmm6-7 = D(12..15), xmm8-9 = temps. +// Frame (sub rsp, 2120): +// [rsp+0..63] = xmm6-xmm9 save area +// [rsp+64..1087] = R_buf (1024 bytes) +// [rsp+1088..2111] = Z_buf (1024 bytes) +// [rsp+2112..2119] = alignment padding +// Saves: xmm6-xmm9 (MS x64 non-volatile) in the frame; uses xmm0-xmm9. +// Reference: official Argon2 SSE2 (blamka-round-ref/opt). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} @@ -523,7 +523,7 @@ jb @row_loop // ========================================================================= - // Step 5: Final XOR — Current = R_buf XOR Z_buf [XOR Current] + // Step 5: Final XOR - Current = R_buf XOR Z_buf [XOR Current] // ========================================================================= test r9, r9 jnz @final_with_xor diff --git a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc index caa3b6b..0db7e32 100644 --- a/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Argon2/Argon2FillBlockSsse3_x86_64.inc @@ -1,29 +1,27 @@ -// SSSE3 implementation of Argon2 FillBlock; SSE2 sibling: -// Argon2FillBlockSse2_x86_64.inc. Unlike the SSE2 sibling, the byte-aligned -// rotations (rot24/rot16) are single pshufb (db-encoded for broad assembler -// compatibility) against masks resident in xmm10/xmm11; rot32 stays pshufd and -// rot63 stays shift+or (not byte-aligned). -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = Left ptr, rdx = Right ptr, +// SSSE3 implementation of Argon2 FillBlock (BlaMka round function); SSE2 +// sibling: Argon2FillBlockSse2_x86_64.inc. Unlike the sibling, the +// byte-aligned rotations (rot24/rot16) are single pshufb against masks +// resident in xmm10/xmm11; rot32 stays pshufd and rot63 stays shift+or +// (not byte-aligned). Diagonalize/Undiagonalize use shufpd (right-rotates +// via a 3-movdqa swap). +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = Left ptr, rdx = Right ptr, // r8 = Current ptr, r9 = WithXor (0 or 1), r10 = byte-rotation masks ptr -// (see ARGON2_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the -// Pascal const needs no special alignment; consumed by the entry mask loads, -// r10 is scratch afterwards). -// Each pointer addresses 128 QWords (1024 bytes). -// Uses xmm0-xmm11; xmm6-xmm11 are MS x64 non-volatile (saved/restored). -// Register map during G rounds: xmm0-1 = A(0..3), xmm2-3 = B(4..7), +// (ARGON2_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment; consumed by the entry mask +// loads, r10 is scratch afterwards). +// Each pointer addresses 128 QWords (1024 bytes). ARight and ACurrent may +// alias; R_buf buffering handles this. r8/r9 survive all loops. +// Register map (G rounds): xmm0-1 = A(0..3), xmm2-3 = B(4..7), // xmm4-5 = C(8..11), xmm6-7 = D(12..15), xmm8-9 = temps, // xmm10 = rot24 mask, xmm11 = rot16 mask. -// Stack layout (sub rsp, 2120): -// [rsp+0..63] xmm6-9 save area -// [rsp+64..1087] R_buf (1024 bytes) -// [rsp+1088..2111] Z_buf (1024 bytes) -// [rsp+2112..2119] alignment padding -// r8 (Current) and r9 (WithXor) survive all loops (not clobbered). -// ARight and ACurrent may alias; R_buf buffering handles this. -// -// Diagonalize/Undiagonalize use shufpd to rotate QWord positions within -// register pairs. Right-rotates require a 3-movdqa swap since shufpd -// naturally places results in the opposite register for that direction. +// Frame (sub rsp, 2120): +// [rsp+0..63] = xmm6-xmm9 save area +// [rsp+64..1087] = R_buf (1024 bytes) +// [rsp+1088..2111] = Z_buf (1024 bytes) +// [rsp+2112..2119] = alignment padding +// Saves: xmm6-xmm11 (MS x64 non-volatile); uses xmm0-xmm11. +// pshufb instructions are db-encoded for broad assembler compatibility. +// Reference: official Argon2 SSSE3 (blamka-round-opt.h). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc index 5f4df7d..366a2e9 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_i386.inc @@ -1,18 +1,19 @@ -// AVX2 implementation of BLAKE2b compress (IA-32; fully unrolled 12 rounds). +// AVX2 implementation of BLAKE2b compress (fully unrolled 12 rounds; IA-32). // 256-bit ymm integer ops work in 32-bit mode; the kernel fits IA-32's -// ymm0-7 exactly. Same structure as Blake2BCompressAvx2_x86_64.inc, with the -// x86_64 version's memory-source vpinsrq message loads (not encodable in -// 32-bit mode) replaced 1:1 by vmovhps (same load-high-qword semantics). -// IA-32: after HlpSimdProc5Begin_i386 - ebx = state ptr, esi = msg ptr, +// ymm0-ymm7 exactly. Same structure as Blake2BCompressAvx2_x86_64.inc, with +// the x86_64 version's memory-source vpinsrq message loads (not encodable +// in 32-bit mode) replaced 1:1 by vmovhps (same load-high-qword semantics). +// Rotations: rot32 via vpshufd, rot24/16 via vpshufb against the resident +// masks, rot63 via shift+or (not byte-aligned). Diagonalize/Undiagonalize +// via vpermq. +// ABI (after HlpSimdProc5Begin_i386.inc): ebx = state ptr, esi = msg ptr, // edi = counter+flags ptr, eax = IV ptr, ecx = byte-rotation masks ptr -// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// (BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the // Pascal const needs no special alignment). -// Register map: ymm0 = a (v0-3), ymm1 = b (v4-7), ymm2 = c (v8-11), ymm3 = d (v12-15), -// ymm4 = message temp, ymm5 = computation temp, ymm6 = rot24 mask, ymm7 = rot16 mask. -// Rotations: ROT32 via vpshufd, ROT16/24 via vpshufb against the resident -// masks, ROT63 via shift+or (not byte-aligned; shifts are the known-best form). -// Diagonalize/Undiagonalize via vpermq. -// Uses ymm0-ymm7; xmm6/xmm7 saved/restored defensively (volatile on IA-32). +// Register map: ymm0 = a (v0-3), ymm1 = b (v4-7), ymm2 = c (v8-11), +// ymm3 = d (v12-15), ymm4 = message temp, ymm5 = computation temp, +// ymm6 = rot24 mask, ymm7 = rot16 mask. +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: sneves/blake2-avx2 by Samuel Neves, HashLib // Blake2BCompressAvx2_x86_64.inc. diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc index 94dfedb..bb79a19 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressAvx2_x86_64.inc @@ -1,18 +1,18 @@ // AVX2 implementation of BLAKE2b compress (fully unrolled 12 rounds). -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// Rotations: rot32 via vpshufd, rot24/16 via vpshufb against the resident +// masks, rot63 via shift+or (not byte-aligned; shifts are the known-best +// form). Diagonalize/Undiagonalize via vpermq. +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, // r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr -// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// (BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the // Pascal const needs no special alignment). -// Register map: ymm0 = a (v0-3), ymm1 = b (v4-7), ymm2 = c (v8-11), ymm3 = d (v12-15), -// ymm4 = message temp, ymm5 = computation temp, ymm6 = rot24 mask, ymm7 = rot16 mask. -// Rotations: ROT32 via vpshufd, ROT16/24 via vpshufb against the resident -// masks, ROT63 via shift+or (not byte-aligned; shifts are the known-best form). -// Diagonalize/Undiagonalize via vpermq. +// Register map: ymm0 = a (v0-3), ymm1 = b (v4-7), ymm2 = c (v8-11), +// ymm3 = d (v12-15), ymm4 = message temp, ymm5 = computation temp, +// ymm6 = rot24 mask, ymm7 = rot16 mask. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV; only xmm6/xmm7 are clobbered here - by the mask loads). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: sneves/blake2-avx2 by Samuel Neves. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV; only xmm6/xmm7 are clobbered here - by the mask loads). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc index 4c005c1..08855b8 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressNeon_aarch64.inc @@ -1,9 +1,8 @@ -// BLAKE2b compress AArch64 NEON implementation. -// Expects AAPCS64: x0 = state ptr (8 x UInt64), x1 = message ptr (128 bytes), -// x2 = counter+flags ptr (32 bytes: t[0..1], f[0..1]), x3 = IV ptr (8 x UInt64). -// Leaf nostackframe; uses v8-v15 for message block (d8-d15 lanes; no save/restore). -// Reference: BLAKE2/BLAKE2 neon/blake2b-neon.c, HashLib Blake2BCompressSse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of BLAKE2b compress (fully unrolled 12 rounds). +// u64 ror-by-32 uses rev64.4s (vrev64q_u32), not rev64.16b. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (8 x UInt64), +// x1 = message ptr (128 bytes), x2 = counter+flags ptr (32 bytes: t[0..1], +// f[0..1]), x3 = IV ptr (8 x UInt64). // Register map: // v0, v1 = row1l, row1h (h[0..3] working, 2 x u64 each) // v2, v3 = row2l, row2h (h[4..7] working) @@ -14,7 +13,11 @@ // v20 = message gather temp b0 (G function) // v21-v23 = rotate / diagonalize temps (2-op insert rotates rename the // rotated row halves through v21/v22; b1 gather uses v23) -// u64 ror-by-32 uses rev64.4s (vrev64q_u32), not rev64.16b. +// Saves: d8-d15 via the shared HlpSimdNonVolatileSave/Restore include +// (v8-v15 hold the message block). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: BLAKE2/BLAKE2 neon/blake2b-neon.c, HashLib +// Blake2BCompressSse2_x86_64.inc. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_i386.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_i386.inc index 18b29de..30b7aff 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_i386.inc @@ -1,10 +1,13 @@ -// SSE2 implementation of BLAKE2b compress (fully unrolled 12 rounds). -// IA-32: after HlpSimdProc4Begin_i386 — ebx = state, esi = msg, edi = counter+flags, eax = IV -// (parallel to MS x64 ABI: rcx, rdx, r8, r9). -// XMM8+ from x64 eliminated: xmm4 scratch + stack, xmm0/1 for diagonal work; uses xmm0–xmm7. -// Non-volatile xmm6–xmm7 saved in stack frame (sub esp, 128). -// Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15) -// with temps folded per IA-32 constraints. +// SSE2 implementation of BLAKE2b compress (fully unrolled 12 rounds; IA-32). +// XMM8+ from the x64 sibling eliminated: xmm4 scratch + stack, xmm0/xmm1 for +// diagonal work. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = msg ptr, +// edi = counter+flags ptr, eax = IV ptr. +// Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), +// xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15), temps folded per the +// IA-32 register budget. +// Frame: sub esp, 128 (spill slots + xmm6-xmm7 save). +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. sub esp, 128 diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc index b001d1d..05a04c6 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSse2_x86_64.inc @@ -1,8 +1,9 @@ // SSE2 implementation of BLAKE2b compress (fully unrolled 12 rounds). -// Expects MS x64 ABI: rcx = state ptr, rdx = msg ptr, r8 = counter+flags ptr, r9 = IV ptr. -// Uses xmm0-xmm9; xmm6-xmm9 are MS x64 non-volatile (saved/restored). +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, +// r8 = counter+flags ptr, r9 = IV ptr. // Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), // xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15), xmm8-9 = temps. +// Saves: xmm6-xmm9 (MS x64 non-volatile); uses xmm0-xmm9. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc index afd2fbb..76ea49f 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_i386.inc @@ -1,16 +1,19 @@ -// SSSE3 implementation of BLAKE2b compress (fully unrolled 12 rounds); SSE2 -// sibling: Blake2BCompressSse2_i386.inc. Unlike the SSE2 sibling, each pair +// SSSE3 implementation of BLAKE2b compress (fully unrolled 12 rounds; IA-32); +// SSE2 sibling: Blake2BCompressSse2_i386.inc. Unlike the sibling, each pair // of byte-aligned rotations (rot24/rot16) is one mask load into the already -// stack-spilled xmm4 scratch plus two pshufb (db-encoded for broad assembler -// compatibility); rot63 stays shift+or (not byte-aligned). -// IA-32: after HlpSimdProc5Begin_i386 - ebx = state, esi = msg, -// edi = counter+flags, eax = IV, ecx = byte-rotation masks ptr -// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so -// the Pascal const needs no special alignment). -// XMM8+ from x64 eliminated: xmm4 scratch + stack, xmm0/1 for diagonal work; uses xmm0-xmm7. -// Non-volatile xmm6-xmm7 saved in stack frame (sub esp, 128). -// Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15) -// with temps folded per IA-32 constraints. +// stack-spilled xmm4 scratch plus two pshufb; rot63 stays shift+or (not +// byte-aligned). XMM8+ from the x64 sibling eliminated: xmm4 scratch + +// stack, xmm0/xmm1 for diagonal work. +// ABI (after HlpSimdProc5Begin_i386.inc): ebx = state ptr, esi = msg ptr, +// edi = counter+flags ptr, eax = IV ptr, ecx = byte-rotation masks ptr +// (BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// Pascal const needs no special alignment). +// Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), +// xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15), temps folded per the +// IA-32 register budget. +// Frame: sub esp, 128 (spill slots + xmm6-xmm7 save). +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. sub esp, 128 diff --git a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc index 284ba07..9cea513 100644 --- a/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2B/Blake2BCompressSsse3_x86_64.inc @@ -1,16 +1,16 @@ // SSSE3 implementation of BLAKE2b compress (fully unrolled 12 rounds); SSE2 -// sibling: Blake2BCompressSse2_x86_64.inc. Unlike the SSE2 sibling, the -// byte-aligned rotations (rot24/rot16) are single pshufb (db-encoded for -// broad assembler compatibility) against masks resident in xmm10/xmm11; -// rot63 stays shift+or (not byte-aligned). -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// sibling: Blake2BCompressSse2_x86_64.inc. Unlike the sibling, the +// byte-aligned rotations (rot24/rot16) are single pshufb against masks +// resident in xmm10/xmm11; rot63 stays shift+or (not byte-aligned). +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, // r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr -// (see BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the +// (BLAKE2B_ROT_MASKS: rot24 at +0, rot16 at +32; read unaligned, so the // Pascal const needs no special alignment). -// Uses xmm0-xmm11; xmm6-xmm11 are MS x64 non-volatile (saved/restored). // Register map: xmm0-1 = row1 (v0-3), xmm2-3 = row2 (v4-7), // xmm4-5 = row3 (v8-11), xmm6-7 = row4 (v12-15), xmm8-9 = temps, // xmm10 = rot24 mask, xmm11 = rot16 mask. +// Saves: xmm6-xmm11 (MS x64 non-volatile); uses xmm0-xmm11. +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc index 3e248c9..7386b05 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_i386.inc @@ -1,21 +1,22 @@ -// AVX (VEX-128) implementation of BLAKE2s compress (IA-32; fully unrolled -// 10 rounds). Same structure as Blake2SCompressAvx_x86_64.inc, -// with the rot8 mask read as a VEX memory operand per site (IA-32 has only -// xmm0-7, so no register is free to keep it resident; VEX memory operands -// are read unaligned, so the Pascal const needs no special alignment). -// IA-32: after HlpSimdProc5Begin_i386 - ebx = state ptr, esi = msg ptr, +// AVX (VEX-128) implementation of BLAKE2s compress (fully unrolled 10 +// rounds; IA-32); the Avx name states the ISA requirement: VEX-128 +// encodings only, no 256-bit ymm. Same structure as +// Blake2SCompressAvx_x86_64.inc, with the rot8 mask read as a VEX memory +// operand per site (IA-32 has only xmm0-xmm7, so no register is free to +// keep it resident; VEX memory operands are read unaligned, so the Pascal +// const needs no special alignment). Rotations: rot16 via vpshufb against +// the resident xmm7 mask, rot8 via vpshufb against the [ecx+$10] memory +// operand, rot12/7 via shift+or (not byte-aligned). +// ABI (after HlpSimdProc5Begin_i386.inc): ebx = state ptr, esi = msg ptr, // edi = counter+flags ptr, eax = IV ptr, ecx = byte-rotation masks ptr -// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16). -// Uses xmm0-xmm7; xmm6/xmm7 saved/restored defensively (volatile on IA-32). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), xmm7 = rot16 mask. -// Rotations: ROT16 via vpshufb against the resident xmm7 mask, ROT8 via -// vpshufb against the [ecx+$10] memory operand, ROT12/7 via shift+or -// (not byte-aligned; shifts are the known-best form). -// 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. +// (BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16). +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = message buffer, xmm5 = temp, +// xmm6 = temp (msg load), xmm7 = rot16 mask. +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves, HashLib -// Blake2SCompressAvx2_x86_64.inc. +// Blake2SCompressAvx_x86_64.inc. // Defensive save of xmm6/xmm7 (volatile on IA-32; saved like the // SSE2 sibling to be safe under every RTL) diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc index e12d64e..f614afe 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressAvx_x86_64.inc @@ -1,15 +1,17 @@ -// AVX (VEX-128) implementation of BLAKE2s compress (fully unrolled 10 rounds). -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// AVX (VEX-128) implementation of BLAKE2s compress (fully unrolled 10 +// rounds); the Avx name states the ISA requirement: VEX-128 encodings only, +// no 256-bit ymm. 3-operand VEX form eliminates the movdqa copies the SSE2 +// rotations need. Rotations: rot16/8 via vpshufb against the resident +// masks, rot12/7 via shift+or (not byte-aligned; shifts are the known-best +// form). +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, // r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr -// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the +// (BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the // Pascal const needs no special alignment). -// Uses xmm0-xmm8; xmm6-xmm8 are MS x64 non-volatile (saved/restored). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), -// xmm7 = rot16 mask, xmm8 = rot8 mask. -// Rotations: ROT16/8 via vpshufb against the resident masks, ROT12/7 via -// shift+or (not byte-aligned; shifts are the known-best form). -// 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = message buffer, xmm5 = temp, +// xmm6 = temp (msg load), xmm7 = rot16 mask, xmm8 = rot8 mask. +// Saves: xmm6-xmm8 (MS x64 non-volatile); uses xmm0-xmm8. // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc index d9045a6..3f93b5e 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressNeon_aarch64.inc @@ -1,9 +1,7 @@ -// BLAKE2s compress AArch64 NEON implementation. -// Expects AAPCS64: x0 = state ptr (8 x UInt32), x1 = message ptr (64 bytes), -// x2 = counter+flags ptr (16 bytes: t[0..1], f[0..1]), x3 = IV ptr (8 x UInt32). -// Leaf nostackframe; caller-saved GPR/vector only. -// Reference: BLAKE2/BLAKE2 neon/blake2s-neon.c, HashLib Blake2SCompressSse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of BLAKE2s compress (fully unrolled 10 rounds). +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (8 x UInt32), +// x1 = message ptr (64 bytes), x2 = counter+flags ptr (16 bytes: t[0..1], +// f[0..1]), x3 = IV ptr (8 x UInt32). // Register map: // v0 = row1 (h[0..3] working) // v1 = row2 (h[4..7] working) @@ -14,6 +12,10 @@ // v20 = message gather temp (G function) // v21-v23 = rotate temps (2-op ushr+sli rotates rename the rotated row // through them; rows return home before the final feed-forward) +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: BLAKE2/BLAKE2 neon/blake2s-neon.c, HashLib +// Blake2SCompressSse2_x86_64.inc. .long 0xad400400 // ldp q0, q1, [x0] .long 0x4ea01c10 // orr v16.16b, v0.16b, v0.16b diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_i386.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_i386.inc index 17c0c76..649dd1c 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_i386.inc @@ -1,12 +1,12 @@ -// SSE2 implementation of BLAKE2s compress (fully unrolled 10 rounds). -// IA-32: after HlpSimdProc4Begin_i386 — ebx = state, esi = msg, edi = counter+flags, eax = IV -// (parallel to MS x64 ABI: rcx, rdx, r8, r9). -// Uses xmm0–xmm6; xmm6 saved/restored defensively (volatile on i386). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load). -// Rotations: ROT16/12/8/7 via psrld/pslld/por. -// Diagonalize/Undiagonalize via pshufd. -// Message loads via movd + punpcklqdq + shufps. +// SSE2 implementation of BLAKE2s compress (fully unrolled 10 rounds; IA-32). +// Rotations: rot16/12/8/7 via psrld/pslld/por. Diagonalize/Undiagonalize +// via pshufd. Message loads via movd + punpcklqdq + shufps. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = msg ptr, +// edi = counter+flags ptr, eax = IV ptr. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = message buffer, xmm5 = temp, +// xmm6 = temp (msg load). +// Saves: xmm6 saved/restored defensively (volatile on IA-32). // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. sub esp, 16 diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc index 3888211..06ce497 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSse2_x86_64.inc @@ -1,11 +1,12 @@ // SSE2 implementation of BLAKE2s compress (fully unrolled 10 rounds). -// Expects MS x64 ABI: rcx = state ptr, rdx = msg ptr, r8 = counter+flags ptr, r9 = IV ptr. -// Uses xmm0-xmm6; xmm6 is MS x64 non-volatile (saved/restored). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load). -// Rotations: ROT16/12/8/7 via psrld/pslld/por. -// Diagonalize/Undiagonalize via pshufd. -// Message loads via movd + punpcklqdq + shufps. +// Rotations: rot16/12/8/7 via psrld/pslld/por. Diagonalize/Undiagonalize +// via pshufd. Message loads via movd + punpcklqdq + shufps. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, +// r8 = counter+flags ptr, r9 = IV ptr. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = message buffer, xmm5 = temp, +// xmm6 = temp (msg load). +// Saves: xmm6 (MS x64 non-volatile); uses xmm0-xmm6. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc index 6f08ee9..43fc267 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_i386.inc @@ -1,18 +1,18 @@ -// SSSE3 implementation of BLAKE2s compress (fully unrolled 10 rounds); SSE2 -// sibling: Blake2SCompressSse2_i386.inc. -// IA-32: after HlpSimdProc5Begin_i386 - ebx = state, esi = msg, -// edi = counter+flags, eax = IV, ecx = byte-rotation masks ptr -// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the +// SSSE3 implementation of BLAKE2s compress (fully unrolled 10 rounds; IA-32); +// SSE2 sibling: Blake2SCompressSse2_i386.inc. Rotations: rot16 via pshufb +// against the resident xmm7 mask; rot8 via a per-site mask reload into the +// xmm5 temp + pshufb (only xmm7 is free); rot12/7 via psrld/pslld/por (not +// byte-aligned). Diagonalize/Undiagonalize via pshufd. Message loads via +// movd + punpcklqdq + shufps. +// ABI (after HlpSimdProc5Begin_i386.inc): ebx = state ptr, esi = msg ptr, +// edi = counter+flags ptr, eax = IV ptr, ecx = byte-rotation masks ptr +// (BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the // Pascal const needs no special alignment). -// Uses xmm0-xmm7; xmm6/xmm7 saved/restored defensively (volatile on i386). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), xmm7 = rot16 mask. -// Rotations: ROT16 via pshufb (db-encoded for broad assembler compatibility) -// against the resident xmm7 mask; ROT8 via a per-site mask reload into the -// xmm5 temp + pshufb (only xmm7 is free); ROT12/7 via psrld/pslld/por -// (not byte-aligned). -// Diagonalize/Undiagonalize via pshufd. -// Message loads via movd + punpcklqdq + shufps. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = message buffer, xmm5 = temp, +// xmm6 = temp (msg load), xmm7 = rot16 mask. +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. sub esp, 32 diff --git a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc index 84004ac..ba519aa 100644 --- a/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake2S/Blake2SCompressSsse3_x86_64.inc @@ -1,17 +1,17 @@ // SSSE3 implementation of BLAKE2s compress (fully unrolled 10 rounds); SSE2 -// sibling: Blake2SCompressSse2_x86_64.inc. -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// sibling: Blake2SCompressSse2_x86_64.inc. Rotations: rot16/8 via pshufb +// against the resident masks; rot12/7 via psrld/pslld/por (not +// byte-aligned). Diagonalize/Undiagonalize via pshufd. Message loads via +// movd + punpcklqdq + shufps. +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, // r8 = counter+flags ptr, r9 = IV ptr, r10 = byte-rotation masks ptr -// (see BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the +// (BLAKE2S_ROT_MASKS: rot16 at +0, rot8 at +16; read unaligned, so the // Pascal const needs no special alignment). -// Uses xmm0-xmm8; xmm6-xmm8 are MS x64 non-volatile (saved/restored). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = message buffer, xmm5 = temp, xmm6 = temp (msg load), -// xmm7 = rot16 mask, xmm8 = rot8 mask. -// Rotations: ROT16/8 via pshufb (db-encoded for broad assembler compatibility) -// against the resident masks; ROT12/7 via psrld/pslld/por (not byte-aligned). -// Diagonalize/Undiagonalize via pshufd. -// Message loads via movd + punpcklqdq + shufps. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = message buffer, xmm5 = temp, +// xmm6 = temp (msg load), xmm7 = rot16 mask, xmm8 = rot8 mask. +// Saves: xmm6-xmm8 (MS x64 non-volatile); uses xmm0-xmm8. +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: BLAKE2/BLAKE2 sse/ by Samuel Neves. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc index 2ff5db8..54443df 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressAvx_x86_64.inc @@ -1,27 +1,26 @@ -// AVX (VEX-128) implementation of BLAKE3 compress (7 rounds with register-based -// message scheduling). -// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Reference: BLAKE3-team/BLAKE3 official SSE2/AVX2 implementation. -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// AVX (VEX-128) implementation of BLAKE3 compress (7 rounds with +// register-based message scheduling); the Avx name states the ISA +// requirement: VEX-128 encodings only, no 256-bit ymm. 3-operand VEX form +// eliminates the movdqa copies the SSE2 rotations need. Rotations: rot16/8 +// via vpshufb against the resident masks, rot12/7 via shift+or (not +// byte-aligned; shifts are the known-best form). Blend emulations use +// vshufps+vpshufd (blend_0xCC) and vpunpckhdq+vshufps (blend_0xC0), +// avoiding the need for mask constants. +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, // r8 = CV ptr, r9 = counterflags ptr, r10 = byte-rotation masks ptr -// (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +32; read unaligned, so the +// (BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +32; read unaligned, so the // Pascal const needs no special alignment). -// Register map: xmm0 = a, xmm1 = b, xmm2 = c, xmm3 = d, -// xmm4 = m0, xmm5 = m1, xmm6 = m2, xmm7 = m3, xmm8/xmm9 = temp, xmm11/xmm14 = temp, -// xmm10 = rot16 mask, xmm12 = rot8 mask. -// Rotations: ROT16/8 via vpshufb against the resident masks, ROT12/7 via -// shift+or (not byte-aligned; shifts are the known-best form). -// 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. -// Blend emulations use vshufps+vpshufd (blend_0xCC) and vpunpckhdq+vshufps (blend_0xC0), -// avoiding the need for mask constants. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV). -// -// Stack layout (sub rsp, 120): -// [rsp + 0.. 95]: xmm6/xmm7/xmm8/xmm9/xmm11/xmm14 save area (6 * 16) -// [rsp + 96..111]: IV staging area (loaded into xmm2) -// [rsp +112..119]: padding +// Register map: xmm0 = a, xmm1 = b, xmm2 = c, xmm3 = d, xmm4-xmm7 = m0-m3, +// xmm8/xmm9 = temp, xmm11/xmm14 = temp, xmm10 = rot16 mask, +// xmm12 = rot8 mask. +// Frame (sub rsp, 120): +// [rsp + 0.. 95] = xmm6/xmm7/xmm8/xmm9/xmm11/xmm14 save area (6 x 16) +// [rsp + 96..111] = IV staging area (loaded into xmm2) +// [rsp +112..119] = padding +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV). +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: BLAKE3-team/BLAKE3 official SSE2/AVX2 implementation. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc index 540b75e..fcace04 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressNeon_aarch64.inc @@ -1,9 +1,8 @@ -// BLAKE3 compress AArch64 NEON implementation. -// Expects AAPCS64: x0 = state ptr (16 x UInt32), x1 = message ptr (64 bytes), -// x2 = CV ptr (8 x UInt32), x3 = counter+flags ptr (16 bytes: t[0..1], len, flags). -// Stack frame 128 bytes; see register map. -// Reference: BLAKE3-team/BLAKE3 c/blake3_impl.h, HashLib Blake3CompressSse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of BLAKE3 compress (7 rounds with register-based +// message scheduling). +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (16 x UInt32), +// x1 = message ptr (64 bytes), x2 = CV ptr (8 x UInt32), +// x3 = counter+flags ptr (16 bytes: t[0..1], len, flags). // Register map: // v0 = a (v[0..3]) // v1 = b (v[4..7]) @@ -15,8 +14,12 @@ // v18-v19 = rotate temps (2-op ushr+sli rotates rename rows b/d through them) // v20 = shufps / non-cyclic pshufd scratch (t14); cyclic diagonalize // shuffles use in-place 'ext' instead -// Stack (128 bytes): [sp, #0] transient t9 (v17) spill during inter-round permute; -// [sp, #96..111] IV constant staging in prologue. +// Frame: 128 bytes ([sp, #0] transient t9 (v17) spill during the inter-round +// permute; [sp, #96..111] IV constant staging in the prologue). +// Saves: none (caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: BLAKE3-team/BLAKE3 c/blake3_impl.h, HashLib +// Blake3CompressSse2_x86_64.inc. sub sp, sp, #128 .long 0x529ccceb // movz w11, #0xe667, lsl #0 diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_i386.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_i386.inc index 0fee3c4..71092ad 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_i386.inc @@ -1,12 +1,14 @@ -// SSE2 implementation of BLAKE3 compress (7 rounds with register-based message scheduling). -// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation (blake3_sse2_x86-64_windows_msvc.asm). -// IA-32: after HlpSimdProc4Begin_i386 — ebx = state, esi = msg, edi = CV, eax = counterflags ptr -// (parallel to MS x64 ABI: rcx, rdx, r8, r9). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15); -// IA-32 uses xmm0–7 only — high-XMM temps from x64 are folded into xmm0/1/2 + stack spill; -// rotations use xmm0 + [esp+$20]. +// SSE2 implementation of BLAKE3 compress (7 rounds with register-based +// message scheduling; IA-32). Message scheduling / diagonalize: same +// strategy as the x64 sibling (blend emulation, pshufd), per sneves. // Rotations: rot16 via pshuflw+pshufhw; rot12/8/7 via pslld/psrld/por. -// Message scheduling / diagonalize: same strategy as x64 (blend emulation, pshufd), per sneves. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = msg ptr, +// edi = CV ptr, eax = counterflags ptr. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15); IA-32 uses xmm0-xmm7 only - high-XMM temps from x64 +// are folded into xmm0/1/2 + stack spill; rotations use xmm0 + [esp+$20]. +// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation +// (blake3_sse2_x86-64_windows_msvc.asm), HashLib Blake3CompressSse2_x86_64.inc. sub esp, 120 movdqu oword ptr [esp], xmm6 @@ -26,7 +28,7 @@ // Initialize state: a=CV[0..3], b=CV[4..7], c=IV[0..3], d=CounterFlags movdqu xmm0, oword ptr [edi] movdqu xmm1, oword ptr [edi + $10] - // xmm2 = IV (loaded above); eax clobbered by IV stores — reload counterflags + // xmm2 = IV (loaded above); eax clobbered by IV stores - reload counterflags mov eax, dword ptr [esp + $30] movdqu xmm3, oword ptr [eax] diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc index 539b444..c3e7379 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressSse2_x86_64.inc @@ -1,20 +1,22 @@ -// SSE2 implementation of BLAKE3 compress (7 rounds with register-based message scheduling). -// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation (blake3_sse2_x86-64_windows_msvc.asm). -// Expects MS x64 ABI: rcx = state ptr, rdx = msg ptr, r8 = CV ptr, r9 = counterflags ptr. -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = m0 (col G1 msg), xmm5 = m1 (col G2 msg), xmm6 = m2 (diag G1 msg), -// xmm7 = m3 (diag G2 msg), xmm8/xmm9 = temp (msg perm), xmm11/xmm14 = temp (rotations). -// Rotations: rot16 via pshuflw+pshufhw; rot12/8/7 via pslld/psrld/por. -// Message scheduling: all 16 words kept in xmm4-7, permuted between rounds using -// shufps/pshufd (blend_0xCC emulated via shufps+pshufd, blend_0xC0 via punpckhdq+shufps). -// Diagonalize/Undiagonalize via pshufd (row1 unrotated, per sneves optimization). -// -// MS x64 non-volatile saves: xmm6, xmm7, xmm8, xmm9, xmm11, xmm14. -// -// Stack layout (sub rsp, 120): -// [rsp + 0.. 95]: xmm6/xmm7/xmm8/xmm9/xmm11/xmm14 save area (6 * 16) -// [rsp + 96..111]: IV staging area (loaded into xmm2) -// [rsp +112..119]: padding +// SSE2 implementation of BLAKE3 compress (7 rounds with register-based +// message scheduling). All 16 message words stay in xmm4-xmm7, permuted +// between rounds via shufps/pshufd (blend_0xCC emulated via shufps+pshufd, +// blend_0xC0 via punpckhdq+shufps). Rotations: rot16 via pshuflw+pshufhw; +// rot12/8/7 via pslld/psrld/por. Diagonalize/Undiagonalize via pshufd +// (row1 unrotated, per sneves optimization). +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, +// r8 = CV ptr, r9 = counterflags ptr. +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4 = m0 (col G1 msg), xmm5 = m1 (col G2 msg), +// xmm6 = m2 (diag G1 msg), xmm7 = m3 (diag G2 msg), +// xmm8/xmm9 = temp (msg perm), xmm11/xmm14 = temp (rotations). +// Frame (sub rsp, 120): +// [rsp + 0.. 95] = xmm6/xmm7/xmm8/xmm9/xmm11/xmm14 save area (6 x 16) +// [rsp + 96..111] = IV staging area (loaded into xmm2) +// [rsp +112..119] = padding +// Saves: xmm6, xmm7, xmm8, xmm9, xmm11, xmm14 (MS x64 non-volatile). +// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation +// (blake3_sse2_x86-64_windows_msvc.asm). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc index 705d4c5..122d926 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3CompressSsse3_x86_64.inc @@ -1,22 +1,22 @@ -// SSSE3 implementation of BLAKE3 compress (7 rounds with register-based message -// scheduling); SSE2 sibling: Blake3CompressSse2_x86_64.inc. -// Reference: BLAKE3-team/BLAKE3 official SSE2/SSE4.1 implementations. -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = msg ptr, +// SSSE3 implementation of BLAKE3 compress (7 rounds with register-based +// message scheduling); SSE2 sibling: Blake3CompressSse2_x86_64.inc. +// Message scheduling: all 16 words kept in xmm4-xmm7, permuted between +// rounds via shufps/pshufd (blend_0xCC emulated via shufps+pshufd, +// blend_0xC0 via punpckhdq+shufps). Rotations: rot16/8 via pshufb against +// the resident masks; rot12/7 via pslld/psrld/por (not byte-aligned). +// Diagonalize/Undiagonalize via pshufd (row1 unrotated, per sneves +// optimization). +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = msg ptr, // r8 = CV ptr, r9 = counterflags ptr, r10 = byte-rotation masks ptr -// (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +32; read unaligned, so the +// (BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +32; read unaligned, so the // Pascal const needs no special alignment). -// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), xmm3 = d (v12-15), -// xmm4 = m0 (col G1 msg), xmm5 = m1 (col G2 msg), xmm6 = m2 (diag G1 msg), -// xmm7 = m3 (diag G2 msg), xmm8/xmm9 = temp (msg perm), xmm11/xmm14 = temp (rotations), -// xmm10 = rot16 mask, xmm12 = rot8 mask. -// Rotations: rot16/8 via pshufb (db-encoded for broad assembler compatibility) -// against the resident masks; rot12/7 via pslld/psrld/por (not byte-aligned). -// Message scheduling: all 16 words kept in xmm4-7, permuted between rounds using -// shufps/pshufd (blend_0xCC emulated via shufps+pshufd, blend_0xC0 via punpckhdq+shufps). -// Diagonalize/Undiagonalize via pshufd (row1 unrotated, per sneves optimization). -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV). +// Register map: xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15), xmm4-xmm7 = m0-m3, xmm8/xmm9 = temp (msg perm), +// xmm11/xmm14 = temp (rotations), xmm10 = rot16 mask, xmm12 = rot8 mask. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV). +// pshufb instructions are db-encoded for broad assembler compatibility. +// Reference: BLAKE3-team/BLAKE3 official SSE2/SSE4.1 implementations. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc index 3763f14..68d79f5 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Neon_aarch64.inc @@ -1,23 +1,27 @@ -// BLAKE3 hash4 AArch64 NEON implementation (4 parallel 1 KiB chunks). -// Expects AAPCS64: x0 = AInput, x1 = AKey, x2 = AOut, -// w3 = ANumChunks (unused; always 16 blocks like SSE2), x4 = ACounter, w5 = AFlags. -// Stack frame 720 bytes; see register map. -// Reference: BLAKE3-team/BLAKE3 c/blake3_impl.h, HashLib Blake3Hash4Sse2_x86_64.inc -// (output chunk order matches HashLib SSE2, not upstream blake3_neon.c store layout). -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of BLAKE3 hash4 (4 parallel 1 KiB chunks). +// Message transpose uses trn1/trn2 + zip1/zip2 (equivalent to SSE punpck / +// neon transpose_vecs_128). +// ABI (after HlpSimdProc6Begin_aarch64.inc): x0 = input ptr, x1 = key ptr, +// x2 = out ptr, w3 = num chunks (unused; always 16 blocks like SSE2), +// x4 = counter, w5 = flags. // Register map: // v0-v7 = state v0..v7 (CV rows, 4-wide) // v8-v11 = state v8..v11 (IV rows, updated each round) -// v16-v17 = G temps (v12/v13 analog; d lane spilled via stack v12-v15 slots) -// v16-v17 double as G temps; every rotate is the 2-op insert form and the -// rotating values (d and b) migrate v_b -> t13 -> v_b within each G +// v16-v17 = G temps (v12/v13 analog); every rotate is the 2-op insert +// form and the rotating values (d and b) migrate v_b -> t13 -> v_b +// within each G; the d lane spills via the stack v12-v15 slots // v20-v23 = transpose / block temps // x19 = block index (0..15), x20 = block byte offset within chunk -// Stack frame 720 bytes (712B SSE2 layout + 8B align): -// [sp, #0..255] transposed message m[0..15] (four 64-byte groups at +0,+64,+128,+192) -// [sp, #256..304] v12-v15 spills (counter lo/hi, block len, flags) -// [sp, #320..568] saved CV, counter vectors, IV, block len, AOut ptr, flags -// Message transpose uses trn1/trn2 + zip1/zip2 (equivalent to SSE punpck / neon transpose_vecs_128). +// Frame: 720 bytes (712B SSE2 layout + 8B align): +// [sp, #0..255] = transposed message m[0..15] (four 64-byte groups) +// [sp, #256..304] = v12-v15 spills (counter lo/hi, block len, flags) +// [sp, #320..568] = saved CV, counter vectors, IV, block len, AOut, flags +// Saves: d8-d15 via the shared HlpSimdNonVolatileSave/Restore include +// (v8-v15 hold IV rows / spills); x19/x20 saved in the prologue. +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: BLAKE3-team/BLAKE3 c/blake3_impl.h, HashLib +// Blake3Hash4Sse2_x86_64.inc (output chunk order matches HashLib SSE2, +// not upstream blake3_neon.c store layout). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_i386.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_i386.inc index 2290419..3461ddd 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_i386.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_i386.inc @@ -1,23 +1,27 @@ -// SSE2 i386 implementation of BLAKE3 hash4: processes up to 4 chunks sequentially. -// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation (blake3_sse2.c / hash_one). -// i386 has only xmm0-xmm7 (8 registers), so inter-chunk parallelism is not possible; -// each chunk is processed one at a time with the inline SSE2 compress kernel. -// Register map during rounds: xmm0=a(v0-3), xmm1=b(v4-7), xmm2=c(v8-11), xmm3=d(v12-15); -// xmm4={m0,m2,m4,m6}, xmm5={m1,m3,m5,m7}, xmm6={m14,m8,m10,m12}, xmm7={m15,m9,m11,m13}. -// After HlpSimdProc6Begin_i386: ebx=P1 (input), esi=P2 (key), edi=P3 (out), eax=P4 (num chunks), -// ecx=P5_lo, edx=P5_hi (chunk counter). Prologue pushed ebx/esi/edi — epilogue pops them. -// Block index (0..15) is kept at [esp+$90] so ebp is never used as a temp (frame-friendly). -// Stack layout (148 bytes, esp-relative after sub esp,148): -// [esp+$00..0F] xmm6 save [esp+$10..1F] xmm7 save -// [esp+$20..2F] TEMP_A (xmm0 spill during rounds) -// [esp+$30..3F] TEMP_B (xmm1 spill during msg permutation — also D_VEC build slot) -// [esp+$40..4F] TEMP_C (xmm2 spill during msg permutation) -// [esp+$50..5F] IV_VEC {$6A09E667,$BB67AE85,$3C6EF372,$A54FF53A} -// [esp+$60..6F] CV_LO (running chaining value low 16 bytes) -// [esp+$70..7F] CV_HI (running chaining value high 16 bytes) -// [esp+$80] CTR_LO [esp+$84] CTR_HI [esp+$88] BASE_FLAGS [esp+$8C] SAVE_NC -// [esp+$90] BLOCK_IDX (current block within chunk, 0..15) -// P6 (flags): FPC i386 [esp+$A4] (16+148 after sub esp,148). Delphi [ebp+8]. +// SSE2 implementation of BLAKE3 hash4 (IA-32): processes up to 4 chunks +// sequentially. IA-32 has only xmm0-xmm7, so inter-chunk parallelism is not +// possible; each chunk runs one at a time through the inline SSE2 compress +// kernel. The block index (0..15) is kept at [esp+$90] so ebp is never used +// as a temp (frame-friendly). +// ABI (after HlpSimdProc6Begin_i386.inc): ebx = AInput, esi = AKey, +// edi = AOut, eax = ANumChunks, ecx = ACounter.lo32, edx = ACounter.hi32. +// P6 (AFlags) is a stack parameter: FPC i386 [esp+$A4] (16+148 after +// sub esp,148); Delphi [ebp+8]. +// Register map (rounds): xmm0 = a (v0-3), xmm1 = b (v4-7), xmm2 = c (v8-11), +// xmm3 = d (v12-15); xmm4 = {m0,m2,m4,m6}, xmm5 = {m1,m3,m5,m7}, +// xmm6 = {m14,m8,m10,m12}, xmm7 = {m15,m9,m11,m13}. +// Frame (sub esp, 148): +// [esp+$00..0F] = xmm6 save [esp+$10..1F] = xmm7 save +// [esp+$20..2F] = TEMP_A (xmm0 spill during rounds) +// [esp+$30..3F] = TEMP_B (xmm1 spill during msg permutation / D_VEC build) +// [esp+$40..4F] = TEMP_C (xmm2 spill during msg permutation) +// [esp+$50..5F] = IV_VEC {$6A09E667,$BB67AE85,$3C6EF372,$A54FF53A} +// [esp+$60..6F] = CV_LO [esp+$70..7F] = CV_HI (running chaining value) +// [esp+$80] = CTR_LO [esp+$84] = CTR_HI [esp+$88] = BASE_FLAGS +// [esp+$8C] = SAVE_NC [esp+$90] = BLOCK_IDX (current block, 0..15) +// Saves: xmm6-xmm7 saved/restored defensively (volatile on IA-32). +// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation +// (blake3_sse2.c / hash_one). sub esp, 148 @@ -63,7 +67,7 @@ @h4_block_loop: // Build D_VEC = {CTR_LO, CTR_HI, BLKLEN=64, flags} at TEMP_B slot [esp+$30] - // (TEMP_B will be overwritten by msg permutation later — that is expected) + // (TEMP_B will be overwritten by msg permutation later - that is expected) mov ecx, dword ptr [esp + $80] // CTR_LO mov edx, dword ptr [esp + $84] // CTR_HI mov eax, dword ptr [esp + $88] // BASE_FLAGS diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc index 6cc80f3..a73c309 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Sse2_x86_64.inc @@ -1,19 +1,18 @@ -// SSE2 implementation of BLAKE3 hash4: processes 4 independent chunks simultaneously. -// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation (blake3_sse2.c / blake3_hash_many). -// Each XMM register holds the same 32-bit word from 4 different chunks (inter-chunk SIMD). -// 7 rounds per block fully unrolled; 16-block loop with branch for chunk start/end flags. -// -// After HlpSimdProc6Begin_x86_64.inc: -// rcx = AInput, rdx = AKey, r8 = AOut, -// r9 = ANumChunks, r10 = ACounter, r11 = AFlags -// +// SSE2 implementation of BLAKE3 hash4: processes 4 independent chunks +// simultaneously. Each XMM register holds the same 32-bit word from 4 +// different chunks (inter-chunk SIMD); 7 rounds per block fully unrolled; +// 16-block loop with branch for chunk start/end flags. Message transpose: +// 4x4 via punpckldq/punpckhdq + punpcklqdq/punpckhqdq (pure SSE2). +// Rotations: rot16 via pshuflw+pshufhw; rot12/8/7 via pslld/psrld/por. +// ABI (after HlpSimdProc6Begin_x86_64.inc): rcx = AInput, rdx = AKey, +// r8 = AOut, r9 = ANumChunks, r10 = ACounter, r11 = AFlags. // Register map: xmm0-xmm7 = state v0-v7, xmm8-xmm11 = state v8-v11, // xmm12-xmm13 = temp, v12-v15 spilled to stack. -// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block byte offset. -// Message transpose: 4x4 via punpckldq/punpckhdq + punpcklqdq/punpckhqdq (pure SSE2). -// Rotations: rot16 via pshuflw+pshufhw; rot12/8/7 via pslld/psrld/por. -// -// MS x64 non-volatile saves: xmm6-xmm13. +// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block +// byte offset. +// Saves: xmm6-xmm13 (MS x64 non-volatile). +// Reference: BLAKE3-team/BLAKE3 official SSE2 implementation +// (blake3_sse2.c / blake3_hash_many). push rbx push rbp diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc index 56fc93a..d059650 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash4Ssse3_x86_64.inc @@ -1,27 +1,25 @@ // SSSE3 implementation of BLAKE3 hash4: processes 4 independent chunks -// simultaneously; SSE2 sibling: Blake3Hash4Sse2_x86_64.inc. -// Reference: BLAKE3-team/BLAKE3 official SSE2/SSE4.1 implementations -// (blake3_hash_many). -// Each XMM register holds the same 32-bit word from 4 different chunks (inter-chunk SIMD). -// 7 rounds per block fully unrolled; 16-block loop with branch for chunk start/end flags. -// -// After HlpSimdProc7Begin_x86_64.inc: -// rcx = AInput, rdx = AKey, r8 = AOut, -// r9 = ANumChunks, r10 = ACounter, r11 = AFlags, -// rax = byte-rotation masks ptr (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 -// at +32; read unaligned, so the Pascal const needs no special alignment; +// simultaneously; SSE2 sibling: Blake3Hash4Sse2_x86_64.inc. Each XMM +// register holds the same 32-bit word from 4 different chunks (inter-chunk +// SIMD); 7 rounds per block fully unrolled; 16-block loop with branch for +// chunk start/end flags. Message transpose: 4x4 via punpckldq/punpckhdq + +// punpcklqdq/punpckhqdq (pure SSE2). Rotations: rot16/8 via pshufb against +// the resident masks; rot12/7 via pslld/psrld/por (not byte-aligned). +// ABI (after HlpSimdProc7Begin_x86_64.inc): rcx = AInput, rdx = AKey, +// r8 = AOut, r9 = ANumChunks, r10 = ACounter, r11 = AFlags, +// rax = byte-rotation masks ptr (BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +// +32; read unaligned, so the Pascal const needs no special alignment; // consumed by the entry mask loads, rax is scratch afterwards). -// // Register map: xmm0-xmm7 = state v0-v7, xmm8-xmm11 = state v8-v11, // xmm12-xmm13 = temp, xmm14 = rot16 mask, xmm15 = rot8 mask, // v12-v15 spilled to stack. -// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block byte offset. -// Message transpose: 4x4 via punpckldq/punpckhdq + punpcklqdq/punpckhqdq (pure SSE2). -// Rotations: rot16/8 via pshufb (db-encoded for broad assembler compatibility) -// against the resident masks; rot12/7 via pslld/psrld/por (not byte-aligned). -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV). +// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block +// byte offset. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV). +// pshufb instructions are db-encoded for broad assembler compatibility. +// Reference: BLAKE3-team/BLAKE3 official SSE2/SSE4.1 implementations +// (blake3_hash_many). push rbx push rbp diff --git a/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc b/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc index 50f1dca..3acdae5 100644 --- a/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/Blake3/Blake3Hash8Avx2_x86_64.inc @@ -1,29 +1,28 @@ -// AVX2 implementation of BLAKE3 hash8: processes 8 independent chunks simultaneously. -// Reference: BLAKE3-team/BLAKE3 official AVX2 implementation (blake3_avx2.c / blake3_hash_many). -// Each YMM register holds the same 32-bit word from 8 different chunks (inter-chunk SIMD). -// All VEX instructions are db-encoded for broad assembler compatibility. -// 7 rounds per block fully unrolled; 16-block loop with branch for chunk start/end flags. -// -// After HlpSimdProc7Begin_x86_64.inc: -// rcx = AInput, rdx = AKey, r8 = AOut, -// r9 = ANumChunks, r10 = ACounter, r11 = AFlags, -// rax = byte-rotation masks ptr (see BLAKE3_ROT_MASKS: rot16 at +0, rot8 -// at +32; read unaligned, so the Pascal const needs no special alignment; +// AVX2 implementation of BLAKE3 hash8: processes 8 independent chunks +// simultaneously. Each YMM register holds the same 32-bit word from 8 +// different chunks (inter-chunk SIMD); 7 rounds per block fully unrolled; +// 16-block loop with branch for chunk start/end flags. Message transpose: +// chunks paired (0+4, 1+5, ...) via vinserti128, then per-lane 4x4. Output +// transpose: full 8x8 via vperm2i128 + vpunpckl/hdq + vpunpcklq/hqdq. +// Rotations: rot16/8 via vpshufb against the resident masks, rot12/7 via +// shift+or (not byte-aligned; shifts are the known-best form). 3-operand +// VEX form eliminates the movdqa copies the SSE2 rotations need. +// ABI (after HlpSimdProc7Begin_x86_64.inc): rcx = AInput, rdx = AKey, +// r8 = AOut, r9 = ANumChunks, r10 = ACounter, r11 = AFlags, +// rax = byte-rotation masks ptr (BLAKE3_ROT_MASKS: rot16 at +0, rot8 at +// +32; read unaligned, so the Pascal const needs no special alignment; // consumed by the entry mask loads, rax is scratch afterwards). -// // Register map: ymm0-ymm7 = state v0-v7, ymm8-ymm11 = state v8-v11, // ymm12-ymm13 = temp, ymm14 = rot16 mask, ymm15 = rot8 mask, // v12-v15 spilled to stack. -// Rotations: ROT16/8 via vpshufb against the resident masks, ROT12/7 via -// shift+or (not byte-aligned; shifts are the known-best form). -// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block byte offset. -// Message transpose: chunks paired (0+4, 1+5, ...) via vinserti128, then per-lane 4x4. -// Output transpose: full 8x8 via vperm2i128 + vpunpckl/hdq + vpunpcklq/hqdq. -// 3-operand VEX form eliminates movdqa copies needed in SSE2 rotations. -// Stack 32-byte aligned via "and rsp, -32" for YMM movdqu stores. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV). +// GPR: rcx = input pointer, rbx = block counter (0..15), rbp = block +// byte offset. +// Frame: stack 32-byte aligned via "and rsp, -32" for YMM movdqu stores. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV). +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: BLAKE3-team/BLAKE3 official AVX2 implementation +// (blake3_avx2.c / blake3_hash_many). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc index ce9d58c..53ea7f6 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_i386.inc @@ -1,8 +1,11 @@ -// MSB-first 64-bit CRC: 16-byte slice (IA-32; SSE2 not required — same as x64 MSB path). -// x64 counterpart: CRCFoldForwardGpr_x86_64.inc. -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength, edi = AState, eax = Ctx. -// Ctx: FoldConstants.CrcBits at +80, TableRow at +96. CrcMask derived from width. -// Result UInt64 in edx:eax. +// Gpr implementation of the MSB-first 64-bit CRC 16-byte slice (IA-32; +// slicing-by-16); the Gpr name states the ISA requirement: none beyond +// base IA-32. x64 counterpart: CRCFoldForwardGpr_x86_64.inc. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = AData, esi = ALength, +// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx). +// Ctx: FoldConstants.CrcBits at +80, TableRow at +96. CrcMask derived +// from the width. Returns the final CRC UInt64 in edx:eax. +// Reference: classic slicing-by-16 table CRC. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc index 391c552..c73f985 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardGpr_x86_64.inc @@ -1,13 +1,13 @@ -// MSB-first 64-bit CRC: 16-byte slice (slicing-by-16), pure GPR - no vector -// instructions (the Gpr name states the ISA requirement: none beyond base x86-64). -// IA-32 counterpart: CRCFoldForwardGpr_i386.inc. -// Signature (after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Forward_Gpr(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// MS x64: rcx=AData, edx=ALength, r8=AState, r9=Ctx. -// Callee-saved: rsi/rdi must be preserved (used as LTempCopy / LBIdx scratch). -// Ctx = PCRCFoldRuntimeCtx: FoldConstants.CrcBits at +80, TableRow at +96. -// CrcMask = ((1 shl (W-1)) - 1) shl 1 or 1; W = dword [r9+80] (TCRC table path: W>=8). +// Gpr implementation of the MSB-first 64-bit CRC 16-byte slice +// (slicing-by-16); the Gpr name states the ISA requirement: none beyond +// base x86-64. IA-32 counterpart: CRCFoldForwardGpr_i386.inc. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = AData, edx = ALength, +// r8 = AState, r9 = Ctx (PCRCFoldRuntimeCtx). +// Ctx: FoldConstants.CrcBits at +80, TableRow at +96. +// CrcMask = ((1 shl (W-1)) - 1) shl 1 or 1; W = dword [r9+80] +// (TCRC table path: W >= 8). Returns the final CRC in rax. +// Saves: rsi/rdi preserved (used as LTempCopy / LBIdx scratch). +// Reference: classic slicing-by-16 table CRC. push rbx push rbp diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc index c522cf0..d3c3d6b 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_i386.inc @@ -1,22 +1,24 @@ -// SSE2 + SSSE3 + PCLMULQDQ CRC folding + Barrett reduction for non-reflected -// (MSB-first) CRCs with width 8..64 (IA-32). Fold-by-4 only: the fold-by-8 -// upper path of the x86-64 kernel needs xmm8-11, which IA-32 does not have. -// PCLMULQDQ/PSHUFB instructions are db-encoded for broad assembler -// compatibility; all byte sequences are verbatim from -// CRCFoldForwardPclmul_x86_64.inc (xmm0-7 forms carry no REX prefix and -// encode identically on IA-32). -// -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), -// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). +// SSE2 + SSSE3 + PCLMULQDQ implementation of CRC folding + Barrett +// reduction for non-reflected (MSB-first) CRCs with width 8..64 (IA-32). +// Fold-by-4 only: the fold-by-8 upper path of the x86-64 kernel needs +// xmm8-xmm11, which IA-32 does not have. All byte sequences are verbatim +// from CRCFoldForwardPclmul_x86_64.inc (xmm0-7 forms carry no REX prefix +// and encode identically on IA-32). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = AData, esi = ALength +// (>= 16), edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants +// at +0). // AState: pointer to the initial CRC pre-shifted left by (64 - Width) -// as one UInt64. +// as one UInt64. Returns the final CRC UInt64 in edx:eax (low qword +// of xmm0). // Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, [+64] BswapMask, // [+80] CrcBits, [+88] BarrettShift. -// Result UInt64 in edx:eax (low qword of xmm0). -// -// pclmulqdq xmm_dst, xmm_src, imm8: 66 0F 3A 44 ModRM imm8 -// pshufb xmm_dst, xmm_src: 66 0F 38 00 ModRM -// ModRM = 11_dst_src. +// PCLMULQDQ/pshufb instructions are db-encoded for broad assembler +// compatibility. Encoding notes: +// pclmulqdq xmm_dst, xmm_src, imm8: 66 0F 3A 44 ModRM imm8 +// pshufb xmm_dst, xmm_src: 66 0F 38 00 ModRM +// ModRM = 11_dst_src. +// Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google), +// HashLib CRCFoldForwardPclmul_x86_64.inc. push ebp mov ebp, eax // Ctx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc index bcc87bf..3a9d051 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPclmul_x86_64.inc @@ -1,33 +1,20 @@ -// SSE2 + SSSE3 + PCLMULQDQ CRC folding + Barrett reduction for non-reflected -// (MSB-first) CRCs with width 8..64. -// PCLMULQDQ instructions are db-encoded for broad assembler compatibility. -// -// Function signature (included after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Forward_Pclmul(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// -// Register mapping (MS x64 ABI after prologue): -// rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as one UInt64. +// SSE2 + SSSE3 + PCLMULQDQ implementation of CRC folding + Barrett +// reduction for non-reflected (MSB-first) CRCs with width 8..64. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = AData, edx = ALength +// (>= 16), r8 = AState, r9 = AConstants. +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) +// as one UInt64. Returns the final CRC in rax. // AConstants layout (TCRCFoldConstants): -// [0..15] = Fold_4x128 -// [16..31] = Fold_1x128 -// [32..47] = Barrett -// [48..63] = Fold_8x128 -// [64..79] = BswapMask -// [80..87] = CrcBits -// [88..95] = BarrettShift -// Returns: final CRC in RAX. -// +// [0..15] = Fold_4x128 [48..63] = Fold_8x128 +// [16..31] = Fold_1x128 [64..79] = BswapMask +// [32..47] = Barrett [80..87] = CrcBits +// [88..95] = BarrettShift +// PCLMULQDQ/pshufb instructions are db-encoded for broad assembler +// compatibility. Encoding notes: +// pclmulqdq xmm_dst, xmm_src, imm8: 66 [REX] 0F 3A 44 ModRM imm8 +// (REX = $44 = REX.R for xmm8-15 dst); ModRM reg-reg: 11_dst_src. +// pshufb xmm_dst, xmm_src (SSSE3): 66 [REX] 0F 38 00 ModRM. // Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google). -// -// pclmulqdq xmm_dst, xmm_src, imm8 (register-register): -// 66 [REX] 0F 3A 44 ModRM imm8 (REX = $44 = REX.R for xmm8-15 dst) -// ModRM for reg-reg: 11_dst_src -// xmm0=000 xmm1=001 xmm2=010 xmm3=011 xmm4=100 -// xmm5=101 xmm6=110 xmm7=111 xmm8-15=REX.R + 000..111 -// pshufb xmm_dst, xmm_src (SSSE3): -// 66 [REX] 0F 38 00 ModRM {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc index 61ffc90..07904bf 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardPmull_aarch64.inc @@ -1,15 +1,12 @@ -// CRC folding (PMULL/PMULL2 + TBL byte-reverse) + Barrett reduction for -// non-reflected (MSB-first) CRCs with width 8..64. -// Expects AAPCS64: x0 = AData, w1 = ALength (>= 16, multiple of 16), -// x2 = AState, x3 = AConstants (PCRCFoldRuntimeCtx; FoldConstants at +0). -// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as one UInt64. +// PMULL implementation of CRC folding (PMULL/PMULL2 + TBL byte-reverse) + +// Barrett reduction for non-reflected (MSB-first) CRCs with width 8..64. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = AData, w1 = ALength (>= 16, +// multiple of 16), x2 = AState, x3 = AConstants (PCRCFoldRuntimeCtx; +// FoldConstants at +0). +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as +// one UInt64. Returns the final CRC in x0. // AConstants: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, // [+64] BswapMask, [+80] CrcBits, [+88] BarrettShift. -// Returns final CRC in x0. -// Leaf nostackframe; caller-saved GPR/vector only (v0-v7, v17, v19-v22). -// Reference: Linux kernel crc-pclmul-template.S (Eric Biggers), -// HashLib CRCFoldForwardPclmul_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. // Register map: // v0-v3 = fold accumulators (xmm0-3) // v4 = pmull-hi temp (xmm4) @@ -18,6 +15,12 @@ // v7 = Fold_8x128 / Fold_4x128 then Fold_1x128 (xmm7) // v17 = dup staging for clmul hi*lo ($01) Barrett mix // v19-v22 = fold-by-8 upper accumulators (xmm8-11) +// Saves: none (leaf nostackframe; caller-saved GPR/vector only: v0-v7, v17, +// v19-v22). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: Linux kernel crc-pclmul-template.S (Eric Biggers), HashLib +// CRCFoldForwardPclmul_x86_64.inc. + .long 0x3dc01066 // ldr q6, [x3, #64] .long 0x7102003f // cmp w1, #128 b.lo .Lcrc_fwd_check64 diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc index 86a24aa..dcf4ca2 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_i386.inc @@ -1,21 +1,24 @@ -// AVX2 + VPCLMULQDQ CRC folding + Barrett reduction for non-reflected -// (MSB-first) CRCs with width 8..64 (IA-32). -// Mirrors CRCFoldForwardVpclmul_x86_64.inc; ymm0-7/xmm0-7 only, so the -// structure carries over 1:1 (all vector registers are volatile on IA-32 - -// no save/restore needed, just vzeroupper before returning). -// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler -// compatibility; every register-register byte sequence is identical to the -// verified x86_64 kernel's encoding (regs 0-7 carry no REX/VEX extension -// bits), and the memory forms are machine-assembled for the IA-32 bases. -// -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), -// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). +// AVX2 + VPCLMULQDQ implementation of CRC folding + Barrett reduction for +// non-reflected (MSB-first) CRCs with width 8..64 (IA-32). Mirrors +// CRCFoldForwardVpclmul_x86_64.inc; ymm0-7/xmm0-7 only, so the structure +// carries over 1:1. Every register-register byte sequence is identical to +// the verified x86_64 kernel's encoding (regs 0-7 carry no REX/VEX +// extension bits); the memory forms are machine-assembled for the IA-32 +// bases. vzeroupper before returning. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = AData, esi = ALength +// (>= 16), edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants +// at +0). // AState: pointer to the initial CRC pre-shifted left by (64 - Width) -// as one UInt64. +// as one UInt64. Returns the final CRC UInt64 in edx:eax (low qword +// of xmm0). // Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, // [+48] Fold_8x128, [+64] BswapMask, [+80] CrcBits, // [+88] BarrettShift. -// Result UInt64 in edx:eax (low qword of xmm0). +// Saves: none (all vector registers are volatile on IA-32). +// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler +// compatibility. +// Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google), +// HashLib CRCFoldForwardVpclmul_x86_64.inc. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc index 203e4e0..0eaa754 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldForwardVpclmul_x86_64.inc @@ -1,30 +1,18 @@ -// AVX2 + VPCLMULQDQ CRC folding + Barrett reduction for non-reflected -// (MSB-first) CRCs with width 8..64. -// AVX2/VPCLMULQDQ/SSSE3 instructions are db-encoded for broad assembler -// compatibility. -// -// Function signature (included after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Forward_Vpclmul(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// -// Register mapping (MS x64 ABI after prologue): -// rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: pointer to the initial CRC pre-shifted left by (64 - Width) as one UInt64. +// AVX2 + VPCLMULQDQ implementation of CRC folding + Barrett reduction for +// non-reflected (MSB-first) CRCs with width 8..64. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = AData, edx = ALength +// (>= 16), r8 = AState, r9 = AConstants. +// AState: pointer to the initial CRC pre-shifted left by (64 - Width) +// as one UInt64. Returns the final CRC in rax. // AConstants layout (TCRCFoldConstants): -// [0..15] = Fold_4x128 (stride 512) -// [16..31] = Fold_1x128 (stride 128) -// [32..47] = Barrett -// [48..63] = Fold_8x128 (stride 1024) -// [64..79] = BswapMask -// [80..87] = CrcBits -// [88..95] = BarrettShift -// Returns: final CRC in RAX. -// +// [0..15] = Fold_4x128 (stride 512) [48..63] = Fold_8x128 (stride 1024) +// [16..31] = Fold_1x128 (stride 128) [64..79] = BswapMask +// [32..47] = Barrett [80..87] = CrcBits +// [88..95] = BarrettShift +// AVX2/VPCLMULQDQ/SSSE3 instructions are db-encoded for broad assembler +// compatibility. Encoding notes (VEX byte layout): +// 2-byte: C5 [R.vvvv.L.pp] 3-byte: C4 [R.X.B.mmmmm] [W.vvvv.L.pp] // Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google). -// -// VEX byte layout reference: -// 2-byte: C5 [R.vvvv.L.pp] -// 3-byte: C4 [R.X.B.mmmmm] [W.vvvv.L.pp] {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc index efb23c3..ecbd2a4 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_i386.inc @@ -1,19 +1,22 @@ -// SSE2 + PCLMULQDQ CRC folding + Barrett reduction for reflected (LSB-first) -// CRCs with width 8..64 (IA-32). CRC-64 uses a special Barrett path for the -// 65-bit G. Fold-by-4 only: the fold-by-8 upper path of the x86-64 kernel -// needs xmm8-11, which IA-32 does not have. -// PCLMULQDQ instructions are db-encoded for broad assembler compatibility; -// all byte sequences are verbatim from CRCFoldReflectedPclmul_x86_64.inc -// (xmm0-7 forms carry no REX prefix and encode identically on IA-32). -// -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), -// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). -// AState: pointer to the initial CRC (reflected) as one UInt64. +// SSE2 + PCLMULQDQ implementation of CRC folding + Barrett reduction for +// reflected (LSB-first) CRCs with width 8..64 (IA-32). CRC-64 uses a +// special Barrett path for the 65-bit G. Fold-by-4 only: the fold-by-8 +// upper path of the x86-64 kernel needs xmm8-xmm11, which IA-32 does not +// have. All byte sequences are verbatim from +// CRCFoldReflectedPclmul_x86_64.inc (xmm0-7 forms carry no REX prefix and +// encode identically on IA-32). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = AData, esi = ALength +// (>= 16), edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants +// at +0). +// AState: pointer to the initial CRC (reflected) as one UInt64. Returns +// the final CRC UInt64 in edx:eax (high qword of xmm0). // Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, [+80] CrcBits. -// Result UInt64 in edx:eax (high qword of xmm0). -// -// pclmulqdq xmm_dst, xmm_src, imm8 (register-register): -// 66 0F 3A 44 ModRM imm8; ModRM = 11_dst_src. +// PCLMULQDQ instructions are db-encoded for broad assembler compatibility. +// Encoding notes: +// pclmulqdq xmm_dst, xmm_src, imm8: 66 0F 3A 44 ModRM imm8; +// ModRM = 11_dst_src. +// Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google), +// HashLib CRCFoldReflectedPclmul_x86_64.inc. push ebp mov ebp, eax // Ctx diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc index 445c97c..17e2bba 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPclmul_x86_64.inc @@ -1,30 +1,19 @@ -// SSE2 + PCLMULQDQ CRC folding + Barrett reduction for reflected (LSB-first) -// CRCs with width 8..64. CRC-64 uses a special Barrett path for the 65-bit G. -// PCLMULQDQ instructions are db-encoded for broad assembler compatibility. -// -// Function signature (included after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Reflected_Pclmul(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// -// Register mapping (MS x64 ABI after prologue): -// rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants +// SSE2 + PCLMULQDQ implementation of CRC folding + Barrett reduction for +// reflected (LSB-first) CRCs with width 8..64. CRC-64 uses a special +// Barrett path for the 65-bit G. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = AData, edx = ALength +// (>= 16), r8 = AState, r9 = AConstants. // AState: pointer to the initial CRC (reflected) as one UInt64. +// Returns the final CRC in rax. // AConstants layout (TCRCFoldConstants): -// [0..15] = Fold_4x128 -// [16..31] = Fold_1x128 -// [32..47] = Barrett -// [48..63] = Fold_8x128 -// [64..79] = BswapMask (unused by this path) -// [80..87] = CrcBits -// Returns: final CRC in RAX. -// +// [0..15] = Fold_4x128 [48..63] = Fold_8x128 +// [16..31] = Fold_1x128 [64..79] = BswapMask (unused by this path) +// [32..47] = Barrett [80..87] = CrcBits +// PCLMULQDQ instructions are db-encoded for broad assembler compatibility. +// Encoding notes: +// pclmulqdq xmm_dst, xmm_src, imm8: 66 [REX] 0F 3A 44 ModRM imm8 +// (REX = $44 = REX.R for xmm8-15 dst); ModRM reg-reg: 11_dst_src. // Reference: Linux kernel crc-pclmul-template.S by Eric Biggers (Google). -// -// pclmulqdq xmm_dst, xmm_src, imm8 (register-register): -// 66 [REX] 0F 3A 44 ModRM imm8 (REX = $44 = REX.R for xmm8-15 dst) -// ModRM for reg-reg: 11_dst_src -// xmm0=000 xmm1=001 xmm2=010 xmm3=011 xmm4=100 -// xmm5=101 xmm6=110 xmm7=111 xmm8-15=REX.R + 000..111 {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc index a95dfed..38ae2c1 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedPmull_aarch64.inc @@ -1,14 +1,13 @@ -// CRC folding (PMULL/PMULL2) + Barrett reduction for reflected (LSB-first) -// CRCs with width 8..64. CRC-64 uses a special Barrett path for the 65-bit G. -// Expects AAPCS64: x0 = AData, w1 = ALength (>= 16, multiple of 16), -// x2 = AState, x3 = AConstants (PCRCFoldRuntimeCtx; FoldConstants at +0). -// AState: pointer to the initial CRC (reflected) as one UInt64. +// PMULL implementation of CRC folding (PMULL/PMULL2) + Barrett reduction for +// reflected (LSB-first) CRCs with width 8..64. CRC-64 uses a special Barrett +// path for the 65-bit G. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = AData, w1 = ALength (>= 16, +// multiple of 16), x2 = AState, x3 = AConstants (PCRCFoldRuntimeCtx; +// FoldConstants at +0). +// AState: pointer to the initial CRC (reflected) as one UInt64. Returns +// the final CRC in x0. // AConstants: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, -// [+80] CrcBits. Returns final CRC in x0. -// Leaf nostackframe; caller-saved GPR/vector only (v0-v7, v16-v22). -// Reference: Linux kernel crc-pclmul-template.S (Eric Biggers), -// HashLib CRCFoldReflectedPclmul_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// [+80] CrcBits. // Register map: // v0-v3 = fold accumulators (xmm0-3) // v4 = pmull-hi temp (xmm4) @@ -19,6 +18,12 @@ // v17 = dup staging for clmul lo*hi ($10) Barrett mixes // v18 = saved Barrett q (CRC-64 x^0 correction) // v19-v22 = fold-by-8 upper accumulators (xmm8-11) +// Saves: none (leaf nostackframe; caller-saved GPR/vector only: v0-v7, +// v16-v22). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: Linux kernel crc-pclmul-template.S (Eric Biggers), HashLib +// CRCFoldReflectedPclmul_x86_64.inc. + .long 0x3dc00467 // ldr q7, [x3, #16] .long 0x7102003f // cmp w1, #128 b.lo .Lcrc_refl_check64 diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc index 9e1efac..7f8a252 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_i386.inc @@ -1,9 +1,13 @@ -// Reflected (LSB-first) 64-bit CRC: 16-byte slice (IA-32 SSE2 + GPR table XOR). -// GPR slicing core; SSE2 is genuinely required for the 128-bit loads and the -// CRC state shuttle - the Sse2 name states the ISA requirement. -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength, edi = AState, eax = Ctx. -// TableRow[i] at Ctx + 96; each entry is a 32-bit (untyped) Pointer. -// Result UInt64 in edx:eax (high:low). Preserves Delphi/FPC i386 frame via push/pop ebp. +// SSE2 implementation of the reflected (LSB-first) 64-bit CRC 16-byte slice +// (IA-32; SSE2 loads + GPR table XOR). GPR slicing core; SSE2 is genuinely +// required for the 128-bit loads and the CRC state shuttle - the Sse2 name +// states the ISA requirement. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = AData, esi = ALength, +// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx). +// TableRow[i] at Ctx + 96; each entry is a 32-bit (untyped) Pointer. +// Returns the final CRC UInt64 in edx:eax (high:low). +// Frame: preserves the i386 frame via push/pop ebp. +// Reference: classic slicing-by-16 table CRC. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc index 47cd99d..d6ba5de 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedSse2_x86_64.inc @@ -1,13 +1,13 @@ -// Reflected (LSB-first) 64-bit CRC: 16-byte slice using SSE2 loads + GPR table XOR. -// GPR slicing core; SSE2 is genuinely required for the 128-bit loads and the -// CRC state shuttle - the Sse2 name states the ISA requirement. -// Signature (after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Reflected_Sse2(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// MS x64: rcx=AData, edx=ALength, r8=AState, r9=Ctx (PCRCFoldRuntimeCtx). -// TableRow[i] begins at Ctx + SizeOf(TCRCFoldConstants) = Ctx + 96. -// -// SSE2: movdqu, movq, pxor, psrldq. No PCLMUL. +// SSE2 implementation of the reflected (LSB-first) 64-bit CRC 16-byte slice +// (SSE2 loads + GPR table XOR). GPR slicing core; SSE2 is genuinely +// required for the 128-bit loads and the CRC state shuttle - the Sse2 name +// states the ISA requirement. SSE2 ops: movdqu, movq, pxor, psrldq; +// no PCLMUL. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = AData, edx = ALength, +// r8 = AState, r9 = Ctx (PCRCFoldRuntimeCtx). +// TableRow[i] begins at Ctx + SizeOf(TCRCFoldConstants) = Ctx + 96. +// Returns the final CRC in rax. +// Reference: classic slicing-by-16 table CRC. push rbx push r12 diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc index 68c5209..c39b09e 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_i386.inc @@ -1,19 +1,24 @@ -// AVX2 + VPCLMULQDQ CRC folding + Barrett reduction for reflected (LSB-first) -// CRCs with width 8..64 (IA-32). CRC-64 uses a special Barrett path for the -// 65-bit G. Mirrors CRCFoldReflectedVpclmul_x86_64.inc; ymm0-7/xmm0-7 only, -// so the structure carries over 1:1 (all vector registers are volatile on -// IA-32 - no save/restore needed, just vzeroupper before returning). -// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler -// compatibility; every register-register byte sequence is identical to the -// verified x86_64 kernel's encoding (regs 0-7 carry no REX/VEX extension -// bits), and the memory forms are machine-assembled for the IA-32 bases. -// -// After HlpSimdProc4Begin_i386: ebx = AData, esi = ALength (>= 16), -// edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants at +0). -// AState: pointer to the initial CRC (reflected) as one UInt64. +// AVX2 + VPCLMULQDQ implementation of CRC folding + Barrett reduction for +// reflected (LSB-first) CRCs with width 8..64 (IA-32). CRC-64 uses a +// special Barrett path for the 65-bit G. Mirrors +// CRCFoldReflectedVpclmul_x86_64.inc; ymm0-7/xmm0-7 only, so the structure +// carries over 1:1. Every register-register byte sequence is identical to +// the verified x86_64 kernel's encoding (regs 0-7 carry no REX/VEX +// extension bits); the memory forms are machine-assembled for the IA-32 +// bases. vzeroupper before returning. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = AData, esi = ALength +// (>= 16), edi = AState, eax = Ctx (PCRCFoldRuntimeCtx; FoldConstants +// at +0). +// AState: pointer to the initial CRC (reflected) as one UInt64. Returns +// the final CRC UInt64 in edx:eax (high qword of xmm0). // Ctx: [+0] Fold_4x128, [+16] Fold_1x128, [+32] Barrett, // [+48] Fold_8x128, [+80] CrcBits. -// Result UInt64 in edx:eax (high qword of xmm0). +// Saves: none (all vector registers are volatile on IA-32). +// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler +// compatibility. +// Reference: zlib-ng crc32_pclmulqdq_tpl.h and Linux kernel +// crc-pclmul-template.S by Eric Biggers, HashLib +// CRCFoldReflectedVpclmul_x86_64.inc. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc index 469962d..1c4a482 100644 --- a/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc +++ b/HashLib/src/Include/Simd/CRC/CRCFoldReflectedVpclmul_x86_64.inc @@ -1,29 +1,19 @@ -// AVX2 + VPCLMULQDQ CRC folding + Barrett reduction for reflected (LSB-first) -// CRCs with width 8..64. CRC-64 uses a special Barrett path for the 65-bit G. -// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler compatibility. -// -// Function signature (included after HlpSimdProc4Begin_x86_64.inc): -// function CRC_Fold_Reflected_Vpclmul(AData: PByte; ALength: UInt32; -// AState: Pointer; AConstants: Pointer): UInt64; -// -// Register mapping (MS x64 ABI after prologue): -// rcx = AData, edx = ALength (>= 16), r8 = AState, r9 = AConstants -// AState: pointer to the initial CRC (reflected) as one UInt64. +// AVX2 + VPCLMULQDQ implementation of CRC folding + Barrett reduction for +// reflected (LSB-first) CRCs with width 8..64. CRC-64 uses a special +// Barrett path for the 65-bit G. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = AData, edx = ALength +// (>= 16), r8 = AState, r9 = AConstants. +// AState: pointer to the initial CRC (reflected) as one UInt64. Returns +// the final CRC in rax. // AConstants layout (TCRCFoldConstants): -// [0..15] = Fold_4x128 (stride 512) -// [16..31] = Fold_1x128 (stride 128) -// [32..47] = Barrett -// [48..63] = Fold_8x128 (stride 1024) -// [64..79] = BswapMask (unused by this path) -// [80..87] = CrcBits -// Returns: final CRC in RAX. -// -// Reference: zlib-ng crc32_pclmulqdq_tpl.h (256-bit VPCLMULQDQ path) -// and Linux kernel crc-pclmul-template.S by Eric Biggers (Barrett reduction). -// -// VEX byte layout reference: -// 2-byte: C5 [R.vvvv.L.pp] -// 3-byte: C4 [R.X.B.mmmmm] [W.vvvv.L.pp] +// [0..15] = Fold_4x128 (stride 512) [48..63] = Fold_8x128 (stride 1024) +// [16..31] = Fold_1x128 (stride 128) [64..79] = BswapMask (unused here) +// [32..47] = Barrett [80..87] = CrcBits +// AVX2/VPCLMULQDQ instructions are db-encoded for broad assembler +// compatibility. Encoding notes (VEX byte layout): +// 2-byte: C5 [R.vvvv.L.pp] 3-byte: C4 [R.X.B.mmmmm] [W.vvvv.L.pp] +// Reference: zlib-ng crc32_pclmulqdq_tpl.h (256-bit VPCLMULQDQ path) and +// Linux kernel crc-pclmul-template.S by Eric Biggers (Barrett reduction). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Common/HlpSimdProc4Begin_aarch64.inc b/HashLib/src/Include/Simd/Common/HlpSimdProc4Begin_aarch64.inc index ec05207..4e560de 100644 --- a/HashLib/src/Include/Simd/Common/HlpSimdProc4Begin_aarch64.inc +++ b/HashLib/src/Include/Simd/Common/HlpSimdProc4Begin_aarch64.inc @@ -1,7 +1,7 @@ // Shared SIMD procedure prologue for 4-parameter assembly functions (AArch64). // After inclusion: x0 = param1, x1 = param2, w2 = param3, x3 = param4 (AAPCS64). // Matches the x86 SimdProc4/5 signature order: (AState, AData, ANumBlocks, -// AConstants[, …]); AAPCS64 already delivers the params in x0,x1,w2,x3, so no +// AConstants[, ...]); AAPCS64 already delivers the params in x0,x1,w2,x3, so no // register remapping (unlike the x86 SysV/MS variants) is needed. // Usage: // procedure MyProc(P1, P2, P3: Pointer; P4: Pointer); diff --git a/HashLib/src/Include/Simd/Common/HlpSimdProc5Begin_i386.inc b/HashLib/src/Include/Simd/Common/HlpSimdProc5Begin_i386.inc index c1d109e..a5e06bc 100644 --- a/HashLib/src/Include/Simd/Common/HlpSimdProc5Begin_i386.inc +++ b/HashLib/src/Include/Simd/Common/HlpSimdProc5Begin_i386.inc @@ -3,7 +3,7 @@ // (i386 register convention). // FPC: param4 and param5 are at [esp+20] and [esp+16] after push EBX/ESI/EDI (see asm). // Delphi Win32: first 3 params in EAX/EDX/ECX; param4 at [ebp+12], param5 at [ebp+8]. -// Callee-saved EBX, ESI, EDI — epilogue must pop EDI, ESI, EBX. +// Callee-saved EBX, ESI, EDI - epilogue must pop EDI, ESI, EBX. // Usage: // procedure MyProc(P1, P2: Pointer; P3, P4: Int32; P5: Pointer); // {$I HlpSimdProc5Begin_i386.inc} diff --git a/HashLib/src/Include/Simd/Common/HlpSimdProc6Begin_i386.inc b/HashLib/src/Include/Simd/Common/HlpSimdProc6Begin_i386.inc index 229122b..769135b 100644 --- a/HashLib/src/Include/Simd/Common/HlpSimdProc6Begin_i386.inc +++ b/HashLib/src/Include/Simd/Common/HlpSimdProc6Begin_i386.inc @@ -4,7 +4,7 @@ // FPC: param4 at [esp+28]; param5 at [esp+20]/[esp+24]; param6 at [esp+16] after push EBX/ESI/EDI (see asm). // Delphi Win32: first 3 params in EAX/EDX/ECX; param4 at [ebp+20], // param5 at [ebp+12]/[ebp+16], param6 at [ebp+8]. -// Callee-saved EBX, ESI, EDI — epilogue must pop EDI, ESI, EBX; SIMD bodies may adjust ESP for locals. +// Callee-saved EBX, ESI, EDI - epilogue must pop EDI, ESI, EBX; SIMD bodies may adjust ESP for locals. // Usage: // procedure MyProc(P1, P2, P3: Pointer; P4: Int32; P5: UInt64; P6: UInt32); // {$I HlpSimdProc6Begin_i386.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc index 4adc220..155cff1 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx2_x86_64.inc @@ -1,17 +1,18 @@ -// SHA-1 AVX2 two-block implementation (VEX-256). Two message blocks are -// scheduled together in 256-bit lanes and the 80 rounds are interleaved with -// the SIMD schedule, so the vector and integer units run in parallel. AVX2 and -// BMI (rorx/andn/shlx) instructions are db-encoded for broad assembler -// compatibility (every AVX2 CPU also provides BMI). +// AVX2 implementation of SHA-1 compress (VEX-256, two-block). Two message +// blocks are scheduled together in 256-bit lanes and the 80 rounds are +// interleaved with the SIMD schedule, so the vector and integer units run +// in parallel. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = K_SHA1_Doubled ptr (the four SHA-1 round +// constants each replicated across 256 bits, then the byte-swap mask and +// a reverse mask; the masks are read unaligned, so the const needs no +// special alignment). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 +// holds the caller rsp across the kernel for the unwind. +// AVX2 and BMI (rorx/andn/shlx) instructions are db-encoded for broad +// assembler compatibility (every AVX2 CPU also provides BMI). // Reference: OpenSSL CRYPTOGAMS sha1-x86_64.pl (AVX2 kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = K_SHA1_Doubled ptr (the four SHA-1 round constants each -// replicated across 256 bits, then the byte-swap mask and a reverse mask; see -// K_SHA1_Doubled). The masks are read unaligned, so the const needs no alignment. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 -// holds the caller rsp across the kernel for the unwind. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc index 9a98708..57ffd5a 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressAvx_i386.inc @@ -1,18 +1,18 @@ -// SHA-1 AVX SIMD-schedule implementation (IA-32). VEX-128 (AVX1) -// instructions only - there is no i386 AVX2 SHA-1 upstream. The 3-operand -// VEX forms eliminate the SSSE3 kernel's register-copy -// movdqa traffic in the interleaved message schedule. All VEX instructions -// are db-encoded for broad assembler compatibility. -// The four round constants and the byte-swap mask are read from +// AVX (VEX-128) implementation of SHA-1 compress (SIMD schedule; IA-32); +// the Avx name states the ISA requirement: VEX-128 encodings only - there +// is no i386 AVX2 SHA-1 upstream. The 3-operand VEX forms eliminate the +// SSSE3 kernel's register-copy movdqa traffic in the interleaved message +// schedule. The four round constants and the byte-swap mask are read from // K_SHA1_Doubled at a 32-byte stride (VEX memory operands are read -// unaligned, so the Pascal const needs no special alignment) and spilled to -// the local frame like the original; the original's PIC table setup and +// unaligned, so the Pascal const needs no special alignment) and spilled +// to the local frame like the original; the original's PIC table setup and // stack-argument reads are replaced by the shared-prologue registers. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = K_SHA1_Doubled ptr. +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here, giving the +// 4-deep frame the original epilogue unwinds via its saved-esp slot. +// AVX instructions are db-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha1-586.pl (AVX function). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, -// edi = numblocks, eax = K_SHA1_Doubled ptr. HlpSimdProc4Begin pushes -// ebx/esi/edi; ebp is pushed here, giving the 4-deep frame the original -// epilogue unwinds via its saved-esp slot. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressCryptoExt_aarch64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressCryptoExt_aarch64.inc index 7e98113..253edcf 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressCryptoExt_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressCryptoExt_aarch64.inc @@ -1,9 +1,7 @@ -// SHA-1 AArch64 FEAT_SHA1 implementation. -// Expects AAPCS64: x0 = state ptr (5 x UInt32), x1 = data ptr, -// w2 = numblocks, x3 = K_SHA1 ptr (16 UInt32: each round constant x4 lanes). -// Leaf nostackframe; caller-saved GPR/vector only. -// Reference: OpenSSL CRYPTOGAMS sha1-armv8.S. -// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// CryptoExt (FEAT_SHA1) implementation of SHA-1 compress. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (5 x UInt32), +// x1 = data ptr, w2 = numblocks, x3 = K_SHA1 ptr (16 UInt32: each round +// constant x4 lanes). // Register map: // v0 = ABCD working state // v1.s[0] = E working state (single lane; sha1c/p/m consume it as a scalar) @@ -12,6 +10,9 @@ // v16-v19 = K round constants (K_00_19, K_20_39, K_40_59, K_60_79) // v20, v21 = W+K per round // v22 = saved ABCD for the final add +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha1-armv8.S. cbz w2, .Lcryptoext_sha1_done .long 0x6e211c21 // eor v1.16b, v1.16b, v1.16b diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc index e5617ff..cfad326 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressGpr_aarch64.inc @@ -1,11 +1,11 @@ -// SHA-1 pure-GPR implementation (AArch64) for cores without the SHA-1 -// crypto extension; the Gpr name states the ISA requirement: none beyond -// base AArch64. Serial SHA maps better onto the 31 GPRs than onto NEON -// lanes (single dependency chain, 1-op ror, rotate-folded eor operands). -// The four round constants are materialized as movz/movk immediates - no -// K table is read. -// Expects AAPCS64 (after HlpSimdProc3Begin_aarch64): x0 = state ptr -// (5 x UInt32), x1 = data ptr, w2 = numblocks. +// Gpr implementation of SHA-1 compress (AArch64) for cores without the +// SHA-1 crypto extension; the Gpr name states the ISA requirement: none +// beyond base AArch64. Serial SHA maps better onto the 31 GPRs than onto +// NEON lanes (single dependency chain, 1-op ror, rotate-folded eor +// operands). The four round constants are materialized as movz/movk +// immediates - no K table is read. +// ABI (after HlpSimdProc3Begin_aarch64.inc): x0 = state ptr (5 x UInt32), +// x1 = data ptr, w2 = numblocks. // Frame: 96-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved). // AArch64 instructions are .long-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha1-armv8.pl (sha1_block_data_order, the diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc index 8439c38..769191e 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_i386.inc @@ -1,16 +1,17 @@ -// SHA-1 SHA-NI implementation (IA-32; Intel SHA Extensions work in 32-bit -// mode). The twenty sha1rnds4 steps carry their round constants as -// immediates; the only table read is the 16-byte flip mask, taken from -// K_SHA1_Doubled at +160 (byte-identical to the original's .LK_XX_XX+80; read -// unaligned - Pascal consts have no alignment guarantee). SHA-NI and shuffle -// instructions are db-encoded for broad assembler compatibility. The -// original's PIC table setup and stack-argument reads are replaced by the -// shared-prologue registers. +// SHA-NI implementation of SHA-1 compress (IA-32; Intel SHA Extensions +// work in 32-bit mode). The twenty sha1rnds4 steps carry their round +// constants as immediates; the only table read is the 16-byte flip mask, +// taken from K_SHA1_Doubled at +160 (byte-identical to the original's +// .LK_XX_XX+80; read unaligned - Pascal consts have no alignment +// guarantee). The original's PIC table setup and stack-argument reads are +// replaced by the shared-prologue registers. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = K_SHA1_Doubled ptr. +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here, giving the +// 4-deep frame the original epilogue unwinds via its saved-esp register. +// SHA-NI and shuffle instructions are db-encoded for broad assembler +// compatibility. // Reference: OpenSSL CRYPTOGAMS sha1-586.pl (shaext function). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, -// edi = numblocks, eax = K_SHA1_Doubled ptr. HlpSimdProc4Begin pushes -// ebx/esi/edi; ebp is pushed here, giving the 4-deep frame the original -// epilogue unwinds via its saved-esp register. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc index 8c3376f..8dcd1ba 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressShaNi_x86_64.inc @@ -1,38 +1,28 @@ -// SHA-1 SHA-NI implementation (Intel SHA Extensions). The 20 sha1rnds4 -// groups run with the message schedule (sha1msg1/sha1msg2/sha1nexte) interleaved. -// The input is byte-swapped with a single pshufb against a full-reverse mask -// (byte-swap and dword-reverse folded into one mask, loaded once into xmm3), so -// no per-word pshufd is needed. The next block's message loads are software- -// pipelined into rounds 64-79 and the data pointer is advanced branchlessly -// (cmovnz). +// SHA-NI implementation of SHA-1 compress (Intel SHA Extensions). The 20 +// sha1rnds4 groups run with the message schedule (sha1msg1/sha1msg2/ +// sha1nexte) interleaved. The input is byte-swapped with a single pshufb +// against a full-reverse mask (byte-swap and dword-reverse folded into one +// mask, loaded once into xmm3), so no per-word pshufd is needed. The next +// block's message loads are software-pipelined into rounds 64-79 and the +// data pointer is advanced branchlessly (cmovnz). +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = round-constant ptr (unused - sha1rnds4 has the +// round constants built in), r10 = byte-swap mask ptr (16 bytes; see +// BSWAP32_MASK, matching OpenSSL K_XX_XX+0xa0). +// Register map (identical to OpenSSL): xmm0 = ABCD state, xmm1 = E, +// xmm2 = E' (ping-pong), xmm3 = byte-swap mask (loaded once), +// xmm4-xmm7 = MSG0-MSG3, xmm8 = ABCD_SAVE, xmm9 = E_SAVE. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); the kernel itself uses only volatile GPRs +// (rcx/rdx/r8-r11). +// SHA-NI instructions are db-encoded for broad assembler compatibility. +// Encoding notes: +// sha1rnds4 dst, src, imm = $0F $3A $CC +// sha1nexte dst, src = $0F $38 $C8 +// sha1msg1 dst, src = $0F $38 $C9 +// sha1msg2 dst, src = $0F $38 $CA +// pshufb dst, src = $66 $0F $38 $00 // Reference: OpenSSL CRYPTOGAMS x86_64 sha1_block_data_order_shaext. -// -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = round-constant ptr (unused - sha1rnds4 has the round -// constants built in), r10 = byte-swap mask ptr (16 bytes; see BSWAP32_MASK, -// matching OpenSSL K_XX_XX+0xa0). -// -// SHA-NI instructions, db-encoded for assembler compatibility: -// sha1rnds4 dst, src, imm = $0F $3A $CC -// sha1nexte dst, src = $0F $38 $C8 -// sha1msg1 dst, src = $0F $38 $C9 -// sha1msg2 dst, src = $0F $38 $CA -// pshufb dst, src = $66 $0F $38 $00 -// -// Register map (identical to OpenSSL): -// xmm0 = ABCD state -// xmm1 = E -// xmm2 = E' (ping-pong E register) -// xmm3 = byte-swap mask (loaded once) -// xmm4 = MSG0 -// xmm5 = MSG1 -// xmm6 = MSG2 -// xmm7 = MSG3 -// xmm8 = ABCD_SAVE -// xmm9 = E_SAVE -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); the kernel itself uses only volatile GPRs (rcx/rdx/r8-r11). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc index 03cc2d7..420c4be 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_i386.inc @@ -1,15 +1,15 @@ -// SHA-1 SSE2 SIMD-schedule implementation (IA-32). The message schedule runs -// in SSE2 (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression -// rounds. The original's only SSSE3-only op is the pshufb input byte-swap, -// emulated in SSE2 as psrlw/psllw/por + pshuflw/pshufhw (the freed -// byte-swap-mask register xmm6 is the scratch); the W-schedule uses no -// palignr. +// SSE2 implementation of SHA-1 compress (SIMD schedule; IA-32). The message +// schedule runs in SSE2 (pxor/pshufd/psrldq/pslldq) interleaved with the +// GPR compression rounds. The original's only SSSE3-only op is the pshufb +// input byte-swap, emulated in SSE2 as psrlw/psllw/por + pshuflw/pshufhw +// (the freed byte-swap-mask register xmm6 is the scratch); the W-schedule +// uses no palignr. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = doubled-K_SHA1 ptr (read at a 32-byte stride so +// the duplicated halves are skipped; see K_SHA1_Doubled). +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K +// pointer, then reused as the data pointer and for the state writeback. // Reference: OpenSSL CRYPTOGAMS sha1-586.pl (SSSE3 kernel). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, -// eax = doubled-K_SHA1 ptr (read at a 32-byte stride so the duplicated halves -// are skipped; see K_SHA1_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is -// pushed here as the K pointer, then reused as the data pointer and for the -// state writeback. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc index c997e8b..e44db04 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSse2_x86_64.inc @@ -1,17 +1,18 @@ -// SHA-1 SSE2 SIMD-schedule implementation. The message schedule runs in SSE2 -// (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression rounds, so the -// vector and integer units run in parallel. The original's only SSSE3-only op here -// is the pshufb input byte-swap, which is emulated in SSE2 (psrlw/psllw/por + -// pshuflw/pshufhw; xmm12 is a free scratch); the W-schedule uses no palignr. The -// appended masks go unused - the byte-swap is computed, not shuffled. +// SSE2 implementation of SHA-1 compress (SIMD schedule). The message +// schedule runs in SSE2 (pxor/pshufd/psrldq/pslldq) interleaved with the +// GPR compression rounds, so the vector and integer units run in parallel. +// The original's only SSSE3-only op here is the pshufb input byte-swap, +// emulated in SSE2 (psrlw/psllw/por + pshuflw/pshufhw; xmm12 is a free +// scratch); the W-schedule uses no palignr. The appended masks go unused - +// the byte-swap is computed, not shuffled. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K_SHA1 ptr (read 128-bit at a 32-byte +// stride, r14 = K + 64, so the duplicated halves are skipped; see +// K_SHA1_Doubled). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 +// holds the caller rsp across the kernel for the unwind. // Reference: OpenSSL CRYPTOGAMS sha1-x86_64.pl (SSSE3 kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = doubled-K_SHA1 ptr (read 128-bit at a 32-byte stride, -// r14 = K + 64, so the duplicated halves are skipped; see K_SHA1_Doubled). -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 -// holds the caller rsp across the kernel for the unwind. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc index 493837a..ff65a72 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_i386.inc @@ -1,15 +1,15 @@ -// SHA-1 SSSE3 SIMD-schedule implementation (IA-32); SSE2 sibling: -// SHA1CompressSse2_i386.inc. -// The message schedule runs in SIMD (pxor/pshufd/psrldq/pslldq) interleaved -// with the GPR compression rounds. Unlike the SSE2 sibling the input -// byte-swaps are real pshufb (db-encoded for broad assembler compatibility) -// against the mask kept resident in xmm6; the W-schedule uses no palignr. +// SSSE3 implementation of SHA-1 compress (SIMD schedule; IA-32); SSE2 +// sibling: SHA1CompressSse2_i386.inc. The message schedule runs in SIMD +// (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression rounds. +// Unlike the SSE2 sibling the input byte-swaps are real pshufb against the +// mask kept resident in xmm6; the W-schedule uses no palignr. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = doubled-K_SHA1 ptr (read at a 32-byte stride so +// the duplicated halves are skipped; see K_SHA1_Doubled). +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K +// pointer, then reused as the data pointer and for the state writeback. +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha1-586.pl (SSSE3 kernel). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, -// eax = doubled-K_SHA1 ptr (read at a 32-byte stride so the duplicated halves -// are skipped; see K_SHA1_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is -// pushed here as the K pointer, then reused as the data pointer and for the -// state writeback. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc index a7ecbc5..6cb779a 100644 --- a/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA1/SHA1CompressSsse3_x86_64.inc @@ -1,18 +1,18 @@ -// SHA-1 SSSE3 SIMD-schedule implementation; SSE2 sibling: -// SHA1CompressSse2_x86_64.inc. -// The message schedule runs in SIMD (pxor/pshufd/psrldq/pslldq) interleaved -// with the GPR compression rounds, so the vector and integer units run in -// parallel. Unlike the SSE2 sibling the input byte-swaps are real pshufb -// (db-encoded for broad assembler compatibility) against the mask kept -// resident in xmm12 (K_SHA1_Doubled + 128); the W-schedule uses no palignr. +// SSSE3 implementation of SHA-1 compress (SIMD schedule); SSE2 sibling: +// SHA1CompressSse2_x86_64.inc. The message schedule runs in SIMD +// (pxor/pshufd/psrldq/pslldq) interleaved with the GPR compression rounds, +// so the vector and integer units run in parallel. Unlike the SSE2 sibling +// the input byte-swaps are real pshufb against the mask kept resident in +// xmm12 (K_SHA1_Doubled + 128); the W-schedule uses no palignr. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K_SHA1 ptr (read 128-bit at a 32-byte +// stride, r14 = K + 64, so the duplicated halves are skipped; see +// K_SHA1_Doubled). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 +// holds the caller rsp across the kernel for the unwind. +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha1-x86_64.pl (SSSE3 kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = doubled-K_SHA1 ptr (read 128-bit at a 32-byte stride, -// r14 = K + 64, so the duplicated halves are skipped; see K_SHA1_Doubled). -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r14 in the local frame; r11 -// holds the caller rsp across the kernel for the unwind. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc index afafd99..1ab6c89 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx2_x86_64.inc @@ -1,19 +1,18 @@ -// SHA-256 AVX2 two-block implementation (VEX-256). Two message blocks are -// scheduled together in 256-bit lanes; the compression rounds stay serial (as -// SHA-256 requires), so scheduling two blocks at once is what makes this faster -// than the single-block AVX path. AVX2 and BMI2 (rorx/andn) instructions are -// db-encoded for broad assembler compatibility (every AVX2 CPU also provides -// BMI2). -// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX2 kernel; that generator -// emits both the SHA-256 and the SHA-512 kernels). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = doubled-K256 ptr (each 128-bit K256 quadruple stored -// twice so one table feeds both 256-bit lanes, with the byte-swap and two -// message-schedule masks appended; see K256_Doubled). The masks are read -// unaligned, so the Pascal const needs no special alignment. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// AVX2 implementation of SHA-256 compress (VEX-256, two-block). Two message +// blocks are scheduled together in 256-bit lanes; the compression rounds +// stay serial (as SHA-256 requires), so scheduling two blocks at once is +// what makes this faster than the single-block AVX path. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K256 ptr (each 128-bit K256 quadruple +// stored twice so one table feeds both 256-bit lanes, with the byte-swap +// and two message-schedule masks appended; see K256_Doubled; the masks +// are read unaligned, so the Pascal const needs no special alignment). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// AVX2 and BMI2 (rorx/andn) instructions are db-encoded for broad assembler +// compatibility (every AVX2 CPU also provides BMI2). +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX2 kernel; that +// generator emits both the SHA-256 and the SHA-512 kernels). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc index ffce73e..346c68c 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc @@ -1,17 +1,18 @@ -// SHA-256 AVX SIMD-schedule implementation (IA-32). VEX-128 (AVX1) -// instructions only - there is no i386 AVX2 SHA-256 upstream. The 3-operand -// VEX forms eliminate the SSSE3 kernel's register-copy -// movdqa traffic; the byte-swap mask stays resident in xmm7. All VEX -// instructions are db-encoded for broad assembler compatibility. -// K256 is read from K256_Doubled at a 32-byte stride (the walk and offsets -// are doubled relative to the original; VEX memory operands are read -// unaligned, so the Pascal const needs no special alignment). +// AVX (VEX-128) implementation of SHA-256 compress (SIMD schedule; IA-32); +// the Avx name states the ISA requirement: VEX-128 encodings only - there +// is no i386 AVX2 SHA-256 upstream. The 3-operand VEX forms eliminate the +// SSSE3 kernel's register-copy movdqa traffic; the byte-swap mask stays +// resident in xmm7. K256 is read from K256_Doubled at a 32-byte stride +// (the walk and offsets are doubled relative to the original; VEX memory +// operands are read unaligned, so the Pascal const needs no special +// alignment). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = K256_Doubled ptr. +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K walk +// pointer. Frame and slot layout (ctx@96/data@100/end@104/savedsp@108) +// mirror the SSE2/SSSE3 siblings. +// AVX instructions are db-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha256-586.pl (AVX section). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, -// edi = numblocks, eax = K256_Doubled ptr. HlpSimdProc4Begin pushes -// ebx/esi/edi; ebp is pushed here as the K walk pointer. Frame and slot -// layout (ctx@96/data@100/end@104/savedsp@108) mirror the SSE2/SSSE3 -// siblings. push ebp mov ebp, eax @@ -27,7 +28,7 @@ mov dword ptr [esp + $4], edi mov dword ptr [esp + $8], eax mov dword ptr [esp + $C], ebx - lea esp, [esp - $60] + sub esp, $60 db $C5, $FC, $77 // vzeroall mov eax, dword ptr [esi] mov ebx, dword ptr [esi + $4] diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressCryptoExt_aarch64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressCryptoExt_aarch64.inc index 4148f1f..5f91033 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressCryptoExt_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressCryptoExt_aarch64.inc @@ -1,16 +1,16 @@ -// SHA-256 AArch64 FEAT_SHA256 implementation. -// Expects AAPCS64: x0 = state ptr (8 x UInt32), x1 = data ptr, -// w2 = numblocks, x3 = K256 ptr (64 UInt32 round constants). -// Leaf nostackframe; caller-saved GPR/vector only. -// K pointer rewound each block (sub x3, #240) after post-index loads. -// Reference: OpenSSL CRYPTOGAMS sha256-armv8.S. -// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// CryptoExt (FEAT_SHA256) implementation of SHA-256 compress. +// The K pointer is rewound each block (sub x3, #240) after post-index loads. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (8 x UInt32), +// x1 = data ptr, w2 = numblocks, x3 = K256 ptr (64 UInt32 round constants). // Register map: // v0, v1 = working state (ABCD, EFGH) // v2 = sha256h2 temp (copy of v0 before each h/h2 pair) // v4-v7 = message schedule (W) // v16, v17 = W+K for sha256h / sha256h2 (ping-pong) // v18, v19 = saved state (ABCD, EFGH) for the final add +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha256-armv8.S. cbz w2, .Lcryptoext_sha256_done .long 0xad400400 // ldp q0, q1, [x0] diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc index 7217099..2a111ff 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressGpr_aarch64.inc @@ -1,16 +1,17 @@ -// SHA-256 pure-GPR implementation (AArch64) for cores without the SHA-256 -// crypto extension; the Gpr name states the ISA requirement: none beyond -// base AArch64. Serial SHA maps better onto the 31 GPRs than onto NEON -// lanes (single dependency chain, 1-op ror, rotate-folded eor operands). -// Expects AAPCS64 (after HlpSimdProc4Begin_aarch64): x0 = state ptr -// (8 x UInt32), x1 = data ptr, w2 = numblocks, x3 = K256_Gpr ptr. -// K256_Gpr carries the 64 round constants PLUS a zero terminator word - the -// message-schedule loop ends when the loaded K word is zero (cbnz), exactly -// like the original's sentinel-terminated table; a plain K256 const cannot -// drive this loop. -// Frame: 128-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved) + 16 bytes -// schedule scratch; x30 (LR) is repurposed as the K walk pointer between the -// save and the restore, as in the original. +// Gpr implementation of SHA-256 compress (AArch64) for cores without the +// SHA-256 crypto extension; the Gpr name states the ISA requirement: none +// beyond base AArch64. Serial SHA maps better onto the 31 GPRs than onto +// NEON lanes (single dependency chain, 1-op ror, rotate-folded eor +// operands). +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (8 x UInt32), +// x1 = data ptr, w2 = numblocks, x3 = K256_Gpr ptr. +// K256_Gpr carries the 64 round constants PLUS a zero terminator word - +// the message-schedule loop ends when the loaded K word is zero (cbnz), +// exactly like the original's sentinel-terminated table; a plain K256 +// const cannot drive this loop. +// Frame: 128-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved) + 16 +// bytes schedule scratch; x30 (LR) is repurposed as the K walk pointer +// between the save and the restore, as in the original. // AArch64 instructions are .long-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha512-armv8.pl (sha256_block_data_order, // the plain path; the generator emits both SHA-256 and SHA-512). diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc index 41469e5..507a989 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_i386.inc @@ -1,15 +1,17 @@ -// SHA-256 SHA-NI implementation (IA-32; Intel SHA Extensions work in 32-bit -// mode), with the unified function's common prologue reproduced by the same -// proven head as the SSE2/SSSE3/AVX siblings (slots ctx/data/end/savedsp; -// the section's sub $32 shifts them to 32/36/40/44). K256 is read from -// K256_Doubled at a 32-byte stride (bias and offsets doubled; read unaligned -// - Pascal consts have no alignment guarantee); the byte-swap mask sits at -// the doubled +512 (= biased +256). SHA-NI and shuffle instructions are -// db-encoded for broad assembler compatibility. +// SHA-NI implementation of SHA-256 compress (IA-32; Intel SHA Extensions +// work in 32-bit mode), with the unified function's common prologue +// reproduced by the same proven head as the SSE2/SSSE3/AVX siblings (slots +// ctx/data/end/savedsp; the section's sub $32 shifts them to 32/36/40/44). +// K256 is read from K256_Doubled at a 32-byte stride (bias and offsets +// doubled; read unaligned - Pascal consts have no alignment guarantee); the +// byte-swap mask sits at the doubled +512 (= biased +256). +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = K256_Doubled ptr. +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K +// pointer. +// SHA-NI and shuffle instructions are db-encoded for broad assembler +// compatibility. // Reference: OpenSSL CRYPTOGAMS sha256-586.pl (shaext section). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, -// edi = numblocks, eax = K256_Doubled ptr. HlpSimdProc4Begin pushes -// ebx/esi/edi; ebp is pushed here as the K pointer. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc index 5ed2a80..7fc621b 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressShaNi_x86_64.inc @@ -1,34 +1,25 @@ -// SHA-256 SHA-NI implementation (Intel SHA Extensions). Each 4-round -// group is two sha256rnds2 with the message schedule (sha256msg1/sha256msg2 + -// palignr) interleaved. The input is byte-swapped with pshufb against -// BSWAP32_MASK (a plain per-dword swap - SHA-256 consumes its words in natural -// order, so no dword reversal is needed). +// SHA-NI implementation of SHA-256 compress (Intel SHA Extensions). Each +// 4-round group is two sha256rnds2 with the message schedule (sha256msg1/ +// sha256msg2 + palignr) interleaved. The input is byte-swapped with pshufb +// against BSWAP32_MASK (a plain per-dword swap - SHA-256 consumes its words +// in natural order, so no dword reversal is needed). +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = K256 ptr (64 UInt32 round constants), +// r10 = byte-swap mask ptr (16 bytes; see BSWAP32_MASK). +// Register map: xmm0 = MSG+K temp for sha256rnds2 (implicit operand), +// xmm1 = STATE0 (ABEF in SHA-NI format), xmm2 = STATE1 (CDGH), +// xmm3-xmm6 = MSG0-MSG3, xmm7 = palignr scratch / byte-swap mask during +// load, xmm8 = ABEF_SAVE, xmm9 = CDGH_SAVE. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); the kernel itself uses only volatile GPRs +// (rcx/rdx/r8-r10). +// SHA-NI instructions are db-encoded for broad assembler compatibility. +// Encoding notes: +// sha256rnds2 dst, src = $0F $38 $CB (implicit xmm0) +// sha256msg1 dst, src = $0F $38 $CC +// sha256msg2 dst, src = $0F $38 $CD +// pshufb dst, src = $66 $0F $38 $00 // Reference: OpenSSL CRYPTOGAMS x86_64 sha256_block_data_order_shaext. -// -// Expects MS x64 ABI (after HlpSimdProc5Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = K256 ptr (64 UInt32 round constants), r10 = byte-swap -// mask ptr (16 bytes; see BSWAP32_MASK). -// -// SHA-NI instructions, db-encoded for assembler compatibility: -// sha256rnds2 dst, src = $0F $38 $CB (implicit xmm0) -// sha256msg1 dst, src = $0F $38 $CC -// sha256msg2 dst, src = $0F $38 $CD -// pshufb dst, src = $66 $0F $38 $00 -// -// Register map: -// xmm0 = MSG+K temp for sha256rnds2 (implicit operand) -// xmm1 = STATE0 (ABEF in SHA-NI format) -// xmm2 = STATE1 (CDGH in SHA-NI format) -// xmm3 = MSG0 -// xmm4 = MSG1 -// xmm5 = MSG2 -// xmm6 = MSG3 -// xmm7 = palignr scratch / byte-swap mask during load -// xmm8 = ABEF_SAVE -// xmm9 = CDGH_SAVE -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); the kernel itself uses only volatile GPRs (rcx/rdx/r8-r10). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc index 9425610..7632cfb 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc @@ -1,14 +1,16 @@ -// SHA-256 SSE2 SIMD-schedule implementation (IA-32). The message schedule runs -// in SSE2 (paddd/psrld/pslld/pxor/pshufd/psrldq/pslldq) interleaved with the GPR -// compression rounds; the 32-bit state lives in eax/ebx/ecx plus the local frame -// (IA-32 has too few GPRs to keep all eight in registers). The original's two -// SSSE3-only ops are emulated in SSE2: the pshufb dword byte-swap becomes -// psrlw/psllw/por + pshuflw/pshufhw, and palignr becomes psrldq/pslldq/por. +// SSE2 implementation of SHA-256 compress (SIMD schedule; IA-32). The +// message schedule runs in SSE2 (paddd/psrld/pslld/pxor/pshufd/psrldq/ +// pslldq) interleaved with the GPR compression rounds; the 32-bit state +// lives in eax/ebx/ecx plus the local frame (IA-32 has too few GPRs to keep +// all eight in registers). The original's two SSSE3-only ops are emulated +// in SSE2: the pshufb dword byte-swap becomes psrlw/psllw/por + +// pshuflw/pshufhw, and palignr becomes psrldq/pslldq/por. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = doubled-K256 ptr (read at a 32-byte stride so +// the duplicated halves are skipped; see K256_Doubled). +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K256 +// walk pointer; state loads into eax/ebx/ecx and the frame. // Reference: OpenSSL CRYPTOGAMS sha256-586.pl (SSSE3 kernel). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, -// eax = doubled-K256 ptr (read at a 32-byte stride so the duplicated halves are -// skipped; see K256_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is pushed -// here as the K256 walk pointer; state loads into eax/ebx/ecx and the frame. push ebp mov ebp, eax @@ -24,7 +26,7 @@ mov dword [esp + $4], edi mov dword [esp + $8], eax mov dword [esp + $C], ebx - lea esp, [esp - $60] + sub esp, $60 mov eax, dword [esi] mov ebx, dword [esi + $4] mov ecx, dword [esi + $8] diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc index 0374ce6..01ce286 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_x86_64.inc @@ -1,17 +1,16 @@ -// SHA-256 SSE2 SIMD-schedule implementation. The message schedule runs in -// SSE2 (paddd/psrld/pslld/pxor/pshufd) interleaved with the GPR compression -// rounds, so the vector and integer units run in parallel. The original's two -// SSSE3-only ops are emulated in SSE2: the pshufb dword byte-swap becomes -// psrlw/psllw/por + pshuflw/pshufhw, and palignr becomes psrldq/pslldq/por -// (xmm8 is a free scratch). -// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (SHA-256 SSSE3 kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, +// SSE2 implementation of SHA-256 compress (SIMD schedule). The message +// schedule runs in SSE2 (paddd/psrld/pslld/pxor/pshufd) interleaved with +// the GPR compression rounds, so the vector and integer units run in +// parallel. The original's two SSSE3-only ops are emulated in SSE2: the +// pshufb dword byte-swap becomes psrlw/psllw/por + pshuflw/pshufhw, and +// palignr becomes psrldq/pslldq/por (xmm8 is a free scratch). +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K256 ptr (read at a 32-byte stride so the -// duplicated halves are skipped; see K256_Doubled). No byte-swap mask table is -// needed - the swap is computed, not shuffled. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// duplicated halves are skipped; see K256_Doubled). No byte-swap mask +// table is needed - the swap is computed, not shuffled. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (SHA-256 SSSE3 kernel). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc index 426a494..d1b2b50 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc @@ -1,16 +1,18 @@ -// SHA-256 SSSE3 SIMD-schedule implementation (IA-32); SSE2 sibling: -// SHA256CompressSse2_i386.inc. -// The message schedule runs in SIMD interleaved with the GPR compression -// rounds; the 32-bit state lives in eax/ebx/ecx plus the local frame (IA-32 -// has too few GPRs to keep all eight in registers). Unlike the SSE2 sibling, -// the two SSSE3 ops are the real instructions (db-encoded for broad assembler -// compatibility): pshufb dword byte-swap against the mask kept in xmm7 for -// the block head, and palignr $4 in the schedule. +// SSSE3 implementation of SHA-256 compress (SIMD schedule; IA-32); SSE2 +// sibling: SHA256CompressSse2_i386.inc. The message schedule runs in SIMD +// interleaved with the GPR compression rounds; the 32-bit state lives in +// eax/ebx/ecx plus the local frame (IA-32 has too few GPRs to keep all +// eight in registers). Unlike the SSE2 sibling, the two SSSE3 ops are the +// real instructions: pshufb dword byte-swap against the mask kept in xmm7 +// for the block head, and palignr $4 in the schedule. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = doubled-K256 ptr (read at a 32-byte stride so +// the duplicated halves are skipped; see K256_Doubled). +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K256 +// walk pointer; state loads into eax/ebx/ecx and the frame. +// pshufb/palignr instructions are db-encoded for broad assembler +// compatibility. // Reference: OpenSSL CRYPTOGAMS sha256-586.pl (SSSE3 kernel). -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, -// eax = doubled-K256 ptr (read at a 32-byte stride so the duplicated halves are -// skipped; see K256_Doubled). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is pushed -// here as the K256 walk pointer; state loads into eax/ebx/ecx and the frame. push ebp mov ebp, eax @@ -26,7 +28,7 @@ mov dword [esp + $4], edi mov dword [esp + $8], eax mov dword [esp + $C], ebx - lea esp, [esp - $60] + sub esp, $60 mov eax, dword [esi] mov ebx, dword [esi + $4] mov ecx, dword [esi + $8] diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc index 80d7d19..2ce26d6 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_x86_64.inc @@ -1,17 +1,18 @@ -// SHA-256 SSSE3 SIMD-schedule implementation; SSE2 sibling: +// SSSE3 implementation of SHA-256 compress (SIMD schedule); SSE2 sibling: // SHA256CompressSse2_x86_64.inc. The message schedule runs in SIMD // (paddd/psrld/pslld/pxor/pshufd) interleaved with the GPR compression // rounds, so the vector and integer units run in parallel. Unlike the SSE2 -// sibling, the two SSSE3 ops are the real instructions (db-encoded for broad -// assembler compatibility): pshufb dword byte-swap against the mask kept in -// xmm8 for the whole kernel, and palignr $4 in the schedule. -// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (SHA-256 SSSE3 kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, +// sibling, the two SSSE3 ops are the real instructions: pshufb dword +// byte-swap against the mask kept in xmm8 for the whole kernel, and +// palignr $4 in the schedule. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, // r8d = numblocks, r9 = doubled-K256 ptr (read at a 32-byte stride so the // duplicated halves are skipped; the byte-swap mask sits at +512). -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// pshufb/palignr instructions are db-encoded for broad assembler +// compatibility. +// Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (SHA-256 SSSE3 kernel). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc index 5c225b8..c3e018d 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2Absorb_x86_64.inc @@ -1,21 +1,12 @@ -// Keccak-f[1600] AVX2 multi-block absorb. -// Fuses data-XOR + permutation into a single loop with one gather/scatter. -// Reference: Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS project), -// as adopted by XKCP (eXtended Keccak Code Package): -// https://github.com/dot-asm/cryptogams/blob/master/x86_64/keccak1600-avx2.pl -// https://github.com/XKCP/XKCP/blob/master/lib/low/KeccakP-1600/AVX2/KeccakP-1600-AVX2.s -// -// Uses "plane-per-register" technique: 25 Keccak lanes packed into 7 YMM registers. -// All VEX instructions are db-encoded for broad assembler compatibility. -// -// After HlpSimdProc5Begin_x86_64.inc: -// rcx = state ptr (25 x UInt64, standard layout) -// rdx = data ptr (input bytes, little-endian UInt64 words) -// r8d = block count -// r9d = block size in bytes -// r10 = constants ptr (K_KECCAK: rhotates, iotas, A_JAGGED) -// -// YMM register mapping (after gather): +// AVX2 implementation of the Keccak-f[1600] multi-block absorb. Fuses +// data-XOR + permutation into a single loop with one gather/scatter. Uses +// the "plane-per-register" technique: 25 Keccak lanes packed into 7 YMM +// registers. +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = state ptr (25 x UInt64, +// standard layout), rdx = data ptr (little-endian UInt64 words), +// r8d = block count, r9d = block size in bytes, r10 = constants ptr +// (K_KECCAK: rhotates, iotas, A_JAGGED). +// Register map (after gather): // ymm0 = broadcast(state[0]) // ymm1 = { state[1], state[2], state[3], state[4] } // ymm2 = { state[10], state[20], state[5], state[15] } @@ -23,24 +14,20 @@ // ymm4 = { state[11], state[22], state[8], state[19] } // ymm5 = { state[21], state[17], state[13], state[9] } // ymm6 = { state[6], state[12], state[18], state[24] } -// -// MS x64 non-volatile saves: xmm6-xmm15, rbx, rbp, r12-r15, rdi, rsi. -// rdi/rsi are also pushed under non-MS ABIs because the absorb loop uses rsi -// as the A_JAGGED base pointer for the duration of the routine. -// -// Stack layout (sub rsp, 424): -// [rsp+ 0..223]: jagged buffer (7 x 32 bytes) -// [rsp+224..255]: scratch -// [rsp+256..415]: xmm6-xmm15 save area -// -// Register allocation across absorb loop: -// r12 = state pointer (for final scatter) -// r13 = data pointer (advances per block) -// r14d = block count (decremented per block) -// r15d = block size in bytes (constant) -// rbx = constants pointer (constant) -// ebp = block size in qwords (constant) -// rsi = A_JAGGED base pointer (constant) +// Absorb-loop GPRs: r12 = state ptr (final scatter), r13 = data ptr +// (advances per block), r14d = block count (decremented), r15d = block +// size in bytes, rbx = constants ptr, ebp = block size in qwords, +// rsi = A_JAGGED base pointer. +// Frame (sub rsp, 424): +// [rsp+ 0..223] = jagged buffer (7 x 32 bytes) +// [rsp+224..255] = scratch +// [rsp+256..415] = xmm6-xmm15 save area +// Saves: xmm6-xmm15, rbx, rbp, r12-r15, rdi, rsi. rdi/rsi are also pushed +// under non-MS ABIs because the absorb loop uses rsi as the A_JAGGED +// base pointer for the duration of the routine. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS), as adopted +// by XKCP (KeccakP-1600-AVX2.s). // ===== Prologue: save callee-saved GPRs ===== push rbx diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc index 561cf53..a642d31 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Avx2_x86_64.inc @@ -1,14 +1,10 @@ -// Keccak-f[1600] AVX2 permutation. -// Reference: Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS project), -// as adopted by XKCP (eXtended Keccak Code Package): -// https://github.com/dot-asm/cryptogams/blob/master/x86_64/keccak1600-avx2.pl -// https://github.com/XKCP/XKCP/blob/master/lib/low/KeccakP-1600/AVX2/KeccakP-1600-AVX2.s -// Uses "plane-per-register" technique: 25 Keccak lanes packed into 7 YMM registers. -// All VEX instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI: rcx = state ptr (25 x UInt64, standard layout), -// rdx = constants ptr (rhotates_left[24], rhotates_right[24], iotas[96]). -// -// YMM register mapping (after gather): +// AVX2 implementation of the Keccak-f[1600] permutation. Uses the +// "plane-per-register" technique: 25 Keccak lanes packed into 7 YMM +// registers. +// ABI (after HlpSimdProc2Begin_x86_64.inc): rcx = state ptr (25 x UInt64, +// standard layout), rdx = constants ptr (rhotates_left[24], +// rhotates_right[24], iotas[96]). +// Register map (after gather): // ymm0 = broadcast(state[0]) // ymm1 = { state[1], state[2], state[3], state[4] } // ymm2 = { state[10], state[20], state[5], state[15] } @@ -16,13 +12,14 @@ // ymm4 = { state[11], state[22], state[8], state[19] } // ymm5 = { state[21], state[17], state[13], state[9] } // ymm6 = { state[6], state[12], state[18], state[24] } -// -// MS x64 non-volatile saves: xmm6-xmm15. -// -// Stack layout (sub rsp, 224): -// [rsp+ 0.. 31]: 32-byte temp buffer for gather/scatter -// [rsp+ 32..191]: xmm6-xmm15 save area -// [rsp+192..223]: padding +// Frame (sub rsp, 224): +// [rsp+ 0.. 31] = 32-byte temp buffer for gather/scatter +// [rsp+ 32..191] = xmm6-xmm15 save area +// [rsp+192..223] = padding +// Saves: xmm6-xmm15 (MS x64 non-volatile) in the frame. +// AVX/AVX2 instructions are db-encoded for broad assembler compatibility. +// Reference: Andy Polyakov's keccak1600-avx2.pl (CRYPTOGAMS), as adopted +// by XKCP (KeccakP-1600-AVX2.s). {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc index a827b35..62e86f7 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExtAbsorb_aarch64.inc @@ -1,13 +1,16 @@ -// Keccak-F1600 absorb AArch64 FEAT_SHA3 implementation. -// Expects AAPCS64: x0 = state ptr (25 x UInt64), x1 = data ptr, -// w2 = numblocks, w3 = blocksize (bytes, = rate), x4 = iotas ptr. -// Saves/restores d8-d15 on 64-byte frame; XORs blocksize bytes per block then permutes. -// Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.S. -// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// CryptoExt (FEAT_SHA3) implementation of the Keccak-f[1600] multi-block +// absorb: XORs blocksize bytes per block into the state, then permutes. +// ABI (after HlpSimdProc5Begin_aarch64.inc): x0 = state ptr (25 x UInt64), +// x1 = data ptr, w2 = numblocks, w3 = blocksize (bytes, = rate), +// x4 = iotas ptr. // Register map: // v0-v24 = Keccak state lanes (data XORed lane-by-lane into v0..) // v25-v30 = permutation scratch // v31 = loaded input lane +// Saves: d8-d15 via the shared HlpSimdNonVolatileSave/Restore include (the +// state uses v0-v24). +// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.S. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} .long 0x6d400400 // ldp d0, d1, [x0] diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc index a6fef56..badbc55 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600CryptoExt_aarch64.inc @@ -1,15 +1,16 @@ -// Keccak-F1600 permute AArch64 FEAT_SHA3 implementation. -// Expects AAPCS64: x0 = state ptr (25 x UInt64, little-endian lanes), -// x1 = iotas ptr (24 x UInt64 round constants == HlpSHA3 RC table). -// Saves/restores d8-d15 on 64-byte frame; state uses v0-v24 (clobbers d8-d15 lanes). -// Leaf (no calls); x30 untouched. -// Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.S. -// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// CryptoExt (FEAT_SHA3) implementation of the Keccak-f[1600] permutation. +// ABI (after HlpSimdProc2Begin_aarch64.inc): x0 = state ptr (25 x UInt64, +// little-endian lanes), x1 = iotas ptr (24 x UInt64 round constants == +// HlpSHA3 RC table). // Register map: // v0-v24 = Keccak state lanes A[y][x] (lane k = v[k], 64 bits in low half) // v25-v29 = Theta C[]/D[] column scratch // v26 = iota round constant (ld1r) // v30-v31 = Rho/Pi scratch +// Saves: d8-d15 via the shared HlpSimdNonVolatileSave/Restore include (the +// state uses v0-v24). Leaf (no calls); x30 untouched. +// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.S. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_aarch64.inc} .long 0x6d400400 // ldp d0, d1, [x0] diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc index c575f0b..bf32a4c 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_aarch64.inc @@ -1,16 +1,16 @@ -// Keccak-f[1600] pure-GPR multi-block absorb (AArch64) for cores without -// FEAT_SHA3; the Gpr name states the ISA requirement: none beyond base -// AArch64. XORs each rate-sized block into the state (unrolled per-lane -// ladder driven by the block size), then runs the same GPR permutation as -// KeccakF1600Gpr_aarch64.inc - the inner is this file's own copy. -// Expects AAPCS64 (after HlpSimdProc5Begin_aarch64): x0 = AState -// (25 x UInt64, standard layout), x1 = AData, w2 = ABlockCount, -// w3 = ABlockSize (bytes), x4 = AConstants (iotas: 24 x UInt64). -// The reference takes a byte length; it is computed as -// ABlockCount * ABlockSize on entry. The reference frame grows 64 -> 80 -// because its own slots occupy [sp,#32..63] - the iotas end pointer for the -// permutation's end-pointer termination (see the permute kernel's header) -// lives at [sp,#64]. +// Gpr implementation of the Keccak-f[1600] multi-block absorb (AArch64) +// for cores without FEAT_SHA3; the Gpr name states the ISA requirement: +// none beyond base AArch64. XORs each rate-sized block into the state +// (unrolled per-lane ladder driven by the block size), then runs the same +// GPR permutation as KeccakF1600Gpr_aarch64.inc - the inner is this file's +// own copy. The reference takes a byte length; it is computed as +// ABlockCount * ABlockSize on entry. +// ABI (after HlpSimdProc5Begin_aarch64.inc): x0 = AState (25 x UInt64, +// standard layout), x1 = AData, w2 = ABlockCount, w3 = ABlockSize +// (bytes), x4 = AConstants (iotas: 24 x UInt64). +// Frame: the reference frame grows 64 -> 80 because its own slots occupy +// [sp,#32..63] - the iotas end pointer for the permutation's end-pointer +// termination (see the permute kernel's header) lives at [sp,#64]. // AArch64 instructions are .long-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.pl (SHA3_absorb + // KeccakF1600_int, the plain path) by Andy Polyakov. diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc index ee600e0..c0c4f2d 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600GprAbsorb_x86_64.inc @@ -1,21 +1,20 @@ -// Keccak-f[1600] sponge absorb for x86-64, pure 64-bit GPR code - the -// asm twin of the AVX2 absorb: XORs whole blocks -// into the state and permutes, keeping the state in the lane-complemented -// domain across the entire batch (the NOT conversion is hoisted out of the -// block loop - the standalone permute pays it per call). -// The permutation body is the same inner as KeccakF1600Gpr_x86_64.inc -// (embedded again because local labels cannot cross include files), with the -// same end-pointer loop termination via the sentinel at [rsp]. +// Gpr implementation of the Keccak-f[1600] multi-block absorb (pure 64-bit +// GPR code) - the asm twin of the AVX2 absorb: XORs whole blocks into the +// state and permutes, keeping the state in the lane-complemented domain +// across the entire batch (the NOT conversion is hoisted out of the block +// loop - the standalone permute pays it per call). The permutation body is +// the same inner as KeccakF1600Gpr_x86_64.inc (embedded again because +// local labels cannot cross include files), with the same end-pointer loop +// termination via the sentinel at [rsp]. +// ABI (after HlpSimdProc5Begin_x86_64.inc): rcx = AState (25 x UInt64, +// standard layout), rdx = AData, r8 = ABlockCount, r9 = ABlockSize (both +// Int32 - upper halves undefined, zero-extended here), r10 = AConstants +// (iotas: 24 x UInt64). +// Frame: 200-byte scratch plane at [rsp+16] (rsi biased +100), sentinel at +// [rsp], spills at [rsi+100..116]. +// Saves: every callee-saved GPR is pushed here (clobbers all GPRs). // Reference: OpenSSL CRYPTOGAMS keccak1600-x86_64.pl (SHA3_absorb) by // Andy Polyakov. -// -// After HlpSimdProc5Begin_x86_64: rcx = AState (25 x UInt64, standard -// layout), rdx = AData, r8 = ABlockCount, r9 = ABlockSize (both Int32 - -// upper halves undefined, zero-extended here), r10 = AConstants (iotas: -// 24 x UInt64 round constants). -// Frame: 200-byte scratch plane at [rsp+16] (rsi biased +100), sentinel at -// [rsp], spills at [rsi+100..116]. Clobbers all GPRs; every callee-saved -// one is pushed here. push rbx push rbp diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc index 401834c..f3bbdc8 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_aarch64.inc @@ -1,16 +1,16 @@ -// Keccak-f[1600] pure-GPR permutation (AArch64) for cores without FEAT_SHA3; -// the Gpr name states the ISA requirement: none beyond base AArch64. The 25 -// lanes live in x0-x17/x19-x25 with x26-x28/x30 as temps; chi is computed -// directly with bic, so no lane complementing exists in this lineage. -// Expects AAPCS64 (after HlpSimdProc2Begin_aarch64): x0 = AState -// (25 x UInt64, standard layout), x1 = AConstants (iotas: 24 x UInt64). -// The original round loop ended on a 256-ALIGNED iotas table (tst #255), -// which a Pascal const cannot guarantee - the termination is patched to an -// end-pointer compare (iotas end stashed at [sp,#40]; the Iota xor is -// hoisted to free x30 for the test; the intervening bic/eor stream writes -// no flags, so the b.ne polarity is unchanged). -// The inner keeps the original called shape (bl/ret); x30 (LR) doubles as a -// temp inside the rounds, as in the original. +// Gpr implementation of the Keccak-f[1600] permutation (AArch64) for cores +// without FEAT_SHA3; the Gpr name states the ISA requirement: none beyond +// base AArch64. The 25 lanes live in x0-x17/x19-x25 with x26-x28/x30 as +// temps; chi is computed directly with bic, so no lane complementing +// exists in this lineage. The original round loop ended on a 256-ALIGNED +// iotas table (tst #255), which a Pascal const cannot guarantee - the +// termination is patched to an end-pointer compare (iotas end stashed at +// [sp,#40]; the Iota xor is hoisted to free x30 for the test; the +// intervening bic/eor stream writes no flags, so the b.ne polarity is +// unchanged). The inner keeps the original called shape (bl/ret); x30 (LR) +// doubles as a temp inside the rounds, as in the original. +// ABI (after HlpSimdProc2Begin_aarch64.inc): x0 = AState (25 x UInt64, +// standard layout), x1 = AConstants (iotas: 24 x UInt64). // AArch64 instructions are .long-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS keccak1600-armv8.pl (KeccakF1600 + // KeccakF1600_int, the plain path) by Andy Polyakov. diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc index 5ace1b4..2859796 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Gpr_x86_64.inc @@ -1,20 +1,20 @@ -// Keccak-f[1600] permutation for x86-64, pure 64-bit GPR code (no SIMD -// registers at all) - the fastest non-AVX2 form of Keccak on x86-64. +// Gpr implementation of the Keccak-f[1600] permutation (pure 64-bit GPR +// code, no SIMD registers at all) - the fastest non-AVX2 form of Keccak on +// x86-64; the Gpr name states the ISA requirement: none beyond base +// x86-64. The inner routine works in the LANE-COMPLEMENTED domain (lanes +// 1, 2, 8, 12, 17 and 20 stored inverted to save NOTs in chi); this +// wrapper converts in and out around the call. The original loop +// terminated on a 256-aligned iotas table (test r15, 255) which a Pascal +// const cannot guarantee - the termination is patched to compare against +// an end pointer stashed at [rsp] (the inner sees it at [rsp + 8] across +// the call). +// ABI (after HlpSimdProc2Begin_x86_64.inc): rcx = AState (25 x UInt64, +// standard layout), rdx = AConstants (iotas: 24 x UInt64). +// Frame: mirrors the OpenSSL wrapper - 200-byte scratch plane (+16 for the +// sentinel slot), rdi/rsi biased by +100, r15 = iotas. The inner keeps +// the original called shape. +// Saves: every callee-saved GPR is pushed here (clobbers all GPRs). // Reference: OpenSSL CRYPTOGAMS keccak1600-x86_64.pl by Andy Polyakov. -// -// The inner routine works in the LANE-COMPLEMENTED domain (lanes 1, 2, 8, -// 12, 17 and 20 stored inverted to save NOTs in chi); this wrapper converts -// in and out around the call. The original loop terminated on a 256-aligned -// iotas table (test r15, 255) which a Pascal const cannot guarantee - the -// termination is patched to compare against an end pointer stashed at -// [rsp] (the inner sees it at [rsp + 8] across the call). -// -// After HlpSimdProc2Begin_x86_64: rcx = AState (25 x UInt64, standard -// layout), rdx = AConstants (iotas: 24 x UInt64 round constants). -// The inner keeps the original called shape; frame mirrors the OpenSSL -// wrapper: 200-byte scratch plane (+16 for the sentinel slot), rdi/rsi -// biased by +100, r15 = iotas. Clobbers rax-rdx, r8-r15, rsi, rdi (all -// GPRs); every callee-saved one is pushed here. push rbx push rbp diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc index 2dcc604..c0e4a39 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2Absorb_i386.inc @@ -1,18 +1,18 @@ -// Keccak-f[1600] sponge absorb for IA-32, pure SSE2 - the asm twin of the -// x86-64 absorb: XORs whole blocks into the state -// and permutes. MMX converted to SSE2 like the permute. -// The permutation body is the same inner as KeccakF1600Sse2_i386.inc -// (embedded again because local labels cannot cross include files). +// SSE2 implementation of the Keccak-f[1600] multi-block absorb (IA-32) - +// the asm twin of the x86-64 absorb: XORs whole blocks into the state and +// permutes. MMX converted to SSE2 like the permute. The permutation body +// is the same inner as KeccakF1600Sse2_i386.inc (embedded again because +// local labels cannot cross include files). +// ABI (after HlpSimdProc5Begin_i386.inc): ebx = AState (25 x UInt64, +// standard layout), esi = AData, edi = ABlockCount, eax = ABlockSize, +// ecx = AConstants (iotas: 24 x UInt64). +// Frame: mirrors the OpenSSL wrapper - ebp = saved esp with spills at +// [ebp-4/-8], 248-byte scratch, esp 8-aligned, inner scratch plane at +// esp+140, state biased by +100. +// Saves: ebp saved here (the shared prologue saves ebx/esi/edi); clobbers +// eax, ecx, edx, xmm0-xmm7. // Reference: OpenSSL CRYPTOGAMS keccak1600-mmx.pl (SHA3_absorb) by // Andy Polyakov. -// -// After HlpSimdProc5Begin_i386: ebx = AState (25 x UInt64, standard layout), -// esi = AData, edi = ABlockCount, eax = ABlockSize, ecx = AConstants -// (iotas: 24 x UInt64 round constants). -// Frame mirrors the OpenSSL wrapper: ebp = saved esp with spills at -// [ebp-4/-8], 248-byte scratch, esp 8-aligned, inner scratch plane at -// esp+140, state biased by +100. Clobbers eax, ecx, edx, xmm0-xmm7; -// ebp saved here (the shared prologue saves ebx/esi/edi). push ebp mov ebp, esp diff --git a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc index 40610c9..23d7312 100644 --- a/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA3/KeccakF1600Sse2_i386.inc @@ -1,19 +1,20 @@ -// Keccak-f[1600] permutation for IA-32, pure SSE2 (64-bit lanes in the low -// qwords of xmm0-xmm7; upper halves carry garbage that is never stored). -// The original MMX inner function is converted to SSE2: mm0-7 -> xmm0-7, -// packed memory-source ops rewritten through a liveness-proven dead scratch -// register (SSE2 has no m64 forms), emms dropped. The round loop XOR-swaps -// esi/edi to ping-pong between the state and the stack scratch plane each -// round (24 rounds = even, so pointers end where they started). +// SSE2 implementation of the Keccak-f[1600] permutation (IA-32; 64-bit +// lanes in the low qwords of xmm0-xmm7, upper halves carry garbage that is +// never stored). The original MMX inner function is converted to SSE2: +// mm0-7 -> xmm0-7, packed memory-source ops rewritten through a +// liveness-proven dead scratch register (SSE2 has no m64 forms), emms +// dropped. The round loop XOR-swaps esi/edi to ping-pong between the state +// and the stack scratch plane each round (24 rounds = even, so pointers +// end where they started). +// ABI (after HlpSimdProc2Begin_i386.inc): ebx = AState (25 x UInt64, +// standard layout), esi = AConstants (iotas: 24 x UInt64). +// Frame: mirrors the OpenSSL wrapper - 240-byte scratch, esp 8-aligned, +// edi = esp + 140, esi biased by +100. The inner routine keeps the +// original calling shape (call/ret) so its esp-relative spill slots stay +// valid. +// Saves: edi/ebp saved here (the shared prologue only saves ebx/esi); +// clobbers eax, ecx, edx, xmm0-xmm7. // Reference: OpenSSL CRYPTOGAMS keccak1600-mmx.pl by Andy Polyakov. -// -// After HlpSimdProc2Begin_i386: ebx = AState (25 x UInt64, standard layout), -// esi = AConstants (iotas: 24 x UInt64 round constants). -// The inner routine keeps the original calling shape (call/ret) so its -// esp-relative spill slots stay valid; frame mirrors the OpenSSL wrapper: -// 240-byte scratch, esp 8-aligned, edi = esp + 140, esi biased by +100. -// Clobbers eax, ecx, edx, xmm0-xmm7; edi/ebp saved here (the shared prologue -// only saves ebx/esi). push edi push ebp diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc index 63edf8c..bfb7a40 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressAvx2_x86_64.inc @@ -1,18 +1,17 @@ -// SHA-512 AVX2 two-block implementation (VEX-256). Two message blocks are -// scheduled together in 256-bit lanes; the compression rounds stay serial (as -// SHA-512 requires), so scheduling two blocks at once is what makes this faster -// than the single-block AVX path. AVX2 and BMI2 (rorx/andn) instructions are -// db-encoded for broad assembler compatibility (every AVX2 CPU also provides -// BMI2). +// AVX2 implementation of SHA-512 compress (VEX-256, two-block). Two message +// blocks are scheduled together in 256-bit lanes; the compression rounds +// stay serial (as SHA-512 requires), so scheduling two blocks at once is +// what makes this faster than the single-block AVX path. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K512 ptr (each 128-bit K512 pair stored +// twice so one table feeds both 256-bit lanes, with the BSWAP64 mask +// appended; see K512_Doubled; the mask is read unaligned, so the Pascal +// const needs no special alignment). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// AVX2 and BMI2 (rorx/andn) instructions are db-encoded for broad assembler +// compatibility (every AVX2 CPU also provides BMI2). // Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX2 kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = doubled-K512 ptr (each 128-bit K512 pair stored twice -// so one table feeds both 256-bit lanes, with the BSWAP64 mask appended; see -// K512_Doubled). The mask is read unaligned, so the Pascal const needs no -// special alignment. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressCryptoExt_aarch64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressCryptoExt_aarch64.inc index a673616..843b028 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressCryptoExt_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressCryptoExt_aarch64.inc @@ -1,16 +1,17 @@ -// SHA-512 AArch64 FEAT_SHA512 implementation. -// Expects AAPCS64: x0 = state ptr (8 x UInt64), x1 = data ptr, -// w2 = numblocks, x3 = K512 ptr (80 UInt64 round constants). -// Leaf nostackframe; caller-saved GPR/vector only. -// K pointer rewound each block (sub x3, #640). Two rounds per iteration; csel avoids OOB prefetch. -// Reference: OpenSSL CRYPTOGAMS sha512-armv8.S. -// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// CryptoExt (FEAT_SHA512) implementation of SHA-512 compress. +// The K pointer is rewound each block (sub x3, #640). Two rounds per +// iteration; csel avoids OOB prefetch. +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (8 x UInt64), +// x1 = data ptr, w2 = numblocks, x3 = K512 ptr (80 UInt64 round constants). // Register map: // v0-v3 = working state (a..h, two UInt64 per register) // v5, v6 = ext scratch (fg, de) v7 = ext scratch (m9_10) // v16-v23 = message schedule (W) // v24, v25 = K + W ping-pong pair // v26-v29 = saved state for the final add +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector/crypto instructions are .long-encoded for broad assembler compatibility. +// Reference: OpenSSL CRYPTOGAMS sha512-armv8.S. cbz w2, .Lcryptoext_sha512_done .long 0xacc14430 // ldp q16, q17, [x1], #32 diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc index 2b0329a..1abcbe2 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressGpr_aarch64.inc @@ -1,17 +1,17 @@ -// SHA-512 pure-GPR implementation (AArch64) for cores without FEAT_SHA512 -// (absent on most consumer Cortex-A7x); the Gpr name states the ISA -// requirement: none beyond base AArch64. Serial SHA maps better onto the -// 31 GPRs than onto NEON lanes (single dependency chain, 1-op ror, -// rotate-folded eor operands). -// Expects AAPCS64 (after HlpSimdProc4Begin_aarch64): x0 = state ptr -// (8 x UInt64), x1 = data ptr, w2 = numblocks, x3 = K512_Gpr ptr. -// K512_Gpr carries the 80 round constants PLUS a zero terminator quad - the -// message-schedule loop ends when the loaded K word is zero (cbnz), exactly -// like the original's sentinel-terminated table; a plain K512 const cannot -// drive this loop. -// Frame: 128-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved) + 32 bytes -// schedule scratch; x30 (LR) is repurposed as the K walk pointer between the -// save and the restore, as in the original. +// Gpr implementation of SHA-512 compress (AArch64) for cores without +// FEAT_SHA512 (absent on most consumer Cortex-A7x); the Gpr name states +// the ISA requirement: none beyond base AArch64. Serial SHA maps better +// onto the 31 GPRs than onto NEON lanes (single dependency chain, 1-op +// ror, rotate-folded eor operands). +// ABI (after HlpSimdProc4Begin_aarch64.inc): x0 = state ptr (8 x UInt64), +// x1 = data ptr, w2 = numblocks, x3 = K512_Gpr ptr. +// K512_Gpr carries the 80 round constants PLUS a zero terminator quad - +// the message-schedule loop ends when the loaded K word is zero (cbnz), +// exactly like the original's sentinel-terminated table; a plain K512 +// const cannot drive this loop. +// Frame: 128-byte AAPCS64 frame (x29/x30 + x19-x28 callee-saved) + 32 +// bytes schedule scratch; x30 (LR) is repurposed as the K walk pointer +// between the save and the restore, as in the original. // AArch64 instructions are .long-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha512-armv8.pl (sha512_block_data_order, // the plain path). diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc index d5e9c05..bfb6032 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_i386.inc @@ -1,11 +1,12 @@ -// SHA-512 SSE2 implementation (IA-32). The 64-bit state and message schedule -// are held in xmm0-xmm7 (low 64 bits) and computed entirely in SSE2 -// (paddq/psrlq/psllq/pxor), so the whole hash runs in the vector unit - -// avoiding IA-32's 32-bit-GPR bottleneck. +// SSE2 implementation of SHA-512 compress (IA-32). The 64-bit state and +// message schedule are held in xmm0-xmm7 (low 64 bits) and computed +// entirely in SSE2 (paddq/psrlq/psllq/pxor), so the whole hash runs in the +// vector unit - avoiding IA-32's 32-bit-GPR bottleneck. +// ABI (after HlpSimdProc4Begin_i386.inc): ebx = state ptr, esi = data ptr, +// edi = numblocks, eax = K512 ptr (80 UInt64). +// Frame: the prologue pushes ebx/esi/edi; ebp is pushed here as the K512 +// walk pointer; state is loaded into xmm0-xmm7. // Reference: OpenSSL CRYPTOGAMS sha512-586.pl. -// Expects (after HlpSimdProc4Begin_i386): ebx = state, esi = data, edi = numblocks, -// eax = K512 ptr (80 UInt64). HlpSimdProc4Begin pushes ebx/esi/edi; ebp is pushed -// here as the K512 walk pointer; state is loaded into xmm0-xmm7. push ebp mov ebp, eax diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc index 3d42fe7..200599a 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSse2_x86_64.inc @@ -1,16 +1,15 @@ -// SHA-512 SSE2 implementation with a SIMD message schedule: the sigma schedule -// runs in 128-bit SSE2 and is interleaved with the 64-bit GPR compression -// rounds, so the vector and integer units run in parallel. This is much faster -// than a scalar message schedule. +// SSE2 implementation of SHA-512 compress (SIMD schedule): the sigma +// schedule runs in 128-bit SSE2 and is interleaved with the 64-bit GPR +// compression rounds, so the vector and integer units run in parallel - +// much faster than a scalar message schedule. The big-endian input +// byte-swap is emulated with pshuflw/pshufhw/psrlw/psllw/por (SSE2 has no +// pshufb), so no mask table is needed. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K512 ptr (K512_Doubled: each 128-bit K512 +// pair stored twice, read at a 32-byte stride). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. // Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX single-block kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = doubled-K512 ptr (K512_Doubled: each 128-bit K512 pair -// stored twice, read at a 32-byte stride). The big-endian input byte-swap is -// emulated with pshuflw/pshufhw/psrlw/psllw/por (SSE2 has no pshufb), so no mask -// table is needed. -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc b/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc index 456c4a7..75e77d3 100644 --- a/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc +++ b/HashLib/src/Include/Simd/SHA512/SHA512CompressSsse3_x86_64.inc @@ -1,16 +1,17 @@ -// SHA-512 SSSE3 implementation with a SIMD message schedule; SSE2 sibling: -// SHA512CompressSse2_x86_64.inc. The sigma schedule runs in 128-bit SIMD and -// is interleaved with the 64-bit GPR compression rounds, so the vector and -// integer units run in parallel. Unlike the SSE2 sibling the big-endian input -// byte-swaps are real pshufb (db-encoded for broad assembler compatibility) -// against the BSWAP64 mask kept resident in xmm12 for the whole kernel. +// SSSE3 implementation of SHA-512 compress (SIMD schedule); SSE2 sibling: +// SHA512CompressSse2_x86_64.inc. The sigma schedule runs in 128-bit SIMD +// and is interleaved with the 64-bit GPR compression rounds, so the vector +// and integer units run in parallel. Unlike the SSE2 sibling the big-endian +// input byte-swaps are real pshufb against the BSWAP64 mask kept resident +// in xmm12 for the whole kernel. +// ABI (after HlpSimdProc4Begin_x86_64.inc): rcx = state ptr, rdx = data ptr, +// r8d = numblocks, r9 = doubled-K512 ptr (K512_Doubled: each 128-bit K512 +// pair stored twice, read at a 32-byte stride; the BSWAP64 mask sits at +// +1280). +// Saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore include +// (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. +// pshufb instructions are db-encoded for broad assembler compatibility. // Reference: OpenSSL CRYPTOGAMS sha512-x86_64.pl (AVX single-block kernel). -// Expects MS x64 ABI (after HlpSimdProc4Begin): rcx = state ptr, rdx = data ptr, -// r8d = numblocks, r9 = doubled-K512 ptr (K512_Doubled: each 128-bit K512 pair -// stored twice, read at a 32-byte stride; the BSWAP64 mask sits at +1280). -// -// MS x64 non-volatile saves: xmm6-xmm15 via the shared HlpSimdNonVolatileSave/Restore -// include (no-op on SysV); rbx, rbp, rdi, rsi, r12-r15 in the local frame. {$I ..\..\Include\Simd\Common\HlpSimdNonVolatileSave_x86_64.inc} diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc index 72d06f5..be4511a 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_i386.inc @@ -1,27 +1,23 @@ // AVX (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted -// data (IA-32). Same structure as ScryptSalsa8Avx_x86_64.inc; the state -// save/reload uses vmovdqu (IA-32 stacks are only 4-aligned), so the frame is -// 64 bytes with no alignment padding. +// data (IA-32); the Avx name states the ISA requirement: VEX-128 encodings +// only, no 256-bit ymm. Same structure as ScryptSalsa8Avx_x86_64.inc; the +// state save/reload uses vmovdqu (IA-32 stacks are only 4-aligned), so the +// frame is 64 bytes with no alignment padding. +// The (i*5 mod 16) Percival data permutation arranges each 16-word Salsa20 +// state into role-based diagonal order, enabling lane-parallel SIMD +// processing of column and row quarter-rounds with pshufd-based +// diagonalize/undiagonalize between them. Operation: +// State = Salsa20/8(State XOR Input). +// ABI (after HlpSimdProc2Begin_i386.inc): ebx = State ptr, esi = Input ptr. +// Each pointer addresses 16 UInt32 (64 bytes) in permuted order. +// Register map: xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, +// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}, xmm4-xmm5 = temps. +// Frame: 64 bytes (saved XOR'd state; no alignment padding). +// Saves: none (uses xmm0-xmm5 and eax only; all volatile on IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// // Reference: Colin Percival, "Stronger Key Derivation via Sequential -// Memory-Hard Functions" (2009), and the Tarsnap scrypt reference -// implementation (crypto_scrypt-sse.c). The (i*5 mod 16) data permutation -// arranges each 16-word Salsa20 state into role-based diagonal order, -// enabling lane-parallel SIMD processing of column and row quarter-rounds -// with vpshufd-based diagonalize/undiagonalize between them. -// -// Identical algorithm to the SSE2 variant but uses VEX-128 3-operand -// encoding, eliminating movdqa register copies and reducing each QR step -// from 7 to 5 instructions. -// -// IA-32: after HlpSimdProc2Begin_i386 - ebx = State ptr, esi = Input ptr -// (parallel to MS x64 ABI: rcx, rdx). -// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: -// xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, -// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}. -// Operation: State = Salsa20/8(State XOR Input) -// Uses xmm0-xmm5 and eax (all volatile). No spills needed. +// Memory-Hard Functions" (2009); Tarsnap crypto_scrypt-sse.c; HashLib +// ScryptSalsa8Avx_x86_64.inc. sub esp, $40 diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc index ad8192b..b38398f 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Avx_x86_64.inc @@ -1,24 +1,22 @@ -// AVX (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted data. +// AVX (VEX-128) implementation of fused XOR + Salsa20/8 on Percival-permuted +// data; the Avx name states the ISA requirement: VEX-128 encodings only, no +// 256-bit ymm. Identical algorithm to the SSE2 variant but the 3-operand +// VEX encoding eliminates movdqa register copies, reducing each QR step +// from 7 to 5 instructions. +// The (i*5 mod 16) Percival data permutation arranges each 16-word Salsa20 +// state into role-based diagonal order, enabling lane-parallel SIMD +// processing of column and row quarter-rounds with pshufd-based +// diagonalize/undiagonalize between them. Operation: +// State = Salsa20/8(State XOR Input). +// ABI (after HlpSimdProc2Begin_x86_64.inc): rcx = State ptr, rdx = Input ptr. +// Each pointer addresses 16 UInt32 (64 bytes) in permuted order. +// Register map: xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, +// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}, xmm4-xmm5 = temps. +// Frame: 72 bytes (64 for the saved XOR'd state + 8 alignment padding). +// Saves: none (uses xmm0-xmm5 only; volatile under both ABIs). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// // Reference: Colin Percival, "Stronger Key Derivation via Sequential -// Memory-Hard Functions" (2009), and the Tarsnap scrypt reference -// implementation (crypto_scrypt-sse.c). The (i*5 mod 16) data permutation -// arranges each 16-word Salsa20 state into role-based diagonal order, -// enabling lane-parallel SIMD processing of column and row quarter-rounds -// with vpshufd-based diagonalize/undiagonalize between them. -// -// Identical algorithm to the SSE2 variant but uses VEX-128 3-operand -// encoding, eliminating movdqa register copies and reducing each QR step -// from 7 to 5 instructions. -// -// Expects MS x64 ABI: rcx = State ptr, rdx = Input ptr. -// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: -// xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, -// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}. -// Operation: State = Salsa20/8(State XOR Input) -// Uses xmm0-xmm5 (all volatile). No spills needed. -// Stack: 72 bytes (64 for saved XOR'd state + 8 alignment padding). +// Memory-Hard Functions" (2009); Tarsnap crypto_scrypt-sse.c. sub rsp, 72 diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Neon_aarch64.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Neon_aarch64.inc index cc8d05e..1310aa9 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Neon_aarch64.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Neon_aarch64.inc @@ -1,11 +1,12 @@ -// Scrypt Salsa20/8 XOR AArch64 NEON implementation (Percival-permuted data). -// Expects AAPCS64: x0 = State ptr, x1 = Input ptr. -// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: -// v0 = {w0,w5,w10,w15}, v1 = {w4,w9,w14,w3}, v2 = {w8,w13,w2,w7}, v3 = {w12,w1,w6,w11}. -// Leaf nostackframe; caller-saved GPR/vector only. -// Column/row quarter-rounds via lane-parallel ext-based diagonalize (see Tarsnap scrypt-sse.c). -// Reference: Tarsnap crypto_scrypt-sse.c, HashLib ScryptSalsa8Sse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of fused XOR + Salsa20/8 on Percival-permuted data. +// The (i*5 mod 16) Percival data permutation arranges each 16-word Salsa20 +// state into role-based diagonal order, enabling lane-parallel column and +// row quarter-rounds via ext-based diagonalize (see Tarsnap scrypt-sse.c). +// Operation: State = Salsa20/8(State XOR Input). +// ABI (after HlpSimdProc2Begin_aarch64.inc): x0 = State ptr, x1 = Input ptr. +// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: +// v0 = {w0,w5,w10,w15}, v1 = {w4,w9,w14,w3}, v2 = {w8,w13,w2,w7}, +// v3 = {w12,w1,w6,w11}. // Register map: // w9 = double-round counter (4 iterations) // v0 = A @@ -14,6 +15,10 @@ // v3 = D // v4-v5 = quarter-round temps (add + shl + sri) // v16-v19 = saved XOR'd state (A,B,C,D) for the final addition +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: Tarsnap crypto_scrypt-sse.c, HashLib ScryptSalsa8Sse2_x86_64.inc. + .long 0x3dc00000 // ldr q0, [x0, #0x0] .long 0x3dc00024 // ldr q4, [x1, #0x0] .long 0x6e241c00 // eor v0.16b, v0.16b, v4.16b diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_i386.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_i386.inc index 8803aca..ea99cce 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_i386.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_i386.inc @@ -1,21 +1,20 @@ -// SSE2 implementation of fused XOR + Salsa20/8 on Percival-permuted data. -// +// SSE2 implementation of fused XOR + Salsa20/8 on Percival-permuted data +// (IA-32). Column QR / diagonal / row QR: same structure as +// ScryptSalsa8Sse2_x86_64.inc. +// The (i*5 mod 16) Percival data permutation arranges each 16-word Salsa20 +// state into role-based diagonal order, enabling lane-parallel SIMD +// processing of column and row quarter-rounds with pshufd-based +// diagonalize/undiagonalize between them. Operation: +// State = Salsa20/8(State XOR Input). +// ABI (after HlpSimdProc2Begin_i386.inc): ebx = State ptr, esi = Input ptr. +// Each pointer addresses 16 UInt32 (64 bytes) in permuted order. +// Register map: xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, +// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}, xmm4-xmm5 = temps. +// Frame (sub esp, 72): 64 for the saved XOR'd state + 8 alignment padding. +// Saves: none (uses xmm0-xmm5 only; all volatile on IA-32). // Reference: Colin Percival, "Stronger Key Derivation via Sequential -// Memory-Hard Functions" (2009), and the Tarsnap scrypt reference -// implementation (crypto_scrypt-sse.c). The (i*5 mod 16) data permutation -// arranges each 16-word Salsa20 state into role-based diagonal order, -// enabling lane-parallel SIMD processing of column and row quarter-rounds -// with pshufd-based diagonalize/undiagonalize between them. -// -// IA-32: after HlpSimdProc2Begin_i386 — ebx = State ptr, esi = Input ptr -// (parallel to MS x64 ABI: rcx, rdx). -// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: -// xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, -// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}. -// Operation: State = Salsa20/8(State XOR Input) -// Uses xmm0–xmm5. Stack: sub esp, 72 (64 for saved XOR'd state + 8 alignment padding). -// -// Column QR / diagonal / row QR: same structure as ScryptSalsa8Sse2_x86_64.inc header on x86-64. +// Memory-Hard Functions" (2009); Tarsnap crypto_scrypt-sse.c; HashLib +// ScryptSalsa8Sse2_x86_64.inc. sub esp, 72 diff --git a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_x86_64.inc b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_x86_64.inc index 50911a5..ca34848 100644 --- a/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_x86_64.inc +++ b/HashLib/src/Include/Simd/Scrypt/ScryptSalsa8Sse2_x86_64.inc @@ -1,26 +1,23 @@ // SSE2 implementation of fused XOR + Salsa20/8 on Percival-permuted data. -// -// Reference: Colin Percival, "Stronger Key Derivation via Sequential -// Memory-Hard Functions" (2009), and the Tarsnap scrypt reference -// implementation (crypto_scrypt-sse.c). The (i*5 mod 16) data permutation -// arranges each 16-word Salsa20 state into role-based diagonal order, -// enabling lane-parallel SIMD processing of column and row quarter-rounds -// with pshufd-based diagonalize/undiagonalize between them. -// -// Expects MS x64 ABI: rcx = State ptr, rdx = Input ptr. -// Each pointer addresses 16 UInt32 (64 bytes) in permuted order: -// xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, -// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}. -// Operation: State = Salsa20/8(State XOR Input) -// Uses xmm0-xmm5 (volatile under both ABIs; no saves needed). -// Stack: 72 bytes (64 for saved XOR'd state + 8 alignment padding). -// +// The (i*5 mod 16) Percival data permutation arranges each 16-word Salsa20 +// state into role-based diagonal order, enabling lane-parallel SIMD +// processing of column and row quarter-rounds with pshufd-based +// diagonalize/undiagonalize between them. Operation: +// State = Salsa20/8(State XOR Input). // Column QR (lane-parallel): // B ^= rotl(A+D,7); C ^= rotl(B+A,9); D ^= rotl(C+B,13); A ^= rotl(D+C,18) // Diag: pshufd B,$93; pshufd C,$4E; pshufd D,$39 // Row QR (lane-parallel, swapped B/D roles): // D' ^= rotl(A+B',7); C' ^= rotl(D'+A,9); B' ^= rotl(C'+D',13); A ^= rotl(B'+C',18) // Undiag: pshufd B,$39; pshufd C,$4E; pshufd D,$93 +// ABI (after HlpSimdProc2Begin_x86_64.inc): rcx = State ptr, rdx = Input ptr. +// Each pointer addresses 16 UInt32 (64 bytes) in permuted order. +// Register map: xmm0 = A = {w0,w5,w10,w15}, xmm1 = B = {w4,w9,w14,w3}, +// xmm2 = C = {w8,w13,w2,w7}, xmm3 = D = {w12,w1,w6,w11}, xmm4-xmm5 = temps. +// Frame: 72 bytes (64 for the saved XOR'd state + 8 alignment padding). +// Saves: none (uses xmm0-xmm5 only; volatile under both ABIs). +// Reference: Colin Percival, "Stronger Key Derivation via Sequential +// Memory-Hard Functions" (2009); Tarsnap crypto_scrypt-sse.c. sub rsp, 72 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc index 0816966..232af57 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_i386.inc @@ -1,8 +1,8 @@ -// AVX2 implementation of XXH3_accumulate_512 (IA-32; fully unrolled, -// 2 x 32-byte chunks). Same structure as XXH3Acc512Avx2_x86_64.inc. -// IA-32: after HlpSimdProc3Begin_i386 - ebx = acc, esi = input, edi = secret -// (parallel to MS x64 ABI: rcx, rdx, r8). -// Uses only volatile registers: ymm0-ymm3. +// AVX2 implementation of XXH3_accumulate_512 (fully unrolled, 2 x 32-byte +// chunks; IA-32). Same structure as XXH3Acc512Avx2_x86_64.inc. +// ABI (after HlpSimdProc3Begin_i386.inc): ebx = acc ptr, esi = input ptr, +// edi = secret ptr. +// Saves: none (uses ymm0-ymm3 only; all volatile on IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: official xxHash C - XXH3_accumulate_512_avx2 in xxhash.h, // HashLib XXH3Acc512Avx2_x86_64.inc. diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_x86_64.inc index 10cc79f..29a80e3 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Avx2_x86_64.inc @@ -1,8 +1,10 @@ -// AVX2 implementation of XXH3_accumulate_512 (fully unrolled, 2 x 32-byte chunks). +// AVX2 implementation of XXH3_accumulate_512 (fully unrolled, 2 x 32-byte +// chunks). +// ABI (after HlpSimdProc3Begin_x86_64.inc): rcx = acc ptr, rdx = input ptr, +// r8 = secret ptr. +// Saves: none (uses ymm0-ymm4 only; volatile under both ABIs). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI: rcx = acc ptr, rdx = input ptr, r8 = secret ptr. -// Uses only volatile registers: ymm0-ymm4. -// Reference: official xxHash C - XXH3_accumulate_512_avx2 in xxhash.h +// Reference: official xxHash C - XXH3_accumulate_512_avx2 in xxhash.h. // --- Chunk 0: acc[0..3], input[0..31], secret[0..31] --- db $C5, $FE, $6F, $01 // vmovdqu ymm0, yword [rcx] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc index d98d523..3f223b7 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Neon_aarch64.inc @@ -1,15 +1,17 @@ -// XXH3 accumulate_512 AArch64 NEON implementation (one 64-byte stripe). -// Expects AAPCS64: x0 = acc ptr (8 x UInt64, 16-byte aligned), x1 = input ptr, -// x2 = secret ptr. -// Leaf nostackframe; caller-saved GPR/vector only. -// Reference: Cyan4973/xxHash xxhash.h XXH3_accumulate_512_neon, HashLib XXH3Acc512Sse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of XXH3_accumulate_512 (one 64-byte stripe). +// ABI (after HlpSimdProc3Begin_aarch64.inc): x0 = acc ptr (8 x UInt64, +// 16-byte aligned), x1 = input ptr, x2 = secret ptr. // Register map: // v0-v3 = acc[0..3] (4 x uint64x2) // v4-v5 = data_vec_1/2 (input) // v6-v7 = key_vec / uzp temps (data_key_lo, data_key_hi) // v16-v17 = data_swap_1/2 (vext input by 8 bytes) // v18-v19 = sum_1/sum_2 (umlal / umlal2 widen-multiply-add into swap) +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: Cyan4973/xxHash xxhash.h XXH3_accumulate_512_neon, HashLib +// XXH3Acc512Sse2_x86_64.inc. + // --- batch i=0: acc[0..1], input[0x0..], secret[0x0..] --- .long 0x3dc00024 // ldr q4, [x1, #0x0] .long 0x3dc00425 // ldr q5, [x1, #0x10] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_i386.inc index ab7d5b6..b29e02e 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_i386.inc @@ -1,8 +1,9 @@ -// SSE2 implementation of XXH3_accumulate_512 (fully unrolled, 4 x 16-byte chunks). -// IA-32: after HlpSimdProc3Begin_i386 — ebx = acc, esi = input, edi = secret -// (parallel to MS x64 ABI: rcx, rdx, r8). -// Uses only volatile XMM: xmm0–xmm5. -// Reference: official xxHash C - XXH3_accumulate_512_sse2 in xxhash.h +// SSE2 implementation of XXH3_accumulate_512 (fully unrolled, 4 x 16-byte +// chunks; IA-32). +// ABI (after HlpSimdProc3Begin_i386.inc): ebx = acc ptr, esi = input ptr, +// edi = secret ptr. +// Saves: none (uses xmm0-xmm5 only; all volatile on IA-32). +// Reference: official xxHash C - XXH3_accumulate_512_sse2 in xxhash.h. movdqu xmm0, oword [ebx] movdqu xmm1, oword [esi] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_x86_64.inc index e1ecd3a..e6abb6b 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3Acc512Sse2_x86_64.inc @@ -1,7 +1,9 @@ -// SSE2 implementation of XXH3_accumulate_512 (fully unrolled, 4 x 16-byte chunks). -// Expects MS x64 ABI: rcx = acc ptr, rdx = input ptr, r8 = secret ptr. -// Uses only volatile registers: xmm0-xmm5. -// Reference: official xxHash C - XXH3_accumulate_512_sse2 in xxhash.h +// SSE2 implementation of XXH3_accumulate_512 (fully unrolled, 4 x 16-byte +// chunks). +// ABI (after HlpSimdProc3Begin_x86_64.inc): rcx = acc ptr, rdx = input ptr, +// r8 = secret ptr. +// Saves: none (uses xmm0-xmm5 only; volatile under both ABIs). +// Reference: official xxHash C - XXH3_accumulate_512_sse2 in xxhash.h. // --- Chunk 0: acc[0..1], input[0..15], secret[0..15] --- movdqu xmm0, oword [rcx] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc index 54cc778..5376d14 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_i386.inc @@ -1,11 +1,13 @@ -// AVX2 implementation of XXH3_initCustomSecret (IA-32; fully unrolled, -// 6 x 32-byte chunks). Same structure as XXH3InitSecretAvx2_x86_64.inc; the -// x86_64 version's vmovq xmm, r64 seed transfers (not encodable in 32-bit -// mode) become the SSE2 i386 sibling's push/vmovq-from-stack pattern, with -// the negation done in 32-bit halves (not/not + add/adc carry). -// IA-32: after HlpSimdProc3Begin_i386 - ebx = customSecret, esi = defaultSecret, -// edi = seed ptr (PUInt64). -// Uses only volatile registers: ymm0-ymm1, eax, ecx, edx (edi reused). +// AVX2 implementation of XXH3_initCustomSecret (fully unrolled, 6 x +// 32-byte chunks; IA-32). Same structure as XXH3InitSecretAvx2_x86_64.inc; +// the x86_64 version's vmovq xmm, r64 seed transfers (not encodable in +// 32-bit mode) become the SSE2 i386 sibling's push/vmovq-from-stack +// pattern, with the negation done in 32-bit halves (not/not + add/adc +// carry). +// ABI (after HlpSimdProc3Begin_i386.inc): ebx = customSecret ptr, +// esi = defaultSecret ptr, edi = seed ptr (PUInt64). +// Saves: none (uses ymm0-ymm1, eax, ecx, edx; edi reused; all volatile on +// IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: official xxHash C - XXH3_initCustomSecret_avx2 in xxhash.h, // HashLib XXH3InitSecretAvx2_x86_64.inc. diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc index 8937c16..6ea3186 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretAvx2_x86_64.inc @@ -1,9 +1,10 @@ -// AVX2 implementation of XXH3_initCustomSecret (fully unrolled, 6 x 32-byte chunks). +// AVX2 implementation of XXH3_initCustomSecret (fully unrolled, 6 x +// 32-byte chunks). +// ABI (after HlpSimdProc3Begin_x86_64.inc): rcx = customSecret ptr, +// rdx = defaultSecret ptr, r8 = seed ptr (PUInt64). +// Saves: none (uses ymm0-ymm2 and rax only; volatile under both ABIs). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI: rcx = customSecret ptr, rdx = defaultSecret ptr, -// r8 = seed ptr (PUInt64). -// Uses only volatile registers: ymm0-ymm2, rax. -// Reference: official xxHash C - XXH3_initCustomSecret_avx2 in xxhash.h +// Reference: official xxHash C - XXH3_initCustomSecret_avx2 in xxhash.h. // Build seed vector ymm0 = [seed, -seed, seed, -seed] mov r8, qword [r8] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc index c210f94..9d3446f 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretNeon_aarch64.inc @@ -1,14 +1,15 @@ -// XXH3 initCustomSecret AArch64 NEON implementation (192-byte custom secret). -// Expects AAPCS64: x0 = customSecret ptr, x1 = defaultSecret ptr, -// x2 = seed ptr (PUInt64). -// Leaf nostackframe; caller-saved GPR/vector only. -// Reference: HashLib XXH3InitSecretSse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of XXH3_initCustomSecret (192-byte custom secret). +// ABI (after HlpSimdProc3Begin_aarch64.inc): x0 = customSecret ptr, +// x1 = defaultSecret ptr, x2 = seed ptr (PUInt64). // Register map: // x3 = negated seed (-seed) // v0 = vSeed broadcast vector [seed, -seed] // v16-v17 = fmov staging for zip1 pack // v2 = defaultSecret block load / add temp +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: HashLib XXH3InitSecretSse2_x86_64.inc. + ldr x2, [x2] neg x3, x2 .long 0x9e670050 // fmov d16, x2 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc index eeee84d..18cbbaa 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_i386.inc @@ -1,8 +1,10 @@ -// SSE2 implementation of XXH3_initCustomSecret (fully unrolled, 12 x 16-byte chunks). -// IA-32: after HlpSimdProc3Begin_i386 - ebx = customSecret, esi = defaultSecret, -// edi = seed ptr (PUInt64). -// Uses only volatile XMM: xmm0-xmm2. -// Reference: official xxHash C - XXH3_initCustomSecret_sse2 in xxhash.h +// SSE2 implementation of XXH3_initCustomSecret (fully unrolled, 12 x +// 16-byte chunks; IA-32). For each 16-byte block: lo_qword += seed, +// hi_qword -= seed. +// ABI (after HlpSimdProc3Begin_i386.inc): ebx = customSecret ptr, +// esi = defaultSecret ptr, edi = seed ptr (PUInt64). +// Saves: none (uses xmm0-xmm2 only; all volatile on IA-32). +// Reference: official xxHash C - XXH3_initCustomSecret_sse2 in xxhash.h. mov eax, dword ptr [edi] mov edx, dword ptr [edi + 4] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc index d39de63..d323b92 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3InitSecretSse2_x86_64.inc @@ -1,9 +1,10 @@ -// SSE2 implementation of XXH3_initCustomSecret (fully unrolled, 12 x 16-byte chunks). -// Expects MS x64 ABI: rcx = customSecret ptr, rdx = defaultSecret ptr, -// r8 = seed ptr (PUInt64). -// Uses only volatile registers: xmm0-xmm2. -// Algorithm: for each 16-byte block, lo_qword += seed, hi_qword -= seed. -// Reference: official xxHash C - XXH3_initCustomSecret_sse2 in xxhash.h +// SSE2 implementation of XXH3_initCustomSecret (fully unrolled, 12 x +// 16-byte chunks). For each 16-byte block: lo_qword += seed, +// hi_qword -= seed. +// ABI (after HlpSimdProc3Begin_x86_64.inc): rcx = customSecret ptr, +// rdx = defaultSecret ptr, r8 = seed ptr (PUInt64). +// Saves: none (uses xmm0-xmm2 only; volatile under both ABIs). +// Reference: official xxHash C - XXH3_initCustomSecret_sse2 in xxhash.h. // Build seed vector xmm0 = [seed, -seed] mov r8, qword [r8] diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc index 716e832..a890624 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_i386.inc @@ -1,8 +1,7 @@ -// AVX2 implementation of XXH3_scrambleAcc (IA-32; fully unrolled, -// 2 x 32-byte chunks). Same structure as XXH3ScrambleAvx2_x86_64.inc. -// IA-32: after HlpSimdProc2Begin_i386 - ebx = acc, esi = secret -// (parallel to MS x64 ABI: rcx, rdx). -// Uses only volatile registers: ymm0-ymm4, eax. +// AVX2 implementation of XXH3_scrambleAcc (fully unrolled, 2 x 32-byte +// chunks; IA-32). Same structure as XXH3ScrambleAvx2_x86_64.inc. +// ABI (after HlpSimdProc2Begin_i386.inc): ebx = acc ptr, esi = secret ptr. +// Saves: none (uses ymm0-ymm4 and eax only; all volatile on IA-32). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. // Reference: official xxHash C - XXH3_scrambleAcc_avx2 in xxhash.h, // HashLib XXH3ScrambleAvx2_x86_64.inc. diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_x86_64.inc index c58e5bb..0dd9b13 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleAvx2_x86_64.inc @@ -1,8 +1,9 @@ -// AVX2 implementation of XXH3_scrambleAcc (fully unrolled, 2 x 32-byte chunks). +// AVX2 implementation of XXH3_scrambleAcc (fully unrolled, 2 x 32-byte +// chunks). +// ABI (after HlpSimdProc2Begin_x86_64.inc): rcx = acc ptr, rdx = secret ptr. +// Saves: none (uses ymm0-ymm4 and eax only; volatile under both ABIs). // AVX/AVX2 instructions are db-encoded for broad assembler compatibility. -// Expects MS x64 ABI: rcx = acc ptr, rdx = secret ptr. -// Uses only volatile registers: ymm0-ymm4, eax. -// Reference: official xxHash C - XXH3_scrambleAcc_avx2 in xxhash.h +// Reference: official xxHash C - XXH3_scrambleAcc_avx2 in xxhash.h. // Broadcast XXH_PRIME32_1 ($9E3779B1) to all dword lanes of ymm4 mov eax, $9E3779B1 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc index 7bf9f56..4825e36 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleNeon_aarch64.inc @@ -1,14 +1,17 @@ -// XXH3 scrambleAcc AArch64 NEON implementation (64-byte secret slice). -// Expects AAPCS64: x0 = acc ptr (8 x UInt64, 16-byte aligned), x1 = secret ptr. -// Leaf nostackframe; caller-saved GPR/vector only. -// Reference: Cyan4973/xxHash xxhash.h XXH3_scrambleAcc_neon, HashLib XXH3ScrambleSse2_x86_64.inc. -// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// NEON implementation of XXH3_scrambleAcc (64-byte secret slice). +// ABI (after HlpSimdProc2Begin_aarch64.inc): x0 = acc ptr (8 x UInt64, +// 16-byte aligned), x1 = secret ptr. // Register map: // w10 = XXH_PRIME32_1 constant loader // v4 = kPrimeHi ({0, PRIME32_1, 0, PRIME32_1} as u32x4) // v5 = kPrimeLo (PRIME32_1 broadcast to u32x2) // v3 = prod_hi (vmul u32) / final chunk result // v1 = shifted acc, secret key, or data_key_lo (xtn) +// Saves: none (leaf nostackframe; caller-saved GPR/vector only). +// AArch64 vector instructions are .long-encoded for broad assembler compatibility. +// Reference: Cyan4973/xxHash xxhash.h XXH3_scrambleAcc_neon, HashLib +// XXH3ScrambleSse2_x86_64.inc. + .long 0x528f362a // movz w10, #0x79b1, lsl #0 .long 0x72b3c6ea // movk w10, #0x9e37, lsl #16 .long 0x0e040d45 // dup v5.2s, w10 diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_i386.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_i386.inc index 16ed7be..354c9b6 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_i386.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_i386.inc @@ -1,12 +1,9 @@ -// SSE2 implementation of XXH3_scrambleAcc (fully unrolled, 4 x 16-byte chunks). -// IA-32: after HlpSimdProc2Begin_i386 — ebx = acc, esi = secret -// (parallel to MS x64 ABI: rcx, rdx). -// Uses only volatile registers: xmm0–xmm5, eax. -// Algorithm per 128-bit chunk: -// acc ^= (acc >> 47) -// acc ^= secret -// acc *= XXH_PRIME32_1 -// Reference: official xxHash C - XXH3_scrambleAcc_sse2 in xxhash.h +// SSE2 implementation of XXH3_scrambleAcc (fully unrolled, 4 x 16-byte +// chunks; IA-32). Algorithm per 128-bit chunk: acc ^= (acc >> 47); +// acc ^= secret; acc *= XXH_PRIME32_1. +// ABI (after HlpSimdProc2Begin_i386.inc): ebx = acc ptr, esi = secret ptr. +// Saves: none (uses xmm0-xmm5 and eax only; all volatile on IA-32). +// Reference: official xxHash C - XXH3_scrambleAcc_sse2 in xxhash.h. mov eax, $9E3779B1 movd xmm5, eax diff --git a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_x86_64.inc b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_x86_64.inc index 50d8218..9a2532b 100644 --- a/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_x86_64.inc +++ b/HashLib/src/Include/Simd/XXH3/XXH3ScrambleSse2_x86_64.inc @@ -1,11 +1,9 @@ -// SSE2 implementation of XXH3_scrambleAcc (fully unrolled, 4 x 16-byte chunks). -// Expects MS x64 ABI: rcx = acc ptr, rdx = secret ptr. -// Uses only volatile registers: xmm0-xmm5, eax. -// Algorithm per 128-bit chunk: -// acc ^= (acc >> 47) -// acc ^= secret -// acc *= XXH_PRIME32_1 -// Reference: official xxHash C - XXH3_scrambleAcc_sse2 in xxhash.h +// SSE2 implementation of XXH3_scrambleAcc (fully unrolled, 4 x 16-byte +// chunks). Algorithm per 128-bit chunk: acc ^= (acc >> 47); acc ^= secret; +// acc *= XXH_PRIME32_1. +// ABI (after HlpSimdProc2Begin_x86_64.inc): rcx = acc ptr, rdx = secret ptr. +// Saves: none (uses xmm0-xmm5 and eax only; volatile under both ABIs). +// Reference: official xxHash C - XXH3_scrambleAcc_sse2 in xxhash.h. // Load XXH_PRIME32_1 ($9E3779B1) into xmm5 as broadcast dword mov eax, $9E3779B1 diff --git a/scripts/maintenance/check-file-format.ps1 b/scripts/maintenance/check-file-format.ps1 new file mode 100644 index 0000000..6c96b84 --- /dev/null +++ b/scripts/maintenance/check-file-format.ps1 @@ -0,0 +1,68 @@ +<# +.SYNOPSIS + Checks repo file-format rules: CRLF line endings, valid UTF-8, no BOM. +.DESCRIPTION + Scans tracked source/text files (*.pas, *.inc, *.md, *.py, *.ps1, *.lpr) + under HashLib, HashLib.Tests, scripts and docs. Fails (non-zero exit) if a + file starts with a UTF-8 BOM, contains bytes that are not valid UTF-8, or + contains any line ending other than CRLF (bare LF or bare CR). +.EXAMPLE + .\scripts\maintenance\check-file-format.ps1 +#> + +$ErrorActionPreference = 'Stop' + +# Repo root: script lives in /scripts/maintenance/check-file-format.ps1 +$root = if ($PSScriptRoot) { Split-Path (Split-Path $PSScriptRoot -Parent) -Parent } else { Get-Location } + +$patterns = @('*.pas', '*.inc', '*.md', '*.py', '*.ps1', '*.lpr') +$dirs = @('HashLib\src', 'HashLib.Tests\src', 'scripts', 'docs') + +$files = foreach ($d in $dirs) { + $p = Join-Path $root $d + if (Test-Path $p) { + Get-ChildItem -Path $p -Include $patterns -Recurse -File -ErrorAction SilentlyContinue + } +} + +$failures = @() +$utf8Strict = New-Object System.Text.UTF8Encoding($false, $true) + +foreach ($f in $files) { + $bytes = [System.IO.File]::ReadAllBytes($f.FullName) + if ($bytes.Length -eq 0) { continue } + + if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { + $failures += "$($f.FullName): UTF-8 BOM present" + } + + try { + [void]$utf8Strict.GetString($bytes) + } catch { + $failures += "$($f.FullName): not valid UTF-8" + } + + for ($i = 0; $i -lt $bytes.Length; $i++) { + $b = $bytes[$i] + if ($b -eq 10) { + if ($i -eq 0 -or $bytes[$i - 1] -ne 13) { + $failures += "$($f.FullName): bare LF at offset $i" + break + } + } elseif ($b -eq 13) { + if ($i -eq $bytes.Length - 1 -or $bytes[$i + 1] -ne 10) { + $failures += "$($f.FullName): bare CR at offset $i" + break + } + } + } +} + +if ($failures.Count -gt 0) { + Write-Host 'File-format check FAILED (rules: CRLF, valid UTF-8, no BOM):' + $failures | ForEach-Object { Write-Host " $_" } + exit 1 +} + +Write-Host "File-format check passed ($(@($files).Count) files)." +exit 0 From 73d09ede6493ca084e6d76641e9f034ad09e959d Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 12:22:46 +0100 Subject: [PATCH 09/10] re-enable auto Simd selection mode --- HashLib/src/Include/HashLib.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HashLib/src/Include/HashLib.inc b/HashLib/src/Include/HashLib.inc index ff32f55..2e90f93 100644 --- a/HashLib/src/Include/HashLib.inc +++ b/HashLib/src/Include/HashLib.inc @@ -173,7 +173,7 @@ {$IFDEF HASHLIB_ARM_SIMD} // Uncomment at most ONE to force a specific Arm SIMD dispatch level: - {$DEFINE HASHLIB_FORCE_NEON} +// {$DEFINE HASHLIB_FORCE_NEON} // {$DEFINE HASHLIB_FORCE_SVE} {$IF (DEFINED(HASHLIB_FORCE_SCALAR) AND DEFINED(HASHLIB_FORCE_NEON)) From e9d43f82b41329fae06d9f9d2b8f13f2f12ec7db Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 12:59:55 +0100 Subject: [PATCH 10/10] Use TBinaryPrimitives native loads/stores in the Blake2 scalar compress Blake2B_Compress_Scalar / Blake2S_Compress_Scalar accessed the state, IV, counter-flags and message words through raw PUInt64/PUInt32 pointer derefs. All four buffers are native value data (the caller converts the message block to native words before the call), so the accesses now go through TBinaryPrimitives.LoadUInt64/StoreUInt64 and LoadUInt32/StoreUInt32 - behavior-identical, alignment-safe, and the wire-vs-native domain is visible in the API used, consistent with the XXH3 scalar cleanup. --- HashLib/src/Crypto/HlpBlake2B.pas | 26 ++++++++++++++++---------- HashLib/src/Crypto/HlpBlake2S.pas | 26 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/HashLib/src/Crypto/HlpBlake2B.pas b/HashLib/src/Crypto/HlpBlake2B.pas index ffa60e6..7bc4d73 100644 --- a/HashLib/src/Crypto/HlpBlake2B.pas +++ b/HashLib/src/Crypto/HlpBlake2B.pas @@ -267,11 +267,13 @@ procedure Blake2B_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); procedure G(AA, AB, AC, AD, AMsgIdx0, AMsgIdx1: Int32); begin - LV[AA] := LV[AA] + LV[AB] + PUInt64(LPMsg + AMsgIdx0 * SizeOf(UInt64))^; + LV[AA] := LV[AA] + LV[AB] + TBinaryPrimitives.LoadUInt64 + (PUInt64(LPMsg + AMsgIdx0 * SizeOf(UInt64))); LV[AD] := TBitOperations.RotateRight64(LV[AD] xor LV[AA], 32); LV[AC] := LV[AC] + LV[AD]; LV[AB] := TBitOperations.RotateRight64(LV[AB] xor LV[AC], 24); - LV[AA] := LV[AA] + LV[AB] + PUInt64(LPMsg + AMsgIdx1 * SizeOf(UInt64))^; + LV[AA] := LV[AA] + LV[AB] + TBinaryPrimitives.LoadUInt64 + (PUInt64(LPMsg + AMsgIdx1 * SizeOf(UInt64))); LV[AD] := TBitOperations.RotateRight64(LV[AD] xor LV[AA], 16); LV[AC] := LV[AC] + LV[AD]; LV[AB] := TBitOperations.RotateRight64(LV[AB] xor LV[AC], 63); @@ -284,14 +286,17 @@ procedure Blake2B_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); LPIV := PByte(AIV); for I := 0 to 7 do - LV[I] := PUInt64(LPState + I * SizeOf(UInt64))^; + LV[I] := TBinaryPrimitives.LoadUInt64(PUInt64(LPState + I * SizeOf(UInt64))); for I := 0 to 7 do - LV[I + 8] := PUInt64(LPIV + I * SizeOf(UInt64))^; + LV[I + 8] := TBinaryPrimitives.LoadUInt64(PUInt64(LPIV + I * SizeOf(UInt64))); - LV[12] := LV[12] xor PUInt64(LPCounterFlags)^; - LV[13] := LV[13] xor PUInt64(LPCounterFlags + SizeOf(UInt64))^; - LV[14] := LV[14] xor PUInt64(LPCounterFlags + 2 * SizeOf(UInt64))^; - LV[15] := LV[15] xor PUInt64(LPCounterFlags + 3 * SizeOf(UInt64))^; + LV[12] := LV[12] xor TBinaryPrimitives.LoadUInt64(PUInt64(LPCounterFlags)); + LV[13] := LV[13] xor TBinaryPrimitives.LoadUInt64 + (PUInt64(LPCounterFlags + SizeOf(UInt64))); + LV[14] := LV[14] xor TBinaryPrimitives.LoadUInt64 + (PUInt64(LPCounterFlags + 2 * SizeOf(UInt64))); + LV[15] := LV[15] xor TBinaryPrimitives.LoadUInt64 + (PUInt64(LPCounterFlags + 3 * SizeOf(UInt64))); for LRound := 0 to 11 do begin @@ -306,8 +311,9 @@ procedure Blake2B_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); end; for I := 0 to 7 do - PUInt64(LPState + I * SizeOf(UInt64))^ := - PUInt64(LPState + I * SizeOf(UInt64))^ xor (LV[I] xor LV[I + 8]); + TBinaryPrimitives.StoreUInt64(PUInt64(LPState + I * SizeOf(UInt64)), + TBinaryPrimitives.LoadUInt64(PUInt64(LPState + I * SizeOf(UInt64))) + xor (LV[I] xor LV[I + 8])); end; type diff --git a/HashLib/src/Crypto/HlpBlake2S.pas b/HashLib/src/Crypto/HlpBlake2S.pas index 6949997..b5e71c9 100644 --- a/HashLib/src/Crypto/HlpBlake2S.pas +++ b/HashLib/src/Crypto/HlpBlake2S.pas @@ -263,11 +263,13 @@ procedure Blake2S_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); procedure G(AA, AB, AC, AD, AMsgIdx0, AMsgIdx1: Int32); begin - LV[AA] := LV[AA] + LV[AB] + PUInt32(LPMsg + AMsgIdx0 * SizeOf(UInt32))^; + LV[AA] := LV[AA] + LV[AB] + TBinaryPrimitives.LoadUInt32 + (PCardinal(LPMsg + AMsgIdx0 * SizeOf(UInt32))); LV[AD] := TBitOperations.RotateRight32(LV[AD] xor LV[AA], 16); LV[AC] := LV[AC] + LV[AD]; LV[AB] := TBitOperations.RotateRight32(LV[AB] xor LV[AC], 12); - LV[AA] := LV[AA] + LV[AB] + PUInt32(LPMsg + AMsgIdx1 * SizeOf(UInt32))^; + LV[AA] := LV[AA] + LV[AB] + TBinaryPrimitives.LoadUInt32 + (PCardinal(LPMsg + AMsgIdx1 * SizeOf(UInt32))); LV[AD] := TBitOperations.RotateRight32(LV[AD] xor LV[AA], 8); LV[AC] := LV[AC] + LV[AD]; LV[AB] := TBitOperations.RotateRight32(LV[AB] xor LV[AC], 7); @@ -280,14 +282,17 @@ procedure Blake2S_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); LPIV := PByte(AIV); for I := 0 to 7 do - LV[I] := PUInt32(LPState + I * SizeOf(UInt32))^; + LV[I] := TBinaryPrimitives.LoadUInt32(PCardinal(LPState + I * SizeOf(UInt32))); for I := 0 to 7 do - LV[I + 8] := PUInt32(LPIV + I * SizeOf(UInt32))^; + LV[I + 8] := TBinaryPrimitives.LoadUInt32(PCardinal(LPIV + I * SizeOf(UInt32))); - LV[12] := LV[12] xor PUInt32(LPCounterFlags)^; - LV[13] := LV[13] xor PUInt32(LPCounterFlags + SizeOf(UInt32))^; - LV[14] := LV[14] xor PUInt32(LPCounterFlags + 2 * SizeOf(UInt32))^; - LV[15] := LV[15] xor PUInt32(LPCounterFlags + 3 * SizeOf(UInt32))^; + LV[12] := LV[12] xor TBinaryPrimitives.LoadUInt32(PCardinal(LPCounterFlags)); + LV[13] := LV[13] xor TBinaryPrimitives.LoadUInt32 + (PCardinal(LPCounterFlags + SizeOf(UInt32))); + LV[14] := LV[14] xor TBinaryPrimitives.LoadUInt32 + (PCardinal(LPCounterFlags + 2 * SizeOf(UInt32))); + LV[15] := LV[15] xor TBinaryPrimitives.LoadUInt32 + (PCardinal(LPCounterFlags + 3 * SizeOf(UInt32))); for LRound := 0 to 9 do begin @@ -302,8 +307,9 @@ procedure Blake2S_Compress_Scalar(AState, AMsg, ACounterFlags, AIV: Pointer); end; for I := 0 to 7 do - PUInt32(LPState + I * SizeOf(UInt32))^ := - PUInt32(LPState + I * SizeOf(UInt32))^ xor (LV[I] xor LV[I + 8]); + TBinaryPrimitives.StoreUInt32(PCardinal(LPState + I * SizeOf(UInt32)), + TBinaryPrimitives.LoadUInt32(PCardinal(LPState + I * SizeOf(UInt32))) + xor (LV[I] xor LV[I + 8])); end; type