build: Fix build with !HAVE_PTHREAD
[libgcrypt.git] / cipher / sha1-avx-bmi2-amd64.S
1 /* sha1-avx-bmi2-amd64.S - Intel AVX/BMI2 accelerated SHA-1 transform function
2  * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3  *
4  * Based on sha1.c:
5  *  Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
6  *
7  * This file is part of Libgcrypt.
8  *
9  * Libgcrypt is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as
11  * published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * Libgcrypt is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22
23 /*
24  * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
25  *  "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
26  *  http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
27  */
28
29 #ifdef __x86_64__
30 #include <config.h>
31
32 #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
33      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
34     defined(HAVE_GCC_INLINE_ASM_BMI2) && \
35     defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA1)
36
37 #include "asm-common-amd64.h"
38
39
40 /* Context structure */
41
42 #define state_h0 0
43 #define state_h1 4
44 #define state_h2 8
45 #define state_h3 12
46 #define state_h4 16
47
48
49 /* Constants */
50
51 .text
52 .align 16
53 .Lbswap_shufb_ctl:
54         .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
55
56 .LK1:   .long 0x5A827999
57 .LK2:   .long 0x6ED9EBA1
58 .LK3:   .long 0x8F1BBCDC
59 .LK4:   .long 0xCA62C1D6
60
61
62 /* Register macros */
63
64 #define RSTATE %r8
65 #define RDATA %r9
66 #define ROLDSTACK %r10
67 #define RNBLKS %r11
68
69 #define a %esi
70 #define b %edi
71 #define c %ebp
72 #define d %edx
73 #define e %ecx
74 #define ne %ebx
75
76 #define RT0 %eax
77 #define RT1 %r12d
78
79 #define Wtmp0 %xmm0
80 #define Wtmp1 %xmm1
81
82 #define W0 %xmm2
83 #define W1 %xmm3
84 #define W2 %xmm4
85 #define W3 %xmm5
86 #define W4 %xmm6
87 #define W5 %xmm7
88 #define W6 %xmm8
89 #define W7 %xmm9
90
91 #define BSWAP_REG %xmm10
92
93 #define K1 %xmm11
94 #define K2 %xmm12
95 #define K3 %xmm13
96 #define K4 %xmm14
97
98
99 /* Round function macros. */
100
101 #define WK(i) (((i) & 15) * 4)(%rsp)
102
103 #define R_F1(a,b,c,d,e,i) \
104         movl c, RT0; \
105         andn d, b, RT1; \
106         addl WK(i), e; \
107         andl b, RT0; \
108         rorxl $2, b, b; \
109         addl RT1, e; \
110         addl ne, a; \
111         leal (RT0,e), ne; \
112         rorxl $27, a, e;
113
114 #define R_F2(a,b,c,d,e,i) \
115         movl c, RT0; \
116         addl WK(i), e; \
117         xorl b, RT0; \
118         rorxl $2, b, b; \
119         xorl d, RT0; \
120         addl ne, a; \
121         leal (RT0,e), ne; \
122         rorxl $27, a, e;
123
124 #define R_F3(a,b,c,d,e,i) \
125         movl c, RT0; \
126         movl b, RT1; \
127         addl WK(i), e; \
128         xorl b, RT0; \
129         andl c, RT1; \
130         andl d, RT0; \
131         addl RT1, e; \
132         rorxl $2, b, b; \
133         addl ne, a; \
134         leal (RT0,e), ne; \
135         rorxl $27, a, e;
136
137 #define R_F4(a,b,c,d,e,i) R_F2(a,b,c,d,e,i)
138
139 #define R(a,b,c,d,e,f,i) \
140         R_##f(a,b,c,d,e,i)
141
142
143 /* Input expansion macros. */
144
145 #define W_PRECALC_00_15_0(i, W, tmp0) \
146         vmovdqu (4*(i))(RDATA), tmp0;
147
148 #define W_PRECALC_00_15_1(i, W, tmp0) \
149         vpshufb BSWAP_REG, tmp0, W;
150
151 #define W_PRECALC_00_15_2(i, W, tmp0, K) \
152         vpaddd K, W, tmp0;
153
154 #define W_PRECALC_00_15_3(i, W, tmp0) \
155         vmovdqa tmp0, WK(i&~3);
156
157 #define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
158         vpalignr $8, W_m16, W_m12, W; \
159         vpsrldq $4, W_m04, tmp0; \
160         vpxor W_m08, W, W;
161
162 #define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
163         vpxor W_m16, tmp0, tmp0; \
164         vpxor tmp0, W, W; \
165         vpslld $1, W, tmp0; \
166         vpslldq $12, W, tmp1; \
167         vpsrld $31, W, W;
168
169 #define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
170         vpor W, tmp0, tmp0; \
171         vpsrld $30, tmp1, W; \
172         vpslld $2, tmp1, tmp1;
173
174 #define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1, K) \
175         vpxor W, tmp0, tmp0; \
176         vpxor tmp1, tmp0, W; \
177         vpaddd K, W, tmp0; \
178         vmovdqa tmp0, WK((i)&~3);
179
180 #define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
181         vpxor W_m28, W, W; \
182         vpalignr $8, W_m08, W_m04, tmp0;
183
184 #define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
185         vpxor W_m16, W, W; \
186         vpxor tmp0, W, W;
187
188 #define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
189         vpsrld $30, W, tmp0; \
190         vpslld $2, W, W;
191
192 #define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0, K) \
193         vpor W, tmp0, W; \
194         vpaddd K, W, tmp0; \
195         vmovdqa tmp0, WK((i)&~3);
196
197
198 /*
199  * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
200  *
201  * unsigned int
202  * _gcry_sha1_transform_amd64_avx_bmi2 (void *ctx, const unsigned char *data,
203  *                                      size_t nblks)
204  */
205 .globl _gcry_sha1_transform_amd64_avx_bmi2
206 ELF(.type _gcry_sha1_transform_amd64_avx_bmi2,@function)
207 .align 16
208 _gcry_sha1_transform_amd64_avx_bmi2:
209   /* input:
210    *    %rdi: ctx, CTX
211    *    %rsi: data (64*nblks bytes)
212    *    %rdx: nblks
213    */
214   CFI_STARTPROC();
215
216   xorl %eax, %eax;
217   cmpq $0, %rdx;
218   jz .Lret;
219
220   vzeroupper;
221
222   movq %rdx, RNBLKS;
223   movq %rdi, RSTATE;
224   movq %rsi, RDATA;
225   pushq %rbx;
226   CFI_PUSH(%rbx);
227   pushq %rbp;
228   CFI_PUSH(%rbp);
229   pushq %r12;
230   CFI_PUSH(%r12);
231
232   movq %rsp, ROLDSTACK;
233   CFI_DEF_CFA_REGISTER(ROLDSTACK);
234
235   subq $(16*4), %rsp;
236   andq $(~31), %rsp;
237
238   /* Get the values of the chaining variables. */
239   movl state_h0(RSTATE), a;
240   movl state_h1(RSTATE), b;
241   movl state_h2(RSTATE), c;
242   movl state_h3(RSTATE), d;
243   movl state_h4(RSTATE), e;
244   xorl ne, ne;
245
246   vmovdqa .Lbswap_shufb_ctl rRIP, BSWAP_REG;
247   vpbroadcastd .LK1 rRIP, K1;
248   vpbroadcastd .LK2 rRIP, K2;
249   vpbroadcastd .LK3 rRIP, K3;
250   vpbroadcastd .LK4 rRIP, K4;
251
252   /* Precalc 0-15. */
253   W_PRECALC_00_15_0(0, W0, Wtmp0);
254   W_PRECALC_00_15_1(1, W0, Wtmp0);
255   W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
256   W_PRECALC_00_15_3(3, W0, Wtmp0);
257   W_PRECALC_00_15_0(4, W7, Wtmp0);
258   W_PRECALC_00_15_1(5, W7, Wtmp0);
259   W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
260   W_PRECALC_00_15_3(7, W7, Wtmp0);
261   W_PRECALC_00_15_0(8, W6, Wtmp0);
262   W_PRECALC_00_15_1(9, W6, Wtmp0);
263   W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
264   W_PRECALC_00_15_3(11, W6, Wtmp0);
265   W_PRECALC_00_15_0(12, W5, Wtmp0);
266   W_PRECALC_00_15_1(13, W5, Wtmp0);
267   W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
268   W_PRECALC_00_15_3(15, W5, Wtmp0);
269
270 .align 8
271 .Loop:
272   addq $64, RDATA;
273
274   /* Transform 0-15 + Precalc 16-31. */
275   R( a, b, c, d, e, F1,  0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
276   R( e, a, b, c, d, F1,  1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
277   R( d, e, a, b, c, F1,  2 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
278   R( c, d, e, a, b, F1,  3 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1, K1);
279   R( b, c, d, e, a, F1,  4 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
280   R( a, b, c, d, e, F1,  5 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
281   R( e, a, b, c, d, F1,  6 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
282   R( d, e, a, b, c, F1,  7 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1, K2);
283   R( c, d, e, a, b, F1,  8 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
284   R( b, c, d, e, a, F1,  9 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
285   R( a, b, c, d, e, F1, 10 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
286   R( e, a, b, c, d, F1, 11 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1, K2);
287   R( d, e, a, b, c, F1, 12 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
288   R( c, d, e, a, b, F1, 13 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
289   R( b, c, d, e, a, F1, 14 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
290   R( a, b, c, d, e, F1, 15 ); W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1, K2);
291
292   /* Transform 16-63 + Precalc 32-79. */
293   R( e, a, b, c, d, F1, 16 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
294   R( d, e, a, b, c, F1, 17 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
295   R( c, d, e, a, b, F1, 18 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
296   R( b, c, d, e, a, F1, 19 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K2);
297   R( a, b, c, d, e, F2, 20 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
298   R( e, a, b, c, d, F2, 21 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
299   R( d, e, a, b, c, F2, 22 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
300   R( c, d, e, a, b, F2, 23 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K2);
301   R( b, c, d, e, a, F2, 24 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
302   R( a, b, c, d, e, F2, 25 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
303   R( e, a, b, c, d, F2, 26 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
304   R( d, e, a, b, c, F2, 27 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K3);
305   R( c, d, e, a, b, F2, 28 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
306   R( b, c, d, e, a, F2, 29 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
307   R( a, b, c, d, e, F2, 30 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
308   R( e, a, b, c, d, F2, 31 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K3);
309   R( d, e, a, b, c, F2, 32 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
310   R( c, d, e, a, b, F2, 33 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
311   R( b, c, d, e, a, F2, 34 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
312   R( a, b, c, d, e, F2, 35 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0, K3);
313   R( e, a, b, c, d, F2, 36 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
314   R( d, e, a, b, c, F2, 37 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
315   R( c, d, e, a, b, F2, 38 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
316   R( b, c, d, e, a, F2, 39 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0, K3);
317   R( a, b, c, d, e, F3, 40 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
318   R( e, a, b, c, d, F3, 41 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
319   R( d, e, a, b, c, F3, 42 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
320   R( c, d, e, a, b, F3, 43 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0, K3);
321   R( b, c, d, e, a, F3, 44 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
322   R( a, b, c, d, e, F3, 45 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
323   R( e, a, b, c, d, F3, 46 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
324   R( d, e, a, b, c, F3, 47 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0, K4);
325   R( c, d, e, a, b, F3, 48 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
326   R( b, c, d, e, a, F3, 49 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
327   R( a, b, c, d, e, F3, 50 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
328   R( e, a, b, c, d, F3, 51 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K4);
329   R( d, e, a, b, c, F3, 52 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
330   R( c, d, e, a, b, F3, 53 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
331   R( b, c, d, e, a, F3, 54 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
332   R( a, b, c, d, e, F3, 55 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K4);
333   R( e, a, b, c, d, F3, 56 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
334   R( d, e, a, b, c, F3, 57 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
335   R( c, d, e, a, b, F3, 58 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
336   R( b, c, d, e, a, F3, 59 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K4);
337   R( a, b, c, d, e, F4, 60 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
338   R( e, a, b, c, d, F4, 61 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
339   R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
340   R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K4);
341
342   decq RNBLKS;
343   jz .Lend;
344
345   /* Transform 64-79 + Precalc 0-15 of next block. */
346   R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
347   R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
348   R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
349   R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
350   R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
351   R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
352   R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
353   R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
354   R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
355   R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
356   R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
357   R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
358   R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
359   R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
360   R( c, d, e, a, b, F4, 78 );
361   addl state_h0(RSTATE), a;   W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
362   R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
363   addl ne, a;
364   xorl ne, ne;
365
366   /* Update the chaining variables. */
367   addl state_h3(RSTATE), d;
368   addl state_h2(RSTATE), c;
369   addl state_h1(RSTATE), b;
370   addl state_h4(RSTATE), e;
371
372   movl d, state_h3(RSTATE);
373   movl c, state_h2(RSTATE);
374   movl b, state_h1(RSTATE);
375   movl a, state_h0(RSTATE);
376   movl e, state_h4(RSTATE);
377
378   jmp .Loop;
379
380 .align 16
381 .Lend:
382   vzeroall;
383
384   /* Transform 64-79 + burn stack */
385   R( b, c, d, e, a, F4, 64 );
386   R( a, b, c, d, e, F4, 65 );
387   R( e, a, b, c, d, F4, 66 );
388   R( d, e, a, b, c, F4, 67 );
389   R( c, d, e, a, b, F4, 68 );
390   R( b, c, d, e, a, F4, 69 );
391   R( a, b, c, d, e, F4, 70 );
392   R( e, a, b, c, d, F4, 71 );
393   R( d, e, a, b, c, F4, 72 );
394   R( c, d, e, a, b, F4, 73 );
395   R( b, c, d, e, a, F4, 74 );
396   R( a, b, c, d, e, F4, 75 );
397   R( e, a, b, c, d, F4, 76 ); vmovdqa %xmm0, (0*16)(%rsp);
398   R( d, e, a, b, c, F4, 77 ); vmovdqa %xmm0, (1*16)(%rsp);
399   R( c, d, e, a, b, F4, 78 ); vmovdqa %xmm0, (2*16)(%rsp);
400   addl state_h0(RSTATE), a;
401   R( b, c, d, e, a, F4, 79 );
402   addl ne, a;
403   xorl ne, ne;
404
405   /* 16*4/16-1 = 3 */
406   vmovdqa %xmm0, (3*16)(%rsp);
407
408   /* Update the chaining variables. */
409   addl state_h3(RSTATE), d;
410   addl state_h2(RSTATE), c;
411   addl state_h1(RSTATE), b;
412   addl state_h4(RSTATE), e;
413
414   movl d, state_h3(RSTATE);
415   movl c, state_h2(RSTATE);
416   movl b, state_h1(RSTATE);
417   movl a, state_h0(RSTATE);
418   movl e, state_h4(RSTATE);
419
420   movq ROLDSTACK, %rsp;
421   CFI_REGISTER(ROLDSTACK, %rsp);
422   CFI_DEF_CFA_REGISTER(%rsp);
423
424   popq %r12;
425   CFI_POP(%r12);
426   popq %rbp;
427   CFI_POP(%rbp);
428   popq %rbx;
429   CFI_POP(%rbx);
430
431   /* stack already burned */
432   xorl %eax, %eax;
433
434 .Lret:
435   ret;
436   CFI_ENDPROC();
437 ELF(.size _gcry_sha1_transform_amd64_avx_bmi2,
438     .-_gcry_sha1_transform_amd64_avx_bmi2;)
439
440 #endif
441 #endif