doc: Fix typo.
[libgcrypt.git] / cipher / sha256-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 ;
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 ;
39 ; This code is described in an Intel White-Paper:
40 ; "Fast SHA-256 Implementations on Intel Architecture Processors"
41 ;
42 ; To find it, surf to http://www.intel.com/p/en_US/embedded
43 ; and search for that title.
44 ; The paper is expected to be released roughly at the end of April, 2012
45 ;
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47 ; This code schedules 2 blocks at a time, with 4 lanes per block
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 */
50 /*
51  * Conversion to GAS assembly and integration to libgcrypt
52  *  by Jussi Kivilinna <jussi.kivilinna@iki.fi>
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_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
61     defined(USE_SHA256)
62
63 #ifdef __PIC__
64 #  define ADD_RIP +rip
65 #else
66 #  define ADD_RIP
67 #endif
68
69 #ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
70 # define ELF(...) __VA_ARGS__
71 #else
72 # define ELF(...) /*_*/
73 #endif
74
75 .intel_syntax noprefix
76
77 #define VMOVDQ vmovdqu /* ; assume buffers not aligned  */
78
79 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros */
80
81 /*  addm [mem], reg */
82 /*  Add reg to mem using reg-mem add and store */
83 .macro addm p1 p2
84         add     \p2, \p1
85         mov     \p1, \p2
86 .endm
87
88 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
89
90 X0 = ymm4
91 X1 = ymm5
92 X2 = ymm6
93 X3 = ymm7
94
95 /*  XMM versions of above */
96 XWORD0 = xmm4
97 XWORD1 = xmm5
98 XWORD2 = xmm6
99 XWORD3 = xmm7
100
101 XTMP0 = ymm0
102 XTMP1 = ymm1
103 XTMP2 = ymm2
104 XTMP3 = ymm3
105 XTMP4 = ymm8
106 XFER =  ymm9
107 XTMP5 = ymm11
108
109 SHUF_00BA = ymm10 /*  shuffle xBxA -> 00BA */
110 SHUF_DC00 = ymm12 /*  shuffle xDxC -> DC00 */
111 BYTE_FLIP_MASK = ymm13
112
113 X_BYTE_FLIP_MASK = xmm13 /*  XMM version of BYTE_FLIP_MASK */
114
115 NUM_BLKS = rdx  /*  3rd arg */
116 CTX =   rsi     /*  2nd arg */
117 INP =   rdi     /*  1st arg */
118 c =     ecx
119 d =     r8d
120 e =     edx     /*  clobbers NUM_BLKS */
121 y3 =    edi     /*  clobbers INP */
122
123 TBL =   rbp
124 SRND =  CTX     /*  SRND is same register as CTX */
125
126 a =     eax
127 b =     ebx
128 f =     r9d
129 g =     r10d
130 h =     r11d
131 old_h = r11d
132
133 T1 = r12d
134 y0 = r13d
135 y1 = r14d
136 y2 = r15d
137
138
139 _XFER_SIZE      = 2*64*4        /*  2 blocks, 64 rounds, 4 bytes/round */
140 _XMM_SAVE_SIZE  = 0
141 _INP_END_SIZE   = 8
142 _INP_SIZE       = 8
143 _CTX_SIZE       = 8
144 _RSP_SIZE       = 8
145
146 _XFER           = 0
147 _XMM_SAVE       = _XFER     + _XFER_SIZE
148 _INP_END        = _XMM_SAVE + _XMM_SAVE_SIZE
149 _INP            = _INP_END  + _INP_END_SIZE
150 _CTX            = _INP      + _INP_SIZE
151 _RSP            = _CTX      + _CTX_SIZE
152 STACK_SIZE      = _RSP      + _RSP_SIZE
153
154 /*  rotate_Xs */
155 /*  Rotate values of symbols X0...X3 */
156 .macro rotate_Xs
157 X_ = X0
158 X0 = X1
159 X1 = X2
160 X2 = X3
161 X3 = X_
162 .endm
163
164 /*  ROTATE_ARGS */
165 /*  Rotate values of symbols a...h */
166 .macro ROTATE_ARGS
167 old_h = h
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 XFER
180 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
181
182         mov     y3, a           /*  y3 = a                                ; MAJA         */
183         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
184         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
185
186         add     h, [\XFER+0*4]          /*  h = k + w + h         ; --   */
187         or      y3, c           /*  y3 = a|c                              ; MAJA         */
188                 vpalignr        XTMP0, X3, X2, 4        /*  XTMP0 = W[-7] */
189         mov     y2, f           /*  y2 = f                                ; CH   */
190         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
191
192         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
193         xor     y2, g           /*  y2 = f^g                              ; CH   */
194                 vpaddd  XTMP0, XTMP0, X0        /*  XTMP0 = W[-7] + W[-16]; y1 = (e >> 6)                                       ; S1 */
195         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
196
197         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
198         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
199         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
200         add     d, h            /*  d = k + w + h + d                     ; --   */
201
202         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
203                 vpalignr        XTMP1, X1, X0, 4        /*  XTMP1 = W[-15] */
204         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
205         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
206
207         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
208                 vpsrld  XTMP2, XTMP1, 7
209         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
210         mov     T1, a           /*  T1 = a                                ; MAJB         */
211         and     T1, c           /*  T1 = a&c                              ; MAJB         */
212
213         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
214                 vpslld  XTMP3, XTMP1, (32-7)
215         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
216         add     h, y1           /*  h = k + w + h + S0                    ; --   */
217
218         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
219                 vpor    XTMP3, XTMP3, XTMP2     /*  XTMP3 = W[-15] ror 7 */
220
221                 vpsrld  XTMP2, XTMP1,18
222         add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
223         lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
224
225
226 ROTATE_ARGS
227
228 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
229
230
231         mov     y3, a           /*  y3 = a                                ; MAJA         */
232         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
233         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
234         add     h, [\XFER+1*4]          /*  h = k + w + h         ; --   */
235         or      y3, c           /*  y3 = a|c                              ; MAJA         */
236
237
238                 vpsrld  XTMP4, XTMP1, 3 /*  XTMP4 = W[-15] >> 3 */
239         mov     y2, f           /*  y2 = f                                ; CH   */
240         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
241         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
242         xor     y2, g           /*  y2 = f^g                              ; CH   */
243
244
245         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
246         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
247         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
248         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
249         add     d, h            /*  d = k + w + h + d                     ; --   */
250
251                 vpslld  XTMP1, XTMP1, (32-18)
252         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
253         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
254
255                 vpxor   XTMP3, XTMP3, XTMP1
256         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
257         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
258
259                 vpxor   XTMP3, XTMP3, XTMP2     /*  XTMP3 = W[-15] ror 7 ^ W[-15] ror 18 */
260         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
261         mov     T1, a           /*  T1 = a                                ; MAJB         */
262         and     T1, c           /*  T1 = a&c                              ; MAJB         */
263         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
264
265                 vpxor   XTMP1, XTMP3, XTMP4     /*  XTMP1 = s0 */
266                 vpshufd XTMP2, X3, 0b11111010   /*  XTMP2 = W[-2] {BBAA} */
267         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
268         add     h, y1           /*  h = k + w + h + S0                    ; --   */
269
270                 vpaddd  XTMP0, XTMP0, XTMP1     /*  XTMP0 = W[-16] + W[-7] + s0 */
271         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
272         add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
273         lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
274
275                 vpsrld  XTMP4, XTMP2, 10        /*  XTMP4 = W[-2] >> 10 {BBAA} */
276
277
278 ROTATE_ARGS
279
280 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
281
282         mov     y3, a           /*  y3 = a                                ; MAJA         */
283         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
284         add     h, [\XFER+2*4]          /*  h = k + w + h         ; --   */
285
286                 vpsrlq  XTMP3, XTMP2, 19        /*  XTMP3 = W[-2] ror 19 {xBxA} */
287         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
288         or      y3, c           /*  y3 = a|c                              ; MAJA         */
289         mov     y2, f           /*  y2 = f                                ; CH   */
290         xor     y2, g           /*  y2 = f^g                              ; CH   */
291
292         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
293         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
294                 vpsrlq  XTMP2, XTMP2, 17        /*  XTMP2 = W[-2] ror 17 {xBxA} */
295         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
296
297         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
298                 vpxor   XTMP2, XTMP2, XTMP3
299         add     d, h            /*  d = k + w + h + d                     ; --   */
300         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
301
302         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
303         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
304                 vpxor   XTMP4, XTMP4, XTMP2     /*  XTMP4 = s1 {xBxA} */
305         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
306
307                 vpshufb XTMP4, XTMP4, SHUF_00BA /*  XTMP4 = s1 {00BA} */
308         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
309         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
310                 vpaddd  XTMP0, XTMP0, XTMP4     /*  XTMP0 = {..., ..., W[1], W[0]} */
311
312         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
313         mov     T1, a           /*  T1 = a                                ; MAJB         */
314         and     T1, c           /*  T1 = a&c                              ; MAJB         */
315         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
316                 vpshufd XTMP2, XTMP0, 0b1010000 /*  XTMP2 = W[-2] {DDCC} */
317
318         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
319         add     h, y1           /*  h = k + w + h + S0                    ; --   */
320         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
321         add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
322
323         lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
324
325
326 ROTATE_ARGS
327
328 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
329
330         mov     y3, a           /*  y3 = a                                ; MAJA         */
331         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
332         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
333         add     h, [\XFER+3*4]          /*  h = k + w + h         ; --   */
334         or      y3, c           /*  y3 = a|c                              ; MAJA         */
335
336
337                 vpsrld  XTMP5, XTMP2,   10      /*  XTMP5 = W[-2] >> 10 {DDCC} */
338         mov     y2, f           /*  y2 = f                                ; CH   */
339         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
340         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
341         xor     y2, g           /*  y2 = f^g                              ; CH   */
342
343
344                 vpsrlq  XTMP3, XTMP2, 19        /*  XTMP3 = W[-2] ror 19 {xDxC} */
345         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
346         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
347         add     d, h            /*  d = k + w + h + d                     ; --   */
348         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
349
350                 vpsrlq  XTMP2, XTMP2, 17        /*  XTMP2 = W[-2] ror 17 {xDxC} */
351         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
352         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
353
354                 vpxor   XTMP2, XTMP2, XTMP3
355         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
356         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
357
358                 vpxor   XTMP5, XTMP5, XTMP2     /*  XTMP5 = s1 {xDxC} */
359         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
360         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
361
362         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
363                 vpshufb XTMP5, XTMP5, SHUF_DC00 /*  XTMP5 = s1 {DC00} */
364
365                 vpaddd  X0, XTMP5, XTMP0        /*  X0 = {W[3], W[2], W[1], W[0]} */
366         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
367         mov     T1, a           /*  T1 = a                                ; MAJB         */
368         and     T1, c           /*  T1 = a&c                              ; MAJB         */
369         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
370
371         add     h, y1           /*  h = k + w + h + S0                    ; --   */
372         add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
373         lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
374
375 ROTATE_ARGS
376 rotate_Xs
377 .endm
378
379 .macro DO_4ROUNDS XFER
380 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;; */
381
382         mov     y2, f           /*  y2 = f                                ; CH   */
383         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
384         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
385         xor     y2, g           /*  y2 = f^g                              ; CH   */
386
387         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
388         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
389         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
390
391         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
392         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
393         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
394         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
395         mov     y3, a           /*  y3 = a                                ; MAJA         */
396
397         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
398         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
399         add     h, [\XFER + 4*0]                /*  h = k + w + h ; --   */
400         or      y3, c           /*  y3 = a|c                              ; MAJA         */
401
402         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
403         mov     T1, a           /*  T1 = a                                ; MAJB         */
404         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
405         and     T1, c           /*  T1 = a&c                              ; MAJB         */
406         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
407
408
409         add     d, h            /*  d = k + w + h + d                     ; --   */
410         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
411         add     h, y1           /*  h = k + w + h + S0                    ; --   */
412
413         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
414
415
416         /* add  h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0; --     */
417
418         /* lea  h, [h + y3]     ; h = t1 + S0 + MAJ                     ; --     */
419
420         ROTATE_ARGS
421
422 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;; */
423
424         add     old_h, y2       /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
425         mov     y2, f           /*  y2 = f                                ; CH   */
426         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
427         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
428         xor     y2, g           /*  y2 = f^g                              ; CH   */
429
430         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
431         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
432         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
433         add     old_h, y3       /*  h = t1 + S0 + MAJ                     ; --   */
434
435         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
436         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
437         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
438         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
439         mov     y3, a           /*  y3 = a                                ; MAJA         */
440
441         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
442         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
443         add     h, [\XFER + 4*1]                /*  h = k + w + h ; --   */
444         or      y3, c           /*  y3 = a|c                              ; MAJA         */
445
446         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
447         mov     T1, a           /*  T1 = a                                ; MAJB         */
448         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
449         and     T1, c           /*  T1 = a&c                              ; MAJB         */
450         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
451
452
453         add     d, h            /*  d = k + w + h + d                     ; --   */
454         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
455         add     h, y1           /*  h = k + w + h + S0                    ; --   */
456
457         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
458
459
460         /* add  h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0; --     */
461
462         /* lea  h, [h + y3]     ; h = t1 + S0 + MAJ                     ; --     */
463
464         ROTATE_ARGS
465
466 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
467
468         add     old_h, y2       /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
469         mov     y2, f           /*  y2 = f                                ; CH   */
470         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
471         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
472         xor     y2, g           /*  y2 = f^g                              ; CH   */
473
474         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
475         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
476         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
477         add     old_h, y3       /*  h = t1 + S0 + MAJ                     ; --   */
478
479         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
480         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
481         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
482         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
483         mov     y3, a           /*  y3 = a                                ; MAJA         */
484
485         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
486         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
487         add     h, [\XFER + 4*2]                /*  h = k + w + h ; --   */
488         or      y3, c           /*  y3 = a|c                              ; MAJA         */
489
490         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
491         mov     T1, a           /*  T1 = a                                ; MAJB         */
492         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
493         and     T1, c           /*  T1 = a&c                              ; MAJB         */
494         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
495
496
497         add     d, h            /*  d = k + w + h + d                     ; --   */
498         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
499         add     h, y1           /*  h = k + w + h + S0                    ; --   */
500
501         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
502
503
504         /* add  h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0; --     */
505
506         /* lea  h, [h + y3]     ; h = t1 + S0 + MAJ                     ; --     */
507
508         ROTATE_ARGS
509
510 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;; */
511
512         add     old_h, y2       /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
513         mov     y2, f           /*  y2 = f                                ; CH   */
514         rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
515         rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
516         xor     y2, g           /*  y2 = f^g                              ; CH   */
517
518         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
519         rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
520         and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
521         add     old_h, y3       /*  h = t1 + S0 + MAJ                     ; --   */
522
523         xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
524         rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
525         xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
526         rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
527         mov     y3, a           /*  y3 = a                                ; MAJA         */
528
529         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
530         rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
531         add     h, [\XFER + 4*3]                /*  h = k + w + h ; --   */
532         or      y3, c           /*  y3 = a|c                              ; MAJA         */
533
534         xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
535         mov     T1, a           /*  T1 = a                                ; MAJB         */
536         and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
537         and     T1, c           /*  T1 = a&c                              ; MAJB         */
538         add     y2, y0          /*  y2 = S1 + CH                          ; --   */
539
540
541         add     d, h            /*  d = k + w + h + d                     ; --   */
542         or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
543         add     h, y1           /*  h = k + w + h + S0                    ; --   */
544
545         add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
546
547
548         add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
549
550         lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
551
552         ROTATE_ARGS
553 .endm
554
555 /*
556 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
558 ;; void sha256_rorx(void *input_data, UINT32 digest[8], UINT64 num_blks)
559 ;; arg 1 : pointer to input data
560 ;; arg 2 : pointer to digest
561 ;; arg 3 : Num blocks
562 */
563 .text
564 .globl _gcry_sha256_transform_amd64_avx2
565 ELF(.type _gcry_sha256_transform_amd64_avx2,@function)
566 .align 32
567 _gcry_sha256_transform_amd64_avx2:
568         push    rbx
569         push    rbp
570         push    r12
571         push    r13
572         push    r14
573         push    r15
574
575         vzeroupper
576
577         mov     rax, rsp
578         sub     rsp, STACK_SIZE
579         and     rsp, -32
580         mov     [rsp + _RSP], rax
581
582         shl     NUM_BLKS, 6     /*  convert to bytes */
583         jz      .Ldone_hash
584         lea     NUM_BLKS, [NUM_BLKS + INP - 64] /*  pointer to last block */
585         mov     [rsp + _INP_END], NUM_BLKS
586
587         cmp     INP, NUM_BLKS
588         je      .Lonly_one_block
589
590         /* ; load initial digest */
591         mov     a,[4*0 + CTX]
592         mov     b,[4*1 + CTX]
593         mov     c,[4*2 + CTX]
594         mov     d,[4*3 + CTX]
595         mov     e,[4*4 + CTX]
596         mov     f,[4*5 + CTX]
597         mov     g,[4*6 + CTX]
598         mov     h,[4*7 + CTX]
599
600         vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
601         vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
602         vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
603
604         mov     [rsp + _CTX], CTX
605
606 .Loop0:
607         lea     TBL, [.LK256 ADD_RIP]
608
609         /* ; Load first 16 dwords from two blocks */
610         VMOVDQ  XTMP0, [INP + 0*32]
611         VMOVDQ  XTMP1, [INP + 1*32]
612         VMOVDQ  XTMP2, [INP + 2*32]
613         VMOVDQ  XTMP3, [INP + 3*32]
614
615         /* ; byte swap data */
616         vpshufb XTMP0, XTMP0, BYTE_FLIP_MASK
617         vpshufb XTMP1, XTMP1, BYTE_FLIP_MASK
618         vpshufb XTMP2, XTMP2, BYTE_FLIP_MASK
619         vpshufb XTMP3, XTMP3, BYTE_FLIP_MASK
620
621         /* ; transpose data into high/low halves */
622         vperm2i128      X0, XTMP0, XTMP2, 0x20
623         vperm2i128      X1, XTMP0, XTMP2, 0x31
624         vperm2i128      X2, XTMP1, XTMP3, 0x20
625         vperm2i128      X3, XTMP1, XTMP3, 0x31
626
627 .Last_block_enter:
628         add     INP, 64
629         mov     [rsp + _INP], INP
630
631         /* ; schedule 48 input dwords, by doing 3 rounds of 12 each */
632         xor     SRND, SRND
633
634 .align 16
635 .Loop1:
636         vpaddd  XFER, X0, [TBL + SRND + 0*32]
637         vmovdqa [rsp + _XFER + SRND + 0*32], XFER
638         FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 0*32
639
640         vpaddd  XFER, X0, [TBL + SRND + 1*32]
641         vmovdqa [rsp + _XFER + SRND + 1*32], XFER
642         FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 1*32
643
644         vpaddd  XFER, X0, [TBL + SRND + 2*32]
645         vmovdqa [rsp + _XFER + SRND + 2*32], XFER
646         FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 2*32
647
648         vpaddd  XFER, X0, [TBL + SRND + 3*32]
649         vmovdqa [rsp + _XFER + SRND + 3*32], XFER
650         FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 3*32
651
652         add     SRND, 4*32
653         cmp     SRND, 3 * 4*32
654         jb      .Loop1
655
656 .Loop2:
657         /* ; Do last 16 rounds with no scheduling */
658         vpaddd  XFER, X0, [TBL + SRND + 0*32]
659         vmovdqa [rsp + _XFER + SRND + 0*32], XFER
660         DO_4ROUNDS      rsp + _XFER + SRND + 0*32
661         vpaddd  XFER, X1, [TBL + SRND + 1*32]
662         vmovdqa [rsp + _XFER + SRND + 1*32], XFER
663         DO_4ROUNDS      rsp + _XFER + SRND + 1*32
664         add     SRND, 2*32
665
666         vmovdqa X0, X2
667         vmovdqa X1, X3
668
669         cmp     SRND, 4 * 4*32
670         jb      .Loop2
671
672         mov     CTX, [rsp + _CTX]
673         mov     INP, [rsp + _INP]
674
675         addm    [4*0 + CTX],a
676         addm    [4*1 + CTX],b
677         addm    [4*2 + CTX],c
678         addm    [4*3 + CTX],d
679         addm    [4*4 + CTX],e
680         addm    [4*5 + CTX],f
681         addm    [4*6 + CTX],g
682         addm    [4*7 + CTX],h
683
684         cmp     INP, [rsp + _INP_END]
685         ja      .Ldone_hash
686
687         /* ;;; Do second block using previously scheduled results */
688         xor     SRND, SRND
689 .align 16
690 .Loop3:
691         DO_4ROUNDS      rsp + _XFER + SRND + 0*32 + 16
692         DO_4ROUNDS      rsp + _XFER + SRND + 1*32 + 16
693         add     SRND, 2*32
694         cmp     SRND, 4 * 4*32
695         jb .Loop3
696
697         mov     CTX, [rsp + _CTX]
698         mov     INP, [rsp + _INP]
699         add     INP, 64
700
701         addm    [4*0 + CTX],a
702         addm    [4*1 + CTX],b
703         addm    [4*2 + CTX],c
704         addm    [4*3 + CTX],d
705         addm    [4*4 + CTX],e
706         addm    [4*5 + CTX],f
707         addm    [4*6 + CTX],g
708         addm    [4*7 + CTX],h
709
710         cmp     INP, [rsp + _INP_END]
711         jb      .Loop0
712         ja      .Ldone_hash
713
714 .Ldo_last_block:
715         /* ;;; do last block */
716         lea     TBL, [.LK256 ADD_RIP]
717
718         VMOVDQ  XWORD0, [INP + 0*16]
719         VMOVDQ  XWORD1, [INP + 1*16]
720         VMOVDQ  XWORD2, [INP + 2*16]
721         VMOVDQ  XWORD3, [INP + 3*16]
722
723         vpshufb XWORD0, XWORD0, X_BYTE_FLIP_MASK
724         vpshufb XWORD1, XWORD1, X_BYTE_FLIP_MASK
725         vpshufb XWORD2, XWORD2, X_BYTE_FLIP_MASK
726         vpshufb XWORD3, XWORD3, X_BYTE_FLIP_MASK
727
728         jmp     .Last_block_enter
729
730 .Lonly_one_block:
731
732         /* ; load initial digest */
733         mov     a,[4*0 + CTX]
734         mov     b,[4*1 + CTX]
735         mov     c,[4*2 + CTX]
736         mov     d,[4*3 + CTX]
737         mov     e,[4*4 + CTX]
738         mov     f,[4*5 + CTX]
739         mov     g,[4*6 + CTX]
740         mov     h,[4*7 + CTX]
741
742         vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
743         vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
744         vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
745
746         mov     [rsp + _CTX], CTX
747         jmp     .Ldo_last_block
748
749 .Ldone_hash:
750         mov     rsp, [rsp + _RSP]
751
752         vzeroall
753
754         pop     r15
755         pop     r14
756         pop     r13
757         pop     r12
758         pop     rbp
759         pop     rbx
760
761         /* stack burn depth */
762         mov     eax, STACK_SIZE + 6*8 + 31
763
764         ret
765
766 .data
767 .align 64
768 .LK256:
769         .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
770         .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
771         .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
772         .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
773         .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
774         .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
775         .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
776         .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
777         .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
778         .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
779         .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
780         .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
781         .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
782         .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
783         .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
784         .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
785         .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
786         .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
787         .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
788         .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
789         .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
790         .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
791         .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
792         .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
793         .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
794         .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
795         .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
796         .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
797         .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
798         .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
799         .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
800         .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
801
802 .LPSHUFFLE_BYTE_FLIP_MASK:
803         .octa 0x0c0d0e0f08090a0b0405060700010203,0x0c0d0e0f08090a0b0405060700010203
804
805 /*  shuffle xBxA -> 00BA */
806 .L_SHUF_00BA:
807         .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100,0xFFFFFFFFFFFFFFFF0b0a090803020100
808
809 /*  shuffle xDxC -> DC00 */
810 .L_SHUF_DC00:
811         .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF,0x0b0a090803020100FFFFFFFFFFFFFFFF
812
813 #endif
814 #endif