Add crypto hash SM3.
[libgcrypt.git] / cipher / sha256-avx-amd64.S
1 /*
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ; Copyright (c) 2012, Intel Corporation
4 ;
5 ; All rights reserved.
6 ;
7 ; Redistribution and use in source and binary forms, with or without
8 ; modification, are permitted provided that the following conditions are
9 ; met:
10 ;
11 ; * Redistributions of source code must retain the above copyright
12 ;   notice, this list of conditions and the following disclaimer.
13 ;
14 ; * Redistributions in binary form must reproduce the above copyright
15 ;   notice, this list of conditions and the following disclaimer in the
16 ;   documentation and/or other materials provided with the
17 ;   distribution.
18 ;
19 ; * Neither the name of the Intel Corporation nor the names of its
20 ;   contributors may be used to endorse or promote products derived from
21 ;   this software without specific prior written permission.
22 ;
23 ;
24 ; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
25 ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 ; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 ; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
28 ; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 ; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
36 ;
37 ; This code is described in an Intel White-Paper:
38 ; "Fast SHA-256 Implementations on Intel Architecture Processors"
39 ;
40 ; To find it, surf to http://www.intel.com/p/en_US/embedded
41 ; and search for that title.
42 ; The paper is expected to be released roughly at the end of April, 2012
43 ;
44 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
45 ; This code schedules 1 blocks at a time, with 4 lanes per block
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47 */
48 /*
49  * Conversion to GAS assembly and integration to libgcrypt
50  *  by Jussi Kivilinna <jussi.kivilinna@iki.fi>
51  *
52  * Note: Based on the SSSE3 implementation.
53  */
54
55 #ifdef __x86_64
56 #include <config.h>
57 #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
58      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
59     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
60     defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA256)
61
62 #ifdef __PIC__
63 #  define ADD_RIP +rip
64 #else
65 #  define ADD_RIP
66 #endif
67
68 #ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
69 # define ELF(...) __VA_ARGS__
70 #else
71 # define ELF(...) /*_*/
72 #endif
73
74 .intel_syntax noprefix
75
76 #define VMOVDQ vmovdqu /* assume buffers not aligned */
77
78 .macro ROR p1 p2
79         /* shld is faster than ror on Intel Sandybridge */
80         shld    \p1, \p1, (32 - \p2)
81 .endm
82
83 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros*/
84
85 /* addm [mem], reg
86  * Add reg to mem using reg-mem add and store */
87 .macro addm p1 p2
88         add     \p2, \p1
89         mov     \p1, \p2
90 .endm
91
92 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
93
94 /* COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask
95  * Load xmm with mem and byte swap each dword */
96 .macro COPY_XMM_AND_BSWAP p1 p2 p3
97         VMOVDQ \p1, \p2
98         vpshufb \p1, \p1, \p3
99 .endm
100
101 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
102
103 X0 = xmm4
104 X1 = xmm5
105 X2 = xmm6
106 X3 = xmm7
107
108 XTMP0 = xmm0
109 XTMP1 = xmm1
110 XTMP2 = xmm2
111 XTMP3 = xmm3
112 XTMP4 = xmm8
113 XFER  = xmm9
114
115 SHUF_00BA = xmm10 /* shuffle xBxA -> 00BA */
116 SHUF_DC00 = xmm11 /* shuffle xDxC -> DC00 */
117 BYTE_FLIP_MASK = xmm12
118
119 NUM_BLKS = rdx  /* 3rd arg */
120 CTX = rsi       /* 2nd arg */
121 INP = rdi       /* 1st arg */
122
123 SRND = rdi      /* clobbers INP */
124 c = ecx
125 d = r8d
126 e = edx
127
128 TBL = rbp
129 a = eax
130 b = ebx
131
132 f = r9d
133 g = r10d
134 h = r11d
135
136 y0 = r13d
137 y1 = r14d
138 y2 = r15d
139
140
141
142 #define _INP_END_SIZE   8
143 #define _INP_SIZE       8
144 #define _XFER_SIZE      8
145 #define _XMM_SAVE_SIZE  0
146 /* STACK_SIZE plus pushes must be an odd multiple of 8 */
147 #define _ALIGN_SIZE     8
148
149 #define _INP_END        0
150 #define _INP            (_INP_END  + _INP_END_SIZE)
151 #define _XFER           (_INP      + _INP_SIZE)
152 #define _XMM_SAVE       (_XFER     + _XFER_SIZE + _ALIGN_SIZE)
153 #define STACK_SIZE      (_XMM_SAVE + _XMM_SAVE_SIZE)
154
155 /* rotate_Xs
156  * Rotate values of symbols X0...X3 */
157 .macro rotate_Xs
158 X_ = X0
159 X0 = X1
160 X1 = X2
161 X2 = X3
162 X3 = X_
163 .endm
164
165 /* ROTATE_ARGS
166  * Rotate values of symbols a...h */
167 .macro ROTATE_ARGS
168 TMP_ = h
169 h = g
170 g = f
171 f = e
172 e = d
173 d = c
174 c = b
175 b = a
176 a = TMP_
177 .endm
178
179 .macro FOUR_ROUNDS_AND_SCHED
180                 /* compute s0 four at a time and s1 two at a time
181                  * compute W[-16] + W[-7] 4 at a time */
182         mov     y0, e           /* y0 = e */
183         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
184         mov     y1, a           /* y1 = a */
185                 vpalignr        XTMP0, X3, X2, 4        /* XTMP0 = W[-7] */
186         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
187         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
188         mov     y2, f           /* y2 = f */
189         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
190         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
191         xor     y2, g           /* y2 = f^g */
192                 vpaddd  XTMP0, XTMP0, X0        /* XTMP0 = W[-7] + W[-16] */
193         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
194         and     y2, e           /* y2 = (f^g)&e */
195         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
196                 /* compute s0 */
197                 vpalignr        XTMP1, X1, X0, 4        /* XTMP1 = W[-15] */
198         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
199         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
200         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
201         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
202         add     y2, y0          /* y2 = S1 + CH */
203         add     y2, [rsp + _XFER + 0*4] /* y2 = k + w + S1 + CH */
204         mov     y0, a           /* y0 = a */
205         add     h, y2           /* h = h + S1 + CH + k + w */
206         mov     y2, a           /* y2 = a */
207                 vpslld  XTMP2, XTMP1, (32-7)
208         or      y0, c           /* y0 = a|c */
209         add     d, h            /* d = d + h + S1 + CH + k + w */
210         and     y2, c           /* y2 = a&c */
211                 vpsrld  XTMP3, XTMP1, 7
212         and     y0, b           /* y0 = (a|c)&b */
213         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
214                 vpor    XTMP3, XTMP3, XTMP2     /* XTMP1 = W[-15] ror 7 */
215         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
216         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
217
218 ROTATE_ARGS
219         mov     y0, e           /* y0 = e */
220         mov     y1, a           /* y1 = a */
221         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
222         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
223         mov     y2, f           /* y2 = f */
224         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
225                 vpslld  XTMP2, XTMP1, (32-18)
226         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
227         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
228         xor     y2, g           /* y2 = f^g */
229                 vpsrld  XTMP4, XTMP1, 18
230         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
231         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
232         and     y2, e           /* y2 = (f^g)&e */
233         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
234                 vpxor   XTMP4, XTMP4, XTMP3
235         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
236         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
237                 vpsrld  XTMP1, XTMP1, 3 /* XTMP4 = W[-15] >> 3 */
238         add     y2, y0          /* y2 = S1 + CH */
239         add     y2, [rsp + _XFER + 1*4] /* y2 = k + w + S1 + CH */
240         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
241                 vpxor   XTMP1, XTMP1, XTMP2     /* XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 */
242         mov     y0, a           /* y0 = a */
243         add     h, y2           /* h = h + S1 + CH + k + w */
244         mov     y2, a           /* y2 = a */
245                 vpxor   XTMP1, XTMP1, XTMP4     /* XTMP1 = s0 */
246         or      y0, c           /* y0 = a|c */
247         add     d, h            /* d = d + h + S1 + CH + k + w */
248         and     y2, c           /* y2 = a&c */
249                 /* compute low s1 */
250                 vpshufd XTMP2, X3, 0b11111010   /* XTMP2 = W[-2] {BBAA} */
251         and     y0, b           /* y0 = (a|c)&b */
252         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
253                 vpaddd  XTMP0, XTMP0, XTMP1     /* XTMP0 = W[-16] + W[-7] + s0 */
254         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
255         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
256
257 ROTATE_ARGS
258         mov     y0, e           /* y0 = e */
259         mov     y1, a           /* y1 = a */
260         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
261         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
262         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
263         mov     y2, f           /* y2 = f */
264         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
265         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
266                 vpsrlq  XTMP3, XTMP2, 17        /* XTMP2 = W[-2] ror 17 {xBxA} */
267         xor     y2, g           /* y2 = f^g */
268                 vpsrlq  XTMP4, XTMP2, 19        /* XTMP3 = W[-2] ror 19 {xBxA} */
269         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
270         and     y2, e           /* y2 = (f^g)&e */
271                 vpsrld  XTMP2, XTMP2, 10        /* XTMP4 = W[-2] >> 10 {BBAA} */
272         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
273         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
274         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
275         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
276                 vpxor   XTMP2, XTMP2, XTMP3
277         add     y2, y0          /* y2 = S1 + CH */
278         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
279         add     y2, [rsp + _XFER + 2*4] /* y2 = k + w + S1 + CH */
280                 vpxor   XTMP4, XTMP4, XTMP2     /* XTMP4 = s1 {xBxA} */
281         mov     y0, a           /* y0 = a */
282         add     h, y2           /* h = h + S1 + CH + k + w */
283         mov     y2, a           /* y2 = a */
284                 vpshufb XTMP4, XTMP4, SHUF_00BA /* XTMP4 = s1 {00BA} */
285         or      y0, c           /* y0 = a|c */
286         add     d, h            /* d = d + h + S1 + CH + k + w */
287         and     y2, c           /* y2 = a&c */
288                 vpaddd  XTMP0, XTMP0, XTMP4     /* XTMP0 = {..., ..., W[1], W[0]} */
289         and     y0, b           /* y0 = (a|c)&b */
290         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
291                 /* compute high s1 */
292                 vpshufd XTMP2, XTMP0, 0b01010000 /* XTMP2 = W[-2] {DDCC} */
293         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
294         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
295
296 ROTATE_ARGS
297         mov     y0, e           /* y0 = e */
298         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
299         mov     y1, a           /* y1 = a */
300         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
301         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
302         mov     y2, f           /* y2 = f */
303         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
304                 vpsrlq  XTMP3, XTMP2, 17        /* XTMP2 = W[-2] ror 17 {xDxC} */
305         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
306         xor     y2, g           /* y2 = f^g */
307                 vpsrlq  X0, XTMP2, 19   /* XTMP3 = W[-2] ror 19 {xDxC} */
308         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
309         and     y2, e           /* y2 = (f^g)&e */
310         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
311                 vpsrld  XTMP2, XTMP2,    10     /* X0 = W[-2] >> 10 {DDCC} */
312         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
313         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
314         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
315                 vpxor   XTMP2, XTMP2, XTMP3
316         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
317         add     y2, y0          /* y2 = S1 + CH */
318         add     y2, [rsp + _XFER + 3*4] /* y2 = k + w + S1 + CH */
319                 vpxor   X0, X0, XTMP2   /* X0 = s1 {xDxC} */
320         mov     y0, a           /* y0 = a */
321         add     h, y2           /* h = h + S1 + CH + k + w */
322         mov     y2, a           /* y2 = a */
323                 vpshufb X0, X0, SHUF_DC00       /* X0 = s1 {DC00} */
324         or      y0, c           /* y0 = a|c */
325         add     d, h            /* d = d + h + S1 + CH + k + w */
326         and     y2, c           /* y2 = a&c */
327                 vpaddd  X0, X0, XTMP0   /* X0 = {W[3], W[2], W[1], W[0]} */
328         and     y0, b           /* y0 = (a|c)&b */
329         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
330         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
331         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
332
333 ROTATE_ARGS
334 rotate_Xs
335 .endm
336
337 /* input is [rsp + _XFER + %1 * 4] */
338 .macro DO_ROUND i1
339         mov     y0, e           /* y0 = e */
340         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
341         mov     y1, a           /* y1 = a */
342         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
343         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
344         mov     y2, f           /* y2 = f */
345         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
346         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
347         xor     y2, g           /* y2 = f^g */
348         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
349         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
350         and     y2, e           /* y2 = (f^g)&e */
351         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
352         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
353         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
354         add     y2, y0          /* y2 = S1 + CH */
355         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
356         add     y2, [rsp + _XFER + \i1 * 4]     /* y2 = k + w + S1 + CH */
357         mov     y0, a           /* y0 = a */
358         add     h, y2           /* h = h + S1 + CH + k + w */
359         mov     y2, a           /* y2 = a */
360         or      y0, c           /* y0 = a|c */
361         add     d, h            /* d = d + h + S1 + CH + k + w */
362         and     y2, c           /* y2 = a&c */
363         and     y0, b           /* y0 = (a|c)&b */
364         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
365         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
366         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
367         ROTATE_ARGS
368 .endm
369
370 /*
371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
372 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
373 ;; void sha256_avx(void *input_data, UINT32 digest[8], UINT64 num_blks)
374 ;; arg 1 : pointer to input data
375 ;; arg 2 : pointer to digest
376 ;; arg 3 : Num blocks
377 */
378 .text
379 .globl _gcry_sha256_transform_amd64_avx
380 ELF(.type  _gcry_sha256_transform_amd64_avx,@function;)
381 .align 16
382 _gcry_sha256_transform_amd64_avx:
383         vzeroupper
384
385         push    rbx
386         push    rbp
387         push    r13
388         push    r14
389         push    r15
390
391         sub     rsp, STACK_SIZE
392
393         shl     NUM_BLKS, 6     /* convert to bytes */
394         jz      .Ldone_hash
395         add     NUM_BLKS, INP   /* pointer to end of data */
396         mov     [rsp + _INP_END], NUM_BLKS
397
398         /* load initial digest */
399         mov     a,[4*0 + CTX]
400         mov     b,[4*1 + CTX]
401         mov     c,[4*2 + CTX]
402         mov     d,[4*3 + CTX]
403         mov     e,[4*4 + CTX]
404         mov     f,[4*5 + CTX]
405         mov     g,[4*6 + CTX]
406         mov     h,[4*7 + CTX]
407
408         vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
409         vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
410         vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
411
412 .Loop0:
413         lea     TBL, [.LK256 ADD_RIP]
414
415         /* byte swap first 16 dwords */
416         COPY_XMM_AND_BSWAP      X0, [INP + 0*16], BYTE_FLIP_MASK
417         COPY_XMM_AND_BSWAP      X1, [INP + 1*16], BYTE_FLIP_MASK
418         COPY_XMM_AND_BSWAP      X2, [INP + 2*16], BYTE_FLIP_MASK
419         COPY_XMM_AND_BSWAP      X3, [INP + 3*16], BYTE_FLIP_MASK
420
421         mov     [rsp + _INP], INP
422
423         /* schedule 48 input dwords, by doing 3 rounds of 16 each */
424         mov     SRND, 3
425 .align 16
426 .Loop1:
427         vpaddd  XFER, X0, [TBL + 0*16]
428         vmovdqa [rsp + _XFER], XFER
429         FOUR_ROUNDS_AND_SCHED
430
431         vpaddd  XFER, X0, [TBL + 1*16]
432         vmovdqa [rsp + _XFER], XFER
433         FOUR_ROUNDS_AND_SCHED
434
435         vpaddd  XFER, X0, [TBL + 2*16]
436         vmovdqa [rsp + _XFER], XFER
437         FOUR_ROUNDS_AND_SCHED
438
439         vpaddd  XFER, X0, [TBL + 3*16]
440         vmovdqa [rsp + _XFER], XFER
441         add     TBL, 4*16
442         FOUR_ROUNDS_AND_SCHED
443
444         sub     SRND, 1
445         jne     .Loop1
446
447         mov     SRND, 2
448 .Loop2:
449         vpaddd  X0, X0, [TBL + 0*16]
450         vmovdqa [rsp + _XFER], X0
451         DO_ROUND        0
452         DO_ROUND        1
453         DO_ROUND        2
454         DO_ROUND        3
455         vpaddd  X1, X1, [TBL + 1*16]
456         vmovdqa [rsp + _XFER], X1
457         add     TBL, 2*16
458         DO_ROUND        0
459         DO_ROUND        1
460         DO_ROUND        2
461         DO_ROUND        3
462
463         vmovdqa X0, X2
464         vmovdqa X1, X3
465
466         sub     SRND, 1
467         jne     .Loop2
468
469         addm    [4*0 + CTX],a
470         addm    [4*1 + CTX],b
471         addm    [4*2 + CTX],c
472         addm    [4*3 + CTX],d
473         addm    [4*4 + CTX],e
474         addm    [4*5 + CTX],f
475         addm    [4*6 + CTX],g
476         addm    [4*7 + CTX],h
477
478         mov     INP, [rsp + _INP]
479         add     INP, 64
480         cmp     INP, [rsp + _INP_END]
481         jne     .Loop0
482
483         vzeroall
484
485 .Ldone_hash:
486         add     rsp, STACK_SIZE
487
488         pop     r15
489         pop     r14
490         pop     r13
491         pop     rbp
492         pop     rbx
493
494         mov     eax, STACK_SIZE + 5*8
495
496         ret
497
498
499 .align 16
500 .LK256:
501         .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
502         .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
503         .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
504         .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
505         .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
506         .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
507         .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
508         .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
509         .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
510         .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
511         .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
512         .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
513         .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
514         .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
515         .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
516         .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
517
518 .LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x0c0d0e0f08090a0b0405060700010203
519
520 /* shuffle xBxA -> 00BA */
521 .L_SHUF_00BA:              .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100
522
523 /* shuffle xDxC -> DC00 */
524 .L_SHUF_DC00:              .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF
525
526 #endif
527 #endif