diff --git a/hashtree_darwin_arm64.syso b/hashtree_darwin_arm64.syso index c9e606f..93a57d2 100644 Binary files a/hashtree_darwin_arm64.syso and b/hashtree_darwin_arm64.syso differ diff --git a/hashtree_linux_amd64.syso b/hashtree_linux_amd64.syso index 0a5be28..a4dc21e 100644 Binary files a/hashtree_linux_amd64.syso and b/hashtree_linux_amd64.syso differ diff --git a/hashtree_linux_arm64.syso b/hashtree_linux_arm64.syso index 943c87e..25054cd 100644 Binary files a/hashtree_linux_arm64.syso and b/hashtree_linux_arm64.syso differ diff --git a/hashtree_windows_amd64.syso b/hashtree_windows_amd64.syso index 12a436d..7fe71a0 100644 Binary files a/hashtree_windows_amd64.syso and b/hashtree_windows_amd64.syso differ diff --git a/src/Makefile b/src/Makefile index 913fdf5..0e622a9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,7 +35,6 @@ $(shell mkdir -p $(LIB_DIR)) ASFLAGS += -g -fpic CFLAGS += -g -Wall -Werror -O3 -CLANG_ASFLAGS = -fno-integrated-as LDFLAGS += -L . testlibs = -lhashtree benchlibs = -lhashtree -lm @@ -81,12 +80,6 @@ ifeq ($(CC), cc) endif endif -ifeq ($(CC),clang) - ifneq ($(ARM),1) - ASFLAGS += $(CLANG_ASFLAGS) - endif -endif - ifeq ($(HAVE_OPENSSL),1) CFLAGS += -DHAVE_OPENSSL benchlibs += -lcrypto diff --git a/src/sha256_avx_x1.S b/src/sha256_avx_x1.S index 98910c0..ddebe4a 100644 --- a/src/sha256_avx_x1.S +++ b/src/sha256_avx_x1.S @@ -97,311 +97,259 @@ Copyright (c) 2012-2023, Intel Corporation vpshufb \dst, \dst, \msk .endm -.equ X0, xmm4 -.equ X1, xmm5 -.equ X2, xmm6 -.equ X3, xmm7 - -.equiv XTMP0, xmm0 -.equiv XTMP1, xmm1 -.equiv XTMP2, xmm2 -.equiv XTMP3, xmm3 -.equiv XTMP4, xmm8 -.equiv XFER, xmm9 -.equiv XTMP5, xmm11 - -.equiv SHUF_00BA, xmm10 // shuffle xBxA -> 00BA -.equiv SHUF_DC00, xmm12 // shuffle xDxC -> DC00 -.equiv BYTE_FLIP_MASK, xmm13 +#define INI_X0 xmm4 +#define INI_X1 xmm5 +#define INI_X2 xmm6 +#define INI_X3 xmm7 + +#define XTMP0 xmm0 +#define XTMP1 xmm1 +#define XTMP2 xmm2 +#define XTMP3 xmm3 +#define XTMP4 xmm8 +#define XFER xmm9 +#define XTMP5 xmm11 + +#define SHUF_00BA xmm10 // shuffle xBxA -> 00BA +#define SHUF_DC00 xmm12 // shuffle xDxC -> DC00 +#define BYTE_FLIP_MASK xmm13 #ifdef __WIN64__ - .equ OUTPUT_PTR, rcx // 1st arg - .equ DATA_PTR, rdx // 2nd arg - .equ d_, ebp - .equiv count, r8 // 3rd arg + #define OUTPUT_PTR rcx // 1st arg + #define DATA_PTR rdx // 2nd arg + #define INI_d ebp + #define count r8 // 3rd arg - .equ TBL, rsi - .equ c_, edi + #define TBL rsi + #define INI_c edi #define _XMM_SAVE 64 #define stack_size 192 #else - .equ OUTPUT_PTR, rdi // 1st arg - .equ DATA_PTR, rsi // 2nd arg - .equ c_, ebp - .equiv count, rdx // 3rd arg + #define OUTPUT_PTR rdi // 1st arg + #define DATA_PTR rsi // 2nd arg + #define INI_c ebp + #define count rdx // 3rd arg - .equ TBL, rcx - .equ d_, r8d + #define TBL rcx + #define INI_d r8d #define stack_size 88 #endif #define _DIGEST 32 -.equ a_, eax -.equ b_, ebx -.equ e_, r9d -.equ f_, r10d -.equ g_, r11d -.equ h_, r12d - -.equiv y0, r13d -.equiv y1, r14d -.equiv y2, r15d - - -.macro rotate_Xs -.equ X_, X0 -.equ X0, X1 -.equ X1, X2 -.equ X2, X3 -.equ X3, X_ -.endm - -.macro ROTATE_ARGS -.equ TMP_, h_ -.equ h_, g_ -.equ g_, f_ -.equ f_, e_ -.equ e_, d_ -.equ d_, c_ -.equ c_, b_ -.equ b_, a_ -.equ a_, TMP_ -.endm - -.macro FOUR_ROUNDS_AND_SCHED - //// compute s0 four at a time and s1 two at a time - //// compute W[-16] + W[-7] 4 at a time - //vmovdqa XTMP0, X3 - mov y0, e_ // y0 = e - MY_ROR y0, (25-11) // y0 = e >> (25-11) - mov y1, a_ // y1 = a - vpalignr XTMP0, X3, X2, 4 // XTMP0 = W[-7] - MY_ROR y1, (22-13) // y1 = a >> (22-13) - xor y0, e_ // y0 = e ^ (e >> (25-11)) - mov y2, f_ // y2 = f - MY_ROR y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - //vmovdqa XTMP1, X1 - xor y1, a_ // y1 = a ^ (a >> (22-13) - xor y2, g_ // y2 = f^g - vpaddd XTMP0, XTMP0, X0 // XTMP0 = W[-7] + W[-16] - xor y0, e_ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e_ // y2 = (f^g)&e - MY_ROR y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - //// compute s0 - vpalignr XTMP1, X1, X0, 4 // XTMP1 = W[-15] - xor y1, a_ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) - MY_ROR y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - xor y2, g_ // y2 = CH = ((f^g)&e)^g - - MY_ROR y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) - add y2, y0 // y2 = S1 + CH - add y2, [rsp + 0*4] // y2 = k + w + S1 + CH - - mov y0, a_ // y0 = a - add h_, y2 // h = h + S1 + CH + k + w - mov y2, a_ // y2 = a - +#define INI_a eax +#define INI_b ebx +#define INI_e r9d +#define INI_f r10d +#define INI_g r11d +#define INI_h r12d + +#define y0 r13d +#define y1 r14d +#define y2 r15d + +// These aliases are used for non-macro code where rotation state is at initial +#define a_ INI_a +#define b_ INI_b +#define c_ INI_c +#define d_ INI_d +#define e_ INI_e +#define f_ INI_f +#define g_ INI_g +#define h_ INI_h +#define X0 INI_X0 +#define X1 INI_X1 +#define X2 INI_X2 +#define X3 INI_X3 + +// Rotation macros removed - using parameterized macros instead + +// Parameterized FOUR_ROUNDS_AND_SCHED +// Takes 12 params: 8 GPR (a-h) and 4 XMM (x0-x3) +// After this macro: GPR state rotates by 4 (a,b,c,d,e,f,g,h) -> (e,f,g,h,a,b,c,d) +// XMM state rotates by 1 (x0,x1,x2,x3) -> (x1,x2,x3,x0) +.macro FOUR_ROUNDS_AND_SCHED_P ra, rb, rc, rd, re, rf, rg, rh, x0, x1, x2, x3 + // Round 0: a=ra, b=rb, c=rc, d=rd, e=re, f=rf, g=rg, h=rh + mov y0, \re + MY_ROR y0, (25-11) + mov y1, \ra + vpalignr XTMP0, \x3, \x2, 4 + MY_ROR y1, (22-13) + xor y0, \re + mov y2, \rf + MY_ROR y0, (11-6) + xor y1, \ra + xor y2, \rg + vpaddd XTMP0, XTMP0, \x0 + xor y0, \re + and y2, \re + MY_ROR y1, (13-2) + vpalignr XTMP1, \x1, \x0, 4 + xor y1, \ra + MY_ROR y0, 6 + xor y2, \rg + MY_ROR y1, 2 + add y2, y0 + add y2, [rsp + 0*4] + mov y0, \ra + add \rh, y2 + mov y2, \ra vpsrld XTMP2, XTMP1, 7 - - or y0, c_ // y0 = a|c - add d_, h_ // d = d + h + S1 + CH + k + w - and y2, c_ // y2 = a&c - + or y0, \rc + add \rd, \rh + and y2, \rc vpslld XTMP3, XTMP1, (32-7) - - and y0, b_ // y0 = (a|c)&b - add h_, y1 // h = h + S1 + CH + k + w + S0 - - vpor XTMP3, XTMP3, XTMP2 // XTMP1 = W[-15] MY_ROR 7 - - or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h_, y0 // h = h + S1 + CH + k + w + S0 + MAJ - -ROTATE_ARGS - - mov y0, e_ // y0 = e - mov y1, a_ // y1 = a - - - MY_ROR y0, (25-11) // y0 = e >> (25-11) - xor y0, e_ // y0 = e ^ (e >> (25-11)) - mov y2, f_ // y2 = f - MY_ROR y1, (22-13) // y1 = a >> (22-13) - + and y0, \rb + add \rh, y1 + vpor XTMP3, XTMP3, XTMP2 + or y0, y2 + add \rh, y0 + + // Round 1: a=rh, b=ra, c=rb, d=rc, e=rd, f=re, g=rf, h=rg + mov y0, \rd + mov y1, \rh + MY_ROR y0, (25-11) + xor y0, \rd + mov y2, \re + MY_ROR y1, (22-13) vpsrld XTMP2, XTMP1,18 - - xor y1, a_ // y1 = a ^ (a >> (22-13) - MY_ROR y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - xor y2, g_ // y2 = f^g - - vpsrld XTMP4, XTMP1, 3 // XTMP4 = W[-15] >> 3 - - MY_ROR y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - xor y0, e_ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e_ // y2 = (f^g)&e - MY_ROR y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - + xor y1, \rh + MY_ROR y0, (11-6) + xor y2, \rf + vpsrld XTMP4, XTMP1, 3 + MY_ROR y1, (13-2) + xor y0, \rd + and y2, \rd + MY_ROR y0, 6 vpslld XTMP1, XTMP1, (32-18) - - xor y1, a_ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) - xor y2, g_ // y2 = CH = ((f^g)&e)^g - + xor y1, \rh + xor y2, \rf vpxor XTMP3, XTMP3, XTMP1 - - add y2, y0 // y2 = S1 + CH - add y2, [rsp + 1*4] // y2 = k + w + S1 + CH - MY_ROR y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) - - vpxor XTMP3, XTMP3, XTMP2 // XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 - - mov y0, a_ // y0 = a - add h_, y2 // h = h + S1 + CH + k + w - mov y2, a_ // y2 = a - - vpxor XTMP1, XTMP3, XTMP4 // XTMP1 = s0 - - or y0, c_ // y0 = a|c - add d_, h_ // d = d + h + S1 + CH + k + w - and y2, c_ // y2 = a&c - //// compute low s1 - vpshufd XTMP2, X3, 0b11111010 // XTMP2 = W[-2] {BBAA} - and y0, b_ // y0 = (a|c)&b - add h_, y1 // h = h + S1 + CH + k + w + S0 - vpaddd XTMP0, XTMP0, XTMP1 // XTMP0 = W[-16] + W[-7] + s0 - or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h_, y0 // h = h + S1 + CH + k + w + S0 + MAJ - -ROTATE_ARGS - //vmovdqa XTMP3, XTMP2 // XTMP3 = W[-2] {BBAA} - - mov y0, e_ // y0 = e - mov y1, a_ // y1 = a - MY_ROR y0, (25-11) // y0 = e >> (25-11) - - //vmovdqa XTMP4, XTMP2 // XTMP4 = W[-2] {BBAA} - - xor y0, e_ // y0 = e ^ (e >> (25-11)) - MY_ROR y1, (22-13) // y1 = a >> (22-13) - mov y2, f_ // y2 = f - xor y1, a_ // y1 = a ^ (a >> (22-13) - MY_ROR y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - - vpsrld XTMP4, XTMP2, 10 // XTMP4 = W[-2] >> 10 {BBAA} - - xor y2, g_ // y2 = f^g - - vpsrlq XTMP3, XTMP2, 19 // XTMP3 = W[-2] MY_ROR 19 {xBxA} - - xor y0, e_ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e_ // y2 = (f^g)&e - - vpsrlq XTMP2, XTMP2, 17 // XTMP2 = W[-2] MY_ROR 17 {xBxA} - - MY_ROR y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - xor y1, a_ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) - xor y2, g_ // y2 = CH = ((f^g)&e)^g - MY_ROR y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + add y2, y0 + add y2, [rsp + 1*4] + MY_ROR y1, 2 + vpxor XTMP3, XTMP3, XTMP2 + mov y0, \rh + add \rg, y2 + mov y2, \rh + vpxor XTMP1, XTMP3, XTMP4 + or y0, \rb + add \rc, \rg + and y2, \rb + vpshufd XTMP2, \x3, 0b11111010 + and y0, \ra + add \rg, y1 + vpaddd XTMP0, XTMP0, XTMP1 + or y0, y2 + add \rg, y0 + + // Round 2: a=rg, b=rh, c=ra, d=rb, e=rc, f=rd, g=re, h=rf + mov y0, \rc + mov y1, \rg + MY_ROR y0, (25-11) + xor y0, \rc + MY_ROR y1, (22-13) + mov y2, \rd + xor y1, \rg + MY_ROR y0, (11-6) + vpsrld XTMP4, XTMP2, 10 + xor y2, \re + vpsrlq XTMP3, XTMP2, 19 + xor y0, \rc + and y2, \rc + vpsrlq XTMP2, XTMP2, 17 + MY_ROR y1, (13-2) + xor y1, \rg + xor y2, \re + MY_ROR y0, 6 vpxor XTMP2, XTMP2, XTMP3 - add y2, y0 // y2 = S1 + CH - MY_ROR y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) - add y2, [rsp + 2*4] // y2 = k + w + S1 + CH - vpxor XTMP4, XTMP4, XTMP2 // XTMP4 = s1 {xBxA} - mov y0, a_ // y0 = a - add h_, y2 // h = h + S1 + CH + k + w - mov y2, a_ // y2 = a - vpshufb XTMP4, XTMP4, SHUF_00BA // XTMP4 = s1 {00BA} - or y0, c_ // y0 = a|c - add d_, h_ // d = d + h + S1 + CH + k + w - and y2, c_ // y2 = a&c - vpaddd XTMP0, XTMP0, XTMP4 // XTMP0 = {..., ..., W[1], W[0]} - and y0, b_ // y0 = (a|c)&b - add h_, y1 // h = h + S1 + CH + k + w + S0 - //// compute high s1 - vpshufd XTMP2, XTMP0, 0b01010000 // XTMP2 = W[-2] {DDCC} - or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h_, y0 // h = h + S1 + CH + k + w + S0 + MAJ - -ROTATE_ARGS - //vmovdqa XTMP3, XTMP2 // XTMP3 = W[-2] {DDCC} - mov y0, e_ // y0 = e - MY_ROR y0, (25-11) // y0 = e >> (25-11) - mov y1, a_ // y1 = a - //vmovdqa XTMP5, XTMP2 // XTMP5 = W[-2] {DDCC} - MY_ROR y1, (22-13) // y1 = a >> (22-13) - xor y0, e_ // y0 = e ^ (e >> (25-11)) - mov y2, f_ // y2 = f - MY_ROR y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - - vpsrld XTMP5, XTMP2, 10 // XTMP5 = W[-2] >> 10 {DDCC} - - xor y1, a_ // y1 = a ^ (a >> (22-13) - xor y2, g_ // y2 = f^g - - vpsrlq XTMP3, XTMP2, 19 // XTMP3 = W[-2] MY_ROR 19 {xDxC} - - xor y0, e_ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e_ // y2 = (f^g)&e - MY_ROR y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - - vpsrlq XTMP2, XTMP2, 17 // XTMP2 = W[-2] MY_ROR 17 {xDxC} - - xor y1, a_ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) - MY_ROR y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - xor y2, g_ // y2 = CH = ((f^g)&e)^g - + add y2, y0 + MY_ROR y1, 2 + add y2, [rsp + 2*4] + vpxor XTMP4, XTMP4, XTMP2 + mov y0, \rg + add \rf, y2 + mov y2, \rg + vpshufb XTMP4, XTMP4, SHUF_00BA + or y0, \ra + add \rb, \rf + and y2, \ra + vpaddd XTMP0, XTMP0, XTMP4 + and y0, \rh + add \rf, y1 + vpshufd XTMP2, XTMP0, 0b01010000 + or y0, y2 + add \rf, y0 + + // Round 3: a=rf, b=rg, c=rh, d=ra, e=rb, f=rc, g=rd, h=re + mov y0, \rb + MY_ROR y0, (25-11) + mov y1, \rf + MY_ROR y1, (22-13) + xor y0, \rb + mov y2, \rc + MY_ROR y0, (11-6) + vpsrld XTMP5, XTMP2, 10 + xor y1, \rf + xor y2, \rd + vpsrlq XTMP3, XTMP2, 19 + xor y0, \rb + and y2, \rb + MY_ROR y1, (13-2) + vpsrlq XTMP2, XTMP2, 17 + xor y1, \rf + MY_ROR y0, 6 + xor y2, \rd vpxor XTMP2, XTMP2, XTMP3 - - MY_ROR y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) - add y2, y0 // y2 = S1 + CH - add y2, [rsp + 3*4] // y2 = k + w + S1 + CH - vpxor XTMP5, XTMP5, XTMP2 // XTMP5 = s1 {xDxC} - mov y0, a_ // y0 = a - add h_, y2 // h = h + S1 + CH + k + w - mov y2, a_ // y2 = a - vpshufb XTMP5, XTMP5, SHUF_DC00 // XTMP5 = s1 {DC00} - or y0, c_ // y0 = a|c - add d_, h_ // d = d + h + S1 + CH + k + w - and y2, c_ // y2 = a&c - vpaddd X0, XTMP5, XTMP0 // X0 = {W[3], W[2], W[1], W[0]} - and y0, b_ // y0 = (a|c)&b - add h_, y1 // h = h + S1 + CH + k + w + S0 - or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h_, y0 // h = h + S1 + CH + k + w + S0 + MAJ -ROTATE_ARGS -rotate_Xs + MY_ROR y1, 2 + add y2, y0 + add y2, [rsp + 3*4] + vpxor XTMP5, XTMP5, XTMP2 + mov y0, \rf + add \re, y2 + mov y2, \rf + vpshufb XTMP5, XTMP5, SHUF_DC00 + or y0, \rh + add \ra, \re + and y2, \rh + vpaddd \x0, XTMP5, XTMP0 + and y0, \rg + add \re, y1 + or y0, y2 + add \re, y0 .endm -.macro DO_ROUND base offset - mov y0, e_ // y0 = e +// Parameterized DO_ROUND - takes all 8 working registers as parameters +// No rotation at end - caller handles register rotation by passing different args +.macro DO_ROUND_P ra, rb, rc, rd, re, rf, rg, rh, base, offset + mov y0, \re // y0 = e MY_ROR y0, (25-11) // y0 = e >> (25-11) - mov y1, a_ // y1 = a - xor y0, e_ // y0 = e ^ (e >> (25-11)) + mov y1, \ra // y1 = a + xor y0, \re // y0 = e ^ (e >> (25-11)) MY_ROR y1, (22-13) // y1 = a >> (22-13) - mov y2, f_ // y2 = f - xor y1, a_ // y1 = a ^ (a >> (22-13) + mov y2, \rf // y2 = f + xor y1, \ra // y1 = a ^ (a >> (22-13) MY_ROR y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - xor y2, g_ // y2 = f^g - xor y0, e_ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + xor y2, \rg // y2 = f^g + xor y0, \re // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) MY_ROR y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - and y2, e_ // y2 = (f^g)&e - xor y1, a_ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + and y2, \re // y2 = (f^g)&e + xor y1, \ra // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) MY_ROR y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - xor y2, g_ // y2 = CH = ((f^g)&e)^g + xor y2, \rg // y2 = CH = ((f^g)&e)^g add y2, y0 // y2 = S1 + CH MY_ROR y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) add y2, [\base + \offset] // y2 = k + w + S1 + CH - mov y0, a_ // y0 = a - add h_, y2 // h = h + S1 + CH + k + w - mov y2, a_ // y2 = a - or y0, c_ // y0 = a|c - add d_, h_ // d = d + h + S1 + CH + k + w - and y2, c_ // y2 = a&c - and y0, b_ // y0 = (a|c)&b - add h_, y1 // h = h + S1 + CH + k + w + S0 + mov y0, \ra // y0 = a + add \rh, y2 // h = h + S1 + CH + k + w + mov y2, \ra // y2 = a + or y0, \rc // y0 = a|c + add \rd, \rh // d = d + h + S1 + CH + k + w + and y2, \rc // y2 = a&c + and y0, \rb // y0 = (a|c)&b + add \rh, y1 // h = h + S1 + CH + k + w + S0 or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h_, y0 // h = h + S1 + CH + k + w + S0 + MAJ - ROTATE_ARGS + add \rh, y0 // h = h + S1 + CH + k + w + S0 + MAJ .endm .global hashtree_sha256_avx_x1 @@ -465,45 +413,101 @@ hashtree_sha256_avx_x1: COPY_XMM_AND_BSWAP X3, [DATA_PTR + 3*16], BYTE_FLIP_MASK //; schedule 48 input dwords, by doing 3 rounds of 16 each -.rept 3 + //; Rep 1 of 3 .align 32 - vpaddd XFER, X0, [TBL + 0*16] + vpaddd XFER, INI_X0, [TBL + 0*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X0, INI_X1, INI_X2, INI_X3 + + vpaddd XFER, INI_X1, [TBL + 1*16] vmovdqa [rsp], XFER - FOUR_ROUNDS_AND_SCHED + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X1, INI_X2, INI_X3, INI_X0 - vpaddd XFER, X0, [TBL + 1*16] + vpaddd XFER, INI_X2, [TBL + 2*16] vmovdqa [rsp], XFER - FOUR_ROUNDS_AND_SCHED + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X2, INI_X3, INI_X0, INI_X1 - vpaddd XFER, X0, [TBL + 2*16] + vpaddd XFER, INI_X3, [TBL + 3*16] vmovdqa [rsp], XFER - FOUR_ROUNDS_AND_SCHED + add TBL, 4*16 + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X3, INI_X0, INI_X1, INI_X2 + + //; Rep 2 of 3 +.align 32 + vpaddd XFER, INI_X0, [TBL + 0*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X0, INI_X1, INI_X2, INI_X3 + + vpaddd XFER, INI_X1, [TBL + 1*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X1, INI_X2, INI_X3, INI_X0 + + vpaddd XFER, INI_X2, [TBL + 2*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X2, INI_X3, INI_X0, INI_X1 + + vpaddd XFER, INI_X3, [TBL + 3*16] + vmovdqa [rsp], XFER + add TBL, 4*16 + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X3, INI_X0, INI_X1, INI_X2 + + //; Rep 3 of 3 +.align 32 + vpaddd XFER, INI_X0, [TBL + 0*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X0, INI_X1, INI_X2, INI_X3 - vpaddd XFER, X0, [TBL + 3*16] + vpaddd XFER, INI_X1, [TBL + 1*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X1, INI_X2, INI_X3, INI_X0 + + vpaddd XFER, INI_X2, [TBL + 2*16] + vmovdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X2, INI_X3, INI_X0, INI_X1 + + vpaddd XFER, INI_X3, [TBL + 3*16] vmovdqa [rsp], XFER add TBL, 4*16 - FOUR_ROUNDS_AND_SCHED -.endr + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X3, INI_X0, INI_X1, INI_X2 + +//; Rounds 48-63 (2 reps of 8 rounds each) + //; Rep 1: rounds 48-55 + vpaddd XFER, X0, [TBL + 0*16] + vmovdqa [rsp], XFER + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, rsp, 0 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, rsp, 4 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, rsp, 8 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, rsp, 12 + + vpaddd XFER, X1, [TBL + 1*16] + vmovdqa [rsp], XFER + add TBL, 2*16 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, rsp, 0 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, rsp, 4 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, rsp, 8 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, rsp, 12 + + vmovdqa X0, X2 + vmovdqa X1, X3 -.rept 2 + //; Rep 2: rounds 56-63 vpaddd XFER, X0, [TBL + 0*16] vmovdqa [rsp], XFER - DO_ROUND rsp, 0 - DO_ROUND rsp, 4 - DO_ROUND rsp, 8 - DO_ROUND rsp, 12 + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, rsp, 0 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, rsp, 4 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, rsp, 8 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, rsp, 12 vpaddd XFER, X1, [TBL + 1*16] vmovdqa [rsp], XFER add TBL, 2*16 - DO_ROUND rsp, 0 - DO_ROUND rsp, 4 - DO_ROUND rsp, 8 - DO_ROUND rsp, 12 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, rsp, 0 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, rsp, 4 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, rsp, 8 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, rsp, 12 vmovdqa X0, X2 vmovdqa X1, X3 -.endr // add old digest @@ -533,11 +537,79 @@ hashtree_sha256_avx_x1: lea TBL,[rip + .LPADDING] -.set .Li, 0 -.rept 64 - DO_ROUND TBL, .Li - .set .Li, .Li+4 -.endr +//; 64 padding rounds - fully unrolled with explicit registers + //; Rounds 0-7 (cycle 1) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 0 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 4 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 8 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 12 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 16 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 20 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 24 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 28 + //; Rounds 8-15 (cycle 2) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 32 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 36 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 40 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 44 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 48 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 52 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 56 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 60 + //; Rounds 16-23 (cycle 3) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 64 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 68 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 72 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 76 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 80 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 84 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 88 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 92 + //; Rounds 24-31 (cycle 4) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 96 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 100 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 104 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 108 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 112 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 116 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 120 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 124 + //; Rounds 32-39 (cycle 5) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 128 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 132 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 136 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 140 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 144 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 148 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 152 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 156 + //; Rounds 40-47 (cycle 6) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 160 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 164 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 168 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 172 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 176 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 180 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 184 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 188 + //; Rounds 48-55 (cycle 7) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 192 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 196 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 200 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 204 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 208 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 212 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 216 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 220 + //; Rounds 56-63 (cycle 8) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 224 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 228 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 232 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 236 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 240 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 244 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 248 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 252 //; add the previous digest add a_, [rsp + _DIGEST + 0*4] diff --git a/src/sha256_avx_x16.S b/src/sha256_avx_x16.S index 8bdff6b..d958e80 100644 --- a/src/sha256_avx_x16.S +++ b/src/sha256_avx_x16.S @@ -53,14 +53,25 @@ Copyright (c) 2012-2023, Intel Corporation #define PADDING arg5 #define DIGEST r11 -.equ A, zmm0 -.equ B, zmm1 -.equ C, zmm2 -.equ D, zmm3 -.equ E, zmm4 -.equ F, zmm5 -.equ G, zmm6 -.equ H, zmm7 +// Initial register assignments for A-H (used by parameterized macros) +#define INI_A zmm0 +#define INI_B zmm1 +#define INI_C zmm2 +#define INI_D zmm3 +#define INI_E zmm4 +#define INI_F zmm5 +#define INI_G zmm6 +#define INI_H zmm7 + +// Aliases for non-macro code (at initial rotation state) +#define A INI_A +#define B INI_B +#define C INI_C +#define D INI_D +#define E INI_E +#define F INI_F +#define G INI_G +#define H INI_H #define T1 zmm8 #define TMP0 zmm9 @@ -88,22 +99,41 @@ Copyright (c) 2012-2023, Intel Corporation #define YW14 ymm30 #define YW15 ymm31 -.equ W0, zmm16 -.equ W1, zmm17 -.equ W2, zmm18 -.equ W3, zmm19 -.equ W4, zmm20 -.equ W5, zmm21 -.equ W6, zmm22 -.equ W7, zmm23 -.equ W8, zmm24 -.equ W9, zmm25 -.equ W10, zmm26 -.equ W11, zmm27 -.equ W12, zmm28 -.equ W13, zmm29 -.equ W14, zmm30 -.equ W15, zmm31 +// Initial register assignments for W0-W15 (used by parameterized macros) +#define INI_W0 zmm16 +#define INI_W1 zmm17 +#define INI_W2 zmm18 +#define INI_W3 zmm19 +#define INI_W4 zmm20 +#define INI_W5 zmm21 +#define INI_W6 zmm22 +#define INI_W7 zmm23 +#define INI_W8 zmm24 +#define INI_W9 zmm25 +#define INI_W10 zmm26 +#define INI_W11 zmm27 +#define INI_W12 zmm28 +#define INI_W13 zmm29 +#define INI_W14 zmm30 +#define INI_W15 zmm31 + +// Aliases for non-macro code (at initial rotation state) +#define W0 INI_W0 +#define W1 INI_W1 +#define W2 INI_W2 +#define W3 INI_W3 +#define W4 INI_W4 +#define W5 INI_W5 +#define W6 INI_W6 +#define W7 INI_W7 +#define W8 INI_W8 +#define W9 INI_W9 +#define W10 INI_W10 +#define W11 INI_W11 +#define W12 INI_W12 +#define W13 INI_W13 +#define W14 INI_W14 +#define W15 INI_W15 # Macros @@ -283,66 +313,36 @@ Copyright (c) 2012-2023, Intel Corporation vmovdqu32 \r2, \t1 // r2 = {p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2} .endm -.macro ROTATE_ARGS -.equ TMP_, H -.equ H, G -.equ G, F -.equ F, E -.equ E, D -.equ D, C -.equ C, B -.equ B, A -.equ A, TMP_ -.endm - -.macro ROTATE_ZMMS -.equ W_, W0 -.equ W0, W1 -.equ W1, W2 -.equ W2, W3 -.equ W3, W4 -.equ W4, W5 -.equ W5, W6 -.equ W6, W7 -.equ W7, W8 -.equ W8, W9 -.equ W9, W10 -.equ W10, W11 -.equ W11, W12 -.equ W12, W13 -.equ W13, W14 -.equ W14, W15 -.equ W15, W_ -.endm +// ROTATE_ARGS and ROTATE_ZMMS removed - using parameterized macros with explicit registers instead -.macro PROCESS_LOOP WT -.if .Lpadding - 1 - vpaddd T1, H, TMP3 // T1 = H + Kt +// Parameterized PROCESS_LOOP with explicit registers (no rotation) +.macro PROCESS_LOOP_P WT, ra, rb, rc, rd, re, rf, rg, rh, is_padding +.if \is_padding - 1 + vpaddd T1, \rh, TMP3 // T1 = H + Kt .endif - vmovdqa32 TMP0, E - vprord TMP1, E, 6 // ROR_6(E) - vprord TMP2, E, 11 // ROR_11(E) - vprord TMP3, E, 25 // ROR_25(E) - vpternlogd TMP0, F, G, 0xCA // TMP0 = CH(E,F,G) -.if .Lpadding - 1 + vmovdqa32 TMP0, \re + vprord TMP1, \re, 6 // ROR_6(E) + vprord TMP2, \re, 11 // ROR_11(E) + vprord TMP3, \re, 25 // ROR_25(E) + vpternlogd TMP0, \rf, \rg, 0xCA // TMP0 = CH(E,F,G) +.if \is_padding - 1 vpaddd T1, T1, \WT // T1 = T1 + Wt .else - vpaddd T1, H, \WT // T1 = H + Wt + Kt + vpaddd T1, \rh, \WT // T1 = H + Wt + Kt .endif vpternlogd TMP1, TMP2, TMP3, 0x96 // TMP1 = SIGMA1(E) vpaddd T1, T1, TMP0 // T1 = T1 + CH(E,F,G) vpaddd T1, T1, TMP1 // T1 = T1 + SIGMA1(E) - vpaddd D, D, T1 // D = D + T1 - - vprord H, A, 2 // ROR_2(A) - vprord TMP2, A, 13 // ROR_13(A) - vprord TMP3, A, 22 // ROR_22(A) - vmovdqa32 TMP0, A - vpternlogd TMP0, B, C, 0xE8 // TMP0 = MAJ(A,B,C) - vpternlogd H, TMP2, TMP3, 0x96 // H(T2) = SIGMA0(A) - vpaddd H, H, TMP0 // H(T2) = SIGMA0(A) + MAJ(A,B,C) - vpaddd H, H, T1 // H(A) = H(T2) + T1 - ROTATE_ARGS + vpaddd \rd, \rd, T1 // D = D + T1 + + vprord \rh, \ra, 2 // ROR_2(A) + vprord TMP2, \ra, 13 // ROR_13(A) + vprord TMP3, \ra, 22 // ROR_22(A) + vmovdqa32 TMP0, \ra + vpternlogd TMP0, \rb, \rc, 0xE8 // TMP0 = MAJ(A,B,C) + vpternlogd \rh, TMP2, TMP3, 0x96 // H(T2) = SIGMA0(A) + vpaddd \rh, \rh, TMP0 // H(T2) = SIGMA0(A) + MAJ(A,B,C) + vpaddd \rh, \rh, T1 // H(A) = H(T2) + T1 .endm .macro MSG_SCHED_ROUND_16_63 WT, WTp1, WTp9, WTp14 @@ -1083,25 +1083,267 @@ hashtree_sha256_avx512_x16: TRANSPOSE16_U32_PRELOADED W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, \ W11, W12, W13, W14, W15, TMP0, TMP1, TMP4, TMP5 -.rept 16 - vpshufb W0, W0, TMP2 - ROTATE_ZMMS -.endr - -.set .LI, 0 -.rept 48 - PROCESS_LOOP W0 - .set .LI, .LI+1 - vmovdqa32 TMP3, [TBL + 64*.LI] // Next Kt - MSG_SCHED_ROUND_16_63 W0, W1, W9, W14 - ROTATE_ZMMS -.endr -.rept 16 - PROCESS_LOOP W0 - .set .LI, .LI+1 - vmovdqa32 TMP3, [TBL + 64*.LI] // Next Kt - ROTATE_ZMMS -.endr + // Byte swap W0-W15 (expanded from .rept 16 + ROTATE_ZMMS) + vpshufb INI_W0, INI_W0, TMP2 + vpshufb INI_W1, INI_W1, TMP2 + vpshufb INI_W2, INI_W2, TMP2 + vpshufb INI_W3, INI_W3, TMP2 + vpshufb INI_W4, INI_W4, TMP2 + vpshufb INI_W5, INI_W5, TMP2 + vpshufb INI_W6, INI_W6, TMP2 + vpshufb INI_W7, INI_W7, TMP2 + vpshufb INI_W8, INI_W8, TMP2 + vpshufb INI_W9, INI_W9, TMP2 + vpshufb INI_W10, INI_W10, TMP2 + vpshufb INI_W11, INI_W11, TMP2 + vpshufb INI_W12, INI_W12, TMP2 + vpshufb INI_W13, INI_W13, TMP2 + vpshufb INI_W14, INI_W14, TMP2 + vpshufb INI_W15, INI_W15, TMP2 + + // Rounds 0-47: PROCESS_LOOP + MSG_SCHED (expanded) + // Each round uses A-H rotation (8-cycle) and W rotation (16-cycle) + // Round 0: A-H state 0, W state 0 + PROCESS_LOOP_P INI_W0, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*1] + MSG_SCHED_ROUND_16_63 INI_W0, INI_W1, INI_W9, INI_W14 + // Round 1: A-H state 1, W state 1 + PROCESS_LOOP_P INI_W1, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*2] + MSG_SCHED_ROUND_16_63 INI_W1, INI_W2, INI_W10, INI_W15 + // Round 2: A-H state 2, W state 2 + PROCESS_LOOP_P INI_W2, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*3] + MSG_SCHED_ROUND_16_63 INI_W2, INI_W3, INI_W11, INI_W0 + // Round 3: A-H state 3, W state 3 + PROCESS_LOOP_P INI_W3, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*4] + MSG_SCHED_ROUND_16_63 INI_W3, INI_W4, INI_W12, INI_W1 + // Round 4: A-H state 4, W state 4 + PROCESS_LOOP_P INI_W4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*5] + MSG_SCHED_ROUND_16_63 INI_W4, INI_W5, INI_W13, INI_W2 + // Round 5: A-H state 5, W state 5 + PROCESS_LOOP_P INI_W5, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*6] + MSG_SCHED_ROUND_16_63 INI_W5, INI_W6, INI_W14, INI_W3 + // Round 6: A-H state 6, W state 6 + PROCESS_LOOP_P INI_W6, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*7] + MSG_SCHED_ROUND_16_63 INI_W6, INI_W7, INI_W15, INI_W4 + // Round 7: A-H state 7, W state 7 + PROCESS_LOOP_P INI_W7, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*8] + MSG_SCHED_ROUND_16_63 INI_W7, INI_W8, INI_W0, INI_W5 + // Round 8: A-H state 0, W state 8 + PROCESS_LOOP_P INI_W8, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*9] + MSG_SCHED_ROUND_16_63 INI_W8, INI_W9, INI_W1, INI_W6 + // Round 9: A-H state 1, W state 9 + PROCESS_LOOP_P INI_W9, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*10] + MSG_SCHED_ROUND_16_63 INI_W9, INI_W10, INI_W2, INI_W7 + // Round 10: A-H state 2, W state 10 + PROCESS_LOOP_P INI_W10, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*11] + MSG_SCHED_ROUND_16_63 INI_W10, INI_W11, INI_W3, INI_W8 + // Round 11: A-H state 3, W state 11 + PROCESS_LOOP_P INI_W11, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*12] + MSG_SCHED_ROUND_16_63 INI_W11, INI_W12, INI_W4, INI_W9 + // Round 12: A-H state 4, W state 12 + PROCESS_LOOP_P INI_W12, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*13] + MSG_SCHED_ROUND_16_63 INI_W12, INI_W13, INI_W5, INI_W10 + // Round 13: A-H state 5, W state 13 + PROCESS_LOOP_P INI_W13, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*14] + MSG_SCHED_ROUND_16_63 INI_W13, INI_W14, INI_W6, INI_W11 + // Round 14: A-H state 6, W state 14 + PROCESS_LOOP_P INI_W14, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*15] + MSG_SCHED_ROUND_16_63 INI_W14, INI_W15, INI_W7, INI_W12 + // Round 15: A-H state 7, W state 15 + PROCESS_LOOP_P INI_W15, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*16] + MSG_SCHED_ROUND_16_63 INI_W15, INI_W0, INI_W8, INI_W13 + // Round 16: A-H state 0, W state 0 + PROCESS_LOOP_P INI_W0, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*17] + MSG_SCHED_ROUND_16_63 INI_W0, INI_W1, INI_W9, INI_W14 + // Round 17: A-H state 1, W state 1 + PROCESS_LOOP_P INI_W1, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*18] + MSG_SCHED_ROUND_16_63 INI_W1, INI_W2, INI_W10, INI_W15 + // Round 18: A-H state 2, W state 2 + PROCESS_LOOP_P INI_W2, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*19] + MSG_SCHED_ROUND_16_63 INI_W2, INI_W3, INI_W11, INI_W0 + // Round 19: A-H state 3, W state 3 + PROCESS_LOOP_P INI_W3, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*20] + MSG_SCHED_ROUND_16_63 INI_W3, INI_W4, INI_W12, INI_W1 + // Round 20: A-H state 4, W state 4 + PROCESS_LOOP_P INI_W4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*21] + MSG_SCHED_ROUND_16_63 INI_W4, INI_W5, INI_W13, INI_W2 + // Round 21: A-H state 5, W state 5 + PROCESS_LOOP_P INI_W5, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*22] + MSG_SCHED_ROUND_16_63 INI_W5, INI_W6, INI_W14, INI_W3 + // Round 22: A-H state 6, W state 6 + PROCESS_LOOP_P INI_W6, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*23] + MSG_SCHED_ROUND_16_63 INI_W6, INI_W7, INI_W15, INI_W4 + // Round 23: A-H state 7, W state 7 + PROCESS_LOOP_P INI_W7, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*24] + MSG_SCHED_ROUND_16_63 INI_W7, INI_W8, INI_W0, INI_W5 + // Round 24: A-H state 0, W state 8 + PROCESS_LOOP_P INI_W8, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*25] + MSG_SCHED_ROUND_16_63 INI_W8, INI_W9, INI_W1, INI_W6 + // Round 25: A-H state 1, W state 9 + PROCESS_LOOP_P INI_W9, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*26] + MSG_SCHED_ROUND_16_63 INI_W9, INI_W10, INI_W2, INI_W7 + // Round 26: A-H state 2, W state 10 + PROCESS_LOOP_P INI_W10, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*27] + MSG_SCHED_ROUND_16_63 INI_W10, INI_W11, INI_W3, INI_W8 + // Round 27: A-H state 3, W state 11 + PROCESS_LOOP_P INI_W11, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*28] + MSG_SCHED_ROUND_16_63 INI_W11, INI_W12, INI_W4, INI_W9 + // Round 28: A-H state 4, W state 12 + PROCESS_LOOP_P INI_W12, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*29] + MSG_SCHED_ROUND_16_63 INI_W12, INI_W13, INI_W5, INI_W10 + // Round 29: A-H state 5, W state 13 + PROCESS_LOOP_P INI_W13, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*30] + MSG_SCHED_ROUND_16_63 INI_W13, INI_W14, INI_W6, INI_W11 + // Round 30: A-H state 6, W state 14 + PROCESS_LOOP_P INI_W14, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*31] + MSG_SCHED_ROUND_16_63 INI_W14, INI_W15, INI_W7, INI_W12 + // Round 31: A-H state 7, W state 15 + PROCESS_LOOP_P INI_W15, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*32] + MSG_SCHED_ROUND_16_63 INI_W15, INI_W0, INI_W8, INI_W13 + // Round 32: A-H state 0, W state 0 + PROCESS_LOOP_P INI_W0, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*33] + MSG_SCHED_ROUND_16_63 INI_W0, INI_W1, INI_W9, INI_W14 + // Round 33: A-H state 1, W state 1 + PROCESS_LOOP_P INI_W1, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*34] + MSG_SCHED_ROUND_16_63 INI_W1, INI_W2, INI_W10, INI_W15 + // Round 34: A-H state 2, W state 2 + PROCESS_LOOP_P INI_W2, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*35] + MSG_SCHED_ROUND_16_63 INI_W2, INI_W3, INI_W11, INI_W0 + // Round 35: A-H state 3, W state 3 + PROCESS_LOOP_P INI_W3, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*36] + MSG_SCHED_ROUND_16_63 INI_W3, INI_W4, INI_W12, INI_W1 + // Round 36: A-H state 4, W state 4 + PROCESS_LOOP_P INI_W4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*37] + MSG_SCHED_ROUND_16_63 INI_W4, INI_W5, INI_W13, INI_W2 + // Round 37: A-H state 5, W state 5 + PROCESS_LOOP_P INI_W5, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*38] + MSG_SCHED_ROUND_16_63 INI_W5, INI_W6, INI_W14, INI_W3 + // Round 38: A-H state 6, W state 6 + PROCESS_LOOP_P INI_W6, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*39] + MSG_SCHED_ROUND_16_63 INI_W6, INI_W7, INI_W15, INI_W4 + // Round 39: A-H state 7, W state 7 + PROCESS_LOOP_P INI_W7, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*40] + MSG_SCHED_ROUND_16_63 INI_W7, INI_W8, INI_W0, INI_W5 + // Round 40: A-H state 0, W state 8 + PROCESS_LOOP_P INI_W8, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*41] + MSG_SCHED_ROUND_16_63 INI_W8, INI_W9, INI_W1, INI_W6 + // Round 41: A-H state 1, W state 9 + PROCESS_LOOP_P INI_W9, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*42] + MSG_SCHED_ROUND_16_63 INI_W9, INI_W10, INI_W2, INI_W7 + // Round 42: A-H state 2, W state 10 + PROCESS_LOOP_P INI_W10, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*43] + MSG_SCHED_ROUND_16_63 INI_W10, INI_W11, INI_W3, INI_W8 + // Round 43: A-H state 3, W state 11 + PROCESS_LOOP_P INI_W11, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*44] + MSG_SCHED_ROUND_16_63 INI_W11, INI_W12, INI_W4, INI_W9 + // Round 44: A-H state 4, W state 12 + PROCESS_LOOP_P INI_W12, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*45] + MSG_SCHED_ROUND_16_63 INI_W12, INI_W13, INI_W5, INI_W10 + // Round 45: A-H state 5, W state 13 + PROCESS_LOOP_P INI_W13, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*46] + MSG_SCHED_ROUND_16_63 INI_W13, INI_W14, INI_W6, INI_W11 + // Round 46: A-H state 6, W state 14 + PROCESS_LOOP_P INI_W14, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*47] + MSG_SCHED_ROUND_16_63 INI_W14, INI_W15, INI_W7, INI_W12 + // Round 47: A-H state 7, W state 15 + PROCESS_LOOP_P INI_W15, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*48] + MSG_SCHED_ROUND_16_63 INI_W15, INI_W0, INI_W8, INI_W13 + + // Rounds 48-63: PROCESS_LOOP only (no message schedule) + // Round 48: A-H state 0, W state 0 + PROCESS_LOOP_P INI_W0, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*49] + // Round 49: A-H state 1, W state 1 + PROCESS_LOOP_P INI_W1, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*50] + // Round 50: A-H state 2, W state 2 + PROCESS_LOOP_P INI_W2, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*51] + // Round 51: A-H state 3, W state 3 + PROCESS_LOOP_P INI_W3, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*52] + // Round 52: A-H state 4, W state 4 + PROCESS_LOOP_P INI_W4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*53] + // Round 53: A-H state 5, W state 5 + PROCESS_LOOP_P INI_W5, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*54] + // Round 54: A-H state 6, W state 6 + PROCESS_LOOP_P INI_W6, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*55] + // Round 55: A-H state 7, W state 7 + PROCESS_LOOP_P INI_W7, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 + vmovdqa32 TMP3, [TBL + 64*56] + // Round 56: A-H state 0, W state 8 + PROCESS_LOOP_P INI_W8, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 0 + vmovdqa32 TMP3, [TBL + 64*57] + // Round 57: A-H state 1, W state 9 + PROCESS_LOOP_P INI_W9, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 0 + vmovdqa32 TMP3, [TBL + 64*58] + // Round 58: A-H state 2, W state 10 + PROCESS_LOOP_P INI_W10, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 0 + vmovdqa32 TMP3, [TBL + 64*59] + // Round 59: A-H state 3, W state 11 + PROCESS_LOOP_P INI_W11, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 0 + vmovdqa32 TMP3, [TBL + 64*60] + // Round 60: A-H state 4, W state 12 + PROCESS_LOOP_P INI_W12, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 0 + vmovdqa32 TMP3, [TBL + 64*61] + // Round 61: A-H state 5, W state 13 + PROCESS_LOOP_P INI_W13, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 0 + vmovdqa32 TMP3, [TBL + 64*62] + // Round 62: A-H state 6, W state 14 + PROCESS_LOOP_P INI_W14, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 0 + vmovdqa32 TMP3, [TBL + 64*63] + // Round 63: A-H state 7, W state 15 + PROCESS_LOOP_P INI_W15, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 0 # Add old digest vpaddd A, A, [DIGEST + 0*64] @@ -1127,14 +1369,199 @@ hashtree_sha256_avx512_x16: vmovdqa32 TMP5, [rip + .LPSHUFFLE_TRANSPOSE_MASK3] vmovdqa32 TMP6, [rip + .LPSHUFFLE_TRANSPOSE_MASK4] - # Rounds with padding -.set .Lpadding, 1 -.set .LI, 0 -.rept 64 - vmovdqa32 TMP4, [PADDING + 64*.LI] // W + K - PROCESS_LOOP TMP4 - .set .LI, .LI+1 -.endr + # Rounds with padding (64 rounds, manually unrolled) + # Round 0: A=INI_A, B=INI_B, C=INI_C, D=INI_D, E=INI_E, F=INI_F, G=INI_G, H=INI_H + vmovdqa32 TMP4, [PADDING + 64*0] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 1: A=INI_H, B=INI_A, C=INI_B, D=INI_C, E=INI_D, F=INI_E, G=INI_F, H=INI_G + vmovdqa32 TMP4, [PADDING + 64*1] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 2: A=INI_G, B=INI_H, C=INI_A, D=INI_B, E=INI_C, F=INI_D, G=INI_E, H=INI_F + vmovdqa32 TMP4, [PADDING + 64*2] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 3: A=INI_F, B=INI_G, C=INI_H, D=INI_A, E=INI_B, F=INI_C, G=INI_D, H=INI_E + vmovdqa32 TMP4, [PADDING + 64*3] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 4: A=INI_E, B=INI_F, C=INI_G, D=INI_H, E=INI_A, F=INI_B, G=INI_C, H=INI_D + vmovdqa32 TMP4, [PADDING + 64*4] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 5: A=INI_D, B=INI_E, C=INI_F, D=INI_G, E=INI_H, F=INI_A, G=INI_B, H=INI_C + vmovdqa32 TMP4, [PADDING + 64*5] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 6: A=INI_C, B=INI_D, C=INI_E, D=INI_F, E=INI_G, F=INI_H, G=INI_A, H=INI_B + vmovdqa32 TMP4, [PADDING + 64*6] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 7: A=INI_B, B=INI_C, C=INI_D, D=INI_E, E=INI_F, F=INI_G, G=INI_H, H=INI_A + vmovdqa32 TMP4, [PADDING + 64*7] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 8: A=INI_A, B=INI_B, C=INI_C, D=INI_D, E=INI_E, F=INI_F, G=INI_G, H=INI_H + vmovdqa32 TMP4, [PADDING + 64*8] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 9 + vmovdqa32 TMP4, [PADDING + 64*9] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 10 + vmovdqa32 TMP4, [PADDING + 64*10] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 11 + vmovdqa32 TMP4, [PADDING + 64*11] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 12 + vmovdqa32 TMP4, [PADDING + 64*12] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 13 + vmovdqa32 TMP4, [PADDING + 64*13] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 14 + vmovdqa32 TMP4, [PADDING + 64*14] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 15 + vmovdqa32 TMP4, [PADDING + 64*15] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 16 + vmovdqa32 TMP4, [PADDING + 64*16] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 17 + vmovdqa32 TMP4, [PADDING + 64*17] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 18 + vmovdqa32 TMP4, [PADDING + 64*18] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 19 + vmovdqa32 TMP4, [PADDING + 64*19] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 20 + vmovdqa32 TMP4, [PADDING + 64*20] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 21 + vmovdqa32 TMP4, [PADDING + 64*21] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 22 + vmovdqa32 TMP4, [PADDING + 64*22] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 23 + vmovdqa32 TMP4, [PADDING + 64*23] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 24 + vmovdqa32 TMP4, [PADDING + 64*24] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 25 + vmovdqa32 TMP4, [PADDING + 64*25] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 26 + vmovdqa32 TMP4, [PADDING + 64*26] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 27 + vmovdqa32 TMP4, [PADDING + 64*27] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 28 + vmovdqa32 TMP4, [PADDING + 64*28] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 29 + vmovdqa32 TMP4, [PADDING + 64*29] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 30 + vmovdqa32 TMP4, [PADDING + 64*30] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 31 + vmovdqa32 TMP4, [PADDING + 64*31] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 32 + vmovdqa32 TMP4, [PADDING + 64*32] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 33 + vmovdqa32 TMP4, [PADDING + 64*33] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 34 + vmovdqa32 TMP4, [PADDING + 64*34] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 35 + vmovdqa32 TMP4, [PADDING + 64*35] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 36 + vmovdqa32 TMP4, [PADDING + 64*36] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 37 + vmovdqa32 TMP4, [PADDING + 64*37] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 38 + vmovdqa32 TMP4, [PADDING + 64*38] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 39 + vmovdqa32 TMP4, [PADDING + 64*39] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 40 + vmovdqa32 TMP4, [PADDING + 64*40] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 41 + vmovdqa32 TMP4, [PADDING + 64*41] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 42 + vmovdqa32 TMP4, [PADDING + 64*42] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 43 + vmovdqa32 TMP4, [PADDING + 64*43] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 44 + vmovdqa32 TMP4, [PADDING + 64*44] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 45 + vmovdqa32 TMP4, [PADDING + 64*45] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 46 + vmovdqa32 TMP4, [PADDING + 64*46] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 47 + vmovdqa32 TMP4, [PADDING + 64*47] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 48 + vmovdqa32 TMP4, [PADDING + 64*48] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 49 + vmovdqa32 TMP4, [PADDING + 64*49] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 50 + vmovdqa32 TMP4, [PADDING + 64*50] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 51 + vmovdqa32 TMP4, [PADDING + 64*51] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 52 + vmovdqa32 TMP4, [PADDING + 64*52] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 53 + vmovdqa32 TMP4, [PADDING + 64*53] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 54 + vmovdqa32 TMP4, [PADDING + 64*54] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 55 + vmovdqa32 TMP4, [PADDING + 64*55] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 + # Round 56 + vmovdqa32 TMP4, [PADDING + 64*56] + PROCESS_LOOP_P TMP4, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, 1 + # Round 57 + vmovdqa32 TMP4, [PADDING + 64*57] + PROCESS_LOOP_P TMP4, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, 1 + # Round 58 + vmovdqa32 TMP4, [PADDING + 64*58] + PROCESS_LOOP_P TMP4, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, INI_F, 1 + # Round 59 + vmovdqa32 TMP4, [PADDING + 64*59] + PROCESS_LOOP_P TMP4, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, INI_E, 1 + # Round 60 + vmovdqa32 TMP4, [PADDING + 64*60] + PROCESS_LOOP_P TMP4, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, INI_D, 1 + # Round 61 + vmovdqa32 TMP4, [PADDING + 64*61] + PROCESS_LOOP_P TMP4, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, INI_C, 1 + # Round 62 + vmovdqa32 TMP4, [PADDING + 64*62] + PROCESS_LOOP_P TMP4, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, INI_B, 1 + # Round 63 + vmovdqa32 TMP4, [PADDING + 64*63] + PROCESS_LOOP_P TMP4, INI_B, INI_C, INI_D, INI_E, INI_F, INI_G, INI_H, INI_A, 1 vmovdqa32 W8, [rip + .LPSHUFFLE_BYTE_FLIP_MASK] # Add old digest @@ -1151,10 +1578,15 @@ hashtree_sha256_avx512_x16: TRANSPOSE_8x16_U32 A, B, C, D, E, F, G, H,\ TMP0, TMP1, TMP2, TMP3, TMP5, TMP6 -.rept 8 - vpshufb A, A, W8 - ROTATE_ARGS -.endr + # Byte swap all 8 registers (unrolled from .rept 8 with ROTATE_ARGS) + vpshufb INI_A, INI_A, W8 + vpshufb INI_H, INI_H, W8 + vpshufb INI_G, INI_G, W8 + vpshufb INI_F, INI_F, W8 + vpshufb INI_E, INI_E, W8 + vpshufb INI_D, INI_D, W8 + vpshufb INI_C, INI_C, W8 + vpshufb INI_B, INI_B, W8 vmovdqu32 [OUTPUT_PTR + 0*64], A vmovdqu32 [OUTPUT_PTR + 1*64], B diff --git a/src/sha256_avx_x4.S b/src/sha256_avx_x4.S index fe7fbe9..7c8879f 100644 --- a/src/sha256_avx_x4.S +++ b/src/sha256_avx_x4.S @@ -174,45 +174,55 @@ Copyright (c) 2012-2023, Intel Corporation .long 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab .long 0x5be0cd19, 0x5be0cd19, 0x5be0cd19, 0x5be0cd19 -.LPSHUFFLE_BYTE_FLIP_MASK: +.LPSHUFFLE_BYTE_FLIP_MASK: .quad 0x0405060700010203, 0x0c0d0e0f08090a0b #ifdef __WIN64__ - .equiv OUTPUT_PTR, rcx // 1st arg - .equiv DATA_PTR, rdx // 2nd arg - .equiv NUM_BLKS, r8 // 3rd arg - .equiv TBL, rax + #define OUTPUT_PTR rcx + #define DATA_PTR rdx + #define NUM_BLKS r8 + #define TBL rax #else - .equiv OUTPUT_PTR, rdi // 1st arg - .equiv DATA_PTR, rsi // 2nd arg - .equiv NUM_BLKS, rdx // 3rd arg - .equiv TBL, rcx + #define OUTPUT_PTR rdi + #define DATA_PTR rsi + #define NUM_BLKS rdx + #define TBL rcx #endif -.equiv ROUND, r9 - -.equ a, xmm0 -.equ b, xmm1 -.equ c, xmm2 -.equ d, xmm3 -.equ e, xmm4 -.equ f, xmm5 -.equ g, xmm6 -.equ h, xmm7 - -.equiv a0, xmm8 -.equiv a1, xmm9 -.equiv a2, xmm10 - -.equiv TT0, xmm14 -.equiv TT1, xmm13 -.equiv TT2, xmm12 -.equiv TT3, xmm11 -.equiv TT4, xmm10 -.equiv TT5, xmm9 - -.equiv T1, xmm14 -.equiv TMP, xmm15 +#define ROUND r9 + +#define INI_a xmm0 +#define INI_b xmm1 +#define INI_c xmm2 +#define INI_d xmm3 +#define INI_e xmm4 +#define INI_f xmm5 +#define INI_g xmm6 +#define INI_h xmm7 + +// Aliases for non-macro code (at initial rotation state) +#define a INI_a +#define b INI_b +#define c INI_c +#define d INI_d +#define e INI_e +#define f INI_f +#define g INI_g +#define h INI_h + +#define a0 xmm8 +#define a1 xmm9 +#define a2 xmm10 + +#define TT0 xmm14 +#define TT1 xmm13 +#define TT2 xmm12 +#define TT3 xmm11 +#define TT4 xmm10 +#define TT5 xmm9 + +#define T1 xmm14 +#define TMP xmm15 #define SZ4 16 #define SHA256_DIGEST_WORD_SIZE 4 @@ -246,18 +256,6 @@ Copyright (c) 2012-2023, Intel Corporation vshufps \t0, \t0, \t1, 0x88 // t0 = {d0 c0 b0 a0} .endm -.macro ROTATE_ARGS -.equ TMP_, h -.equ h, g -.equ g, f -.equ f, e -.equ e, d -.equ d, c -.equ c, b -.equ b, a -.equ a, TMP_ -.endm - .macro PRORD3 reg, imm, tmp vpslld \tmp, \reg, (32-(\imm)) @@ -279,67 +277,67 @@ Copyright (c) 2012-2023, Intel Corporation PRORD_nd4 \dst, \amt, TMP, \src .endm -.macro ROUND_00_15 T1, index - PRORD_nd a0, e, (11-6) // sig1: a0 = (e >> 5) - - vpxor a2, f, g // ch: a2 = f^g - vpand a2, a2, e // ch: a2 = (f^g)&e - vpxor a2, a2, g // a2 = ch - - PRORD_nd a1, e, 25 // sig1: a1 = (e >> 25) -.if .Lpadding - 1 - vmovdqa [SZ4*(\index&0xf) + rsp + _DATA], \T1 - vpaddd \T1, \T1, [TBL + ROUND] // T1 = W + K -.else - vmovdqa \T1, [TBL + ROUND] -.endif - vpxor a0, a0, e // sig1: a0 = e ^ (e >> 5) +// Parameterized ROUND_00_15 - takes all 8 XMM registers as parameters +// No rotation at end - caller handles register rotation by passing different args +.macro ROUND_00_15_P ra, rb, rc, rd, re, rf, rg, rh, T1_reg, index, is_padding + PRORD_nd a0, \re, (11-6) // sig1: a0 = (e >> 5) + + vpxor a2, \rf, \rg // ch: a2 = f^g + vpand a2, a2, \re // ch: a2 = (f^g)&e + vpxor a2, a2, \rg // a2 = ch + + PRORD_nd a1, \re, 25 // sig1: a1 = (e >> 25) +.if \is_padding - 1 + vmovdqa [SZ4*(\index&0xf) + rsp + _DATA], \T1_reg + vpaddd \T1_reg, \T1_reg, [TBL + ROUND] // T1 = W + K +.else + vmovdqa \T1_reg, [TBL + ROUND] +.endif + vpxor a0, a0, \re // sig1: a0 = e ^ (e >> 5) PRORD a0, 6 // sig1: a0 = (e >> 6) ^ (e >> 11) - vpaddd h, h, a2 // h = h + ch - PRORD_nd a2, a, (13-2) // sig0: a2 = (a >> 11) - vpaddd h, h, \T1 // h = h + ch + W + K + vpaddd \rh, \rh, a2 // h = h + ch + PRORD_nd a2, \ra, (13-2) // sig0: a2 = (a >> 11) + vpaddd \rh, \rh, \T1_reg // h = h + ch + W + K vpxor a0, a0, a1 // a0 = sigma1 - PRORD_nd a1, a, 22 // sig0: a1 = (a >> 22) - vpxor \T1, a, c // maj: T1 = a^c + PRORD_nd a1, \ra, 22 // sig0: a1 = (a >> 22) + vpxor \T1_reg, \ra, \rc // maj: T1 = a^c add ROUND, SZ4 // ROUND++ - vpand \T1, \T1, b // maj: T1 = (a^c)&b - vpaddd h, h, a0 + vpand \T1_reg, \T1_reg, \rb // maj: T1 = (a^c)&b + vpaddd \rh, \rh, a0 - vpaddd d, d, h + vpaddd \rd, \rd, \rh - vpxor a2, a2, a // sig0: a2 = a ^ (a >> 11) + vpxor a2, a2, \ra // sig0: a2 = a ^ (a >> 11) PRORD a2, 2 // sig0: a2 = (a >> 2) ^ (a >> 13) vpxor a2, a2, a1 // a2 = sig0 - vpand a1, a, c // maj: a1 = a&c - vpor a1, a1, \T1 // a1 = maj - vpaddd h, h, a1 // h = h + ch + W + K + maj - vpaddd h, h, a2 // h = h + ch + W + K + maj + sigma0 - - ROTATE_ARGS + vpand a1, \ra, \rc // maj: a1 = a&c + vpor a1, a1, \T1_reg // a1 = maj + vpaddd \rh, \rh, a1 // h = h + ch + W + K + maj + vpaddd \rh, \rh, a2 // h = h + ch + W + K + maj + sigma0 .endm -//; arguments passed implicitly in preprocessor symbols i, a...h -.macro ROUND_16_XX T1, index - vmovdqa \T1, [SZ4*((\index-15)&0xf) + rsp + _DATA] +// Parameterized ROUND_16_XX - takes all 8 XMM registers as parameters +.macro ROUND_16_XX_P ra, rb, rc, rd, re, rf, rg, rh, T1_reg, index + vmovdqa \T1_reg, [SZ4*((\index-15)&0xf) + rsp + _DATA] vmovdqa a1, [SZ4*((\index-2)&0xf) + rsp + _DATA] - vmovdqa a0, \T1 - PRORD \T1, 18-7 + vmovdqa a0, \T1_reg + PRORD \T1_reg, 18-7 vmovdqa a2, a1 PRORD a1, 19-17 - vpxor \T1, \T1, a0 - PRORD \T1, 7 + vpxor \T1_reg, \T1_reg, a0 + PRORD \T1_reg, 7 vpxor a1, a1, a2 PRORD a1, 17 vpsrld a0, a0, 3 - vpxor \T1, \T1, a0 + vpxor \T1_reg, \T1_reg, a0 vpsrld a2, a2, 10 vpxor a1, a1, a2 - vpaddd \T1, \T1, [SZ4*((\index-16)&0xf) + rsp + _DATA] + vpaddd \T1_reg, \T1_reg, [SZ4*((\index-16)&0xf) + rsp + _DATA] vpaddd a1, a1, [SZ4*((\index-7)&0xf) + rsp + _DATA] - vpaddd \T1, \T1, a1 + vpaddd \T1_reg, \T1_reg, a1 - ROUND_00_15 \T1, \index + ROUND_00_15_P \ra, \rb, \rc, \rd, \re, \rf, \rg, \rh, \T1_reg, \index, 0 .endm .text @@ -369,7 +367,6 @@ hashtree_sha256_avx_x4: #endif .Lsha256_4_avx_loop: -.set .Lpadding, 0 cmp NUM_BLKS, 4 jl .Lsha256_4_avx_epilog @@ -388,32 +385,91 @@ hashtree_sha256_avx_x4: lea TBL, [rip + .LK256_4] -.set .Li, 0 -.rept 4 +//; Rounds 0-15: Load and process data (4 iterations of 4 rounds each) + //; Iteration 0: rounds 0-3 vmovdqa TMP, [rip + .LPSHUFFLE_BYTE_FLIP_MASK] - VMOVPS TT2,[DATA_PTR + 0*64 + .Li*16] - VMOVPS TT1,[DATA_PTR + 1*64 + .Li*16] - VMOVPS TT4,[DATA_PTR + 2*64 + .Li*16] - VMOVPS TT3,[DATA_PTR + 3*64 + .Li*16] + VMOVPS TT2,[DATA_PTR + 0*64 + 0*16] + VMOVPS TT1,[DATA_PTR + 1*64 + 0*16] + VMOVPS TT4,[DATA_PTR + 2*64 + 0*16] + VMOVPS TT3,[DATA_PTR + 3*64 + 0*16] TRANSPOSE TT2, TT1, TT4, TT3, TT0, TT5 vpshufb TT0, TT0, TMP vpshufb TT1, TT1, TMP vpshufb TT2, TT2, TMP vpshufb TT3, TT3, TMP - ROUND_00_15 TT0, 4*.Li - ROUND_00_15 TT1, 4*.Li + 1 - ROUND_00_15 TT2, 4*.Li + 2 - ROUND_00_15 TT3, 4*.Li + 3 -.set .Li, .Li+1 -.endr -.set .Li, 4*.Li + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TT0, 0, 0 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TT1, 1, 0 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TT2, 2, 0 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TT3, 3, 0 + + //; Iteration 1: rounds 4-7 + vmovdqa TMP, [rip + .LPSHUFFLE_BYTE_FLIP_MASK] + VMOVPS TT2,[DATA_PTR + 0*64 + 1*16] + VMOVPS TT1,[DATA_PTR + 1*64 + 1*16] + VMOVPS TT4,[DATA_PTR + 2*64 + 1*16] + VMOVPS TT3,[DATA_PTR + 3*64 + 1*16] + TRANSPOSE TT2, TT1, TT4, TT3, TT0, TT5 + vpshufb TT0, TT0, TMP + vpshufb TT1, TT1, TMP + vpshufb TT2, TT2, TMP + vpshufb TT3, TT3, TMP + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TT0, 4, 0 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TT1, 5, 0 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TT2, 6, 0 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TT3, 7, 0 + + //; Iteration 2: rounds 8-11 + vmovdqa TMP, [rip + .LPSHUFFLE_BYTE_FLIP_MASK] + VMOVPS TT2,[DATA_PTR + 0*64 + 2*16] + VMOVPS TT1,[DATA_PTR + 1*64 + 2*16] + VMOVPS TT4,[DATA_PTR + 2*64 + 2*16] + VMOVPS TT3,[DATA_PTR + 3*64 + 2*16] + TRANSPOSE TT2, TT1, TT4, TT3, TT0, TT5 + vpshufb TT0, TT0, TMP + vpshufb TT1, TT1, TMP + vpshufb TT2, TT2, TMP + vpshufb TT3, TT3, TMP + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TT0, 8, 0 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TT1, 9, 0 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TT2, 10, 0 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TT3, 11, 0 + + //; Iteration 3: rounds 12-15 + vmovdqa TMP, [rip + .LPSHUFFLE_BYTE_FLIP_MASK] + VMOVPS TT2,[DATA_PTR + 0*64 + 3*16] + VMOVPS TT1,[DATA_PTR + 1*64 + 3*16] + VMOVPS TT4,[DATA_PTR + 2*64 + 3*16] + VMOVPS TT3,[DATA_PTR + 3*64 + 3*16] + TRANSPOSE TT2, TT1, TT4, TT3, TT0, TT5 + vpshufb TT0, TT0, TMP + vpshufb TT1, TT1, TMP + vpshufb TT2, TT2, TMP + vpshufb TT3, TT3, TMP + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TT0, 12, 0 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TT1, 13, 0 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TT2, 14, 0 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TT3, 15, 0 + jmp .Lrounds_16_xx .align 16 .Lrounds_16_xx: -.rept 16 - ROUND_16_XX T1, .Li -.set .Li, .Li+1 -.endr +//; Rounds 16-31 (16 rounds, rotating registers) + ROUND_16_XX_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 16 + ROUND_16_XX_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 17 + ROUND_16_XX_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 18 + ROUND_16_XX_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 19 + ROUND_16_XX_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 20 + ROUND_16_XX_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 21 + ROUND_16_XX_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 22 + ROUND_16_XX_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 23 + ROUND_16_XX_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 24 + ROUND_16_XX_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 25 + ROUND_16_XX_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 26 + ROUND_16_XX_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 27 + ROUND_16_XX_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 28 + ROUND_16_XX_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 29 + ROUND_16_XX_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 30 + ROUND_16_XX_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 31 cmp ROUND,ROUNDS jb .Lrounds_16_xx @@ -448,10 +504,79 @@ hashtree_sha256_avx_x4: .align 16 .Lrounds_padding: -.set .Lpadding, 1 -.rept 64 - ROUND_00_15 T1, 0 -.endr +//; 64 padding rounds - fully unrolled with explicit registers + //; Rounds 0-7 (cycle 1) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 8-15 (cycle 2) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 16-23 (cycle 3) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 24-31 (cycle 4) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 32-39 (cycle 5) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 40-47 (cycle 6) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 48-55 (cycle 7) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 + //; Rounds 56-63 (cycle 8) + ROUND_00_15_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, T1, 0, 1 + ROUND_00_15_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, T1, 0, 1 + ROUND_00_15_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, T1, 0, 1 + ROUND_00_15_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, T1, 0, 1 + ROUND_00_15_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, T1, 0, 1 + ROUND_00_15_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, T1, 0, 1 + ROUND_00_15_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, T1, 0, 1 + ROUND_00_15_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, T1, 0, 1 // add old digest vpaddd a, a, [rsp + _DIGEST + 0*SZ4] diff --git a/src/sha256_avx_x8.S b/src/sha256_avx_x8.S index 7f235c8..a946b22 100644 --- a/src/sha256_avx_x8.S +++ b/src/sha256_avx_x8.S @@ -318,40 +318,50 @@ Copyright (c) 2012-2023, Intel Corporation #ifdef __WIN64__ - .equiv OUTPUT_PTR, rcx // 1st arg - .equiv DATA_PTR, rdx // 2nd arg - .equiv NUM_BLKS, r8 // 3rd arg - .equiv TBL, rsi + #define OUTPUT_PTR rcx + #define DATA_PTR rdx + #define NUM_BLKS r8 + #define TBL rsi #else - .equiv OUTPUT_PTR, rdi // 1st arg - .equiv DATA_PTR, rsi // 2nd arg - .equiv NUM_BLKS, rdx // 3rd arg - .equiv TBL, rcx + #define OUTPUT_PTR rdi + #define DATA_PTR rsi + #define NUM_BLKS rdx + #define TBL rcx #endif -.equ a, ymm0 -.equ b, ymm1 -.equ c, ymm2 -.equ d, ymm3 -.equ e, ymm4 -.equ f, ymm5 -.equ g, ymm6 -.equ h, ymm7 - -.equiv a0, ymm12 -.equiv a1, ymm13 -.equiv a2, ymm14 -.equiv TMP, ymm15 -.equiv TMP0, ymm6 -.equiv TMP1, ymm7 -.equiv TT0, ymm8 -.equiv TT1, ymm9 -.equiv TT2, ymm10 -.equiv TT3, ymm11 -.equiv TT4, ymm12 -.equiv TT5, ymm13 -.equiv TT6, ymm14 -.equiv TT7, ymm15 +#define INI_a ymm0 +#define INI_b ymm1 +#define INI_c ymm2 +#define INI_d ymm3 +#define INI_e ymm4 +#define INI_f ymm5 +#define INI_g ymm6 +#define INI_h ymm7 + +// Aliases for non-macro code (at initial rotation state) +#define a INI_a +#define b INI_b +#define c INI_c +#define d INI_d +#define e INI_e +#define f INI_f +#define g INI_g +#define h INI_h + +#define a0 ymm12 +#define a1 ymm13 +#define a2 ymm14 +#define TMP ymm15 +#define TMP0 ymm6 +#define TMP1 ymm7 +#define TT0 ymm8 +#define TT1 ymm9 +#define TT2 ymm10 +#define TT3 ymm11 +#define TT4 ymm12 +#define TT5 ymm13 +#define TT6 ymm14 +#define TT7 ymm15 #define SZ8 32 @@ -375,17 +385,7 @@ Copyright (c) 2012-2023, Intel Corporation #endif #define VMOVPS vmovups -.macro ROTATE_ARGS -.equ TMP_, h -.equ h, g -.equ g, f -.equ f, e -.equ e, d -.equ d, c -.equ c, b -.equ b, a -.equ a, TMP_ -.endm +// ROTATE_ARGS removed - using parameterized macros with explicit registers instead .macro TRANSPOSE8_U32_LOAD8 r0, r1, r2, r3, r4, r5, r6, r7, addr0, addr1, addr2,\ addr3, addr4, addr5, addr6, addr7,\ @@ -517,44 +517,45 @@ Copyright (c) 2012-2023, Intel Corporation PRORD_nd4 \dst, \amt, TMP, \src .endm -.macro ROUND_00_15 T1, i, j - PRORD_nd a0, e, (11-6) // sig1: a0 = (e >> 5) +// Parameterized ROUND_00_15 macro with explicit registers (no rotation) +.macro ROUND_00_15_P T1, i, j, ra, rb, rc, rd, re, rf, rg, rh, is_padding + PRORD_nd a0, \re, (11-6) // sig1: a0 = (e >> 5) - vpxor a2, f, g // ch: a2 = f^g - vpand a2, a2, e // ch: a2 = (f^g)&e - vpxor a2, a2, g // a2 = ch + vpxor a2, \rf, \rg // ch: a2 = f^g + vpand a2, a2, \re // ch: a2 = (f^g)&e + vpxor a2, a2, \rg // a2 = ch - PRORD_nd a1, e, 25 // sig1: a1 = (e >> 25) -.if .Lpadding - 1 + PRORD_nd a1, \re, 25 // sig1: a1 = (e >> 25) +.if \is_padding - 1 vmovdqa [SZ8*(\i&0xf) + rsp], \T1 // save current temp message vpaddd \T1, \T1, [TBL + \j] // T1 = W + K .else vmovdqa \T1, [TBL + (32*\i)] // T1 = W + K .endif - vpxor a0, a0, e // sig1: a0 = e ^ (e >> 5) + vpxor a0, a0, \re // sig1: a0 = e ^ (e >> 5) PRORD a0, 6 // sig1: a0 = (e >> 6) ^ (e >> 11) - vpaddd h, h, a2 // h = h + ch - PRORD_nd a2, a, (13-2) // sig0: a2 = (a >> 11) - vpaddd h, h, \T1 // h = h + ch + W + K + vpaddd \rh, \rh, a2 // h = h + ch + PRORD_nd a2, \ra, (13-2) // sig0: a2 = (a >> 11) + vpaddd \rh, \rh, \T1 // h = h + ch + W + K vpxor a0, a0, a1 // a0 = sigma1 - PRORD_nd a1, a, 22 // sig0: a1 = (a >> 22) - vpxor \T1, a, c // maj: T1 = a^c - vpand \T1, \T1, b // maj: T1 = (a^c)&b - vpaddd h, h, a0 + PRORD_nd a1, \ra, 22 // sig0: a1 = (a >> 22) + vpxor \T1, \ra, \rc // maj: T1 = a^c + vpand \T1, \T1, \rb // maj: T1 = (a^c)&b + vpaddd \rh, \rh, a0 - vpaddd d, d, h + vpaddd \rd, \rd, \rh - vpxor a2, a2, a // sig0: a2 = a ^ (a >> 11) + vpxor a2, a2, \ra // sig0: a2 = a ^ (a >> 11) PRORD a2, 2 // sig0: a2 = (a >> 2) ^ (a >> 13) vpxor a2, a2, a1 // a2 = sig0 - vpand a1, a, c // maj: a1 = a&c + vpand a1, \ra, \rc // maj: a1 = a&c vpor a1, a1, \T1 // a1 = maj - vpaddd h, h, a1 // h = h + ch + W + K + maj - vpaddd h, h, a2 // h = h + ch + W + K + maj + sigma0 - ROTATE_ARGS + vpaddd \rh, \rh, a1 // h = h + ch + W + K + maj + vpaddd \rh, \rh, a2 // h = h + ch + W + K + maj + sigma0 .endm -.macro ROUND_16_XX T1, i +// Parameterized ROUND_16_XX macro with explicit registers (no rotation) +.macro ROUND_16_XX_P T1, i, ra, rb, rc, rd, re, rf, rg, rh vmovdqa \T1, [SZ8*((\i-15)&0xf) + rsp] vmovdqa a1, [SZ8*((\i-2)&0xf) + rsp] vmovdqa a0, \T1 @@ -573,7 +574,7 @@ Copyright (c) 2012-2023, Intel Corporation vpaddd a1, a1, [SZ8*((\i-7)&0xf) + rsp] // + W[i-7] vpaddd \T1, \T1, a1 - ROUND_00_15 \T1, \i, 32*\i + ROUND_00_15_P \T1, \i, 32*\i, \ra, \rb, \rc, \rd, \re, \rf, \rg, \rh, 0 .endm .text @@ -614,7 +615,6 @@ hashtree_sha256_avx2_x8: .Lsha256_8_avx2_loop: -.set .Lpadding, 0 cmp NUM_BLKS, 8 jb .Lsha256_8_avx2_epilog @@ -630,8 +630,50 @@ hashtree_sha256_avx2_x8: lea TBL,[rip + .LK256_8] -.set .Li, 0 -.rept 2 + // Iteration 0 (.Li=0): rounds 0-7 + TRANSPOSE8_U32_LOAD8 TT0, TT1, TT2, TT3, TT4, TT5, TT6, TT7, \ + DATA_PTR + 0*64, \ + DATA_PTR + 1*64, \ + DATA_PTR + 2*64, \ + DATA_PTR + 3*64, \ + DATA_PTR + 4*64, \ + DATA_PTR + 5*64, \ + DATA_PTR + 6*64, \ + DATA_PTR + 7*64, \ + 0 + + vmovdqa [YTMP0], g + vmovdqa [YTMP1], h + TRANSPOSE8_U32_PRELOADED TT0, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TMP0, TMP1 + vmovdqa TMP1, [rip + .LPSHUFFLE_BYTE_FLIP_MASK] + vmovdqa g, [YTMP0] + vpshufb TT0, TT0, TMP1 + vpshufb TT1, TT1, TMP1 + vpshufb TT2, TT2, TMP1 + vpshufb TT3, TT3, TMP1 + vpshufb TT4, TT4, TMP1 + vpshufb TT5, TT5, TMP1 + vpshufb TT6, TT6, TMP1 + vpshufb TT7, TT7, TMP1 + vmovdqa h, [YTMP1] + vmovdqa [YTMP0], TT4 + vmovdqa [YTMP1], TT5 + vmovdqa [YTMP2], TT6 + vmovdqa [YTMP3], TT7 + ROUND_00_15_P TT0, 0, 0, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 0 + vmovdqa TT0, [YTMP0] + ROUND_00_15_P TT1, 1, 32, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 0 + vmovdqa TT1, [YTMP1] + ROUND_00_15_P TT2, 2, 64, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 0 + vmovdqa TT2, [YTMP2] + ROUND_00_15_P TT3, 3, 96, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 0 + vmovdqa TT3, [YTMP3] + ROUND_00_15_P TT0, 4, 128, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 0 + ROUND_00_15_P TT1, 5, 160, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 0 + ROUND_00_15_P TT2, 6, 192, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 0 + ROUND_00_15_P TT3, 7, 224, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 0 + + // Iteration 1 (.Li=1): rounds 8-15 TRANSPOSE8_U32_LOAD8 TT0, TT1, TT2, TT3, TT4, TT5, TT6, TT7, \ DATA_PTR + 0*64, \ DATA_PTR + 1*64, \ @@ -641,7 +683,7 @@ hashtree_sha256_avx2_x8: DATA_PTR + 5*64, \ DATA_PTR + 6*64, \ DATA_PTR + 7*64, \ - 32*.Li + 32 vmovdqa [YTMP0], g vmovdqa [YTMP1], h @@ -661,26 +703,116 @@ hashtree_sha256_avx2_x8: vmovdqa [YTMP1], TT5 vmovdqa [YTMP2], TT6 vmovdqa [YTMP3], TT7 - ROUND_00_15 TT0, 8*.Li, 32*8*.Li + ROUND_00_15_P TT0, 8, 256, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 0 vmovdqa TT0, [YTMP0] - ROUND_00_15 TT1, 8*.Li+1, 32*(8*.Li+1) + ROUND_00_15_P TT1, 9, 288, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 0 vmovdqa TT1, [YTMP1] - ROUND_00_15 TT2, 8*.Li+2, 32*(8*.Li+2) + ROUND_00_15_P TT2, 10, 320, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 0 vmovdqa TT2, [YTMP2] - ROUND_00_15 TT3, 8*.Li+3, 32*(8*.Li+3) + ROUND_00_15_P TT3, 11, 352, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 0 vmovdqa TT3, [YTMP3] - ROUND_00_15 TT0, 8*.Li+4, 32*(8*.Li+4) - ROUND_00_15 TT1, 8*.Li+5, 32*(8*.Li+5) - ROUND_00_15 TT2, 8*.Li+6, 32*(8*.Li+6) - ROUND_00_15 TT3, 8*.Li+7, 32*(8*.Li+7) -.set .Li, .Li+1 -.endr - -.set .Li, 16 -.rept 48 - ROUND_16_XX TT0, .Li -.set .Li, (.Li+1) -.endr + ROUND_00_15_P TT0, 12, 384, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 0 + ROUND_00_15_P TT1, 13, 416, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 0 + ROUND_00_15_P TT2, 14, 448, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 0 + ROUND_00_15_P TT3, 15, 480, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 0 + + // Rounds 16-63: message schedule expansion + // Round 16 (mod 8 = 0) + ROUND_16_XX_P TT0, 16, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h + // Round 17 (mod 8 = 1) + ROUND_16_XX_P TT0, 17, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g + // Round 18 (mod 8 = 2) + ROUND_16_XX_P TT0, 18, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f + // Round 19 (mod 8 = 3) + ROUND_16_XX_P TT0, 19, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e + // Round 20 (mod 8 = 4) + ROUND_16_XX_P TT0, 20, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d + // Round 21 (mod 8 = 5) + ROUND_16_XX_P TT0, 21, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c + // Round 22 (mod 8 = 6) + ROUND_16_XX_P TT0, 22, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b + // Round 23 (mod 8 = 7) + ROUND_16_XX_P TT0, 23, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a + // Round 24 (mod 8 = 0) + ROUND_16_XX_P TT0, 24, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h + // Round 25 (mod 8 = 1) + ROUND_16_XX_P TT0, 25, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g + // Round 26 (mod 8 = 2) + ROUND_16_XX_P TT0, 26, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f + // Round 27 (mod 8 = 3) + ROUND_16_XX_P TT0, 27, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e + // Round 28 (mod 8 = 4) + ROUND_16_XX_P TT0, 28, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d + // Round 29 (mod 8 = 5) + ROUND_16_XX_P TT0, 29, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c + // Round 30 (mod 8 = 6) + ROUND_16_XX_P TT0, 30, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b + // Round 31 (mod 8 = 7) + ROUND_16_XX_P TT0, 31, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a + // Round 32 (mod 8 = 0) + ROUND_16_XX_P TT0, 32, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h + // Round 33 (mod 8 = 1) + ROUND_16_XX_P TT0, 33, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g + // Round 34 (mod 8 = 2) + ROUND_16_XX_P TT0, 34, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f + // Round 35 (mod 8 = 3) + ROUND_16_XX_P TT0, 35, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e + // Round 36 (mod 8 = 4) + ROUND_16_XX_P TT0, 36, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d + // Round 37 (mod 8 = 5) + ROUND_16_XX_P TT0, 37, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c + // Round 38 (mod 8 = 6) + ROUND_16_XX_P TT0, 38, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b + // Round 39 (mod 8 = 7) + ROUND_16_XX_P TT0, 39, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a + // Round 40 (mod 8 = 0) + ROUND_16_XX_P TT0, 40, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h + // Round 41 (mod 8 = 1) + ROUND_16_XX_P TT0, 41, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g + // Round 42 (mod 8 = 2) + ROUND_16_XX_P TT0, 42, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f + // Round 43 (mod 8 = 3) + ROUND_16_XX_P TT0, 43, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e + // Round 44 (mod 8 = 4) + ROUND_16_XX_P TT0, 44, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d + // Round 45 (mod 8 = 5) + ROUND_16_XX_P TT0, 45, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c + // Round 46 (mod 8 = 6) + ROUND_16_XX_P TT0, 46, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b + // Round 47 (mod 8 = 7) + ROUND_16_XX_P TT0, 47, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a + // Round 48 (mod 8 = 0) + ROUND_16_XX_P TT0, 48, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h + // Round 49 (mod 8 = 1) + ROUND_16_XX_P TT0, 49, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g + // Round 50 (mod 8 = 2) + ROUND_16_XX_P TT0, 50, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f + // Round 51 (mod 8 = 3) + ROUND_16_XX_P TT0, 51, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e + // Round 52 (mod 8 = 4) + ROUND_16_XX_P TT0, 52, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d + // Round 53 (mod 8 = 5) + ROUND_16_XX_P TT0, 53, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c + // Round 54 (mod 8 = 6) + ROUND_16_XX_P TT0, 54, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b + // Round 55 (mod 8 = 7) + ROUND_16_XX_P TT0, 55, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a + // Round 56 (mod 8 = 0) + ROUND_16_XX_P TT0, 56, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h + // Round 57 (mod 8 = 1) + ROUND_16_XX_P TT0, 57, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g + // Round 58 (mod 8 = 2) + ROUND_16_XX_P TT0, 58, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f + // Round 59 (mod 8 = 3) + ROUND_16_XX_P TT0, 59, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e + // Round 60 (mod 8 = 4) + ROUND_16_XX_P TT0, 60, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d + // Round 61 (mod 8 = 5) + ROUND_16_XX_P TT0, 61, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c + // Round 62 (mod 8 = 6) + ROUND_16_XX_P TT0, 62, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b + // Round 63 (mod 8 = 7) + ROUND_16_XX_P TT0, 63, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a # add old digest lea TBL,[rip + .LDIGEST_8] @@ -708,13 +840,136 @@ hashtree_sha256_avx2_x8: lea TBL,[rip + .LPADDING_8] -.set .Lpadding, 1 -.set .Li, 0 .align 16 -.rept 64 - ROUND_00_15 TT0, .Li, 32*.Li -.set .Li, (.Li + 1) -.endr + // Padding rounds 0-63 (is_padding=1) + // Round 0 (mod 8 = 0) + ROUND_00_15_P TT0, 0, 0, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 1 (mod 8 = 1) + ROUND_00_15_P TT0, 1, 32, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 2 (mod 8 = 2) + ROUND_00_15_P TT0, 2, 64, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 3 (mod 8 = 3) + ROUND_00_15_P TT0, 3, 96, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 4 (mod 8 = 4) + ROUND_00_15_P TT0, 4, 128, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 5 (mod 8 = 5) + ROUND_00_15_P TT0, 5, 160, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 6 (mod 8 = 6) + ROUND_00_15_P TT0, 6, 192, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 7 (mod 8 = 7) + ROUND_00_15_P TT0, 7, 224, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 8 (mod 8 = 0) + ROUND_00_15_P TT0, 8, 256, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 9 (mod 8 = 1) + ROUND_00_15_P TT0, 9, 288, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 10 (mod 8 = 2) + ROUND_00_15_P TT0, 10, 320, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 11 (mod 8 = 3) + ROUND_00_15_P TT0, 11, 352, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 12 (mod 8 = 4) + ROUND_00_15_P TT0, 12, 384, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 13 (mod 8 = 5) + ROUND_00_15_P TT0, 13, 416, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 14 (mod 8 = 6) + ROUND_00_15_P TT0, 14, 448, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 15 (mod 8 = 7) + ROUND_00_15_P TT0, 15, 480, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 16 (mod 8 = 0) + ROUND_00_15_P TT0, 16, 512, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 17 (mod 8 = 1) + ROUND_00_15_P TT0, 17, 544, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 18 (mod 8 = 2) + ROUND_00_15_P TT0, 18, 576, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 19 (mod 8 = 3) + ROUND_00_15_P TT0, 19, 608, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 20 (mod 8 = 4) + ROUND_00_15_P TT0, 20, 640, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 21 (mod 8 = 5) + ROUND_00_15_P TT0, 21, 672, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 22 (mod 8 = 6) + ROUND_00_15_P TT0, 22, 704, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 23 (mod 8 = 7) + ROUND_00_15_P TT0, 23, 736, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 24 (mod 8 = 0) + ROUND_00_15_P TT0, 24, 768, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 25 (mod 8 = 1) + ROUND_00_15_P TT0, 25, 800, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 26 (mod 8 = 2) + ROUND_00_15_P TT0, 26, 832, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 27 (mod 8 = 3) + ROUND_00_15_P TT0, 27, 864, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 28 (mod 8 = 4) + ROUND_00_15_P TT0, 28, 896, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 29 (mod 8 = 5) + ROUND_00_15_P TT0, 29, 928, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 30 (mod 8 = 6) + ROUND_00_15_P TT0, 30, 960, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 31 (mod 8 = 7) + ROUND_00_15_P TT0, 31, 992, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 32 (mod 8 = 0) + ROUND_00_15_P TT0, 32, 1024, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 33 (mod 8 = 1) + ROUND_00_15_P TT0, 33, 1056, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 34 (mod 8 = 2) + ROUND_00_15_P TT0, 34, 1088, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 35 (mod 8 = 3) + ROUND_00_15_P TT0, 35, 1120, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 36 (mod 8 = 4) + ROUND_00_15_P TT0, 36, 1152, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 37 (mod 8 = 5) + ROUND_00_15_P TT0, 37, 1184, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 38 (mod 8 = 6) + ROUND_00_15_P TT0, 38, 1216, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 39 (mod 8 = 7) + ROUND_00_15_P TT0, 39, 1248, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 40 (mod 8 = 0) + ROUND_00_15_P TT0, 40, 1280, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 41 (mod 8 = 1) + ROUND_00_15_P TT0, 41, 1312, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 42 (mod 8 = 2) + ROUND_00_15_P TT0, 42, 1344, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 43 (mod 8 = 3) + ROUND_00_15_P TT0, 43, 1376, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 44 (mod 8 = 4) + ROUND_00_15_P TT0, 44, 1408, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 45 (mod 8 = 5) + ROUND_00_15_P TT0, 45, 1440, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 46 (mod 8 = 6) + ROUND_00_15_P TT0, 46, 1472, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 47 (mod 8 = 7) + ROUND_00_15_P TT0, 47, 1504, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 48 (mod 8 = 0) + ROUND_00_15_P TT0, 48, 1536, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 49 (mod 8 = 1) + ROUND_00_15_P TT0, 49, 1568, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 50 (mod 8 = 2) + ROUND_00_15_P TT0, 50, 1600, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 51 (mod 8 = 3) + ROUND_00_15_P TT0, 51, 1632, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 52 (mod 8 = 4) + ROUND_00_15_P TT0, 52, 1664, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 53 (mod 8 = 5) + ROUND_00_15_P TT0, 53, 1696, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 54 (mod 8 = 6) + ROUND_00_15_P TT0, 54, 1728, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 55 (mod 8 = 7) + ROUND_00_15_P TT0, 55, 1760, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 + // Round 56 (mod 8 = 0) + ROUND_00_15_P TT0, 56, 1792, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, 1 + // Round 57 (mod 8 = 1) + ROUND_00_15_P TT0, 57, 1824, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, 1 + // Round 58 (mod 8 = 2) + ROUND_00_15_P TT0, 58, 1856, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, 1 + // Round 59 (mod 8 = 3) + ROUND_00_15_P TT0, 59, 1888, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, 1 + // Round 60 (mod 8 = 4) + ROUND_00_15_P TT0, 60, 1920, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, 1 + // Round 61 (mod 8 = 5) + ROUND_00_15_P TT0, 61, 1952, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, 1 + // Round 62 (mod 8 = 6) + ROUND_00_15_P TT0, 62, 1984, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, 1 + // Round 63 (mod 8 = 7) + ROUND_00_15_P TT0, 63, 2016, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, 1 # add old digest vpaddd a, a, [rsp + _DIGEST + 0*SZ8] vpaddd b, b, [rsp + _DIGEST + 1*SZ8] diff --git a/src/sha256_shani.S b/src/sha256_shani.S index 9e7cf55..422c3ff 100644 --- a/src/sha256_shani.S +++ b/src/sha256_shani.S @@ -70,41 +70,41 @@ SOFTWARE. .long 0xd2c741c6, 0x07237ea3, 0xa4954b68, 0x4c191d76 #ifdef __WIN64__ - .equiv OUTPUT_PTR,rcx // 1st arg - .equiv DATA_PTR, rdx // 2nd arg - .equiv NUM_BLKS, r8 // 3rd arg - .equiv SHA256PADDING, r9 + #define OUTPUT_PTR rcx // 1st arg + #define DATA_PTR rdx // 2nd arg + #define NUM_BLKS r8 // 3rd arg + #define SHA256PADDING r9 #define _DIGEST 160 #define frame_size 248 #else - .equiv OUTPUT_PTR, rdi // 1st arg - .equiv DATA_PTR, rsi // 2nd arg - .equiv NUM_BLKS, rdx // 3rd arg - .equiv SHA256PADDING, rcx + #define OUTPUT_PTR rdi // 1st arg + #define DATA_PTR rsi // 2nd arg + #define NUM_BLKS rdx // 3rd arg + #define SHA256PADDING rcx #define _DIGEST 0 #define frame_size 88 #endif -.equiv SHA256CONSTANTS, rax - -.equiv MSG, xmm0 -.equiv STATE0, xmm1 -.equiv STATE1, xmm2 -.equiv MSGTMP0, xmm3 -.equiv MSGTMP1, xmm4 -.equiv MSGTMP2, xmm5 -.equiv MSGTMP3, xmm6 -.equiv MSGTMP4, xmm7 -.equiv SHUF_MASK, xmm8 -.equiv ABEF_SAVE, xmm9 -.equiv CDGH_SAVE, xmm10 -.equiv STATE0b, xmm9 -.equiv STATE1b, xmm10 -.equiv MSGTMP0b, xmm11 -.equiv MSGTMP1b, xmm12 -.equiv MSGTMP2b, xmm13 -.equiv MSGTMP3b, xmm14 -.equiv MSGTMP4b, xmm15 +#define SHA256CONSTANTS rax + +#define MSG xmm0 +#define STATE0 xmm1 +#define STATE1 xmm2 +#define MSGTMP0 xmm3 +#define MSGTMP1 xmm4 +#define MSGTMP2 xmm5 +#define MSGTMP3 xmm6 +#define MSGTMP4 xmm7 +#define SHUF_MASK xmm8 +#define ABEF_SAVE xmm9 +#define CDGH_SAVE xmm10 +#define STATE0b xmm9 +#define STATE1b xmm10 +#define MSGTMP0b xmm11 +#define MSGTMP1b xmm12 +#define MSGTMP2b xmm13 +#define MSGTMP3b xmm14 +#define MSGTMP4b xmm15 .text .global hashtree_sha256_shani_x2 diff --git a/src/sha256_sse_x1.S b/src/sha256_sse_x1.S index 460e841..924fbae 100644 --- a/src/sha256_sse_x1.S +++ b/src/sha256_sse_x1.S @@ -85,54 +85,67 @@ Copied parts are .quad 0xFFFFFFFFFFFFFFFF, 0x0b0a090803020100 -#define MOVDQ movdqu +#define MOVDQ movdqu .macro COPY_XMM_AND_BSWAP t1, t2, t3 MOVDQ \t1, \t2 pshufb \t1, \t3 .endm +#define INI_X0 xmm4 +#define INI_X1 xmm5 +#define INI_X2 xmm6 +#define INI_X3 xmm7 -.equ X0, xmm4 -.equ X1, xmm5 -.equ X2, xmm6 -.equ X3, xmm7 +#define XTMP0 xmm0 +#define XTMP1 xmm1 +#define XTMP2 xmm2 +#define XTMP3 xmm3 +#define XTMP4 xmm8 +#define XFER xmm9 -.equiv XTMP0, xmm0 -.equiv XTMP1, xmm1 -.equiv XTMP2, xmm2 -.equiv XTMP3, xmm3 -.equiv XTMP4, xmm8 -.equiv XFER , xmm9 - -.equiv SHUF_00BA, xmm10 -.equiv SHUF_DC00, xmm11 -.equiv BYTE_FLIP_MASK, xmm12 +#define SHUF_00BA xmm10 +#define SHUF_DC00 xmm11 +#define BYTE_FLIP_MASK xmm12 #ifdef __WIN64__ - .equiv OUTPUT_PTR, rcx - .equiv DATA_PTR, rdx - .equiv count, r8 - .equ c, edi - .equ d, esi + #define OUTPUT_PTR rcx + #define DATA_PTR rdx + #define count r8 + #define INI_c edi + #define INI_d esi #else - .equiv OUTPUT_PTR, rdi - .equiv DATA_PTR, rsi - .equiv count, rdx - .equ c, ecx - .equ d, r8d + #define OUTPUT_PTR rdi + #define DATA_PTR rsi + #define count rdx + #define INI_c ecx + #define INI_d r8d #endif -.equiv TBL, rbp -.equ a, eax -.equ b, ebx -.equ f, r9d -.equ g, r10d -.equ h, r11d -.equ e, r12d - -.equiv y0, r13d -.equiv y1, r14d -.equiv y2, r15d +#define TBL rbp +#define INI_a eax +#define INI_b ebx +#define INI_f r9d +#define INI_g r10d +#define INI_h r11d +#define INI_e r12d + +#define y0 r13d +#define y1 r14d +#define y2 r15d + +// Aliases for non-macro code (at initial rotation state) +#define a INI_a +#define b INI_b +#define c INI_c +#define d INI_d +#define e INI_e +#define f INI_f +#define g INI_g +#define h INI_h +#define X0 INI_X0 +#define X1 INI_X1 +#define X2 INI_X2 +#define X3 INI_X3 # stack usage #ifdef __WIN64__ @@ -140,225 +153,209 @@ Copied parts are #define STACK_SIZE 192 #else #define STACK_SIZE 88 -#endif +#endif #define _DIGEST 32 -.macro ROTATE_ARGS -.equ TMP_, h -.equ h, g -.equ g, f -.equ f, e -.equ e, d -.equ d, c -.equ c, b -.equ b, a -.equ a, TMP_ -.endm - -.macro rotate_Xs -.equ X_, X0 -.equ X0, X1 -.equ X1, X2 -.equ X2, X3 -.equ X3, X_ -.endm -.macro FOUR_ROUNDS_AND_SCHED +// Parameterized FOUR_ROUNDS_AND_SCHED +// Takes 12 params: 8 GPR (a-h) and 4 XMM (x0-x3) +// After this macro: GPR state rotates by 4 (a,b,c,d,e,f,g,h) -> (e,f,g,h,a,b,c,d) +// XMM state rotates by 1 (x0,x1,x2,x3) -> (x1,x2,x3,x0) +.macro FOUR_ROUNDS_AND_SCHED_P ra, rb, rc, rd, re, rf, rg, rh, x0, x1, x2, x3 # compute s0 four at a time and s1 two at a time # compute W[-16] + W[-7] 4 at a time - movdqa XTMP0, X3 - mov y0, e // y0 = e + movdqa XTMP0, \x3 + mov y0, \re // y0 = e ror y0, (25-11) // y0 = e >> (25-11) - mov y1, a // y1 = a - palignr XTMP0, X2, 4 // XTMP0 = W[-7] + mov y1, \ra // y1 = a + palignr XTMP0, \x2, 4 // XTMP0 = W[-7] ror y1, (22-13) // y1 = a >> (22-13) - xor y0, e // y0 = e ^ (e >> (25-11)) - mov y2, f // y2 = f + xor y0, \re // y0 = e ^ (e >> (25-11)) + mov y2, \rf // y2 = f ror y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - movdqa XTMP1, X1 - xor y1, a // y1 = a ^ (a >> (22-13) - xor y2, g // y2 = f^g - paddd XTMP0, X0 // XTMP0 = W[-7] + W[-16] - xor y0, e // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e // y2 = (f^g)&e + movdqa XTMP1, \x1 + xor y1, \ra // y1 = a ^ (a >> (22-13) + xor y2, \rg // y2 = f^g + paddd XTMP0, \x0 // XTMP0 = W[-7] + W[-16] + xor y0, \re // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, \re // y2 = (f^g)&e ror y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) # compute s0 - palignr XTMP1, X0, 4 // XTMP1 = W[-15] - xor y1, a // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + palignr XTMP1, \x0, 4 // XTMP1 = W[-15] + xor y1, \ra // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) ror y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - xor y2, g // y2 = CH = ((f^g)&e)^g + xor y2, \rg // y2 = CH = ((f^g)&e)^g movdqa XTMP2, XTMP1 // XTMP2 = W[-15] ror y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) add y2, y0 // y2 = S1 + CH add y2, [rsp + 0*4] // y2 = k + w + S1 + CH movdqa XTMP3, XTMP1 // XTMP3 = W[-15] - mov y0, a // y0 = a - add h, y2 // h = h + S1 + CH + k + w - mov y2, a // y2 = a + mov y0, \ra // y0 = a + add \rh, y2 // h = h + S1 + CH + k + w + mov y2, \ra // y2 = a pslld XTMP1, (32-7) - or y0, c // y0 = a|c - add d, h // d = d + h + S1 + CH + k + w - and y2, c // y2 = a&c + or y0, \rc // y0 = a|c + add \rd, \rh // d = d + h + S1 + CH + k + w + and y2, \rc // y2 = a&c psrld XTMP2, 7 - and y0, b // y0 = (a|c)&b - add h, y1 // h = h + S1 + CH + k + w + S0 + and y0, \rb // y0 = (a|c)&b + add \rh, y1 // h = h + S1 + CH + k + w + S0 por XTMP1, XTMP2 // XTMP1 = W[-15] ror 7 or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h, y0 // h = h + S1 + CH + k + w + S0 + MAJ + add \rh, y0 // h = h + S1 + CH + k + w + S0 + MAJ -ROTATE_ARGS + // Round 1: a=rh, b=ra, c=rb, d=rc, e=rd, f=re, g=rf, h=rg movdqa XTMP2, XTMP3 // XTMP2 = W[-15] - mov y0, e // y0 = e - mov y1, a // y1 = a + mov y0, \rd // y0 = e + mov y1, \rh // y1 = a movdqa XTMP4, XTMP3 // XTMP4 = W[-15] ror y0, (25-11) // y0 = e >> (25-11) - xor y0, e // y0 = e ^ (e >> (25-11)) - mov y2, f // y2 = f + xor y0, \rd // y0 = e ^ (e >> (25-11)) + mov y2, \re // y2 = f ror y1, (22-13) // y1 = a >> (22-13) pslld XTMP3, (32-18) - xor y1, a // y1 = a ^ (a >> (22-13) + xor y1, \rh // y1 = a ^ (a >> (22-13) ror y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - xor y2, g // y2 = f^g + xor y2, \rf // y2 = f^g psrld XTMP2, 18 ror y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - xor y0, e // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e // y2 = (f^g)&e + xor y0, \rd // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, \rd // y2 = (f^g)&e ror y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) pxor XTMP1, XTMP3 - xor y1, a // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) - xor y2, g // y2 = CH = ((f^g)&e)^g + xor y1, \rh // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + xor y2, \rf // y2 = CH = ((f^g)&e)^g psrld XTMP4, 3 // XTMP4 = W[-15] >> 3 add y2, y0 // y2 = S1 + CH add y2, [rsp + 1*4] // y2 = k + w + S1 + CH ror y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) pxor XTMP1, XTMP2 // XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 - mov y0, a // y0 = a - add h, y2 // h = h + S1 + CH + k + w - mov y2, a // y2 = a + mov y0, \rh // y0 = a + add \rg, y2 // h = h + S1 + CH + k + w + mov y2, \rh // y2 = a pxor XTMP1, XTMP4 // XTMP1 = s0 - or y0, c // y0 = a|c - add d, h // d = d + h + S1 + CH + k + w - and y2, c // y2 = a&c + or y0, \rb // y0 = a|c + add \rc, \rg // d = d + h + S1 + CH + k + w + and y2, \rb // y2 = a&c # compute low s1 - pshufd XTMP2, X3, 0b11111010 // XTMP2 = W[-2] {BBAA} - and y0, b // y0 = (a|c)&b - add h, y1 // h = h + S1 + CH + k + w + S0 + pshufd XTMP2, \x3, 0b11111010 // XTMP2 = W[-2] {BBAA} + and y0, \ra // y0 = (a|c)&b + add \rg, y1 // h = h + S1 + CH + k + w + S0 paddd XTMP0, XTMP1 // XTMP0 = W[-16] + W[-7] + s0 or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h, y0 // h = h + S1 + CH + k + w + S0 + MAJ + add \rg, y0 // h = h + S1 + CH + k + w + S0 + MAJ -ROTATE_ARGS + // Round 2: a=rg, b=rh, c=ra, d=rb, e=rc, f=rd, g=re, h=rf movdqa XTMP3, XTMP2 // XTMP3 = W[-2] {BBAA} - mov y0, e // y0 = e - mov y1, a // y1 = a + mov y0, \rc // y0 = e + mov y1, \rg // y1 = a ror y0, (25-11) // y0 = e >> (25-11) movdqa XTMP4, XTMP2 // XTMP4 = W[-2] {BBAA} - xor y0, e // y0 = e ^ (e >> (25-11)) + xor y0, \rc // y0 = e ^ (e >> (25-11)) ror y1, (22-13) // y1 = a >> (22-13) - mov y2, f // y2 = f - xor y1, a // y1 = a ^ (a >> (22-13) + mov y2, \rd // y2 = f + xor y1, \rg // y1 = a ^ (a >> (22-13) ror y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) psrlq XTMP2, 17 // XTMP2 = W[-2] ror 17 {xBxA} - xor y2, g // y2 = f^g + xor y2, \re // y2 = f^g psrlq XTMP3, 19 // XTMP3 = W[-2] ror 19 {xBxA} - xor y0, e // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e // y2 = (f^g)&e + xor y0, \rc // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, \rc // y2 = (f^g)&e psrld XTMP4, 10 // XTMP4 = W[-2] >> 10 {BBAA} ror y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - xor y1, a // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) - xor y2, g // y2 = CH = ((f^g)&e)^g + xor y1, \rg // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + xor y2, \re // y2 = CH = ((f^g)&e)^g ror y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) pxor XTMP2, XTMP3 add y2, y0 // y2 = S1 + CH ror y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) add y2, [rsp + 2*4] // y2 = k + w + S1 + CH pxor XTMP4, XTMP2 // XTMP4 = s1 {xBxA} - mov y0, a // y0 = a - add h, y2 // h = h + S1 + CH + k + w - mov y2, a // y2 = a + mov y0, \rg // y0 = a + add \rf, y2 // h = h + S1 + CH + k + w + mov y2, \rg // y2 = a pshufb XTMP4, SHUF_00BA // XTMP4 = s1 {00BA} - or y0, c // y0 = a|c - add d, h // d = d + h + S1 + CH + k + w - and y2, c // y2 = a&c + or y0, \ra // y0 = a|c + add \rb, \rf // d = d + h + S1 + CH + k + w + and y2, \ra // y2 = a&c paddd XTMP0, XTMP4 // XTMP0 = {..., ..., W[1], W[0]} - and y0, b // y0 = (a|c)&b - add h, y1 // h = h + S1 + CH + k + w + S0 + and y0, \rh // y0 = (a|c)&b + add \rf, y1 // h = h + S1 + CH + k + w + S0 # compute high s1 pshufd XTMP2, XTMP0, 0b01010000 // XTMP2 = W[-2] {DDCC} or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h, y0 // h = h + S1 + CH + k + w + S0 + MAJ + add \rf, y0 // h = h + S1 + CH + k + w + S0 + MAJ -ROTATE_ARGS + // Round 3: a=rf, b=rg, c=rh, d=ra, e=rb, f=rc, g=rd, h=re movdqa XTMP3, XTMP2 // XTMP3 = W[-2] {DDCC} - mov y0, e // y0 = e + mov y0, \rb // y0 = e ror y0, (25-11) // y0 = e >> (25-11) - mov y1, a // y1 = a - movdqa X0, XTMP2 // X0 = W[-2] {DDCC} + mov y1, \rf // y1 = a + movdqa \x0, XTMP2 // X0 = W[-2] {DDCC} ror y1, (22-13) // y1 = a >> (22-13) - xor y0, e // y0 = e ^ (e >> (25-11)) - mov y2, f // y2 = f + xor y0, \rb // y0 = e ^ (e >> (25-11)) + mov y2, \rc // y2 = f ror y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) psrlq XTMP2, 17 // XTMP2 = W[-2] ror 17 {xDxC} - xor y1, a // y1 = a ^ (a >> (22-13) - xor y2, g // y2 = f^g + xor y1, \rf // y1 = a ^ (a >> (22-13) + xor y2, \rd // y2 = f^g psrlq XTMP3, 19 // XTMP3 = W[-2] ror 19 {xDxC} - xor y0, e // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) - and y2, e // y2 = (f^g)&e + xor y0, \rb // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, \rb // y2 = (f^g)&e ror y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - psrld X0, 10 // X0 = W[-2] >> 10 {DDCC} - xor y1, a // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + psrld \x0, 10 // X0 = W[-2] >> 10 {DDCC} + xor y1, \rf // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) ror y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - xor y2, g // y2 = CH = ((f^g)&e)^g + xor y2, \rd // y2 = CH = ((f^g)&e)^g pxor XTMP2, XTMP3 ror y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) add y2, y0 // y2 = S1 + CH add y2, [rsp + 3*4] // y2 = k + w + S1 + CH - pxor X0, XTMP2 // X0 = s1 {xDxC} - mov y0, a // y0 = a - add h, y2 // h = h + S1 + CH + k + w - mov y2, a // y2 = a - pshufb X0, SHUF_DC00 // X0 = s1 {DC00} - or y0, c // y0 = a|c - add d, h // d = d + h + S1 + CH + k + w - and y2, c // y2 = a&c - paddd X0, XTMP0 // X0 = {W[3], W[2], W[1], W[0]} - and y0, b // y0 = (a|c)&b - add h, y1 // h = h + S1 + CH + k + w + S0 + pxor \x0, XTMP2 // X0 = s1 {xDxC} + mov y0, \rf // y0 = a + add \re, y2 // h = h + S1 + CH + k + w + mov y2, \rf // y2 = a + pshufb \x0, SHUF_DC00 // X0 = s1 {DC00} + or y0, \rh // y0 = a|c + add \ra, \re // d = d + h + S1 + CH + k + w + and y2, \rh // y2 = a&c + paddd \x0, XTMP0 // X0 = {W[3], W[2], W[1], W[0]} + and y0, \rg // y0 = (a|c)&b + add \re, y1 // h = h + S1 + CH + k + w + S0 or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h, y0 // h = h + S1 + CH + k + w + S0 + MAJ -ROTATE_ARGS -rotate_Xs + add \re, y0 // h = h + S1 + CH + k + w + S0 + MAJ .endm -.macro DO_ROUND base, offset - mov y0, e // y0 = e +// Parameterized DO_ROUND - takes all 8 working registers as parameters +// No rotation at end - caller handles register rotation by passing different args +.macro DO_ROUND_P ra, rb, rc, rd, re, rf, rg, rh, base, offset + mov y0, \re // y0 = e ror y0, (25-11) // y0 = e >> (25-11) - mov y1, a // y1 = a - xor y0, e // y0 = e ^ (e >> (25-11)) + mov y1, \ra // y1 = a + xor y0, \re // y0 = e ^ (e >> (25-11)) ror y1, (22-13) // y1 = a >> (22-13) - mov y2, f // y2 = f - xor y1, a // y1 = a ^ (a >> (22-13) + mov y2, \rf // y2 = f + xor y1, \ra // y1 = a ^ (a >> (22-13) ror y0, (11-6) // y0 = (e >> (11-6)) ^ (e >> (25-6)) - xor y2, g // y2 = f^g - xor y0, e // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + xor y2, \rg // y2 = f^g + xor y0, \re // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) ror y1, (13-2) // y1 = (a >> (13-2)) ^ (a >> (22-2)) - and y2, e // y2 = (f^g)&e - xor y1, a // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + and y2, \re // y2 = (f^g)&e + xor y1, \ra // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) ror y0, 6 // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) - xor y2, g // y2 = CH = ((f^g)&e)^g + xor y2, \rg // y2 = CH = ((f^g)&e)^g add y2, y0 // y2 = S1 + CH ror y1, 2 // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) add y2, [\base + \offset] // y2 = k + w + S1 + CH - mov y0, a // y0 = a - add h, y2 // h = h + S1 + CH + k + w - mov y2, a // y2 = a - or y0, c // y0 = a|c - add d, h // d = d + h + S1 + CH + k + w - and y2, c // y2 = a&c - and y0, b // y0 = (a|c)&b - add h, y1 // h = h + S1 + CH + k + w + S0 + mov y0, \ra // y0 = a + add \rh, y2 // h = h + S1 + CH + k + w + mov y2, \ra // y2 = a + or y0, \rc // y0 = a|c + add \rd, \rh // d = d + h + S1 + CH + k + w + and y2, \rc // y2 = a&c + and y0, \rb // y0 = (a|c)&b + add \rh, y1 // h = h + S1 + CH + k + w + S0 or y0, y2 // y0 = MAJ = (a|c)&b)|(a&c) - add h, y0 // h = h + S1 + CH + k + w + S0 + MAJ - ROTATE_ARGS + add \rh, y0 // h = h + S1 + CH + k + w + S0 + MAJ .endm .text @@ -423,49 +420,113 @@ hashtree_sha256_sse_x1: COPY_XMM_AND_BSWAP X3, [DATA_PTR + 3*16], BYTE_FLIP_MASK # schedule 48 input dwords, by doing 3 rounds of 16 each + # Rep 1 of 3 +.align 16 + movdqa XFER, [TBL + 0*16] + paddd XFER, INI_X0 + movdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X0, INI_X1, INI_X2, INI_X3 + + movdqa XFER, [TBL + 1*16] + paddd XFER, INI_X1 + movdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X1, INI_X2, INI_X3, INI_X0 + + movdqa XFER, [TBL + 2*16] + paddd XFER, INI_X2 + movdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X2, INI_X3, INI_X0, INI_X1 -.rept 3 + movdqa XFER, [TBL + 3*16] + paddd XFER, INI_X3 + movdqa [rsp], XFER + add TBL, 4*16 + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X3, INI_X0, INI_X1, INI_X2 + + # Rep 2 of 3 .align 16 movdqa XFER, [TBL + 0*16] - paddd XFER, X0 + paddd XFER, INI_X0 movdqa [rsp], XFER - FOUR_ROUNDS_AND_SCHED + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X0, INI_X1, INI_X2, INI_X3 movdqa XFER, [TBL + 1*16] - paddd XFER, X0 + paddd XFER, INI_X1 movdqa [rsp], XFER - FOUR_ROUNDS_AND_SCHED + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X1, INI_X2, INI_X3, INI_X0 movdqa XFER, [TBL + 2*16] - paddd XFER, X0 + paddd XFER, INI_X2 movdqa [rsp], XFER - FOUR_ROUNDS_AND_SCHED + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X2, INI_X3, INI_X0, INI_X1 movdqa XFER, [TBL + 3*16] - paddd XFER, X0 + paddd XFER, INI_X3 movdqa [rsp], XFER add TBL, 4*16 - FOUR_ROUNDS_AND_SCHED -.endr + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X3, INI_X0, INI_X1, INI_X2 -.rept 2 + # Rep 3 of 3 +.align 16 + movdqa XFER, [TBL + 0*16] + paddd XFER, INI_X0 + movdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X0, INI_X1, INI_X2, INI_X3 + + movdqa XFER, [TBL + 1*16] + paddd XFER, INI_X1 + movdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X1, INI_X2, INI_X3, INI_X0 + + movdqa XFER, [TBL + 2*16] + paddd XFER, INI_X2 + movdqa [rsp], XFER + FOUR_ROUNDS_AND_SCHED_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_X2, INI_X3, INI_X0, INI_X1 + + movdqa XFER, [TBL + 3*16] + paddd XFER, INI_X3 + movdqa [rsp], XFER + add TBL, 4*16 + FOUR_ROUNDS_AND_SCHED_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_X3, INI_X0, INI_X1, INI_X2 + +//; Rounds 48-63 (2 reps of 8 rounds each) + //; Rep 1: rounds 48-55 paddd X0, [TBL + 0*16] movdqa [rsp], X0 - DO_ROUND rsp, 0 - DO_ROUND rsp, 4 - DO_ROUND rsp, 8 - DO_ROUND rsp, 12 + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, rsp, 0 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, rsp, 4 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, rsp, 8 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, rsp, 12 + paddd X1, [TBL + 1*16] movdqa [rsp], X1 add TBL, 2*16 - DO_ROUND rsp, 0 - DO_ROUND rsp, 4 - DO_ROUND rsp, 8 - DO_ROUND rsp, 12 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, rsp, 0 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, rsp, 4 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, rsp, 8 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, rsp, 12 movdqa X0, X2 movdqa X1, X3 -.endr + + //; Rep 2: rounds 56-63 + paddd X0, [TBL + 0*16] + movdqa [rsp], X0 + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, rsp, 0 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, rsp, 4 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, rsp, 8 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, rsp, 12 + + paddd X1, [TBL + 1*16] + movdqa [rsp], X1 + add TBL, 2*16 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, rsp, 0 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, rsp, 4 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, rsp, 8 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, rsp, 12 + + movdqa X0, X2 + movdqa X1, X3 lea TBL,[rip + .LDIGEST] add a, [TBL + 0*4] @@ -491,11 +552,79 @@ hashtree_sha256_sse_x1: lea TBL,[rip + .LPADDING] -.set .Li, 0 -.rept 64 - DO_ROUND TBL, .Li - .set .Li, .Li+4 -.endr +//; 64 padding rounds - fully unrolled with explicit registers + //; Rounds 0-7 (cycle 1) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 0 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 4 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 8 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 12 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 16 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 20 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 24 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 28 + //; Rounds 8-15 (cycle 2) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 32 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 36 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 40 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 44 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 48 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 52 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 56 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 60 + //; Rounds 16-23 (cycle 3) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 64 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 68 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 72 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 76 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 80 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 84 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 88 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 92 + //; Rounds 24-31 (cycle 4) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 96 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 100 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 104 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 108 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 112 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 116 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 120 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 124 + //; Rounds 32-39 (cycle 5) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 128 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 132 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 136 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 140 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 144 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 148 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 152 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 156 + //; Rounds 40-47 (cycle 6) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 160 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 164 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 168 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 172 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 176 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 180 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 184 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 188 + //; Rounds 48-55 (cycle 7) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 192 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 196 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 200 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 204 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 208 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 212 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 216 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 220 + //; Rounds 56-63 (cycle 8) + DO_ROUND_P INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, TBL, 224 + DO_ROUND_P INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, TBL, 228 + DO_ROUND_P INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, INI_f, TBL, 232 + DO_ROUND_P INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, INI_e, TBL, 236 + DO_ROUND_P INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, INI_d, TBL, 240 + DO_ROUND_P INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, INI_c, TBL, 244 + DO_ROUND_P INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, INI_b, TBL, 248 + DO_ROUND_P INI_b, INI_c, INI_d, INI_e, INI_f, INI_g, INI_h, INI_a, TBL, 252 // add the previous digest add a, [rsp + _DIGEST + 0*4]