ecc: Simplify compute_keygrip.
[libgcrypt.git] / cipher / twofish-amd64.S
1 /* twofish-amd64.S  -  AMD64 assembly implementation of Twofish cipher
2  *
3  * Copyright (C) 2013-2015 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) || \
24     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_TWOFISH)
25
26 #include "asm-common-amd64.h"
27
28 .text
29
30 /* structure of TWOFISH_context: */
31 #define s0 0
32 #define s1 ((s0) + 4 * 256)
33 #define s2 ((s1) + 4 * 256)
34 #define s3 ((s2) + 4 * 256)
35 #define w  ((s3) + 4 * 256)
36 #define k  ((w) + 4 * 8)
37
38 /* register macros */
39 #define CTX     %rdi
40
41 #define RA      %rax
42 #define RB      %rbx
43 #define RC      %rcx
44 #define RD      %rdx
45
46 #define RAd     %eax
47 #define RBd     %ebx
48 #define RCd     %ecx
49 #define RDd     %edx
50
51 #define RAbl    %al
52 #define RBbl    %bl
53 #define RCbl    %cl
54 #define RDbl    %dl
55
56 #define RAbh    %ah
57 #define RBbh    %bh
58 #define RCbh    %ch
59 #define RDbh    %dh
60
61 #define RX      %r8
62 #define RY      %r9
63
64 #define RXd     %r8d
65 #define RYd     %r9d
66
67 #define RT0     %rsi
68 #define RT1     %rbp
69 #define RT2     %r10
70 #define RT3     %r11
71
72 #define RT0d    %esi
73 #define RT1d    %ebp
74 #define RT2d    %r10d
75 #define RT3d    %r11d
76
77 /***********************************************************************
78  * AMD64 assembly implementation of the Twofish cipher
79  ***********************************************************************/
80 #define enc_g1_2(a, b, x, y) \
81         movzbl b ## bl, RT3d; \
82         movzbl b ## bh, RT1d; \
83         movzbl a ## bl, RT2d; \
84         movzbl a ## bh, RT0d; \
85         rorl $16, b ## d; \
86         rorl $16, a ## d; \
87         movl s1(CTX, RT3, 4), RYd; \
88         movzbl b ## bl, RT3d; \
89         movl s0(CTX, RT2, 4), RXd; \
90         movzbl a ## bl, RT2d; \
91         xorl s2(CTX, RT1, 4), RYd; \
92         movzbl b ## bh, RT1d; \
93         xorl s1(CTX, RT0, 4), RXd; \
94         movzbl a ## bh, RT0d; \
95         rorl $16, b ## d; \
96         rorl $16, a ## d; \
97         xorl s3(CTX, RT3, 4), RYd; \
98         xorl s2(CTX, RT2, 4), RXd; \
99         xorl s0(CTX, RT1, 4), RYd; \
100         xorl s3(CTX, RT0, 4), RXd;
101
102 #define dec_g1_2(a, b, x, y) \
103         movzbl a ## bl, RT2d; \
104         movzbl a ## bh, RT0d; \
105         movzbl b ## bl, RT3d; \
106         movzbl b ## bh, RT1d; \
107         rorl $16, a ## d; \
108         rorl $16, b ## d; \
109         movl s0(CTX, RT2, 4), RXd; \
110         movzbl a ## bl, RT2d; \
111         movl s1(CTX, RT3, 4), RYd; \
112         movzbl b ## bl, RT3d; \
113         xorl s1(CTX, RT0, 4), RXd; \
114         movzbl a ## bh, RT0d; \
115         xorl s2(CTX, RT1, 4), RYd; \
116         movzbl b ## bh, RT1d; \
117         rorl $16, a ## d; \
118         rorl $16, b ## d; \
119         xorl s2(CTX, RT2, 4), RXd; \
120         xorl s3(CTX, RT3, 4), RYd; \
121         xorl s3(CTX, RT0, 4), RXd; \
122         xorl s0(CTX, RT1, 4), RYd;
123
124 #define encrypt_round(ra, rb, rc, rd, n) \
125         enc_g1_2(##ra, ##rb, RX, RY); \
126         \
127         leal (RXd, RYd, 2), RT0d; \
128         addl RYd, RXd; \
129         addl (k + 8 * (n) + 4)(CTX), RT0d; \
130         roll $1, rd ## d; \
131         addl (k + 8 * (n))(CTX), RXd; \
132         xorl RT0d, rd ## d; \
133         xorl RXd, rc ## d; \
134         rorl $1, rc ## d;
135
136 #define decrypt_round(ra, rb, rc, rd, n) \
137         dec_g1_2(##ra, ##rb, RX, RY); \
138         \
139         leal (RXd, RYd, 2), RT0d; \
140         addl RYd, RXd; \
141         addl (k + 8 * (n) + 4)(CTX), RT0d; \
142         roll $1, rc ## d; \
143         addl (k + 8 * (n))(CTX), RXd; \
144         xorl RXd, rc ## d; \
145         xorl RT0d, rd ## d; \
146         rorl $1, rd ## d;
147
148 #define encrypt_cycle(a, b, c, d, nc) \
149         encrypt_round(##a, ##b, ##c, ##d, (nc) * 2); \
150         encrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1);
151
152 #define decrypt_cycle(a, b, c, d, nc) \
153         decrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1); \
154         decrypt_round(##a, ##b, ##c, ##d, (nc) * 2);
155
156 #define inpack(in, n, x, m) \
157         movl (4 * (n))(in), x; \
158         xorl (w + 4 * (m))(CTX), x;
159
160 #define outunpack(out, n, x, m) \
161         xorl (w + 4 * (m))(CTX), x; \
162         movl x, (4 * (n))(out);
163
164 .align 8
165 .globl _gcry_twofish_amd64_encrypt_block
166 ELF(.type   _gcry_twofish_amd64_encrypt_block,@function;)
167
168 _gcry_twofish_amd64_encrypt_block:
169         /* input:
170          *      %rdi: context, CTX
171          *      %rsi: dst
172          *      %rdx: src
173          */
174         CFI_STARTPROC();
175         ENTER_SYSV_FUNC_PARAMS_0_4
176
177         subq $(3 * 8), %rsp;
178         CFI_ADJUST_CFA_OFFSET(3 * 8);
179         movq %rsi, (0 * 8)(%rsp);
180         movq %rbp, (1 * 8)(%rsp);
181         movq %rbx, (2 * 8)(%rsp);
182         CFI_REL_OFFSET(%rbp, 1 * 8);
183         CFI_REL_OFFSET(%rbx, 2 * 8);
184
185         movq %rdx, RX;
186         inpack(RX, 0, RAd, 0);
187         inpack(RX, 1, RBd, 1);
188         inpack(RX, 2, RCd, 2);
189         inpack(RX, 3, RDd, 3);
190
191         encrypt_cycle(RA, RB, RC, RD, 0);
192         encrypt_cycle(RA, RB, RC, RD, 1);
193         encrypt_cycle(RA, RB, RC, RD, 2);
194         encrypt_cycle(RA, RB, RC, RD, 3);
195         encrypt_cycle(RA, RB, RC, RD, 4);
196         encrypt_cycle(RA, RB, RC, RD, 5);
197         encrypt_cycle(RA, RB, RC, RD, 6);
198         encrypt_cycle(RA, RB, RC, RD, 7);
199
200         movq (0 * 8)(%rsp), RX; /*dst*/
201         outunpack(RX, 0, RCd, 4);
202         outunpack(RX, 1, RDd, 5);
203         outunpack(RX, 2, RAd, 6);
204         outunpack(RX, 3, RBd, 7);
205
206         movq (2 * 8)(%rsp), %rbx;
207         movq (1 * 8)(%rsp), %rbp;
208         CFI_RESTORE(%rbx);
209         CFI_RESTORE(%rbp);
210         addq $(3 * 8), %rsp;
211         CFI_ADJUST_CFA_OFFSET(-3 * 8);
212
213         EXIT_SYSV_FUNC
214         ret;
215         CFI_ENDPROC();
216 ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
217
218 .align 8
219 .globl _gcry_twofish_amd64_decrypt_block
220 ELF(.type   _gcry_twofish_amd64_decrypt_block,@function;)
221
222 _gcry_twofish_amd64_decrypt_block:
223         /* input:
224          *      %rdi: context, CTX
225          *      %rsi: dst
226          *      %rdx: src
227          */
228         CFI_STARTPROC();
229         ENTER_SYSV_FUNC_PARAMS_0_4
230
231         subq $(3 * 8), %rsp;
232         CFI_ADJUST_CFA_OFFSET(3 * 8);
233         movq %rsi, (0 * 8)(%rsp);
234         movq %rbp, (1 * 8)(%rsp);
235         movq %rbx, (2 * 8)(%rsp);
236         CFI_REL_OFFSET(%rbp, 1 * 8);
237         CFI_REL_OFFSET(%rbx, 2 * 8);
238
239         movq %rdx, RX;
240         inpack(RX, 0, RCd, 4);
241         inpack(RX, 1, RDd, 5);
242         inpack(RX, 2, RAd, 6);
243         inpack(RX, 3, RBd, 7);
244
245         decrypt_cycle(RA, RB, RC, RD, 7);
246         decrypt_cycle(RA, RB, RC, RD, 6);
247         decrypt_cycle(RA, RB, RC, RD, 5);
248         decrypt_cycle(RA, RB, RC, RD, 4);
249         decrypt_cycle(RA, RB, RC, RD, 3);
250         decrypt_cycle(RA, RB, RC, RD, 2);
251         decrypt_cycle(RA, RB, RC, RD, 1);
252         decrypt_cycle(RA, RB, RC, RD, 0);
253
254         movq (0 * 8)(%rsp), RX; /*dst*/
255         outunpack(RX, 0, RAd, 0);
256         outunpack(RX, 1, RBd, 1);
257         outunpack(RX, 2, RCd, 2);
258         outunpack(RX, 3, RDd, 3);
259
260         movq (2 * 8)(%rsp), %rbx;
261         movq (1 * 8)(%rsp), %rbp;
262         CFI_RESTORE(%rbx);
263         CFI_RESTORE(%rbp);
264         addq $(3 * 8), %rsp;
265         CFI_ADJUST_CFA_OFFSET(-3 * 8);
266
267         EXIT_SYSV_FUNC
268         ret;
269         CFI_ENDPROC();
270 ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
271
272 #undef CTX
273
274 #undef RA
275 #undef RB
276 #undef RC
277 #undef RD
278
279 #undef RAd
280 #undef RBd
281 #undef RCd
282 #undef RDd
283
284 #undef RAbl
285 #undef RBbl
286 #undef RCbl
287 #undef RDbl
288
289 #undef RAbh
290 #undef RBbh
291 #undef RCbh
292 #undef RDbh
293
294 #undef RX
295 #undef RY
296
297 #undef RXd
298 #undef RYd
299
300 #undef RT0
301 #undef RT1
302 #undef RT2
303 #undef RT3
304
305 #undef RT0d
306 #undef RT1d
307 #undef RT2d
308 #undef RT3d
309
310 /***********************************************************************
311  * AMD64 assembly implementation of the Twofish cipher, 3-way parallel
312  ***********************************************************************/
313 #define CTX %rdi
314 #define RIO %rdx
315
316 #define RAB0 %rax
317 #define RAB1 %rbx
318 #define RAB2 %rcx
319
320 #define RAB0d %eax
321 #define RAB1d %ebx
322 #define RAB2d %ecx
323
324 #define RAB0bh %ah
325 #define RAB1bh %bh
326 #define RAB2bh %ch
327
328 #define RAB0bl %al
329 #define RAB1bl %bl
330 #define RAB2bl %cl
331
332 #define RCD0 %r8
333 #define RCD1 %r9
334 #define RCD2 %r10
335
336 #define RCD0d %r8d
337 #define RCD1d %r9d
338 #define RCD2d %r10d
339
340 #define RX0 %rbp
341 #define RX1 %r11
342 #define RX2 %r12
343
344 #define RX0d %ebp
345 #define RX1d %r11d
346 #define RX2d %r12d
347
348 #define RY0 %r13
349 #define RY1 %r14
350 #define RY2 %r15
351
352 #define RY0d %r13d
353 #define RY1d %r14d
354 #define RY2d %r15d
355
356 #define RT0 %rdx
357 #define RT1 %rsi
358
359 #define RT0d %edx
360 #define RT1d %esi
361
362 #define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
363         movzbl ab ## bl,                tmp2 ## d; \
364         movzbl ab ## bh,                tmp1 ## d; \
365         rorq $(rot),                    ab; \
366         op1##l T0(CTX, tmp2, 4),        dst ## d; \
367         op2##l T1(CTX, tmp1, 4),        dst ## d;
368
369 /*
370  * Combined G1 & G2 function. Reordered with help of rotates to have moves
371  * at beginning.
372  */
373 #define g1g2_3(ab, cd, Tx0, Tx1, Tx2, Tx3, Ty0, Ty1, Ty2, Ty3, x, y) \
374         /* G1,1 && G2,1 */ \
375         do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 0, ab ## 0, x ## 0); \
376         do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 0, ab ## 0, y ## 0); \
377         \
378         do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 1, ab ## 1, x ## 1); \
379         do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 1, ab ## 1, y ## 1); \
380         \
381         do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 2, ab ## 2, x ## 2); \
382         do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 2, ab ## 2, y ## 2); \
383         \
384         /* G1,2 && G2,2 */ \
385         do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
386         do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
387         movq ab ## 0, RT0; \
388         movq cd ## 0, ab ## 0; \
389         movq RT0, cd ## 0; \
390         \
391         do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
392         do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
393         movq ab ## 1, RT0; \
394         movq cd ## 1, ab ## 1; \
395         movq RT0, cd ## 1; \
396         \
397         do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
398         do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
399         movq ab ## 2, RT0; \
400         movq cd ## 2, ab ## 2; \
401         movq RT0, cd ## 2;
402
403 #define enc_round_end(ab, x, y, n) \
404         addl y ## d,                    x ## d; \
405         addl x ## d,                    y ## d; \
406         addl k+4*(2*(n))(CTX),          x ## d; \
407         xorl ab ## d,                   x ## d; \
408         addl k+4*(2*(n)+1)(CTX),        y ## d; \
409         shrq $32,                       ab; \
410         roll $1,                        ab ## d; \
411         xorl y ## d,                    ab ## d; \
412         shlq $32,                       ab; \
413         rorl $1,                        x ## d; \
414         orq x,                          ab;
415
416 #define dec_round_end(ba, x, y, n) \
417         addl y ## d,                    x ## d; \
418         addl x ## d,                    y ## d; \
419         addl k+4*(2*(n))(CTX),          x ## d; \
420         addl k+4*(2*(n)+1)(CTX),        y ## d; \
421         xorl ba ## d,                   y ## d; \
422         shrq $32,                       ba; \
423         roll $1,                        ba ## d; \
424         xorl x ## d,                    ba ## d; \
425         shlq $32,                       ba; \
426         rorl $1,                        y ## d; \
427         orq y,                          ba;
428
429 #define encrypt_round3(ab, cd, n) \
430         g1g2_3(ab, cd, s0, s1, s2, s3, s0, s1, s2, s3, RX, RY); \
431         \
432         enc_round_end(ab ## 0, RX0, RY0, n); \
433         enc_round_end(ab ## 1, RX1, RY1, n); \
434         enc_round_end(ab ## 2, RX2, RY2, n);
435
436 #define decrypt_round3(ba, dc, n) \
437         g1g2_3(ba, dc, s1, s2, s3, s0, s3, s0, s1, s2, RY, RX); \
438         \
439         dec_round_end(ba ## 0, RX0, RY0, n); \
440         dec_round_end(ba ## 1, RX1, RY1, n); \
441         dec_round_end(ba ## 2, RX2, RY2, n);
442
443 #define encrypt_cycle3(ab, cd, n) \
444         encrypt_round3(ab, cd, n*2); \
445         encrypt_round3(ab, cd, (n*2)+1);
446
447 #define decrypt_cycle3(ba, dc, n) \
448         decrypt_round3(ba, dc, (n*2)+1); \
449         decrypt_round3(ba, dc, (n*2));
450
451 #define inpack3(xy, m) \
452         xorq w+4*m(CTX),                xy ## 0; \
453         xorq w+4*m(CTX),                xy ## 1; \
454         xorq w+4*m(CTX),                xy ## 2;
455
456 #define outunpack3(xy, m) \
457         xorq w+4*m(CTX),                xy ## 0; \
458         xorq w+4*m(CTX),                xy ## 1; \
459         xorq w+4*m(CTX),                xy ## 2;
460
461 #define inpack_enc3() \
462         inpack3(RAB, 0); \
463         inpack3(RCD, 2);
464
465 #define outunpack_enc3() \
466         outunpack3(RAB, 6); \
467         outunpack3(RCD, 4);
468
469 #define inpack_dec3() \
470         inpack3(RAB, 4); \
471         rorq $32,                       RAB0; \
472         rorq $32,                       RAB1; \
473         rorq $32,                       RAB2; \
474         inpack3(RCD, 6); \
475         rorq $32,                       RCD0; \
476         rorq $32,                       RCD1; \
477         rorq $32,                       RCD2;
478
479 #define outunpack_dec3() \
480         rorq $32,                       RCD0; \
481         rorq $32,                       RCD1; \
482         rorq $32,                       RCD2; \
483         outunpack3(RCD, 0); \
484         rorq $32,                       RAB0; \
485         rorq $32,                       RAB1; \
486         rorq $32,                       RAB2; \
487         outunpack3(RAB, 2);
488
489 .align 8
490 ELF(.type __twofish_enc_blk3,@function;)
491
492 __twofish_enc_blk3:
493         /* input:
494          *      %rdi: ctx, CTX
495          *      RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three plaintext blocks
496          * output:
497          *      RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three ciphertext blocks
498          */
499         CFI_STARTPROC();
500
501         inpack_enc3();
502
503         encrypt_cycle3(RAB, RCD, 0);
504         encrypt_cycle3(RAB, RCD, 1);
505         encrypt_cycle3(RAB, RCD, 2);
506         encrypt_cycle3(RAB, RCD, 3);
507         encrypt_cycle3(RAB, RCD, 4);
508         encrypt_cycle3(RAB, RCD, 5);
509         encrypt_cycle3(RAB, RCD, 6);
510         encrypt_cycle3(RAB, RCD, 7);
511
512         outunpack_enc3();
513
514         ret;
515         CFI_ENDPROC();
516 ELF(.size __twofish_enc_blk3,.-__twofish_enc_blk3;)
517
518 .align 8
519 ELF(.type  __twofish_dec_blk3,@function;)
520
521 __twofish_dec_blk3:
522         /* input:
523          *      %rdi: ctx, CTX
524          *      RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three ciphertext blocks
525          * output:
526          *      RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three plaintext blocks
527          */
528         CFI_STARTPROC();
529
530         inpack_dec3();
531
532         decrypt_cycle3(RAB, RCD, 7);
533         decrypt_cycle3(RAB, RCD, 6);
534         decrypt_cycle3(RAB, RCD, 5);
535         decrypt_cycle3(RAB, RCD, 4);
536         decrypt_cycle3(RAB, RCD, 3);
537         decrypt_cycle3(RAB, RCD, 2);
538         decrypt_cycle3(RAB, RCD, 1);
539         decrypt_cycle3(RAB, RCD, 0);
540
541         outunpack_dec3();
542
543         ret;
544         CFI_ENDPROC();
545 ELF(.size __twofish_dec_blk3,.-__twofish_dec_blk3;)
546
547 .align 8
548 .globl _gcry_twofish_amd64_ctr_enc
549 ELF(.type   _gcry_twofish_amd64_ctr_enc,@function;)
550 _gcry_twofish_amd64_ctr_enc:
551         /* input:
552          *      %rdi: ctx, CTX
553          *      %rsi: dst (3 blocks)
554          *      %rdx: src (3 blocks)
555          *      %rcx: iv (big endian, 128bit)
556          */
557         CFI_STARTPROC();
558         ENTER_SYSV_FUNC_PARAMS_0_4
559
560         subq $(8 * 8), %rsp;
561         CFI_ADJUST_CFA_OFFSET(8 * 8);
562         movq %rbp, (0 * 8)(%rsp);
563         movq %rbx, (1 * 8)(%rsp);
564         movq %r12, (2 * 8)(%rsp);
565         movq %r13, (3 * 8)(%rsp);
566         movq %r14, (4 * 8)(%rsp);
567         movq %r15, (5 * 8)(%rsp);
568         CFI_REL_OFFSET(%rbp, 0 * 8);
569         CFI_REL_OFFSET(%rbx, 1 * 8);
570         CFI_REL_OFFSET(%r12, 2 * 8);
571         CFI_REL_OFFSET(%r13, 3 * 8);
572         CFI_REL_OFFSET(%r14, 4 * 8);
573         CFI_REL_OFFSET(%r15, 5 * 8);
574
575         movq %rsi, (6 * 8)(%rsp);
576         movq %rdx, (7 * 8)(%rsp);
577         movq %rcx, RX0;
578
579         /* load IV and byteswap */
580         movq 8(RX0), RT0;
581         movq 0(RX0), RT1;
582         movq RT0, RCD0;
583         movq RT1, RAB0;
584         bswapq RT0;
585         bswapq RT1;
586
587         /* construct IVs */
588         movq RT0, RCD1;
589         movq RT1, RAB1;
590         movq RT0, RCD2;
591         movq RT1, RAB2;
592         addq $1, RCD1;
593         adcq $0, RAB1;
594         bswapq RCD1;
595         bswapq RAB1;
596         addq $2, RCD2;
597         adcq $0, RAB2;
598         bswapq RCD2;
599         bswapq RAB2;
600         addq $3, RT0;
601         adcq $0, RT1;
602         bswapq RT0;
603         bswapq RT1;
604
605         /* store new IV */
606         movq RT0, 8(RX0);
607         movq RT1, 0(RX0);
608
609         call __twofish_enc_blk3;
610
611         movq (7 * 8)(%rsp), RX0; /*src*/
612         movq (6 * 8)(%rsp), RX1; /*dst*/
613
614         /* XOR key-stream with plaintext */
615         xorq (0 * 8)(RX0), RCD0;
616         xorq (1 * 8)(RX0), RAB0;
617         xorq (2 * 8)(RX0), RCD1;
618         xorq (3 * 8)(RX0), RAB1;
619         xorq (4 * 8)(RX0), RCD2;
620         xorq (5 * 8)(RX0), RAB2;
621         movq RCD0, (0 * 8)(RX1);
622         movq RAB0, (1 * 8)(RX1);
623         movq RCD1, (2 * 8)(RX1);
624         movq RAB1, (3 * 8)(RX1);
625         movq RCD2, (4 * 8)(RX1);
626         movq RAB2, (5 * 8)(RX1);
627
628         movq (0 * 8)(%rsp), %rbp;
629         movq (1 * 8)(%rsp), %rbx;
630         movq (2 * 8)(%rsp), %r12;
631         movq (3 * 8)(%rsp), %r13;
632         movq (4 * 8)(%rsp), %r14;
633         movq (5 * 8)(%rsp), %r15;
634         CFI_RESTORE(%rbp);
635         CFI_RESTORE(%rbx);
636         CFI_RESTORE(%r12);
637         CFI_RESTORE(%r13);
638         CFI_RESTORE(%r14);
639         CFI_RESTORE(%r15);
640         addq $(8 * 8), %rsp;
641         CFI_ADJUST_CFA_OFFSET(-8 * 8);
642
643         EXIT_SYSV_FUNC
644         ret;
645         CFI_ENDPROC();
646 ELF(.size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;)
647
648 .align 8
649 .globl _gcry_twofish_amd64_cbc_dec
650 ELF(.type   _gcry_twofish_amd64_cbc_dec,@function;)
651 _gcry_twofish_amd64_cbc_dec:
652         /* input:
653          *      %rdi: ctx, CTX
654          *      %rsi: dst (3 blocks)
655          *      %rdx: src (3 blocks)
656          *      %rcx: iv (128bit)
657          */
658         CFI_STARTPROC();
659         ENTER_SYSV_FUNC_PARAMS_0_4
660
661         subq $(9 * 8), %rsp;
662         CFI_ADJUST_CFA_OFFSET(9 * 8);
663         movq %rbp, (0 * 8)(%rsp);
664         movq %rbx, (1 * 8)(%rsp);
665         movq %r12, (2 * 8)(%rsp);
666         movq %r13, (3 * 8)(%rsp);
667         movq %r14, (4 * 8)(%rsp);
668         movq %r15, (5 * 8)(%rsp);
669         CFI_REL_OFFSET(%rbp, 0 * 8);
670         CFI_REL_OFFSET(%rbx, 1 * 8);
671         CFI_REL_OFFSET(%r12, 2 * 8);
672         CFI_REL_OFFSET(%r13, 3 * 8);
673         CFI_REL_OFFSET(%r14, 4 * 8);
674         CFI_REL_OFFSET(%r15, 5 * 8);
675
676         movq %rsi, (6 * 8)(%rsp);
677         movq %rdx, (7 * 8)(%rsp);
678         movq %rcx, (8 * 8)(%rsp);
679         movq %rdx, RX0;
680
681         /* load input */
682         movq (0 * 8)(RX0), RAB0;
683         movq (1 * 8)(RX0), RCD0;
684         movq (2 * 8)(RX0), RAB1;
685         movq (3 * 8)(RX0), RCD1;
686         movq (4 * 8)(RX0), RAB2;
687         movq (5 * 8)(RX0), RCD2;
688
689         call __twofish_dec_blk3;
690
691         movq (8 * 8)(%rsp), RT0; /*iv*/
692         movq (7 * 8)(%rsp), RX0; /*src*/
693         movq (6 * 8)(%rsp), RX1; /*dst*/
694
695         movq (4 * 8)(RX0), RY0;
696         movq (5 * 8)(RX0), RY1;
697         xorq (0 * 8)(RT0), RCD0;
698         xorq (1 * 8)(RT0), RAB0;
699         xorq (0 * 8)(RX0), RCD1;
700         xorq (1 * 8)(RX0), RAB1;
701         xorq (2 * 8)(RX0), RCD2;
702         xorq (3 * 8)(RX0), RAB2;
703         movq RY0, (0 * 8)(RT0);
704         movq RY1, (1 * 8)(RT0);
705
706         movq RCD0, (0 * 8)(RX1);
707         movq RAB0, (1 * 8)(RX1);
708         movq RCD1, (2 * 8)(RX1);
709         movq RAB1, (3 * 8)(RX1);
710         movq RCD2, (4 * 8)(RX1);
711         movq RAB2, (5 * 8)(RX1);
712
713         movq (0 * 8)(%rsp), %rbp;
714         movq (1 * 8)(%rsp), %rbx;
715         movq (2 * 8)(%rsp), %r12;
716         movq (3 * 8)(%rsp), %r13;
717         movq (4 * 8)(%rsp), %r14;
718         movq (5 * 8)(%rsp), %r15;
719         CFI_RESTORE(%rbp);
720         CFI_RESTORE(%rbx);
721         CFI_RESTORE(%r12);
722         CFI_RESTORE(%r13);
723         CFI_RESTORE(%r14);
724         CFI_RESTORE(%r15);
725         addq $(9 * 8), %rsp;
726         CFI_ADJUST_CFA_OFFSET(-9 * 8);
727
728         EXIT_SYSV_FUNC
729         ret;
730         CFI_ENDPROC();
731 ELF(.size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;)
732
733 .align 8
734 .globl _gcry_twofish_amd64_cfb_dec
735 ELF(.type   _gcry_twofish_amd64_cfb_dec,@function;)
736 _gcry_twofish_amd64_cfb_dec:
737         /* input:
738          *      %rdi: ctx, CTX
739          *      %rsi: dst (3 blocks)
740          *      %rdx: src (3 blocks)
741          *      %rcx: iv (128bit)
742          */
743         CFI_STARTPROC();
744         ENTER_SYSV_FUNC_PARAMS_0_4
745
746         subq $(8 * 8), %rsp;
747         CFI_ADJUST_CFA_OFFSET(8 * 8);
748         movq %rbp, (0 * 8)(%rsp);
749         movq %rbx, (1 * 8)(%rsp);
750         movq %r12, (2 * 8)(%rsp);
751         movq %r13, (3 * 8)(%rsp);
752         movq %r14, (4 * 8)(%rsp);
753         movq %r15, (5 * 8)(%rsp);
754         CFI_REL_OFFSET(%rbp, 0 * 8);
755         CFI_REL_OFFSET(%rbx, 1 * 8);
756         CFI_REL_OFFSET(%r12, 2 * 8);
757         CFI_REL_OFFSET(%r13, 3 * 8);
758         CFI_REL_OFFSET(%r14, 4 * 8);
759         CFI_REL_OFFSET(%r15, 5 * 8);
760
761         movq %rsi, (6 * 8)(%rsp);
762         movq %rdx, (7 * 8)(%rsp);
763         movq %rdx, RX0;
764         movq %rcx, RX1;
765
766         /* load input */
767         movq (0 * 8)(RX1), RAB0;
768         movq (1 * 8)(RX1), RCD0;
769         movq (0 * 8)(RX0), RAB1;
770         movq (1 * 8)(RX0), RCD1;
771         movq (2 * 8)(RX0), RAB2;
772         movq (3 * 8)(RX0), RCD2;
773
774         /* Update IV */
775         movq (4 * 8)(RX0), RY0;
776         movq (5 * 8)(RX0), RY1;
777         movq RY0, (0 * 8)(RX1);
778         movq RY1, (1 * 8)(RX1);
779
780         call __twofish_enc_blk3;
781
782         movq (7 * 8)(%rsp), RX0; /*src*/
783         movq (6 * 8)(%rsp), RX1; /*dst*/
784
785         xorq (0 * 8)(RX0), RCD0;
786         xorq (1 * 8)(RX0), RAB0;
787         xorq (2 * 8)(RX0), RCD1;
788         xorq (3 * 8)(RX0), RAB1;
789         xorq (4 * 8)(RX0), RCD2;
790         xorq (5 * 8)(RX0), RAB2;
791         movq RCD0, (0 * 8)(RX1);
792         movq RAB0, (1 * 8)(RX1);
793         movq RCD1, (2 * 8)(RX1);
794         movq RAB1, (3 * 8)(RX1);
795         movq RCD2, (4 * 8)(RX1);
796         movq RAB2, (5 * 8)(RX1);
797
798         movq (0 * 8)(%rsp), %rbp;
799         movq (1 * 8)(%rsp), %rbx;
800         movq (2 * 8)(%rsp), %r12;
801         movq (3 * 8)(%rsp), %r13;
802         movq (4 * 8)(%rsp), %r14;
803         movq (5 * 8)(%rsp), %r15;
804         CFI_RESTORE(%rbp);
805         CFI_RESTORE(%rbx);
806         CFI_RESTORE(%r12);
807         CFI_RESTORE(%r13);
808         CFI_RESTORE(%r14);
809         CFI_RESTORE(%r15);
810         addq $(8 * 8), %rsp;
811         CFI_ADJUST_CFA_OFFSET(-8 * 8);
812
813         EXIT_SYSV_FUNC
814         ret;
815         CFI_ENDPROC();
816 ELF(.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;)
817
818 .align 8
819 .globl _gcry_twofish_amd64_ocb_enc
820 ELF(.type   _gcry_twofish_amd64_ocb_enc,@function;)
821 _gcry_twofish_amd64_ocb_enc:
822         /* input:
823          *      %rdi: ctx, CTX
824          *      %rsi: dst (3 blocks)
825          *      %rdx: src (3 blocks)
826          *      %rcx: offset
827          *      %r8 : checksum
828          *      %r9 : L pointers (void *L[3])
829          */
830         CFI_STARTPROC();
831         ENTER_SYSV_FUNC_PARAMS_6
832
833         subq $(8 * 8), %rsp;
834         CFI_ADJUST_CFA_OFFSET(8 * 8);
835         movq %rbp, (0 * 8)(%rsp);
836         movq %rbx, (1 * 8)(%rsp);
837         movq %r12, (2 * 8)(%rsp);
838         movq %r13, (3 * 8)(%rsp);
839         movq %r14, (4 * 8)(%rsp);
840         movq %r15, (5 * 8)(%rsp);
841         CFI_REL_OFFSET(%rbp, 0 * 8);
842         CFI_REL_OFFSET(%rbx, 1 * 8);
843         CFI_REL_OFFSET(%r12, 2 * 8);
844         CFI_REL_OFFSET(%r13, 3 * 8);
845         CFI_REL_OFFSET(%r14, 4 * 8);
846         CFI_REL_OFFSET(%r15, 5 * 8);
847
848         movq %rsi, (6 * 8)(%rsp);
849         movq %rdx, RX0;
850         movq %rcx, RX1;
851         movq %r8, RX2;
852         movq %r9, RY0;
853         movq %rsi, RY1;
854
855         /* Load offset */
856         movq (0 * 8)(RX1), RT0;
857         movq (1 * 8)(RX1), RT1;
858
859         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
860         movq (RY0), RY2;
861         xorq (0 * 8)(RY2), RT0;
862         xorq (1 * 8)(RY2), RT1;
863         movq (0 * 8)(RX0), RAB0;
864         movq (1 * 8)(RX0), RCD0;
865         /* Store Offset_i */
866         movq RT0, (0 * 8)(RY1);
867         movq RT1, (1 * 8)(RY1);
868         /* Checksum_i = Checksum_{i-1} xor P_i  */
869         xor RAB0, (0 * 8)(RX2);
870         xor RCD0, (1 * 8)(RX2);
871         /* PX_i = P_i xor Offset_i */
872         xorq RT0, RAB0;
873         xorq RT1, RCD0;
874
875         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
876         movq 8(RY0), RY2;
877         xorq (0 * 8)(RY2), RT0;
878         xorq (1 * 8)(RY2), RT1;
879         movq (2 * 8)(RX0), RAB1;
880         movq (3 * 8)(RX0), RCD1;
881         /* Store Offset_i */
882         movq RT0, (2 * 8)(RY1);
883         movq RT1, (3 * 8)(RY1);
884         /* Checksum_i = Checksum_{i-1} xor P_i  */
885         xor RAB1, (0 * 8)(RX2);
886         xor RCD1, (1 * 8)(RX2);
887         /* PX_i = P_i xor Offset_i */
888         xorq RT0, RAB1;
889         xorq RT1, RCD1;
890
891         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
892         movq 16(RY0), RY2;
893         xorq (0 * 8)(RY2), RT0;
894         xorq (1 * 8)(RY2), RT1;
895         movq (4 * 8)(RX0), RAB2;
896         movq (5 * 8)(RX0), RCD2;
897         /* Store Offset_i */
898         movq RT0, (4 * 8)(RY1);
899         movq RT1, (5 * 8)(RY1);
900         /* Checksum_i = Checksum_{i-1} xor P_i  */
901         xor RAB2, (0 * 8)(RX2);
902         xor RCD2, (1 * 8)(RX2);
903         /* PX_i = P_i xor Offset_i */
904         xorq RT0, RAB2;
905         xorq RT1, RCD2;
906
907         /* Store offset */
908         movq RT0, (0 * 8)(RX1);
909         movq RT1, (1 * 8)(RX1);
910
911         /* CX_i = ENCIPHER(K, PX_i)  */
912         call __twofish_enc_blk3;
913
914         movq (6 * 8)(%rsp), RX1; /*dst*/
915
916         /* C_i = CX_i xor Offset_i  */
917         xorq RCD0, (0 * 8)(RX1);
918         xorq RAB0, (1 * 8)(RX1);
919         xorq RCD1, (2 * 8)(RX1);
920         xorq RAB1, (3 * 8)(RX1);
921         xorq RCD2, (4 * 8)(RX1);
922         xorq RAB2, (5 * 8)(RX1);
923
924         movq (0 * 8)(%rsp), %rbp;
925         movq (1 * 8)(%rsp), %rbx;
926         movq (2 * 8)(%rsp), %r12;
927         movq (3 * 8)(%rsp), %r13;
928         movq (4 * 8)(%rsp), %r14;
929         movq (5 * 8)(%rsp), %r15;
930         CFI_RESTORE(%rbp);
931         CFI_RESTORE(%rbx);
932         CFI_RESTORE(%r12);
933         CFI_RESTORE(%r13);
934         CFI_RESTORE(%r14);
935         CFI_RESTORE(%r15);
936         addq $(8 * 8), %rsp;
937         CFI_ADJUST_CFA_OFFSET(-8 * 8);
938
939         EXIT_SYSV_FUNC
940         ret;
941         CFI_ENDPROC();
942 ELF(.size _gcry_twofish_amd64_ocb_enc,.-_gcry_twofish_amd64_ocb_enc;)
943
944 .align 8
945 .globl _gcry_twofish_amd64_ocb_dec
946 ELF(.type   _gcry_twofish_amd64_ocb_dec,@function;)
947 _gcry_twofish_amd64_ocb_dec:
948         /* input:
949          *      %rdi: ctx, CTX
950          *      %rsi: dst (3 blocks)
951          *      %rdx: src (3 blocks)
952          *      %rcx: offset
953          *      %r8 : checksum
954          *      %r9 : L pointers (void *L[3])
955          */
956         CFI_STARTPROC();
957         ENTER_SYSV_FUNC_PARAMS_6
958
959         subq $(8 * 8), %rsp;
960         CFI_ADJUST_CFA_OFFSET(8 * 8);
961         movq %rbp, (0 * 8)(%rsp);
962         movq %rbx, (1 * 8)(%rsp);
963         movq %r12, (2 * 8)(%rsp);
964         movq %r13, (3 * 8)(%rsp);
965         movq %r14, (4 * 8)(%rsp);
966         movq %r15, (5 * 8)(%rsp);
967         CFI_REL_OFFSET(%rbp, 0 * 8);
968         CFI_REL_OFFSET(%rbx, 1 * 8);
969         CFI_REL_OFFSET(%r12, 2 * 8);
970         CFI_REL_OFFSET(%r13, 3 * 8);
971         CFI_REL_OFFSET(%r14, 4 * 8);
972         CFI_REL_OFFSET(%r15, 5 * 8);
973
974         movq %rsi, (6 * 8)(%rsp);
975         movq %r8,  (7 * 8)(%rsp);
976         movq %rdx, RX0;
977         movq %rcx, RX1;
978         movq %r9, RY0;
979         movq %rsi, RY1;
980
981         /* Load offset */
982         movq (0 * 8)(RX1), RT0;
983         movq (1 * 8)(RX1), RT1;
984
985         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
986         movq (RY0), RY2;
987         xorq (0 * 8)(RY2), RT0;
988         xorq (1 * 8)(RY2), RT1;
989         movq (0 * 8)(RX0), RAB0;
990         movq (1 * 8)(RX0), RCD0;
991         /* Store Offset_i */
992         movq RT0, (0 * 8)(RY1);
993         movq RT1, (1 * 8)(RY1);
994         /* CX_i = C_i xor Offset_i */
995         xorq RT0, RAB0;
996         xorq RT1, RCD0;
997
998         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
999         movq 8(RY0), RY2;
1000         xorq (0 * 8)(RY2), RT0;
1001         xorq (1 * 8)(RY2), RT1;
1002         movq (2 * 8)(RX0), RAB1;
1003         movq (3 * 8)(RX0), RCD1;
1004         /* Store Offset_i */
1005         movq RT0, (2 * 8)(RY1);
1006         movq RT1, (3 * 8)(RY1);
1007         /* PX_i = P_i xor Offset_i */
1008         xorq RT0, RAB1;
1009         xorq RT1, RCD1;
1010
1011         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1012         movq 16(RY0), RY2;
1013         xorq (0 * 8)(RY2), RT0;
1014         xorq (1 * 8)(RY2), RT1;
1015         movq (4 * 8)(RX0), RAB2;
1016         movq (5 * 8)(RX0), RCD2;
1017         /* Store Offset_i */
1018         movq RT0, (4 * 8)(RY1);
1019         movq RT1, (5 * 8)(RY1);
1020         /* PX_i = P_i xor Offset_i */
1021         xorq RT0, RAB2;
1022         xorq RT1, RCD2;
1023
1024         /* Store offset */
1025         movq RT0, (0 * 8)(RX1);
1026         movq RT1, (1 * 8)(RX1);
1027
1028         /* PX_i = DECIPHER(K, CX_i)  */
1029         call __twofish_dec_blk3;
1030
1031         movq (7 * 8)(%rsp), RX2; /*checksum*/
1032         movq (6 * 8)(%rsp), RX1; /*dst*/
1033
1034         /* Load checksum */
1035         movq (0 * 8)(RX2), RT0;
1036         movq (1 * 8)(RX2), RT1;
1037
1038         /* P_i = PX_i xor Offset_i  */
1039         xorq RCD0, (0 * 8)(RX1);
1040         xorq RAB0, (1 * 8)(RX1);
1041         xorq RCD1, (2 * 8)(RX1);
1042         xorq RAB1, (3 * 8)(RX1);
1043         xorq RCD2, (4 * 8)(RX1);
1044         xorq RAB2, (5 * 8)(RX1);
1045
1046         /* Checksum_i = Checksum_{i-1} xor P_i  */
1047         xorq (0 * 8)(RX1), RT0;
1048         xorq (1 * 8)(RX1), RT1;
1049         xorq (2 * 8)(RX1), RT0;
1050         xorq (3 * 8)(RX1), RT1;
1051         xorq (4 * 8)(RX1), RT0;
1052         xorq (5 * 8)(RX1), RT1;
1053
1054         /* Store checksum */
1055         movq RT0, (0 * 8)(RX2);
1056         movq RT1, (1 * 8)(RX2);
1057
1058         movq (0 * 8)(%rsp), %rbp;
1059         movq (1 * 8)(%rsp), %rbx;
1060         movq (2 * 8)(%rsp), %r12;
1061         movq (3 * 8)(%rsp), %r13;
1062         movq (4 * 8)(%rsp), %r14;
1063         movq (5 * 8)(%rsp), %r15;
1064         CFI_RESTORE(%rbp);
1065         CFI_RESTORE(%rbx);
1066         CFI_RESTORE(%r12);
1067         CFI_RESTORE(%r13);
1068         CFI_RESTORE(%r14);
1069         CFI_RESTORE(%r15);
1070         addq $(8 * 8), %rsp;
1071         CFI_ADJUST_CFA_OFFSET(-8 * 8);
1072
1073         EXIT_SYSV_FUNC
1074         ret;
1075         CFI_ENDPROC();
1076 ELF(.size _gcry_twofish_amd64_ocb_dec,.-_gcry_twofish_amd64_ocb_dec;)
1077
1078 .align 8
1079 .globl _gcry_twofish_amd64_ocb_auth
1080 ELF(.type   _gcry_twofish_amd64_ocb_auth,@function;)
1081 _gcry_twofish_amd64_ocb_auth:
1082         /* input:
1083          *      %rdi: ctx, CTX
1084          *      %rsi: abuf (3 blocks)
1085          *      %rdx: offset
1086          *      %rcx: checksum
1087          *      %r8 : L pointers (void *L[3])
1088          */
1089         CFI_STARTPROC();
1090         ENTER_SYSV_FUNC_PARAMS_5
1091
1092         subq $(8 * 8), %rsp;
1093         CFI_ADJUST_CFA_OFFSET(8 * 8);
1094         movq %rbp, (0 * 8)(%rsp);
1095         movq %rbx, (1 * 8)(%rsp);
1096         movq %r12, (2 * 8)(%rsp);
1097         movq %r13, (3 * 8)(%rsp);
1098         movq %r14, (4 * 8)(%rsp);
1099         movq %r15, (5 * 8)(%rsp);
1100         CFI_REL_OFFSET(%rbp, 0 * 8);
1101         CFI_REL_OFFSET(%rbx, 1 * 8);
1102         CFI_REL_OFFSET(%r12, 2 * 8);
1103         CFI_REL_OFFSET(%r13, 3 * 8);
1104         CFI_REL_OFFSET(%r14, 4 * 8);
1105         CFI_REL_OFFSET(%r15, 5 * 8);
1106
1107         movq %rcx, (6 * 8)(%rsp);
1108         movq %rsi, RX0;
1109         movq %rdx, RX1;
1110         movq %r8, RY0;
1111
1112         /* Load offset */
1113         movq (0 * 8)(RX1), RT0;
1114         movq (1 * 8)(RX1), RT1;
1115
1116         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1117         movq (RY0), RY2;
1118         xorq (0 * 8)(RY2), RT0;
1119         xorq (1 * 8)(RY2), RT1;
1120         movq (0 * 8)(RX0), RAB0;
1121         movq (1 * 8)(RX0), RCD0;
1122         /* PX_i = P_i xor Offset_i */
1123         xorq RT0, RAB0;
1124         xorq RT1, RCD0;
1125
1126         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1127         movq 8(RY0), RY2;
1128         xorq (0 * 8)(RY2), RT0;
1129         xorq (1 * 8)(RY2), RT1;
1130         movq (2 * 8)(RX0), RAB1;
1131         movq (3 * 8)(RX0), RCD1;
1132         /* PX_i = P_i xor Offset_i */
1133         xorq RT0, RAB1;
1134         xorq RT1, RCD1;
1135
1136         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1137         movq 16(RY0), RY2;
1138         xorq (0 * 8)(RY2), RT0;
1139         xorq (1 * 8)(RY2), RT1;
1140         movq (4 * 8)(RX0), RAB2;
1141         movq (5 * 8)(RX0), RCD2;
1142         /* PX_i = P_i xor Offset_i */
1143         xorq RT0, RAB2;
1144         xorq RT1, RCD2;
1145
1146         /* Store offset */
1147         movq RT0, (0 * 8)(RX1);
1148         movq RT1, (1 * 8)(RX1);
1149
1150         /* C_i = ENCIPHER(K, PX_i)  */
1151         call __twofish_enc_blk3;
1152
1153         movq (6 * 8)(%rsp), RX1; /*checksum*/
1154
1155         /* Checksum_i = C_i xor Checksum_i  */
1156         xorq RCD0, RCD1;
1157         xorq RAB0, RAB1;
1158         xorq RCD1, RCD2;
1159         xorq RAB1, RAB2;
1160         xorq RCD2, (0 * 8)(RX1);
1161         xorq RAB2, (1 * 8)(RX1);
1162
1163         movq (0 * 8)(%rsp), %rbp;
1164         movq (1 * 8)(%rsp), %rbx;
1165         movq (2 * 8)(%rsp), %r12;
1166         movq (3 * 8)(%rsp), %r13;
1167         movq (4 * 8)(%rsp), %r14;
1168         movq (5 * 8)(%rsp), %r15;
1169         CFI_RESTORE(%rbp);
1170         CFI_RESTORE(%rbx);
1171         CFI_RESTORE(%r12);
1172         CFI_RESTORE(%r13);
1173         CFI_RESTORE(%r14);
1174         CFI_RESTORE(%r15);
1175         addq $(8 * 8), %rsp;
1176         CFI_ADJUST_CFA_OFFSET(-8 * 8);
1177
1178         EXIT_SYSV_FUNC
1179         ret;
1180         CFI_ENDPROC();
1181 ELF(.size _gcry_twofish_amd64_ocb_auth,.-_gcry_twofish_amd64_ocb_auth;)
1182
1183 #endif /*USE_TWOFISH*/
1184 #endif /*__x86_64*/