SHA-1/SSSE3: Improve performance on large buffers
[libgcrypt.git] / cipher / sha512-avx2-bmi2-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 ; This code schedules 1 blocks at a time, with 4 lanes per block
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 */
39 /*
40  * Conversion to GAS assembly and integration to libgcrypt
41  *  by Jussi Kivilinna <jussi.kivilinna@iki.fi>
42  */
43
44 #ifdef __x86_64
45 #include <config.h>
46 #if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
47     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
48     defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
49     defined(USE_SHA512)
50
51 #ifdef __PIC__
52 #  define ADD_RIP +rip
53 #else
54 #  define ADD_RIP
55 #endif
56
57 .intel_syntax noprefix
58
59 .text
60
61 /* Virtual Registers */
62 Y_0 = ymm4
63 Y_1 = ymm5
64 Y_2 = ymm6
65 Y_3 = ymm7
66
67 YTMP0 = ymm0
68 YTMP1 = ymm1
69 YTMP2 = ymm2
70 YTMP3 = ymm3
71 YTMP4 = ymm8
72 XFER =  YTMP0
73
74 BYTE_FLIP_MASK =  ymm9
75
76 INP =         rdi /* 1st arg */
77 CTX =         rsi /* 2nd arg */
78 NUM_BLKS =    rdx /* 3rd arg */
79 c =           rcx
80 d =           r8
81 e =           rdx
82 y3 =          rdi
83
84 TBL =   rbp
85
86 a =     rax
87 b =     rbx
88
89 f =     r9
90 g =     r10
91 h =     r11
92 old_h = r11
93
94 T1 =    r12
95 y0 =    r13
96 y1 =    r14
97 y2 =    r15
98
99 y4 =    r12
100
101 /* Local variables (stack frame) */
102 #define frame_XFER      0
103 #define frame_XFER_size (4*8)
104 #define frame_SRND      (frame_XFER + frame_XFER_size)
105 #define frame_SRND_size (1*8)
106 #define frame_INP      (frame_SRND + frame_SRND_size)
107 #define frame_INP_size (1*8)
108 #define frame_INPEND      (frame_INP + frame_INP_size)
109 #define frame_INPEND_size (1*8)
110 #define frame_RSPSAVE      (frame_INPEND + frame_INPEND_size)
111 #define frame_RSPSAVE_size (1*8)
112 #define frame_GPRSAVE      (frame_RSPSAVE + frame_RSPSAVE_size)
113 #define frame_GPRSAVE_size (6*8)
114 #define frame_size (frame_GPRSAVE + frame_GPRSAVE_size)
115
116 #define VMOVDQ vmovdqu /*; assume buffers not aligned  */
117
118 /* addm [mem], reg */
119 /* Add reg to mem using reg-mem add and store */
120 .macro addm p1 p2
121         add     \p2, \p1
122         mov     \p1, \p2
123 .endm
124
125
126 /* COPY_YMM_AND_BSWAP ymm, [mem], byte_flip_mask */
127 /* Load ymm with mem and byte swap each dword */
128 .macro COPY_YMM_AND_BSWAP p1 p2 p3
129         VMOVDQ \p1, \p2
130         vpshufb \p1, \p1, \p3
131 .endm
132 /* rotate_Ys */
133 /* Rotate values of symbols Y0...Y3 */
134 .macro rotate_Ys
135         __Y_ = Y_0
136         Y_0 = Y_1
137         Y_1 = Y_2
138         Y_2 = Y_3
139         Y_3 = __Y_
140 .endm
141
142 /* RotateState */
143 .macro RotateState
144         /* Rotate symbles a..h right */
145         old_h =  h
146         __TMP_ = h
147         h =      g
148         g =      f
149         f =      e
150         e =      d
151         d =      c
152         c =      b
153         b =      a
154         a =      __TMP_
155 .endm
156
157 /* %macro MY_VPALIGNR   YDST, YSRC1, YSRC2, RVAL */
158 /* YDST = {YSRC1, YSRC2} >> RVAL*8 */
159 .macro MY_VPALIGNR YDST, YSRC1, YSRC2, RVAL
160         vperm2f128      \YDST, \YSRC1, \YSRC2, 0x3      /* YDST = {YS1_LO, YS2_HI} */
161         vpalignr        \YDST, \YDST, \YSRC2, \RVAL     /* YDST = {YDS1, YS2} >> RVAL*8 */
162 .endm
163
164 .macro FOUR_ROUNDS_AND_SCHED
165 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
166
167                 /* Extract w[t-7] */
168                 MY_VPALIGNR     YTMP0, Y_3, Y_2, 8              /* YTMP0 = W[-7] */
169                 /* Calculate w[t-16] + w[t-7] */
170                 vpaddq          YTMP0, YTMP0, Y_0               /* YTMP0 = W[-7] + W[-16] */
171                 /* Extract w[t-15] */
172                 MY_VPALIGNR     YTMP1, Y_1, Y_0, 8              /* YTMP1 = W[-15] */
173
174                 /* Calculate sigma0 */
175
176                 /* Calculate w[t-15] ror 1 */
177                 vpsrlq          YTMP2, YTMP1, 1
178                 vpsllq          YTMP3, YTMP1, (64-1)
179                 vpor            YTMP3, YTMP3, YTMP2             /* YTMP3 = W[-15] ror 1 */
180                 /* Calculate w[t-15] shr 7 */
181                 vpsrlq          YTMP4, YTMP1, 7                 /* YTMP4 = W[-15] >> 7 */
182
183         mov     y3, a           /* y3 = a                                       ; MAJA   */
184         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
185         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
186
187         add     h, [rsp+frame_XFER+0*8]         /* h = k + w + h                                ; --     */
188         or      y3, c           /* y3 = a|c                                     ; MAJA   */
189         mov     y2, f           /* y2 = f                                       ; CH     */
190         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
191
192         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
193         xor     y2, g           /* y2 = f^g                                     ; CH     */
194         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
195
196         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
197         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
198         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
199         add     d, h            /* d = k + w + h + d                            ; --     */
200
201         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
202         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
203         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
204
205         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
206         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
207         mov     T1, a           /* T1 = a                                       ; MAJB   */
208         and     T1, c           /* T1 = a&c                                     ; MAJB   */
209
210         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
211         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
212         add     h, y1           /* h = k + w + h + S0                           ; --     */
213
214         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
215
216         add     h, y2           /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
217         add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
218
219 RotateState
220
221 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
222
223 /*;;;;;;;;;;;;;;;;;;;;;;;;; */
224
225                 /* Calculate w[t-15] ror 8 */
226                 vpsrlq          YTMP2, YTMP1, 8
227                 vpsllq          YTMP1, YTMP1, (64-8)
228                 vpor            YTMP1, YTMP1, YTMP2             /* YTMP1 = W[-15] ror 8 */
229                 /* XOR the three components */
230                 vpxor           YTMP3, YTMP3, YTMP4             /* YTMP3 = W[-15] ror 1 ^ W[-15] >> 7 */
231                 vpxor           YTMP1, YTMP3, YTMP1             /* YTMP1 = s0 */
232
233
234                 /* Add three components, w[t-16], w[t-7] and sigma0 */
235                 vpaddq          YTMP0, YTMP0, YTMP1             /* YTMP0 = W[-16] + W[-7] + s0 */
236                 /* Move to appropriate lanes for calculating w[16] and w[17] */
237                 vperm2f128      Y_0, YTMP0, YTMP0, 0x0          /* Y_0 = W[-16] + W[-7] + s0 {BABA} */
238                 /* Move to appropriate lanes for calculating w[18] and w[19] */
239                 vpand           YTMP0, YTMP0, [.LMASK_YMM_LO ADD_RIP]   /* YTMP0 = W[-16] + W[-7] + s0 {DC00} */
240
241                 /* Calculate w[16] and w[17] in both 128 bit lanes */
242
243                 /* Calculate sigma1 for w[16] and w[17] on both 128 bit lanes */
244                 vperm2f128      YTMP2, Y_3, Y_3, 0x11           /* YTMP2 = W[-2] {BABA} */
245                 vpsrlq          YTMP4, YTMP2, 6                 /* YTMP4 = W[-2] >> 6 {BABA} */
246
247
248         mov     y3, a           /* y3 = a                                       ; MAJA   */
249         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
250         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
251         add     h, [rsp+frame_XFER+1*8]         /* h = k + w + h                                ; --     */
252         or      y3, c           /* y3 = a|c                                     ; MAJA   */
253
254
255         mov     y2, f           /* y2 = f                                       ; CH     */
256         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
257         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
258         xor     y2, g           /* y2 = f^g                                     ; CH     */
259
260
261         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
262         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
263         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
264         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
265         add     d, h            /* d = k + w + h + d                            ; --     */
266
267         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
268         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
269
270         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
271         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
272
273         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
274         mov     T1, a           /* T1 = a                                       ; MAJB   */
275         and     T1, c           /* T1 = a&c                                     ; MAJB   */
276         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
277
278         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
279         add     h, y1           /* h = k + w + h + S0                           ; --     */
280
281         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
282         add     h, y2           /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
283         add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
284
285 RotateState
286
287
288
289
290 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
291
292 /*;;;;;;;;;;;;;;;;;;;;;;;;; */
293
294
295                 vpsrlq          YTMP3, YTMP2, 19                /* YTMP3 = W[-2] >> 19 {BABA} */
296                 vpsllq          YTMP1, YTMP2, (64-19)           /* YTMP1 = W[-2] << 19 {BABA} */
297                 vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 19 {BABA} */
298                 vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {BABA} */
299                 vpsrlq          YTMP3, YTMP2, 61                /* YTMP3 = W[-2] >> 61 {BABA} */
300                 vpsllq          YTMP1, YTMP2, (64-61)           /* YTMP1 = W[-2] << 61 {BABA} */
301                 vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 61 {BABA} */
302                 vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) {BABA} */
303
304                 /* Add sigma1 to the other compunents to get w[16] and w[17] */
305                 vpaddq          Y_0, Y_0, YTMP4                 /* Y_0 = {W[1], W[0], W[1], W[0]} */
306
307                 /* Calculate sigma1 for w[18] and w[19] for upper 128 bit lane */
308                 vpsrlq          YTMP4, Y_0, 6                   /* YTMP4 = W[-2] >> 6 {DC--} */
309
310         mov     y3, a           /* y3 = a                                       ; MAJA   */
311         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
312         add     h, [rsp+frame_XFER+2*8]         /* h = k + w + h                                ; --     */
313
314         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
315         or      y3, c           /* y3 = a|c                                     ; MAJA   */
316         mov     y2, f           /* y2 = f                                       ; CH     */
317         xor     y2, g           /* y2 = f^g                                     ; CH     */
318
319         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
320         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
321         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
322
323         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
324         add     d, h            /* d = k + w + h + d                            ; --     */
325         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
326
327         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
328         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
329         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
330
331         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
332         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
333
334         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
335         mov     T1, a           /* T1 = a                                       ; MAJB   */
336         and     T1, c           /* T1 = a&c                                     ; MAJB   */
337         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
338
339         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
340         add     h, y1           /* h = k + w + h + S0                           ; --     */
341         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
342         add     h, y2           /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
343
344         add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
345
346 RotateState
347
348 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
349
350 /*;;;;;;;;;;;;;;;;;;;;;;;;; */
351
352                 vpsrlq          YTMP3, Y_0, 19                  /* YTMP3 = W[-2] >> 19 {DC--} */
353                 vpsllq          YTMP1, Y_0, (64-19)             /* YTMP1 = W[-2] << 19 {DC--} */
354                 vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 19 {DC--} */
355                 vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {DC--} */
356                 vpsrlq          YTMP3, Y_0, 61                  /* YTMP3 = W[-2] >> 61 {DC--} */
357                 vpsllq          YTMP1, Y_0, (64-61)             /* YTMP1 = W[-2] << 61 {DC--} */
358                 vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 61 {DC--} */
359                 vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) {DC--} */
360
361                 /* Add the sigma0 + w[t-7] + w[t-16] for w[18] and w[19] to newly calculated sigma1 to get w[18] and w[19] */
362                 vpaddq          YTMP2, YTMP0, YTMP4             /* YTMP2 = {W[3], W[2], --, --} */
363
364                 /* Form w[19, w[18], w17], w[16] */
365                 vpblendd                Y_0, Y_0, YTMP2, 0xF0           /* Y_0 = {W[3], W[2], W[1], W[0]} */
366 /*              vperm2f128              Y_0, Y_0, YTMP2, 0x30 */
367
368         mov     y3, a           /* y3 = a                                       ; MAJA   */
369         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
370         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
371         add     h, [rsp+frame_XFER+3*8]         /* h = k + w + h                                ; --     */
372         or      y3, c           /* y3 = a|c                                     ; MAJA   */
373
374
375         mov     y2, f           /* y2 = f                                       ; CH     */
376         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
377         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
378         xor     y2, g           /* y2 = f^g                                     ; CH     */
379
380
381         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
382         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
383         add     d, h            /* d = k + w + h + d                            ; --     */
384         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
385
386         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
387         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
388
389         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
390         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
391
392         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
393         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
394
395         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
396
397         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
398         mov     T1, a           /* T1 = a                                       ; MAJB   */
399         and     T1, c           /* T1 = a&c                                     ; MAJB   */
400         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
401
402         add     h, y1           /* h = k + w + h + S0                           ; --     */
403         add     h, y2           /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
404         add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
405
406 RotateState
407
408 rotate_Ys
409 .endm
410
411 .macro DO_4ROUNDS
412
413 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
414
415         mov     y2, f           /* y2 = f                                       ; CH     */
416         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
417         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
418         xor     y2, g           /* y2 = f^g                                     ; CH     */
419
420         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
421         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
422         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
423
424         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
425         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
426         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
427         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
428         mov     y3, a           /* y3 = a                                       ; MAJA   */
429
430         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
431         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
432         add     h, [rsp + frame_XFER + 8*0]             /* h = k + w + h                                ; --     */
433         or      y3, c           /* y3 = a|c                                     ; MAJA   */
434
435         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
436         mov     T1, a           /* T1 = a                                       ; MAJB   */
437         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
438         and     T1, c           /* T1 = a&c                                     ; MAJB   */
439         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
440
441
442         add     d, h            /* d = k + w + h + d                            ; --     */
443         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
444         add     h, y1           /* h = k + w + h + S0                           ; --     */
445
446         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
447
448
449         /*add   h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0       ; --      */
450
451         /*add   h, y3           ; h = t1 + S0 + MAJ                            ; --      */
452
453         RotateState
454
455 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
456
457         add     old_h, y2       /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
458         mov     y2, f           /* y2 = f                                       ; CH     */
459         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
460         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
461         xor     y2, g           /* y2 = f^g                                     ; CH     */
462
463         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
464         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
465         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
466         add     old_h, y3       /* h = t1 + S0 + MAJ                            ; --     */
467
468         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
469         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
470         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
471         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
472         mov     y3, a           /* y3 = a                                       ; MAJA   */
473
474         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
475         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
476         add     h, [rsp + frame_XFER + 8*1]             /* h = k + w + h                                ; --     */
477         or      y3, c           /* y3 = a|c                                     ; MAJA   */
478
479         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
480         mov     T1, a           /* T1 = a                                       ; MAJB   */
481         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
482         and     T1, c           /* T1 = a&c                                     ; MAJB   */
483         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
484
485
486         add     d, h            /* d = k + w + h + d                            ; --     */
487         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
488         add     h, y1           /* h = k + w + h + S0                           ; --     */
489
490         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
491
492
493         /*add   h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0       ; --      */
494
495         /*add   h, y3           ; h = t1 + S0 + MAJ                            ; --      */
496
497         RotateState
498
499 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
500
501         add     old_h, y2               /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
502         mov     y2, f           /* y2 = f                                       ; CH     */
503         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
504         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
505         xor     y2, g           /* y2 = f^g                                     ; CH     */
506
507         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
508         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
509         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
510         add     old_h, y3       /* h = t1 + S0 + MAJ                            ; --     */
511
512         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
513         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
514         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
515         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
516         mov     y3, a           /* y3 = a                                       ; MAJA   */
517
518         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
519         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
520         add     h, [rsp + frame_XFER + 8*2]             /* h = k + w + h                                ; --     */
521         or      y3, c           /* y3 = a|c                                     ; MAJA   */
522
523         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
524         mov     T1, a           /* T1 = a                                       ; MAJB   */
525         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
526         and     T1, c           /* T1 = a&c                                     ; MAJB   */
527         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
528
529
530         add     d, h            /* d = k + w + h + d                            ; --     */
531         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
532         add     h, y1           /* h = k + w + h + S0                           ; --     */
533
534         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
535
536
537         /*add   h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0       ; --      */
538
539         /*add   h, y3           ; h = t1 + S0 + MAJ                            ; --      */
540
541         RotateState
542
543 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
544
545         add     old_h, y2               /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
546         mov     y2, f           /* y2 = f                                       ; CH     */
547         rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
548         rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
549         xor     y2, g           /* y2 = f^g                                     ; CH     */
550
551         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
552         rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
553         and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
554         add     old_h, y3       /* h = t1 + S0 + MAJ                            ; --     */
555
556         xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
557         rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
558         xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
559         rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
560         mov     y3, a           /* y3 = a                                       ; MAJA   */
561
562         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
563         rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
564         add     h, [rsp + frame_XFER + 8*3]             /* h = k + w + h                                ; --     */
565         or      y3, c           /* y3 = a|c                                     ; MAJA   */
566
567         xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
568         mov     T1, a           /* T1 = a                                       ; MAJB   */
569         and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
570         and     T1, c           /* T1 = a&c                                     ; MAJB   */
571         add     y2, y0          /* y2 = S1 + CH                                 ; --     */
572
573
574         add     d, h            /* d = k + w + h + d                            ; --     */
575         or      y3, T1          /* y3 = MAJ = (a|c)&b)|(a&c)                    ; MAJ    */
576         add     h, y1           /* h = k + w + h + S0                           ; --     */
577
578         add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
579
580
581         add     h, y2           /* h = k + w + h + S0 + S1 + CH = t1 + S0       ; --     */
582
583         add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
584
585         RotateState
586
587 .endm
588
589 /*
590 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
591 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
592 ; void sha512_rorx(const void* M, void* D, uint64_t L);
593 ; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
594 ; The size of the message pointed to by M must be an integer multiple of SHA512
595 ;   message blocks.
596 ; L is the message length in SHA512 blocks
597 */
598 .globl _gcry_sha512_transform_amd64_avx2
599 .type _gcry_sha512_transform_amd64_avx2,@function;
600 .align 16
601 _gcry_sha512_transform_amd64_avx2:
602         xor eax, eax
603
604         cmp rdx, 0
605         je .Lnowork
606
607         vzeroupper
608
609         /* Allocate Stack Space */
610         mov     rax, rsp
611         sub     rsp, frame_size
612         and     rsp, ~(0x20 - 1)
613         mov     [rsp + frame_RSPSAVE], rax
614
615         /* Save GPRs */
616         mov     [rsp + frame_GPRSAVE + 8 * 0], rbp
617         mov     [rsp + frame_GPRSAVE + 8 * 1], rbx
618         mov     [rsp + frame_GPRSAVE + 8 * 2], r12
619         mov     [rsp + frame_GPRSAVE + 8 * 3], r13
620         mov     [rsp + frame_GPRSAVE + 8 * 4], r14
621         mov     [rsp + frame_GPRSAVE + 8 * 5], r15
622
623         vpblendd        xmm0, xmm0, xmm1, 0xf0
624         vpblendd        ymm0, ymm0, ymm1, 0xf0
625
626         shl     NUM_BLKS, 7     /* convert to bytes */
627         jz      .Ldone_hash
628         add     NUM_BLKS, INP   /* pointer to end of data */
629         mov     [rsp + frame_INPEND], NUM_BLKS
630
631         /*; load initial digest */
632         mov     a,[8*0 + CTX]
633         mov     b,[8*1 + CTX]
634         mov     c,[8*2 + CTX]
635         mov     d,[8*3 + CTX]
636         mov     e,[8*4 + CTX]
637         mov     f,[8*5 + CTX]
638         mov     g,[8*6 + CTX]
639         mov     h,[8*7 + CTX]
640
641         vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
642
643 .Loop0:
644         lea     TBL,[.LK512 ADD_RIP]
645
646         /*; byte swap first 16 dwords */
647         COPY_YMM_AND_BSWAP      Y_0, [INP + 0*32], BYTE_FLIP_MASK
648         COPY_YMM_AND_BSWAP      Y_1, [INP + 1*32], BYTE_FLIP_MASK
649         COPY_YMM_AND_BSWAP      Y_2, [INP + 2*32], BYTE_FLIP_MASK
650         COPY_YMM_AND_BSWAP      Y_3, [INP + 3*32], BYTE_FLIP_MASK
651
652         mov     [rsp + frame_INP], INP
653
654         /*; schedule 64 input dwords, by doing 12 rounds of 4 each */
655         movq    [rsp + frame_SRND],4
656
657 .align 16
658 .Loop1:
659         vpaddq  XFER, Y_0, [TBL + 0*32]
660         vmovdqa [rsp + frame_XFER], XFER
661         FOUR_ROUNDS_AND_SCHED
662
663         vpaddq  XFER, Y_0, [TBL + 1*32]
664         vmovdqa [rsp + frame_XFER], XFER
665         FOUR_ROUNDS_AND_SCHED
666
667         vpaddq  XFER, Y_0, [TBL + 2*32]
668         vmovdqa [rsp + frame_XFER], XFER
669         FOUR_ROUNDS_AND_SCHED
670
671         vpaddq  XFER, Y_0, [TBL + 3*32]
672         vmovdqa [rsp + frame_XFER], XFER
673         add     TBL, 4*32
674         FOUR_ROUNDS_AND_SCHED
675
676         subq    [rsp + frame_SRND], 1
677         jne     .Loop1
678
679         movq    [rsp + frame_SRND], 2
680 .Loop2:
681         vpaddq  XFER, Y_0, [TBL + 0*32]
682         vmovdqa [rsp + frame_XFER], XFER
683         DO_4ROUNDS
684         vpaddq  XFER, Y_1, [TBL + 1*32]
685         vmovdqa [rsp + frame_XFER], XFER
686         add     TBL, 2*32
687         DO_4ROUNDS
688
689         vmovdqa Y_0, Y_2
690         vmovdqa Y_1, Y_3
691
692         subq    [rsp + frame_SRND], 1
693         jne     .Loop2
694
695         addm    [8*0 + CTX],a
696         addm    [8*1 + CTX],b
697         addm    [8*2 + CTX],c
698         addm    [8*3 + CTX],d
699         addm    [8*4 + CTX],e
700         addm    [8*5 + CTX],f
701         addm    [8*6 + CTX],g
702         addm    [8*7 + CTX],h
703
704         mov     INP, [rsp + frame_INP]
705         add     INP, 128
706         cmp     INP, [rsp + frame_INPEND]
707         jne     .Loop0
708
709 .Ldone_hash:
710
711         /* Restore GPRs */
712         mov     rbp, [rsp + frame_GPRSAVE + 8 * 0]
713         mov     rbx, [rsp + frame_GPRSAVE + 8 * 1]
714         mov     r12, [rsp + frame_GPRSAVE + 8 * 2]
715         mov     r13, [rsp + frame_GPRSAVE + 8 * 3]
716         mov     r14, [rsp + frame_GPRSAVE + 8 * 4]
717         mov     r15, [rsp + frame_GPRSAVE + 8 * 5]
718
719         /* Restore Stack Pointer */
720         mov     rsp, [rsp + frame_RSPSAVE]
721
722         vzeroall
723
724         mov     eax, frame_size + 31
725 .Lnowork:
726         ret
727
728 /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
729 /*;; Binary Data */
730
731 .data
732
733 .align 64
734 /* K[t] used in SHA512 hashing */
735 .LK512:
736         .quad   0x428a2f98d728ae22,0x7137449123ef65cd
737         .quad   0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
738         .quad   0x3956c25bf348b538,0x59f111f1b605d019
739         .quad   0x923f82a4af194f9b,0xab1c5ed5da6d8118
740         .quad   0xd807aa98a3030242,0x12835b0145706fbe
741         .quad   0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
742         .quad   0x72be5d74f27b896f,0x80deb1fe3b1696b1
743         .quad   0x9bdc06a725c71235,0xc19bf174cf692694
744         .quad   0xe49b69c19ef14ad2,0xefbe4786384f25e3
745         .quad   0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
746         .quad   0x2de92c6f592b0275,0x4a7484aa6ea6e483
747         .quad   0x5cb0a9dcbd41fbd4,0x76f988da831153b5
748         .quad   0x983e5152ee66dfab,0xa831c66d2db43210
749         .quad   0xb00327c898fb213f,0xbf597fc7beef0ee4
750         .quad   0xc6e00bf33da88fc2,0xd5a79147930aa725
751         .quad   0x06ca6351e003826f,0x142929670a0e6e70
752         .quad   0x27b70a8546d22ffc,0x2e1b21385c26c926
753         .quad   0x4d2c6dfc5ac42aed,0x53380d139d95b3df
754         .quad   0x650a73548baf63de,0x766a0abb3c77b2a8
755         .quad   0x81c2c92e47edaee6,0x92722c851482353b
756         .quad   0xa2bfe8a14cf10364,0xa81a664bbc423001
757         .quad   0xc24b8b70d0f89791,0xc76c51a30654be30
758         .quad   0xd192e819d6ef5218,0xd69906245565a910
759         .quad   0xf40e35855771202a,0x106aa07032bbd1b8
760         .quad   0x19a4c116b8d2d0c8,0x1e376c085141ab53
761         .quad   0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
762         .quad   0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
763         .quad   0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
764         .quad   0x748f82ee5defb2fc,0x78a5636f43172f60
765         .quad   0x84c87814a1f0ab72,0x8cc702081a6439ec
766         .quad   0x90befffa23631e28,0xa4506cebde82bde9
767         .quad   0xbef9a3f7b2c67915,0xc67178f2e372532b
768         .quad   0xca273eceea26619c,0xd186b8c721c0c207
769         .quad   0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
770         .quad   0x06f067aa72176fba,0x0a637dc5a2c898a6
771         .quad   0x113f9804bef90dae,0x1b710b35131c471b
772         .quad   0x28db77f523047d84,0x32caab7b40c72493
773         .quad   0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
774         .quad   0x4cc5d4becb3e42b6,0x597f299cfc657e2a
775         .quad   0x5fcb6fab3ad6faec,0x6c44198c4a475817
776
777 .align 32
778
779 /* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
780 .LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x08090a0b0c0d0e0f0001020304050607
781                            .octa 0x18191a1b1c1d1e1f1011121314151617
782
783 .LMASK_YMM_LO:             .octa 0x00000000000000000000000000000000
784                            .octa 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
785
786 #endif
787 #endif