pkgconfig: Fix libgcrypt.pc.
[libgcrypt.git] / cipher / sha1-avx2-bmi2-amd64.S
1 /* sha1-avx2-bmi2-amd64.S - Intel AVX2/BMI2 accelerated SHA-1 transform function
2  * Copyright (C) 2019 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) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
35      defined(HAVE_GCC_INLINE_ASM_AVX2) && 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 #define WK_STACK_WORDS (80 * 2)
52
53 .text
54 .align 16
55 .Lbswap_shufb_ctl:
56         .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
57
58 .LK1:   .long 0x5A827999
59 .LK2:   .long 0x6ED9EBA1
60 .LK3:   .long 0x8F1BBCDC
61 .LK4:   .long 0xCA62C1D6
62
63
64 /* Register macros */
65
66 #define RSTATE %r8
67 #define RDATA %r9
68 #define ROLDSTACK %r10
69 #define RNBLKS %r11
70
71 #define a %eax
72 #define b %ebx
73 #define c %ecx
74 #define d %edx
75 #define e %edi
76 #define ne %r12d
77
78 #define RT0 %esi
79 #define RT1 %ebp
80
81 #define Wtmp0 %ymm0
82 #define Wtmp1 %ymm1
83 #define Wtmp0x %xmm0
84 #define Wtmp1x %xmm1
85
86 #define W0 %ymm2
87 #define W1 %ymm3
88 #define W2 %ymm4
89 #define W3 %ymm5
90 #define W4 %ymm6
91 #define W5 %ymm7
92 #define W6 %ymm8
93 #define W7 %ymm9
94
95 #define BSWAP_REG %ymm10
96
97 #define K1 %ymm11
98 #define K2 %ymm12
99 #define K3 %ymm13
100 #define K4 %ymm14
101
102
103 /* Round function macros. */
104
105 #define WK(i,block) ((block) * 16 + ((i) / 4) * 32 + ((i) % 4) * 4)(%rsp)
106 #define PRE_WK(i) ((i) * 4 * 2)(%rsp)
107
108 #define R_F1(a,b,c,d,e,i,block) \
109         movl c, RT0; \
110         andn d, b, RT1; \
111         addl WK(i,block), e; \
112         andl b, RT0; \
113         leal (a,ne), a; \
114         rorxl $2, b, b; \
115         addl RT1, e; \
116         rorxl $27, a, ne; \
117         addl RT0, e;
118
119 #define R_F2(a,b,c,d,e,i,block) \
120         addl WK(i,block), e; \
121         movl c, RT0; \
122         xorl b, RT0; \
123         leal (a,ne), a; \
124         rorxl $2, b, b; \
125         xorl d, RT0; \
126         addl RT0, e; \
127         rorxl $27, a, ne;
128
129 #define R_F3(a,b,c,d,e,i,block) \
130         movl c, RT0; \
131         addl WK(i,block), e; \
132         movl b, RT1; \
133         xorl b, RT0; \
134         leal (a,ne), a; \
135         rorxl $2, b, b; \
136         andl c, RT1; \
137         addl RT1, e; \
138         andl d, RT0; \
139         rorxl $27, a, ne; \
140         addl RT0, e;
141
142 #define R_F4(a,b,c,d,e,i,block) R_F2(a,b,c,d,e,i,block)
143
144 #define R(a,b,c,d,e,f,i,block) \
145         R_##f(a,b,c,d,e,i,block)
146
147
148 /* Input expansion macros. */
149
150 #define W_PRECALC_00_15_0(i, W, tmp0) \
151         vmovdqu (4*(i))(RDATA), tmp0##x; \
152         vinserti128 $1, (4*(i) + 64)(RDATA), tmp0, tmp0;
153
154 #define W_PRECALC_00_15_1(i, W, tmp0) \
155         vpshufb BSWAP_REG, tmp0, W;
156
157 #define W_PRECALC_00_15_2(i, W, tmp0, K) \
158         vpaddd K, W, tmp0;
159
160 #define W_PRECALC_00_15_3(i, W, tmp0) \
161         vmovdqa tmp0, PRE_WK((i)&~3);
162
163 #define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
164         vpalignr $8, W_m16, W_m12, W; \
165         vpsrldq $4, W_m04, tmp0; \
166         vpxor W_m08, W, W;
167
168 #define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
169         vpxor W_m16, tmp0, tmp0; \
170         vpxor tmp0, W, W; \
171         vpslld $1, W, tmp0; \
172         vpslldq $12, W, tmp1; \
173         vpsrld $31, W, W;
174
175 #define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
176         vpor W, tmp0, tmp0; \
177         vpsrld $30, tmp1, W; \
178         vpslld $2, tmp1, tmp1;
179
180 #define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1, K) \
181         vpxor W, tmp0, tmp0; \
182         vpxor tmp1, tmp0, W; \
183         vpaddd K, W, tmp0; \
184         vmovdqa tmp0, PRE_WK((i)&~3);
185
186 #define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
187         vpxor W_m28, W, W; \
188         vpalignr $8, W_m08, W_m04, tmp0;
189
190 #define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
191         vpxor W_m16, W, W; \
192         vpxor tmp0, W, W;
193
194 #define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
195         vpsrld $30, W, tmp0; \
196         vpslld $2, W, W;
197
198 #define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0, K) \
199         vpor W, tmp0, W; \
200         vpaddd K, W, tmp0; \
201         vmovdqa tmp0, PRE_WK((i)&~3);
202
203
204 /*
205  * Transform 2*nblks*64 bytes (2*nblks*16 32-bit words) at DATA.
206  *
207  * unsigned int
208  * _gcry_sha1_transform_amd64_avx2_bmi2 (void *ctx, const unsigned char *data,
209  *                                       size_t nblks)
210  */
211 .globl _gcry_sha1_transform_amd64_avx2_bmi2
212 ELF(.type _gcry_sha1_transform_amd64_avx2_bmi2,@function)
213 .align 16
214 _gcry_sha1_transform_amd64_avx2_bmi2:
215   /* input:
216    *    %rdi: ctx, CTX
217    *    %rsi: data (64*nblks bytes)
218    *    %rdx: nblks (multiple of 2, larger than 0)
219    */
220   CFI_STARTPROC();
221
222   vzeroupper;
223
224   movq %rdx, RNBLKS;
225   movq %rdi, RSTATE;
226   movq %rsi, RDATA;
227   pushq %rbx;
228   CFI_PUSH(%rbx);
229   pushq %rbp;
230   CFI_PUSH(%rbp);
231   pushq %r12;
232   CFI_PUSH(%r12);
233
234   movq %rsp, ROLDSTACK;
235   CFI_DEF_CFA_REGISTER(ROLDSTACK);
236
237   subq $(WK_STACK_WORDS*4), %rsp;
238   andq $(~63), %rsp;
239
240   /* Get the values of the chaining variables. */
241   movl state_h0(RSTATE), a;
242   movl state_h1(RSTATE), b;
243   movl state_h2(RSTATE), c;
244   movl state_h3(RSTATE), d;
245   movl state_h4(RSTATE), e;
246   xorl ne, ne;
247
248   vbroadcasti128 .Lbswap_shufb_ctl rRIP, BSWAP_REG;
249   vpbroadcastd .LK1 rRIP, K1;
250   vpbroadcastd .LK2 rRIP, K2;
251   vpbroadcastd .LK3 rRIP, K3;
252   vpbroadcastd .LK4 rRIP, K4;
253
254   /* Precalc 0-31 for block 1 & 2. */
255   W_PRECALC_00_15_0(0, W0, Wtmp0);
256   W_PRECALC_00_15_1(1, W0, Wtmp0);
257   W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
258   W_PRECALC_00_15_3(3, W0, Wtmp0);
259   W_PRECALC_00_15_0(4, W7, Wtmp0);
260   W_PRECALC_00_15_1(5, W7, Wtmp0);
261   W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
262   W_PRECALC_00_15_3(7, W7, Wtmp0);
263   W_PRECALC_00_15_0(8, W6, Wtmp0);
264   W_PRECALC_00_15_1(9, W6, Wtmp0);
265   W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
266   W_PRECALC_00_15_3(11, W6, Wtmp0);
267   W_PRECALC_00_15_0(12, W5, Wtmp0);
268   W_PRECALC_00_15_1(13, W5, Wtmp0);
269   W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
270   W_PRECALC_00_15_3(15, W5, Wtmp0);
271   W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
272   W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
273   W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
274   W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1, K1);
275   W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
276   W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
277   W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
278   W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1, K2);
279   W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
280   W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
281   W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
282   W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1, K2);
283   W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
284   W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
285   W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
286   W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1, K2);
287
288 .align 8
289 .Loop:
290   addq $(2 * 64), RDATA;
291
292   /* Transform 0-15 for block 1 + Precalc 32-47 for block 1 & 2. */
293   R( a, b, c, d, e, F1,  0, 0 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
294   R( e, a, b, c, d, F1,  1, 0 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
295   R( d, e, a, b, c, F1,  2, 0 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
296   R( c, d, e, a, b, F1,  3, 0 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K2);
297   R( b, c, d, e, a, F1,  4, 0 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
298   R( a, b, c, d, e, F1,  5, 0 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
299   R( e, a, b, c, d, F1,  6, 0 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
300   R( d, e, a, b, c, F1,  7, 0 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K2);
301   R( c, d, e, a, b, F1,  8, 0 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
302   R( b, c, d, e, a, F1,  9, 0 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
303   R( a, b, c, d, e, F1, 10, 0 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
304   R( e, a, b, c, d, F1, 11, 0 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K3);
305   R( d, e, a, b, c, F1, 12, 0 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
306   R( c, d, e, a, b, F1, 13, 0 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
307   R( b, c, d, e, a, F1, 14, 0 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
308   R( a, b, c, d, e, F1, 15, 0 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K3);
309
310   /* Transform 16-47 for block 1 + Precalc 48-79 for block 1 & 2. */
311   R( e, a, b, c, d, F1, 16, 0 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
312   R( d, e, a, b, c, F1, 17, 0 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
313   R( c, d, e, a, b, F1, 18, 0 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
314   R( b, c, d, e, a, F1, 19, 0 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0, K3);
315   R( a, b, c, d, e, F2, 20, 0 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
316   R( e, a, b, c, d, F2, 21, 0 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
317   R( d, e, a, b, c, F2, 22, 0 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
318   R( c, d, e, a, b, F2, 23, 0 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0, K3);
319   R( b, c, d, e, a, F2, 24, 0 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
320   R( a, b, c, d, e, F2, 25, 0 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
321   R( e, a, b, c, d, F2, 26, 0 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
322   R( d, e, a, b, c, F2, 27, 0 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0, K3);
323   R( c, d, e, a, b, F2, 28, 0 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
324   R( b, c, d, e, a, F2, 29, 0 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
325   R( a, b, c, d, e, F2, 30, 0 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
326   R( e, a, b, c, d, F2, 31, 0 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0, K4);
327   R( d, e, a, b, c, F2, 32, 0 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
328   R( c, d, e, a, b, F2, 33, 0 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
329   R( b, c, d, e, a, F2, 34, 0 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
330   R( a, b, c, d, e, F2, 35, 0 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K4);
331   R( e, a, b, c, d, F2, 36, 0 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
332   R( d, e, a, b, c, F2, 37, 0 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
333   R( c, d, e, a, b, F2, 38, 0 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
334   R( b, c, d, e, a, F2, 39, 0 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K4);
335   R( a, b, c, d, e, F3, 40, 0 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
336   R( e, a, b, c, d, F3, 41, 0 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
337   R( d, e, a, b, c, F3, 42, 0 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
338   R( c, d, e, a, b, F3, 43, 0 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K4);
339   R( b, c, d, e, a, F3, 44, 0 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
340   R( a, b, c, d, e, F3, 45, 0 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
341   R( e, a, b, c, d, F3, 46, 0 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
342   R( d, e, a, b, c, F3, 47, 0 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K4);
343
344   /* Transform 48-79 for block 1. */
345   R( c, d, e, a, b, F3, 48, 0 );
346   R( b, c, d, e, a, F3, 49, 0 );
347   R( a, b, c, d, e, F3, 50, 0 );
348   R( e, a, b, c, d, F3, 51, 0 );
349   R( d, e, a, b, c, F3, 52, 0 );
350   R( c, d, e, a, b, F3, 53, 0 );
351   R( b, c, d, e, a, F3, 54, 0 );
352   R( a, b, c, d, e, F3, 55, 0 );
353   R( e, a, b, c, d, F3, 56, 0 );
354   R( d, e, a, b, c, F3, 57, 0 );
355   R( c, d, e, a, b, F3, 58, 0 );
356   R( b, c, d, e, a, F3, 59, 0 );
357   R( a, b, c, d, e, F4, 60, 0 );
358   R( e, a, b, c, d, F4, 61, 0 );
359   R( d, e, a, b, c, F4, 62, 0 );
360   R( c, d, e, a, b, F4, 63, 0 );
361   R( b, c, d, e, a, F4, 64, 0 );
362   R( a, b, c, d, e, F4, 65, 0 );
363   R( e, a, b, c, d, F4, 66, 0 );
364   R( d, e, a, b, c, F4, 67, 0 );
365   R( c, d, e, a, b, F4, 68, 0 );
366   R( b, c, d, e, a, F4, 69, 0 );
367   R( a, b, c, d, e, F4, 70, 0 );
368   R( e, a, b, c, d, F4, 71, 0 );
369   R( d, e, a, b, c, F4, 72, 0 );
370   R( c, d, e, a, b, F4, 73, 0 );
371   R( b, c, d, e, a, F4, 74, 0 );
372   R( a, b, c, d, e, F4, 75, 0 );
373   R( e, a, b, c, d, F4, 76, 0 );
374   R( d, e, a, b, c, F4, 77, 0 );
375   R( c, d, e, a, b, F4, 78, 0 );
376   addl state_h0(RSTATE), a;
377   R( b, c, d, e, a, F4, 79, 0 );
378   addl ne, a;
379   xorl ne, ne;
380
381   /* Update the chaining variables. */
382   addl state_h3(RSTATE), d;
383   addl state_h2(RSTATE), c;
384   addl state_h1(RSTATE), b;
385   addl state_h4(RSTATE), e;
386
387   movl d, state_h3(RSTATE);
388   movl c, state_h2(RSTATE);
389   movl b, state_h1(RSTATE);
390   movl a, state_h0(RSTATE);
391   movl e, state_h4(RSTATE);
392
393   /* Transform 0-47 for block 2. */
394   R( a, b, c, d, e, F1,  0, 1 );
395   R( e, a, b, c, d, F1,  1, 1 );
396   R( d, e, a, b, c, F1,  2, 1 );
397   R( c, d, e, a, b, F1,  3, 1 );
398   R( b, c, d, e, a, F1,  4, 1 );
399   R( a, b, c, d, e, F1,  5, 1 );
400   R( e, a, b, c, d, F1,  6, 1 );
401   R( d, e, a, b, c, F1,  7, 1 );
402   R( c, d, e, a, b, F1,  8, 1 );
403   R( b, c, d, e, a, F1,  9, 1 );
404   R( a, b, c, d, e, F1, 10, 1 );
405   R( e, a, b, c, d, F1, 11, 1 );
406   R( d, e, a, b, c, F1, 12, 1 );
407   R( c, d, e, a, b, F1, 13, 1 );
408   R( b, c, d, e, a, F1, 14, 1 );
409   R( a, b, c, d, e, F1, 15, 1 );
410   R( e, a, b, c, d, F1, 16, 1 );
411   R( d, e, a, b, c, F1, 17, 1 );
412   R( c, d, e, a, b, F1, 18, 1 );
413   R( b, c, d, e, a, F1, 19, 1 );
414   R( a, b, c, d, e, F2, 20, 1 );
415   R( e, a, b, c, d, F2, 21, 1 );
416   R( d, e, a, b, c, F2, 22, 1 );
417   R( c, d, e, a, b, F2, 23, 1 );
418   R( b, c, d, e, a, F2, 24, 1 );
419   R( a, b, c, d, e, F2, 25, 1 );
420   R( e, a, b, c, d, F2, 26, 1 );
421   R( d, e, a, b, c, F2, 27, 1 );
422   R( c, d, e, a, b, F2, 28, 1 );
423   R( b, c, d, e, a, F2, 29, 1 );
424   R( a, b, c, d, e, F2, 30, 1 );
425   R( e, a, b, c, d, F2, 31, 1 );
426   R( d, e, a, b, c, F2, 32, 1 );
427   R( c, d, e, a, b, F2, 33, 1 );
428   R( b, c, d, e, a, F2, 34, 1 );
429   R( a, b, c, d, e, F2, 35, 1 );
430   R( e, a, b, c, d, F2, 36, 1 );
431   R( d, e, a, b, c, F2, 37, 1 );
432   R( c, d, e, a, b, F2, 38, 1 );
433   R( b, c, d, e, a, F2, 39, 1 );
434   R( a, b, c, d, e, F3, 40, 1 );
435   R( e, a, b, c, d, F3, 41, 1 );
436   R( d, e, a, b, c, F3, 42, 1 );
437   R( c, d, e, a, b, F3, 43, 1 );
438   R( b, c, d, e, a, F3, 44, 1 );
439   R( a, b, c, d, e, F3, 45, 1 );
440   R( e, a, b, c, d, F3, 46, 1 );
441   R( d, e, a, b, c, F3, 47, 1 );
442
443   addq $-2, RNBLKS;
444   jz .Lend;
445
446   /* Transform 48-79 for block 2 + Precalc 0-31 for next two blocks. */
447   R( c, d, e, a, b, F3, 48, 1 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
448   R( b, c, d, e, a, F3, 49, 1 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
449   R( a, b, c, d, e, F3, 50, 1 ); W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
450   R( e, a, b, c, d, F3, 51, 1 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
451   R( d, e, a, b, c, F3, 52, 1 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
452   R( c, d, e, a, b, F3, 53, 1 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
453   R( b, c, d, e, a, F3, 54, 1 ); W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
454   R( a, b, c, d, e, F3, 55, 1 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
455   R( e, a, b, c, d, F3, 56, 1 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
456   R( d, e, a, b, c, F3, 57, 1 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
457   R( c, d, e, a, b, F3, 58, 1 ); W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
458   R( b, c, d, e, a, F3, 59, 1 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
459   R( a, b, c, d, e, F4, 60, 1 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
460   R( e, a, b, c, d, F4, 61, 1 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
461   R( d, e, a, b, c, F4, 62, 1 ); W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
462   R( c, d, e, a, b, F4, 63, 1 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
463   R( b, c, d, e, a, F4, 64, 1 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
464   R( a, b, c, d, e, F4, 65, 1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
465   R( e, a, b, c, d, F4, 66, 1 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
466   R( d, e, a, b, c, F4, 67, 1 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1, K1);
467   R( c, d, e, a, b, F4, 68, 1 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
468   R( b, c, d, e, a, F4, 69, 1 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
469   R( a, b, c, d, e, F4, 70, 1 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
470   R( e, a, b, c, d, F4, 71, 1 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1, K2);
471   R( d, e, a, b, c, F4, 72, 1 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
472   R( c, d, e, a, b, F4, 73, 1 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
473   R( b, c, d, e, a, F4, 74, 1 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
474   R( a, b, c, d, e, F4, 75, 1 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1, K2);
475   R( e, a, b, c, d, F4, 76, 1 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
476   R( d, e, a, b, c, F4, 77, 1 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
477   R( c, d, e, a, b, F4, 78, 1 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
478   addl state_h0(RSTATE), a;      W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1, K2);
479   R( b, c, d, e, a, F4, 79, 1 );
480   addl ne, a;
481   xorl ne, ne;
482
483   /* Update the chaining variables. */
484   addl state_h3(RSTATE), d;
485   addl state_h2(RSTATE), c;
486   addl state_h1(RSTATE), b;
487   addl state_h4(RSTATE), e;
488
489   movl d, state_h3(RSTATE);
490   movl c, state_h2(RSTATE);
491   movl b, state_h1(RSTATE);
492   movl a, state_h0(RSTATE);
493   movl e, state_h4(RSTATE);
494
495   jmp .Loop;
496
497 .align 16
498 .Lend:
499   vzeroall;
500
501   /* Transform 48-79 for block 2 + burn stack */
502   R( c, d, e, a, b, F3, 48, 1 );
503   R( b, c, d, e, a, F3, 49, 1 );
504   R( a, b, c, d, e, F3, 50, 1 );
505   R( e, a, b, c, d, F3, 51, 1 );
506   R( d, e, a, b, c, F3, 52, 1 );
507   R( c, d, e, a, b, F3, 53, 1 );
508   R( b, c, d, e, a, F3, 54, 1 );
509   R( a, b, c, d, e, F3, 55, 1 );
510   R( e, a, b, c, d, F3, 56, 1 );
511   R( d, e, a, b, c, F3, 57, 1 );
512   R( c, d, e, a, b, F3, 58, 1 );
513   R( b, c, d, e, a, F3, 59, 1 );
514   R( a, b, c, d, e, F4, 60, 1 ); vmovdqa %ymm0, (0*32)(%rsp);
515   R( e, a, b, c, d, F4, 61, 1 ); vmovdqa %ymm0, (1*32)(%rsp);
516   R( d, e, a, b, c, F4, 62, 1 ); vmovdqa %ymm0, (2*32)(%rsp);
517   R( c, d, e, a, b, F4, 63, 1 ); vmovdqa %ymm0, (3*32)(%rsp);
518   R( b, c, d, e, a, F4, 64, 1 ); vmovdqa %ymm0, (4*32)(%rsp);
519   R( a, b, c, d, e, F4, 65, 1 ); vmovdqa %ymm0, (5*32)(%rsp);
520   R( e, a, b, c, d, F4, 66, 1 ); vmovdqa %ymm0, (6*32)(%rsp);
521   R( d, e, a, b, c, F4, 67, 1 ); vmovdqa %ymm0, (7*32)(%rsp);
522   R( c, d, e, a, b, F4, 68, 1 ); vmovdqa %ymm0, (8*32)(%rsp);
523   R( b, c, d, e, a, F4, 69, 1 ); vmovdqa %ymm0, (9*32)(%rsp);
524   R( a, b, c, d, e, F4, 70, 1 ); vmovdqa %ymm0, (10*32)(%rsp);
525   R( e, a, b, c, d, F4, 71, 1 ); vmovdqa %ymm0, (11*32)(%rsp);
526   R( d, e, a, b, c, F4, 72, 1 ); vmovdqa %ymm0, (12*32)(%rsp);
527   R( c, d, e, a, b, F4, 73, 1 ); vmovdqa %ymm0, (13*32)(%rsp);
528   R( b, c, d, e, a, F4, 74, 1 ); vmovdqa %ymm0, (14*32)(%rsp);
529   R( a, b, c, d, e, F4, 75, 1 ); vmovdqa %ymm0, (15*32)(%rsp);
530   R( e, a, b, c, d, F4, 76, 1 ); vmovdqa %ymm0, (16*32)(%rsp);
531   R( d, e, a, b, c, F4, 77, 1 ); vmovdqa %ymm0, (17*32)(%rsp);
532   R( c, d, e, a, b, F4, 78, 1 ); vmovdqa %ymm0, (18*32)(%rsp);
533   addl state_h0(RSTATE), a;
534   R( b, c, d, e, a, F4, 79, 1 );
535   addl ne, a;
536   xorl ne, ne;
537
538   /* WK_STACK_WORDS*4/32-1 = 19 */
539   vmovdqa %ymm0, (19*32)(%rsp);
540
541   /* Update the chaining variables. */
542   addl state_h3(RSTATE), d;
543   addl state_h2(RSTATE), c;
544   addl state_h1(RSTATE), b;
545   addl state_h4(RSTATE), e;
546
547   movl d, state_h3(RSTATE);
548   movl c, state_h2(RSTATE);
549   movl b, state_h1(RSTATE);
550   movl a, state_h0(RSTATE);
551   movl e, state_h4(RSTATE);
552
553   movq ROLDSTACK, %rsp;
554   CFI_REGISTER(ROLDSTACK, %rsp);
555   CFI_DEF_CFA_REGISTER(%rsp);
556
557   popq %r12;
558   CFI_POP(%r12);
559   popq %rbp;
560   CFI_POP(%rbp);
561   popq %rbx;
562   CFI_POP(%rbx);
563
564   /* stack already burned */
565   xorl %eax, %eax;
566
567   ret;
568   CFI_ENDPROC();
569 ELF(.size _gcry_sha1_transform_amd64_avx2_bmi2,
570     .-_gcry_sha1_transform_amd64_avx2_bmi2;)
571
572 #endif
573 #endif