From 5c6c699a4363865e855d2c27fc138830f419b9d8 Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 06:07:45 +0100 Subject: [PATCH 1/3] 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. --- scripts/maintenance/check-file-format.ps1 | 68 +++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 scripts/maintenance/check-file-format.ps1 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 769e5e5b72c47050d7ae7585ee1ba5c39ee7101c Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 11:54:32 +0100 Subject: [PATCH 2/3] 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. --- .../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 | 27 +++++---- .../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 | 22 +++---- .../Simd/SHA256/SHA256CompressSse2_x86_64.inc | 25 ++++---- .../Simd/SHA256/SHA256CompressSsse3_i386.inc | 26 ++++---- .../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 ++--- 110 files changed, 1325 insertions(+), 1317 deletions(-) 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..dbb0b5b 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 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..a248d0c 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 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..07858ea 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 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 From 348b376fdaae72d9c14631c37b0439f89900c32d Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Mon, 13 Jul 2026 12:03:46 +0100 Subject: [PATCH 3/3] 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. --- HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc | 2 +- HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc | 2 +- HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc index dbb0b5b..346c68c 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressAvx_i386.inc @@ -28,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/SHA256CompressSse2_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc index a248d0c..7632cfb 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSse2_i386.inc @@ -26,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/SHA256CompressSsse3_i386.inc b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc index 07858ea..d1b2b50 100644 --- a/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc +++ b/HashLib/src/Include/Simd/SHA256/SHA256CompressSsse3_i386.inc @@ -28,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]