pubkey: Re-map all depreccated RSA algo numbers.
[libgcrypt.git] / cipher / serpent-sse2-amd64.S
1 /* serpent-sse2-amd64.S  -  SSE2 implementation of Serpent cipher
2  *
3  * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef __x86_64
22 #include <config.h>
23 #if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_SERPENT)
24
25 #ifdef __PIC__
26 #  define RIP (%rip)
27 #else
28 #  define RIP
29 #endif
30
31 /* struct serpent_context: */
32 #define ctx_keys 0
33
34 /* register macros */
35 #define CTX %rdi
36
37 /* vector registers */
38 #define RA0 %xmm0
39 #define RA1 %xmm1
40 #define RA2 %xmm2
41 #define RA3 %xmm3
42 #define RA4 %xmm4
43
44 #define RB0 %xmm5
45 #define RB1 %xmm6
46 #define RB2 %xmm7
47 #define RB3 %xmm8
48 #define RB4 %xmm9
49
50 #define RNOT %xmm10
51 #define RTMP0 %xmm11
52 #define RTMP1 %xmm12
53 #define RTMP2 %xmm13
54
55 /**********************************************************************
56   helper macros
57  **********************************************************************/
58
59 /* vector 32-bit rotation to left */
60 #define vec_rol(reg, nleft, tmp) \
61         movdqa reg, tmp;                \
62         pslld $(nleft), tmp;            \
63         psrld $(32 - (nleft)), reg;     \
64         por tmp, reg;
65
66 /* vector 32-bit rotation to right */
67 #define vec_ror(reg, nright, tmp) \
68         vec_rol(reg, 32 - nright, tmp)
69
70 /* 4x4 32-bit integer matrix transpose */
71 #define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
72         movdqa    x0, t2; \
73         punpckhdq x1, t2; \
74         punpckldq x1, x0; \
75         \
76         movdqa    x2, t1; \
77         punpckldq x3, t1; \
78         punpckhdq x3, x2; \
79         \
80         movdqa     x0, x1; \
81         punpckhqdq t1, x1; \
82         punpcklqdq t1, x0; \
83         \
84         movdqa     t2, x3; \
85         punpckhqdq x2, x3; \
86         punpcklqdq x2, t2; \
87         movdqa     t2, x2;
88
89 /* fill xmm register with 32-bit value from memory */
90 #define pbroadcastd(mem32, xreg) \
91         movd mem32, xreg; \
92         pshufd $0, xreg, xreg;
93
94 /* xor with unaligned memory operand */
95 #define pxor_u(umem128, xreg, t) \
96         movdqu umem128, t; \
97         pxor t, xreg;
98
99 /* 128-bit wide byte swap */
100 #define pbswap(xreg, t0) \
101         /* reorder 32-bit words, [a,b,c,d] => [d,c,b,a] */ \
102         pshufd $0x1b, xreg, xreg; \
103         /* reorder high&low 16-bit words, [d0,d1,c0,c1] => [d1,d0,c1,c0] */ \
104         pshuflw $0xb1, xreg, xreg; \
105         pshufhw $0xb1, xreg, xreg; \
106         /* reorder bytes in 16-bit words */ \
107         movdqa xreg, t0; \
108         psrlw $8, t0; \
109         psllw $8, xreg; \
110         por t0, xreg;
111
112 /**********************************************************************
113   8-way serpent
114  **********************************************************************/
115
116 /*
117  * These are the S-Boxes of Serpent from following research paper.
118  *
119  *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
120  *   (New York, New York, USA), p. 317–329, National Institute of Standards and
121  *   Technology, 2000.
122  *
123  * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
124  *
125  */
126 #define SBOX0(r0, r1, r2, r3, r4) \
127         pxor    r0, r3;         movdqa  r1, r4;         \
128         pand    r3, r1;         pxor    r2, r4;         \
129         pxor    r0, r1;         por     r3, r0;         \
130         pxor    r4, r0;         pxor    r3, r4;         \
131         pxor    r2, r3;         por     r1, r2;         \
132         pxor    r4, r2;         pxor    RNOT, r4;       \
133         por     r1, r4;         pxor    r3, r1;         \
134         pxor    r4, r1;         por     r0, r3;         \
135         pxor    r3, r1;         pxor    r3, r4;
136
137 #define SBOX0_INVERSE(r0, r1, r2, r3, r4) \
138         pxor    RNOT, r2;       movdqa  r1, r4;         \
139         por     r0, r1;         pxor    RNOT, r4;       \
140         pxor    r2, r1;         por     r4, r2;         \
141         pxor    r3, r1;         pxor    r4, r0;         \
142         pxor    r0, r2;         pand    r3, r0;         \
143         pxor    r0, r4;         por     r1, r0;         \
144         pxor    r2, r0;         pxor    r4, r3;         \
145         pxor    r1, r2;         pxor    r0, r3;         \
146         pxor    r1, r3; \
147         pand    r3, r2; \
148         pxor    r2, r4;
149
150 #define SBOX1(r0, r1, r2, r3, r4) \
151         pxor    RNOT, r0;       pxor    RNOT, r2;       \
152         movdqa  r0, r4;         pand    r1, r0;         \
153         pxor    r0, r2;         por     r3, r0;         \
154         pxor    r2, r3;         pxor    r0, r1;         \
155         pxor    r4, r0;         por     r1, r4;         \
156         pxor    r3, r1;         por     r0, r2;         \
157         pand    r4, r2;         pxor    r1, r0;         \
158         pand    r2, r1; \
159         pxor    r0, r1;         pand    r2, r0;         \
160         pxor    r4, r0;
161
162 #define SBOX1_INVERSE(r0, r1, r2, r3, r4) \
163         movdqa  r1, r4;         pxor    r3, r1;         \
164         pand    r1, r3;         pxor    r2, r4;         \
165         pxor    r0, r3;         por     r1, r0;         \
166         pxor    r3, r2;         pxor    r4, r0;         \
167         por     r2, r0;         pxor    r3, r1;         \
168         pxor    r1, r0;         por     r3, r1;         \
169         pxor    r0, r1;         pxor    RNOT, r4;       \
170         pxor    r1, r4;         por     r0, r1;         \
171         pxor    r0, r1; \
172         por     r4, r1; \
173         pxor    r1, r3;
174
175 #define SBOX2(r0, r1, r2, r3, r4) \
176         movdqa  r0, r4;         pand    r2, r0;         \
177         pxor    r3, r0;         pxor    r1, r2;         \
178         pxor    r0, r2;         por     r4, r3;         \
179         pxor    r1, r3;         pxor    r2, r4;         \
180         movdqa  r3, r1;         por     r4, r3;         \
181         pxor    r0, r3;         pand    r1, r0;         \
182         pxor    r0, r4;         pxor    r3, r1;         \
183         pxor    r4, r1;         pxor    RNOT, r4;
184
185 #define SBOX2_INVERSE(r0, r1, r2, r3, r4) \
186         pxor    r3, r2;         pxor    r0, r3;         \
187         movdqa  r3, r4;         pand    r2, r3;         \
188         pxor    r1, r3;         por     r2, r1;         \
189         pxor    r4, r1;         pand    r3, r4;         \
190         pxor    r3, r2;         pand    r0, r4;         \
191         pxor    r2, r4;         pand    r1, r2;         \
192         por     r0, r2;         pxor    RNOT, r3;       \
193         pxor    r3, r2;         pxor    r3, r0;         \
194         pand    r1, r0;         pxor    r4, r3;         \
195         pxor    r0, r3;
196
197 #define SBOX3(r0, r1, r2, r3, r4) \
198         movdqa  r0, r4;         por     r3, r0;         \
199         pxor    r1, r3;         pand    r4, r1;         \
200         pxor    r2, r4;         pxor    r3, r2;         \
201         pand    r0, r3;         por     r1, r4;         \
202         pxor    r4, r3;         pxor    r1, r0;         \
203         pand    r0, r4;         pxor    r3, r1;         \
204         pxor    r2, r4;         por     r0, r1;         \
205         pxor    r2, r1;         pxor    r3, r0;         \
206         movdqa  r1, r2;         por     r3, r1;         \
207         pxor    r0, r1;
208
209 #define SBOX3_INVERSE(r0, r1, r2, r3, r4) \
210         movdqa  r2, r4;         pxor    r1, r2;         \
211         pxor    r2, r0;         pand    r2, r4;         \
212         pxor    r0, r4;         pand    r1, r0;         \
213         pxor    r3, r1;         por     r4, r3;         \
214         pxor    r3, r2;         pxor    r3, r0;         \
215         pxor    r4, r1;         pand    r2, r3;         \
216         pxor    r1, r3;         pxor    r0, r1;         \
217         por     r2, r1;         pxor    r3, r0;         \
218         pxor    r4, r1; \
219         pxor    r1, r0;
220
221 #define SBOX4(r0, r1, r2, r3, r4) \
222         pxor    r3, r1;         pxor    RNOT, r3;       \
223         pxor    r3, r2;         pxor    r0, r3;         \
224         movdqa  r1, r4;         pand    r3, r1;         \
225         pxor    r2, r1;         pxor    r3, r4;         \
226         pxor    r4, r0;         pand    r4, r2;         \
227         pxor    r0, r2;         pand    r1, r0;         \
228         pxor    r0, r3;         por     r1, r4;         \
229         pxor    r0, r4;         por     r3, r0;         \
230         pxor    r2, r0;         pand    r3, r2;         \
231         pxor    RNOT, r0;       pxor    r2, r4;
232
233 #define SBOX4_INVERSE(r0, r1, r2, r3, r4) \
234         movdqa  r2, r4;         pand    r3, r2;         \
235         pxor    r1, r2;         por     r3, r1;         \
236         pand    r0, r1;         pxor    r2, r4;         \
237         pxor    r1, r4;         pand    r2, r1;         \
238         pxor    RNOT, r0;       pxor    r4, r3;         \
239         pxor    r3, r1;         pand    r0, r3;         \
240         pxor    r2, r3;         pxor    r1, r0;         \
241         pand    r0, r2;         pxor    r0, r3;         \
242         pxor    r4, r2; \
243         por     r3, r2;         pxor    r0, r3;         \
244         pxor    r1, r2;
245
246 #define SBOX5(r0, r1, r2, r3, r4) \
247         pxor    r1, r0;         pxor    r3, r1;         \
248         pxor    RNOT, r3;       movdqa  r1, r4;         \
249         pand    r0, r1;         pxor    r3, r2;         \
250         pxor    r2, r1;         por     r4, r2;         \
251         pxor    r3, r4;         pand    r1, r3;         \
252         pxor    r0, r3;         pxor    r1, r4;         \
253         pxor    r2, r4;         pxor    r0, r2;         \
254         pand    r3, r0;         pxor    RNOT, r2;       \
255         pxor    r4, r0;         por     r3, r4;         \
256         pxor    r4, r2;
257
258 #define SBOX5_INVERSE(r0, r1, r2, r3, r4) \
259         pxor    RNOT, r1;       movdqa  r3, r4;         \
260         pxor    r1, r2;         por     r0, r3;         \
261         pxor    r2, r3;         por     r1, r2;         \
262         pand    r0, r2;         pxor    r3, r4;         \
263         pxor    r4, r2;         por     r0, r4;         \
264         pxor    r1, r4;         pand    r2, r1;         \
265         pxor    r3, r1;         pxor    r2, r4;         \
266         pand    r4, r3;         pxor    r1, r4;         \
267         pxor    r4, r3;         pxor    RNOT, r4;       \
268         pxor    r0, r3;
269
270 #define SBOX6(r0, r1, r2, r3, r4) \
271         pxor    RNOT, r2;       movdqa  r3, r4;         \
272         pand    r0, r3;         pxor    r4, r0;         \
273         pxor    r2, r3;         por     r4, r2;         \
274         pxor    r3, r1;         pxor    r0, r2;         \
275         por     r1, r0;         pxor    r1, r2;         \
276         pxor    r0, r4;         por     r3, r0;         \
277         pxor    r2, r0;         pxor    r3, r4;         \
278         pxor    r0, r4;         pxor    RNOT, r3;       \
279         pand    r4, r2; \
280         pxor    r3, r2;
281
282 #define SBOX6_INVERSE(r0, r1, r2, r3, r4) \
283         pxor    r2, r0;         movdqa  r2, r4;         \
284         pand    r0, r2;         pxor    r3, r4;         \
285         pxor    RNOT, r2;       pxor    r1, r3;         \
286         pxor    r3, r2;         por     r0, r4;         \
287         pxor    r2, r0;         pxor    r4, r3;         \
288         pxor    r1, r4;         pand    r3, r1;         \
289         pxor    r0, r1;         pxor    r3, r0;         \
290         por     r2, r0;         pxor    r1, r3;         \
291         pxor    r0, r4;
292
293 #define SBOX7(r0, r1, r2, r3, r4) \
294         movdqa  r1, r4;         por     r2, r1;         \
295         pxor    r3, r1;         pxor    r2, r4;         \
296         pxor    r1, r2;         por     r4, r3;         \
297         pand    r0, r3;         pxor    r2, r4;         \
298         pxor    r1, r3;         por     r4, r1;         \
299         pxor    r0, r1;         por     r4, r0;         \
300         pxor    r2, r0;         pxor    r4, r1;         \
301         pxor    r1, r2;         pand    r0, r1;         \
302         pxor    r4, r1;         pxor    RNOT, r2;       \
303         por     r0, r2; \
304         pxor    r2, r4;
305
306 #define SBOX7_INVERSE(r0, r1, r2, r3, r4) \
307         movdqa  r2, r4;         pxor    r0, r2;         \
308         pand    r3, r0;         por     r3, r4;         \
309         pxor    RNOT, r2;       pxor    r1, r3;         \
310         por     r0, r1;         pxor    r2, r0;         \
311         pand    r4, r2;         pand    r4, r3;         \
312         pxor    r2, r1;         pxor    r0, r2;         \
313         por     r2, r0;         pxor    r1, r4;         \
314         pxor    r3, r0;         pxor    r4, r3;         \
315         por     r0, r4;         pxor    r2, r3;         \
316         pxor    r2, r4;
317
318 /* Apply SBOX number WHICH to to the block.  */
319 #define SBOX(which, r0, r1, r2, r3, r4) \
320         SBOX##which (r0, r1, r2, r3, r4)
321
322 /* Apply inverse SBOX number WHICH to to the block.  */
323 #define SBOX_INVERSE(which, r0, r1, r2, r3, r4) \
324         SBOX##which##_INVERSE (r0, r1, r2, r3, r4)
325
326 /* XOR round key into block state in r0,r1,r2,r3. r4 used as temporary.  */
327 #define BLOCK_XOR_KEY(r0, r1, r2, r3, r4, round) \
328         pbroadcastd ((ctx_keys + (round) * 16 + 0 * 4)(CTX), r4); \
329         pxor r4, r0; \
330         pbroadcastd ((ctx_keys + (round) * 16 + 1 * 4)(CTX), r4); \
331         pxor r4, r1; \
332         pbroadcastd ((ctx_keys + (round) * 16 + 2 * 4)(CTX), r4); \
333         pxor r4, r2; \
334         pbroadcastd ((ctx_keys + (round) * 16 + 3 * 4)(CTX), r4); \
335         pxor r4, r3;
336
337 /* Apply the linear transformation to BLOCK.  */
338 #define LINEAR_TRANSFORMATION(r0, r1, r2, r3, r4) \
339         vec_rol(r0, 13, r4);    \
340         vec_rol(r2, 3, r4);     \
341         pxor r0, r1;            \
342         pxor r2, r1;            \
343         movdqa r0, r4;          \
344         pslld $3, r4;           \
345         pxor r2, r3;            \
346         pxor r4, r3;            \
347         vec_rol(r1, 1, r4);     \
348         vec_rol(r3, 7, r4);     \
349         pxor r1, r0;            \
350         pxor r3, r0;            \
351         movdqa r1, r4;          \
352         pslld $7, r4;           \
353         pxor r3, r2;            \
354         pxor r4, r2;            \
355         vec_rol(r0, 5, r4);     \
356         vec_rol(r2, 22, r4);
357
358 /* Apply the inverse linear transformation to BLOCK.  */
359 #define LINEAR_TRANSFORMATION_INVERSE(r0, r1, r2, r3, r4) \
360         vec_ror(r2, 22, r4);    \
361         vec_ror(r0, 5, r4);     \
362         movdqa r1, r4;          \
363         pslld $7, r4;           \
364         pxor r3, r2;            \
365         pxor r4, r2;            \
366         pxor r1, r0;            \
367         pxor r3, r0;            \
368         vec_ror(r3, 7, r4);     \
369         vec_ror(r1, 1, r4);     \
370         movdqa r0, r4;          \
371         pslld $3, r4;           \
372         pxor r2, r3;            \
373         pxor r4, r3;            \
374         pxor r0, r1;            \
375         pxor r2, r1;            \
376         vec_ror(r2, 3, r4);     \
377         vec_ror(r0, 13, r4);
378
379 /* Apply a Serpent round to eight parallel blocks.  This macro increments
380    `round'.  */
381 #define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
382                             b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
383         BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round);              \
384         SBOX (which, a0, a1, a2, a3, a4);                       \
385                 BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round);              \
386                 SBOX (which, b0, b1, b2, b3, b4);                       \
387         LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4);        \
388                 LINEAR_TRANSFORMATION (nb0, nb1, nb2, nb3, nb4);
389
390 /* Apply the last Serpent round to eight parallel blocks.  This macro increments
391    `round'.  */
392 #define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
393                                  b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
394         BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round);              \
395         SBOX (which, a0, a1, a2, a3, a4);                       \
396                 BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round);              \
397                 SBOX (which, b0, b1, b2, b3, b4);                       \
398         BLOCK_XOR_KEY (na0, na1, na2, na3, na4, ((round) + 1));         \
399                 BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, ((round) + 1));
400
401 /* Apply an inverse Serpent round to eight parallel blocks.  This macro
402    increments `round'.  */
403 #define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
404                                     na0, na1, na2, na3, na4, \
405                                     b0, b1, b2, b3, b4, \
406                                     nb0, nb1, nb2, nb3, nb4) \
407         LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4);     \
408                 LINEAR_TRANSFORMATION_INVERSE (b0, b1, b2, b3, b4);     \
409         SBOX_INVERSE (which, a0, a1, a2, a3, a4);               \
410         BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round);         \
411                 SBOX_INVERSE (which, b0, b1, b2, b3, b4);               \
412                 BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
413
414 /* Apply the first inverse Serpent round to eight parallel blocks.  This macro
415    increments `round'.  */
416 #define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
417                                           na0, na1, na2, na3, na4, \
418                                           b0, b1, b2, b3, b4, \
419                                           nb0, nb1, nb2, nb3, nb4) \
420         BLOCK_XOR_KEY (a0, a1, a2, a3, a4, ((round) + 1));      \
421                 BLOCK_XOR_KEY (b0, b1, b2, b3, b4, ((round) + 1));      \
422         SBOX_INVERSE (which, a0, a1, a2, a3, a4);       \
423         BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
424                 SBOX_INVERSE (which, b0, b1, b2, b3, b4);       \
425                 BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
426
427 .text
428
429 .align 8
430 .type   __serpent_enc_blk8,@function;
431 __serpent_enc_blk8:
432         /* input:
433          *      %rdi: ctx, CTX
434          *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
435          *                                              blocks
436          * output:
437          *      RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: eight parallel
438          *                                              ciphertext blocks
439          */
440
441         pcmpeqd RNOT, RNOT;
442
443         transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
444         transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
445
446         ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
447                      RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
448         ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
449                      RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
450         ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
451                      RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
452         ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
453                      RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
454         ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
455                      RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
456         ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
457                      RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
458         ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
459                      RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
460         ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
461                      RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
462         ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
463                      RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
464         ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
465                      RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
466         ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
467                       RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
468         ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
469                       RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
470         ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
471                       RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
472         ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
473                       RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
474         ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
475                       RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
476         ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
477                       RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
478         ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
479                       RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
480         ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
481                       RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
482         ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
483                       RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
484         ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
485                       RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
486         ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
487                       RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
488         ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
489                       RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
490         ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
491                       RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
492         ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
493                       RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
494         ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
495                       RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
496         ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
497                       RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
498         ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
499                       RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
500         ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
501                       RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
502         ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
503                       RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
504         ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
505                       RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
506         ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
507                       RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
508         ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
509                            RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
510
511         transpose_4x4(RA4, RA1, RA2, RA0, RA3, RTMP0, RTMP1);
512         transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
513
514         ret;
515 .size __serpent_enc_blk8,.-__serpent_enc_blk8;
516
517 .align 8
518 .type   __serpent_dec_blk8,@function;
519 __serpent_dec_blk8:
520         /* input:
521          *      %rdi: ctx, CTX
522          *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
523          *                                              ciphertext blocks
524          * output:
525          *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
526          *                                              blocks
527          */
528
529         pcmpeqd RNOT, RNOT;
530
531         transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
532         transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
533
534         ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
535                                     RA3, RA0, RA1, RA4, RA2,
536                                     RB0, RB1, RB2, RB3, RB4,
537                                     RB3, RB0, RB1, RB4, RB2);
538         ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
539                               RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
540         ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
541                               RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
542         ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
543                               RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
544         ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
545                               RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
546         ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
547                               RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
548         ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
549                               RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
550         ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
551                               RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
552         ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
553                               RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
554         ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
555                               RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
556         ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
557                               RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
558         ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
559                               RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
560         ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
561                               RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
562         ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
563                               RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
564         ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
565                               RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
566         ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
567                               RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
568         ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
569                               RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
570         ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
571                               RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
572         ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
573                               RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
574         ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
575                               RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
576         ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
577                               RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
578         ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
579                               RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
580         ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
581                              RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
582         ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
583                              RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
584         ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
585                              RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
586         ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
587                              RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
588         ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
589                              RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
590         ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
591                              RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
592         ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
593                              RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
594         ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
595                              RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
596         ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
597                              RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
598         ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
599                              RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
600
601         transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
602         transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
603
604         ret;
605 .size __serpent_dec_blk8,.-__serpent_dec_blk8;
606
607 .align 8
608 .globl _gcry_serpent_sse2_ctr_enc
609 .type   _gcry_serpent_sse2_ctr_enc,@function;
610 _gcry_serpent_sse2_ctr_enc:
611         /* input:
612          *      %rdi: ctx, CTX
613          *      %rsi: dst (8 blocks)
614          *      %rdx: src (8 blocks)
615          *      %rcx: iv (big endian, 128bit)
616          */
617
618         /* load IV and byteswap */
619         movdqu (%rcx), RA0;
620         movdqa RA0, RTMP0;
621         pbswap(RTMP0, RTMP1); /* be => le */
622
623         pcmpeqd RNOT, RNOT;
624         psrldq $8, RNOT; /* low: -1, high: 0 */
625         movdqa RNOT, RTMP2;
626         paddq RTMP2, RTMP2; /* low: -2, high: 0 */
627
628         /* construct IVs */
629         movdqa RTMP0, RTMP1;
630         psubq RNOT, RTMP0; /* +1 */
631         movdqa RTMP0, RA1;
632         psubq RTMP2, RTMP1; /* +2 */
633         movdqa RTMP1, RA2;
634         psubq RTMP2, RTMP0; /* +3 */
635         movdqa RTMP0, RA3;
636         psubq RTMP2, RTMP1; /* +4 */
637         movdqa RTMP1, RB0;
638         psubq RTMP2, RTMP0; /* +5 */
639         movdqa RTMP0, RB1;
640         psubq RTMP2, RTMP1; /* +6 */
641         movdqa RTMP1, RB2;
642         psubq RTMP2, RTMP0; /* +7 */
643         movdqa RTMP0, RB3;
644         psubq RTMP2, RTMP1; /* +8 */
645
646         /* check need for handling 64-bit overflow and carry */
647         cmpl $0xffffffff, 8(%rcx);
648         jne .Lno_ctr_carry;
649
650         movl 12(%rcx), %eax;
651         bswapl %eax;
652         cmpl $-8, %eax;
653         jb .Lno_ctr_carry;
654         pslldq $8, RNOT; /* low: 0, high: -1 */
655         je .Lcarry_RTMP0;
656
657         cmpl $-6, %eax;
658         jb .Lcarry_RB3;
659         je .Lcarry_RB2;
660
661         cmpl $-4, %eax;
662         jb .Lcarry_RB1;
663         je .Lcarry_RB0;
664
665         cmpl $-2, %eax;
666         jb .Lcarry_RA3;
667         je .Lcarry_RA2;
668
669         psubq RNOT, RA1;
670 .Lcarry_RA2:
671         psubq RNOT, RA2;
672 .Lcarry_RA3:
673         psubq RNOT, RA3;
674 .Lcarry_RB0:
675         psubq RNOT, RB0;
676 .Lcarry_RB1:
677         psubq RNOT, RB1;
678 .Lcarry_RB2:
679         psubq RNOT, RB2;
680 .Lcarry_RB3:
681         psubq RNOT, RB3;
682 .Lcarry_RTMP0:
683         psubq RNOT, RTMP1;
684
685 .Lno_ctr_carry:
686         /* le => be */
687         pbswap(RA1, RTMP0);
688         pbswap(RA2, RTMP0);
689         pbswap(RA3, RTMP0);
690         pbswap(RB0, RTMP0);
691         pbswap(RB1, RTMP0);
692         pbswap(RB2, RTMP0);
693         pbswap(RB3, RTMP0);
694         pbswap(RTMP1, RTMP0);
695         /* store new IV */
696         movdqu RTMP1, (%rcx);
697
698         call __serpent_enc_blk8;
699
700         pxor_u((0 * 16)(%rdx), RA4, RTMP0);
701         pxor_u((1 * 16)(%rdx), RA1, RTMP0);
702         pxor_u((2 * 16)(%rdx), RA2, RTMP0);
703         pxor_u((3 * 16)(%rdx), RA0, RTMP0);
704         pxor_u((4 * 16)(%rdx), RB4, RTMP0);
705         pxor_u((5 * 16)(%rdx), RB1, RTMP0);
706         pxor_u((6 * 16)(%rdx), RB2, RTMP0);
707         pxor_u((7 * 16)(%rdx), RB0, RTMP0);
708
709         movdqu RA4, (0 * 16)(%rsi);
710         movdqu RA1, (1 * 16)(%rsi);
711         movdqu RA2, (2 * 16)(%rsi);
712         movdqu RA0, (3 * 16)(%rsi);
713         movdqu RB4, (4 * 16)(%rsi);
714         movdqu RB1, (5 * 16)(%rsi);
715         movdqu RB2, (6 * 16)(%rsi);
716         movdqu RB0, (7 * 16)(%rsi);
717
718         /* clear the used registers */
719         pxor RA0, RA0;
720         pxor RA1, RA1;
721         pxor RA2, RA2;
722         pxor RA3, RA3;
723         pxor RA4, RA4;
724         pxor RB0, RB0;
725         pxor RB1, RB1;
726         pxor RB2, RB2;
727         pxor RB3, RB3;
728         pxor RB4, RB4;
729         pxor RTMP0, RTMP0;
730         pxor RTMP1, RTMP1;
731         pxor RTMP2, RTMP2;
732         pxor RNOT, RNOT;
733
734         ret
735 .size _gcry_serpent_sse2_ctr_enc,.-_gcry_serpent_sse2_ctr_enc;
736
737 .align 8
738 .globl _gcry_serpent_sse2_cbc_dec
739 .type   _gcry_serpent_sse2_cbc_dec,@function;
740 _gcry_serpent_sse2_cbc_dec:
741         /* input:
742          *      %rdi: ctx, CTX
743          *      %rsi: dst (8 blocks)
744          *      %rdx: src (8 blocks)
745          *      %rcx: iv
746          */
747
748         movdqu (0 * 16)(%rdx), RA0;
749         movdqu (1 * 16)(%rdx), RA1;
750         movdqu (2 * 16)(%rdx), RA2;
751         movdqu (3 * 16)(%rdx), RA3;
752         movdqu (4 * 16)(%rdx), RB0;
753         movdqu (5 * 16)(%rdx), RB1;
754         movdqu (6 * 16)(%rdx), RB2;
755         movdqu (7 * 16)(%rdx), RB3;
756
757         call __serpent_dec_blk8;
758
759         movdqu (7 * 16)(%rdx), RNOT;
760         pxor_u((%rcx), RA0, RTMP0);
761         pxor_u((0 * 16)(%rdx), RA1, RTMP0);
762         pxor_u((1 * 16)(%rdx), RA2, RTMP0);
763         pxor_u((2 * 16)(%rdx), RA3, RTMP0);
764         pxor_u((3 * 16)(%rdx), RB0, RTMP0);
765         pxor_u((4 * 16)(%rdx), RB1, RTMP0);
766         pxor_u((5 * 16)(%rdx), RB2, RTMP0);
767         pxor_u((6 * 16)(%rdx), RB3, RTMP0);
768         movdqu RNOT, (%rcx); /* store new IV */
769
770         movdqu RA0, (0 * 16)(%rsi);
771         movdqu RA1, (1 * 16)(%rsi);
772         movdqu RA2, (2 * 16)(%rsi);
773         movdqu RA3, (3 * 16)(%rsi);
774         movdqu RB0, (4 * 16)(%rsi);
775         movdqu RB1, (5 * 16)(%rsi);
776         movdqu RB2, (6 * 16)(%rsi);
777         movdqu RB3, (7 * 16)(%rsi);
778
779         /* clear the used registers */
780         pxor RA0, RA0;
781         pxor RA1, RA1;
782         pxor RA2, RA2;
783         pxor RA3, RA3;
784         pxor RA4, RA4;
785         pxor RB0, RB0;
786         pxor RB1, RB1;
787         pxor RB2, RB2;
788         pxor RB3, RB3;
789         pxor RB4, RB4;
790         pxor RTMP0, RTMP0;
791         pxor RTMP1, RTMP1;
792         pxor RTMP2, RTMP2;
793         pxor RNOT, RNOT;
794
795         ret
796 .size _gcry_serpent_sse2_cbc_dec,.-_gcry_serpent_sse2_cbc_dec;
797
798 .align 8
799 .globl _gcry_serpent_sse2_cfb_dec
800 .type   _gcry_serpent_sse2_cfb_dec,@function;
801 _gcry_serpent_sse2_cfb_dec:
802         /* input:
803          *      %rdi: ctx, CTX
804          *      %rsi: dst (8 blocks)
805          *      %rdx: src (8 blocks)
806          *      %rcx: iv
807          */
808
809         /* Load input */
810         movdqu (%rcx), RA0;
811         movdqu 0 * 16(%rdx), RA1;
812         movdqu 1 * 16(%rdx), RA2;
813         movdqu 2 * 16(%rdx), RA3;
814         movdqu 3 * 16(%rdx), RB0;
815         movdqu 4 * 16(%rdx), RB1;
816         movdqu 5 * 16(%rdx), RB2;
817         movdqu 6 * 16(%rdx), RB3;
818
819         /* Update IV */
820         movdqu 7 * 16(%rdx), RNOT;
821         movdqu RNOT, (%rcx);
822
823         call __serpent_enc_blk8;
824
825         pxor_u((0 * 16)(%rdx), RA4, RTMP0);
826         pxor_u((1 * 16)(%rdx), RA1, RTMP0);
827         pxor_u((2 * 16)(%rdx), RA2, RTMP0);
828         pxor_u((3 * 16)(%rdx), RA0, RTMP0);
829         pxor_u((4 * 16)(%rdx), RB4, RTMP0);
830         pxor_u((5 * 16)(%rdx), RB1, RTMP0);
831         pxor_u((6 * 16)(%rdx), RB2, RTMP0);
832         pxor_u((7 * 16)(%rdx), RB0, RTMP0);
833
834         movdqu RA4, (0 * 16)(%rsi);
835         movdqu RA1, (1 * 16)(%rsi);
836         movdqu RA2, (2 * 16)(%rsi);
837         movdqu RA0, (3 * 16)(%rsi);
838         movdqu RB4, (4 * 16)(%rsi);
839         movdqu RB1, (5 * 16)(%rsi);
840         movdqu RB2, (6 * 16)(%rsi);
841         movdqu RB0, (7 * 16)(%rsi);
842
843         /* clear the used registers */
844         pxor RA0, RA0;
845         pxor RA1, RA1;
846         pxor RA2, RA2;
847         pxor RA3, RA3;
848         pxor RA4, RA4;
849         pxor RB0, RB0;
850         pxor RB1, RB1;
851         pxor RB2, RB2;
852         pxor RB3, RB3;
853         pxor RB4, RB4;
854         pxor RTMP0, RTMP0;
855         pxor RTMP1, RTMP1;
856         pxor RTMP2, RTMP2;
857         pxor RNOT, RNOT;
858
859         ret
860 .size _gcry_serpent_sse2_cfb_dec,.-_gcry_serpent_sse2_cfb_dec;
861
862 #endif /*defined(USE_SERPENT)*/
863 #endif /*__x86_64*/