mac: Fix gcry_mac_close to allow for a NULL handle.
[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_INTEL_SYNTAX_PLATFORM_AS) && \
59     defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA256)
60
61 #ifdef __PIC__
62 #  define ADD_RIP +rip
63 #else
64 #  define ADD_RIP
65 #endif
66
67 .intel_syntax noprefix
68
69 #define VMOVDQ vmovdqu /* assume buffers not aligned */
70
71 .macro ROR p1 p2
72         /* shld is faster than ror on Intel Sandybridge */
73         shld    \p1, \p1, (32 - \p2)
74 .endm
75
76 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros*/
77
78 /* addm [mem], reg
79  * Add reg to mem using reg-mem add and store */
80 .macro addm p1 p2
81         add     \p2, \p1
82         mov     \p1, \p2
83 .endm
84
85 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
86
87 /* COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask
88  * Load xmm with mem and byte swap each dword */
89 .macro COPY_XMM_AND_BSWAP p1 p2 p3
90         VMOVDQ \p1, \p2
91         vpshufb \p1, \p1, \p3
92 .endm
93
94 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
95
96 X0 = xmm4
97 X1 = xmm5
98 X2 = xmm6
99 X3 = xmm7
100
101 XTMP0 = xmm0
102 XTMP1 = xmm1
103 XTMP2 = xmm2
104 XTMP3 = xmm3
105 XTMP4 = xmm8
106 XFER  = xmm9
107
108 SHUF_00BA = xmm10 /* shuffle xBxA -> 00BA */
109 SHUF_DC00 = xmm11 /* shuffle xDxC -> DC00 */
110 BYTE_FLIP_MASK = xmm12
111
112 NUM_BLKS = rdx  /* 3rd arg */
113 CTX = rsi       /* 2nd arg */
114 INP = rdi       /* 1st arg */
115
116 SRND = rdi      /* clobbers INP */
117 c = ecx
118 d = r8d
119 e = edx
120
121 TBL = rbp
122 a = eax
123 b = ebx
124
125 f = r9d
126 g = r10d
127 h = r11d
128
129 y0 = r13d
130 y1 = r14d
131 y2 = r15d
132
133
134
135 #define _INP_END_SIZE   8
136 #define _INP_SIZE       8
137 #define _XFER_SIZE      8
138 #define _XMM_SAVE_SIZE  0
139 /* STACK_SIZE plus pushes must be an odd multiple of 8 */
140 #define _ALIGN_SIZE     8
141
142 #define _INP_END        0
143 #define _INP            (_INP_END  + _INP_END_SIZE)
144 #define _XFER           (_INP      + _INP_SIZE)
145 #define _XMM_SAVE       (_XFER     + _XFER_SIZE + _ALIGN_SIZE)
146 #define STACK_SIZE      (_XMM_SAVE + _XMM_SAVE_SIZE)
147
148 /* rotate_Xs
149  * Rotate values of symbols X0...X3 */
150 .macro rotate_Xs
151 X_ = X0
152 X0 = X1
153 X1 = X2
154 X2 = X3
155 X3 = X_
156 .endm
157
158 /* ROTATE_ARGS
159  * Rotate values of symbols a...h */
160 .macro ROTATE_ARGS
161 TMP_ = h
162 h = g
163 g = f
164 f = e
165 e = d
166 d = c
167 c = b
168 b = a
169 a = TMP_
170 .endm
171
172 .macro FOUR_ROUNDS_AND_SCHED
173                 /* compute s0 four at a time and s1 two at a time
174                  * compute W[-16] + W[-7] 4 at a time */
175         mov     y0, e           /* y0 = e */
176         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
177         mov     y1, a           /* y1 = a */
178                 vpalignr        XTMP0, X3, X2, 4        /* XTMP0 = W[-7] */
179         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
180         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
181         mov     y2, f           /* y2 = f */
182         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
183         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
184         xor     y2, g           /* y2 = f^g */
185                 vpaddd  XTMP0, XTMP0, X0        /* XTMP0 = W[-7] + W[-16] */
186         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
187         and     y2, e           /* y2 = (f^g)&e */
188         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
189                 /* compute s0 */
190                 vpalignr        XTMP1, X1, X0, 4        /* XTMP1 = W[-15] */
191         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
192         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
193         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
194         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
195         add     y2, y0          /* y2 = S1 + CH */
196         add     y2, [rsp + _XFER + 0*4] /* y2 = k + w + S1 + CH */
197         mov     y0, a           /* y0 = a */
198         add     h, y2           /* h = h + S1 + CH + k + w */
199         mov     y2, a           /* y2 = a */
200                 vpslld  XTMP2, XTMP1, (32-7)
201         or      y0, c           /* y0 = a|c */
202         add     d, h            /* d = d + h + S1 + CH + k + w */
203         and     y2, c           /* y2 = a&c */
204                 vpsrld  XTMP3, XTMP1, 7
205         and     y0, b           /* y0 = (a|c)&b */
206         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
207                 vpor    XTMP3, XTMP3, XTMP2     /* XTMP1 = W[-15] ror 7 */
208         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
209         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
210
211 ROTATE_ARGS
212         mov     y0, e           /* y0 = e */
213         mov     y1, a           /* y1 = a */
214         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
215         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
216         mov     y2, f           /* y2 = f */
217         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
218                 vpslld  XTMP2, XTMP1, (32-18)
219         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
220         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
221         xor     y2, g           /* y2 = f^g */
222                 vpsrld  XTMP4, XTMP1, 18
223         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
224         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
225         and     y2, e           /* y2 = (f^g)&e */
226         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
227                 vpxor   XTMP4, XTMP4, XTMP3
228         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
229         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
230                 vpsrld  XTMP1, XTMP1, 3 /* XTMP4 = W[-15] >> 3 */
231         add     y2, y0          /* y2 = S1 + CH */
232         add     y2, [rsp + _XFER + 1*4] /* y2 = k + w + S1 + CH */
233         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
234                 vpxor   XTMP1, XTMP1, XTMP2     /* XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 */
235         mov     y0, a           /* y0 = a */
236         add     h, y2           /* h = h + S1 + CH + k + w */
237         mov     y2, a           /* y2 = a */
238                 vpxor   XTMP1, XTMP1, XTMP4     /* XTMP1 = s0 */
239         or      y0, c           /* y0 = a|c */
240         add     d, h            /* d = d + h + S1 + CH + k + w */
241         and     y2, c           /* y2 = a&c */
242                 /* compute low s1 */
243                 vpshufd XTMP2, X3, 0b11111010   /* XTMP2 = W[-2] {BBAA} */
244         and     y0, b           /* y0 = (a|c)&b */
245         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
246                 vpaddd  XTMP0, XTMP0, XTMP1     /* XTMP0 = W[-16] + W[-7] + s0 */
247         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
248         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
249
250 ROTATE_ARGS
251         mov     y0, e           /* y0 = e */
252         mov     y1, a           /* y1 = a */
253         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
254         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
255         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
256         mov     y2, f           /* y2 = f */
257         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
258         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
259                 vpsrlq  XTMP3, XTMP2, 17        /* XTMP2 = W[-2] ror 17 {xBxA} */
260         xor     y2, g           /* y2 = f^g */
261                 vpsrlq  XTMP4, XTMP2, 19        /* XTMP3 = W[-2] ror 19 {xBxA} */
262         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
263         and     y2, e           /* y2 = (f^g)&e */
264                 vpsrld  XTMP2, XTMP2, 10        /* XTMP4 = W[-2] >> 10 {BBAA} */
265         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
266         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
267         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
268         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
269                 vpxor   XTMP2, XTMP2, XTMP3
270         add     y2, y0          /* y2 = S1 + CH */
271         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
272         add     y2, [rsp + _XFER + 2*4] /* y2 = k + w + S1 + CH */
273                 vpxor   XTMP4, XTMP4, XTMP2     /* XTMP4 = s1 {xBxA} */
274         mov     y0, a           /* y0 = a */
275         add     h, y2           /* h = h + S1 + CH + k + w */
276         mov     y2, a           /* y2 = a */
277                 vpshufb XTMP4, XTMP4, SHUF_00BA /* XTMP4 = s1 {00BA} */
278         or      y0, c           /* y0 = a|c */
279         add     d, h            /* d = d + h + S1 + CH + k + w */
280         and     y2, c           /* y2 = a&c */
281                 vpaddd  XTMP0, XTMP0, XTMP4     /* XTMP0 = {..., ..., W[1], W[0]} */
282         and     y0, b           /* y0 = (a|c)&b */
283         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
284                 /* compute high s1 */
285                 vpshufd XTMP2, XTMP0, 0b01010000 /* XTMP2 = W[-2] {DDCC} */
286         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
287         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
288
289 ROTATE_ARGS
290         mov     y0, e           /* y0 = e */
291         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
292         mov     y1, a           /* y1 = a */
293         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
294         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
295         mov     y2, f           /* y2 = f */
296         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
297                 vpsrlq  XTMP3, XTMP2, 17        /* XTMP2 = W[-2] ror 17 {xDxC} */
298         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
299         xor     y2, g           /* y2 = f^g */
300                 vpsrlq  X0, XTMP2, 19   /* XTMP3 = W[-2] ror 19 {xDxC} */
301         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
302         and     y2, e           /* y2 = (f^g)&e */
303         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
304                 vpsrld  XTMP2, XTMP2,    10     /* X0 = W[-2] >> 10 {DDCC} */
305         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
306         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
307         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
308                 vpxor   XTMP2, XTMP2, XTMP3
309         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
310         add     y2, y0          /* y2 = S1 + CH */
311         add     y2, [rsp + _XFER + 3*4] /* y2 = k + w + S1 + CH */
312                 vpxor   X0, X0, XTMP2   /* X0 = s1 {xDxC} */
313         mov     y0, a           /* y0 = a */
314         add     h, y2           /* h = h + S1 + CH + k + w */
315         mov     y2, a           /* y2 = a */
316                 vpshufb X0, X0, SHUF_DC00       /* X0 = s1 {DC00} */
317         or      y0, c           /* y0 = a|c */
318         add     d, h            /* d = d + h + S1 + CH + k + w */
319         and     y2, c           /* y2 = a&c */
320                 vpaddd  X0, X0, XTMP0   /* X0 = {W[3], W[2], W[1], W[0]} */
321         and     y0, b           /* y0 = (a|c)&b */
322         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
323         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
324         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
325
326 ROTATE_ARGS
327 rotate_Xs
328 .endm
329
330 /* input is [rsp + _XFER + %1 * 4] */
331 .macro DO_ROUND i1
332         mov     y0, e           /* y0 = e */
333         ROR     y0, (25-11)     /* y0 = e >> (25-11) */
334         mov     y1, a           /* y1 = a */
335         xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
336         ROR     y1, (22-13)     /* y1 = a >> (22-13) */
337         mov     y2, f           /* y2 = f */
338         xor     y1, a           /* y1 = a ^ (a >> (22-13) */
339         ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
340         xor     y2, g           /* y2 = f^g */
341         xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
342         ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
343         and     y2, e           /* y2 = (f^g)&e */
344         xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
345         ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
346         xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
347         add     y2, y0          /* y2 = S1 + CH */
348         ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
349         add     y2, [rsp + _XFER + \i1 * 4]     /* y2 = k + w + S1 + CH */
350         mov     y0, a           /* y0 = a */
351         add     h, y2           /* h = h + S1 + CH + k + w */
352         mov     y2, a           /* y2 = a */
353         or      y0, c           /* y0 = a|c */
354         add     d, h            /* d = d + h + S1 + CH + k + w */
355         and     y2, c           /* y2 = a&c */
356         and     y0, b           /* y0 = (a|c)&b */
357         add     h, y1           /* h = h + S1 + CH + k + w + S0 */
358         or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
359         lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
360         ROTATE_ARGS
361 .endm
362
363 /*
364 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366 ;; void sha256_avx(void *input_data, UINT32 digest[8], UINT64 num_blks)
367 ;; arg 1 : pointer to input data
368 ;; arg 2 : pointer to digest
369 ;; arg 3 : Num blocks
370 */
371 .text
372 .globl _gcry_sha256_transform_amd64_avx
373 .type  _gcry_sha256_transform_amd64_avx,@function;
374 .align 16
375 _gcry_sha256_transform_amd64_avx:
376         vzeroupper
377
378         push    rbx
379         push    rbp
380         push    r13
381         push    r14
382         push    r15
383
384         sub     rsp, STACK_SIZE
385
386         shl     NUM_BLKS, 6     /* convert to bytes */
387         jz      .Ldone_hash
388         add     NUM_BLKS, INP   /* pointer to end of data */
389         mov     [rsp + _INP_END], NUM_BLKS
390
391         /* load initial digest */
392         mov     a,[4*0 + CTX]
393         mov     b,[4*1 + CTX]
394         mov     c,[4*2 + CTX]
395         mov     d,[4*3 + CTX]
396         mov     e,[4*4 + CTX]
397         mov     f,[4*5 + CTX]
398         mov     g,[4*6 + CTX]
399         mov     h,[4*7 + CTX]
400
401         vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
402         vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
403         vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
404
405 .Loop0:
406         lea     TBL, [.LK256 ADD_RIP]
407
408         /* byte swap first 16 dwords */
409         COPY_XMM_AND_BSWAP      X0, [INP + 0*16], BYTE_FLIP_MASK
410         COPY_XMM_AND_BSWAP      X1, [INP + 1*16], BYTE_FLIP_MASK
411         COPY_XMM_AND_BSWAP      X2, [INP + 2*16], BYTE_FLIP_MASK
412         COPY_XMM_AND_BSWAP      X3, [INP + 3*16], BYTE_FLIP_MASK
413
414         mov     [rsp + _INP], INP
415
416         /* schedule 48 input dwords, by doing 3 rounds of 16 each */
417         mov     SRND, 3
418 .align 16
419 .Loop1:
420         vpaddd  XFER, X0, [TBL + 0*16]
421         vmovdqa [rsp + _XFER], XFER
422         FOUR_ROUNDS_AND_SCHED
423
424         vpaddd  XFER, X0, [TBL + 1*16]
425         vmovdqa [rsp + _XFER], XFER
426         FOUR_ROUNDS_AND_SCHED
427
428         vpaddd  XFER, X0, [TBL + 2*16]
429         vmovdqa [rsp + _XFER], XFER
430         FOUR_ROUNDS_AND_SCHED
431
432         vpaddd  XFER, X0, [TBL + 3*16]
433         vmovdqa [rsp + _XFER], XFER
434         add     TBL, 4*16
435         FOUR_ROUNDS_AND_SCHED
436
437         sub     SRND, 1
438         jne     .Loop1
439
440         mov     SRND, 2
441 .Loop2:
442         vpaddd  X0, X0, [TBL + 0*16]
443         vmovdqa [rsp + _XFER], X0
444         DO_ROUND        0
445         DO_ROUND        1
446         DO_ROUND        2
447         DO_ROUND        3
448         vpaddd  X1, X1, [TBL + 1*16]
449         vmovdqa [rsp + _XFER], X1
450         add     TBL, 2*16
451         DO_ROUND        0
452         DO_ROUND        1
453         DO_ROUND        2
454         DO_ROUND        3
455
456         vmovdqa X0, X2
457         vmovdqa X1, X3
458
459         sub     SRND, 1
460         jne     .Loop2
461
462         addm    [4*0 + CTX],a
463         addm    [4*1 + CTX],b
464         addm    [4*2 + CTX],c
465         addm    [4*3 + CTX],d
466         addm    [4*4 + CTX],e
467         addm    [4*5 + CTX],f
468         addm    [4*6 + CTX],g
469         addm    [4*7 + CTX],h
470
471         mov     INP, [rsp + _INP]
472         add     INP, 64
473         cmp     INP, [rsp + _INP_END]
474         jne     .Loop0
475
476         vzeroall
477
478 .Ldone_hash:
479         add     rsp, STACK_SIZE
480
481         pop     r15
482         pop     r14
483         pop     r13
484         pop     rbp
485         pop     rbx
486
487         mov     eax, STACK_SIZE + 5*8
488
489         ret
490
491
492 .data
493 .align 16
494 .LK256:
495         .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
496         .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
497         .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
498         .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
499         .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
500         .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
501         .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
502         .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
503         .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
504         .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
505         .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
506         .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
507         .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
508         .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
509         .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
510         .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
511
512 .LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x0c0d0e0f08090a0b0405060700010203
513
514 /* shuffle xBxA -> 00BA */
515 .L_SHUF_00BA:              .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100
516
517 /* shuffle xDxC -> DC00 */
518 .L_SHUF_DC00:              .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF
519
520 #endif
521 #endif