GCM: GHASH optimizations
[libgcrypt.git] / cipher / twofish-amd64.S
1 /* twofish-amd64.S  -  AMD64 assembly implementation of Twofish cipher
2  *
3  * Copyright © 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_TWOFISH)
24
25 #ifdef __PIC__
26 #  define RIP %rip
27 #else
28 #  define RIP
29 #endif
30
31 .text
32
33 /* structure of TWOFISH_context: */
34 #define s0 0
35 #define s1 ((s0) + 4 * 256)
36 #define s2 ((s1) + 4 * 256)
37 #define s3 ((s2) + 4 * 256)
38 #define w  ((s3) + 4 * 256)
39 #define k  ((w) + 4 * 8)
40
41 /* register macros */
42 #define CTX     %rdi
43
44 #define RA      %rax
45 #define RB      %rbx
46 #define RC      %rcx
47 #define RD      %rdx
48
49 #define RAd     %eax
50 #define RBd     %ebx
51 #define RCd     %ecx
52 #define RDd     %edx
53
54 #define RAbl    %al
55 #define RBbl    %bl
56 #define RCbl    %cl
57 #define RDbl    %dl
58
59 #define RAbh    %ah
60 #define RBbh    %bh
61 #define RCbh    %ch
62 #define RDbh    %dh
63
64 #define RX      %r8
65 #define RY      %r9
66
67 #define RXd     %r8d
68 #define RYd     %r9d
69
70 #define RT0     %rsi
71 #define RT1     %rbp
72 #define RT2     %r10
73 #define RT3     %r11
74
75 #define RT0d    %esi
76 #define RT1d    %ebp
77 #define RT2d    %r10d
78 #define RT3d    %r11d
79
80 /***********************************************************************
81  * AMD64 assembly implementation of the Twofish cipher
82  ***********************************************************************/
83 #define enc_g1_2(a, b, x, y) \
84         movzbl b ## bl, RT3d; \
85         movzbl b ## bh, RT1d; \
86         movzbl a ## bl, RT2d; \
87         movzbl a ## bh, RT0d; \
88         rorl $16, b ## d; \
89         rorl $16, a ## d; \
90         movl s1(CTX, RT3, 4), RYd; \
91         movzbl b ## bl, RT3d; \
92         movl s0(CTX, RT2, 4), RXd; \
93         movzbl a ## bl, RT2d; \
94         xorl s2(CTX, RT1, 4), RYd; \
95         movzbl b ## bh, RT1d; \
96         xorl s1(CTX, RT0, 4), RXd; \
97         movzbl a ## bh, RT0d; \
98         rorl $16, b ## d; \
99         rorl $16, a ## d; \
100         xorl s3(CTX, RT3, 4), RYd; \
101         xorl s2(CTX, RT2, 4), RXd; \
102         xorl s0(CTX, RT1, 4), RYd; \
103         xorl s3(CTX, RT0, 4), RXd;
104
105 #define dec_g1_2(a, b, x, y) \
106         movzbl a ## bl, RT2d; \
107         movzbl a ## bh, RT0d; \
108         movzbl b ## bl, RT3d; \
109         movzbl b ## bh, RT1d; \
110         rorl $16, a ## d; \
111         rorl $16, b ## d; \
112         movl s0(CTX, RT2, 4), RXd; \
113         movzbl a ## bl, RT2d; \
114         movl s1(CTX, RT3, 4), RYd; \
115         movzbl b ## bl, RT3d; \
116         xorl s1(CTX, RT0, 4), RXd; \
117         movzbl a ## bh, RT0d; \
118         xorl s2(CTX, RT1, 4), RYd; \
119         movzbl b ## bh, RT1d; \
120         rorl $16, a ## d; \
121         rorl $16, b ## d; \
122         xorl s2(CTX, RT2, 4), RXd; \
123         xorl s3(CTX, RT3, 4), RYd; \
124         xorl s3(CTX, RT0, 4), RXd; \
125         xorl s0(CTX, RT1, 4), RYd;
126
127 #define encrypt_round(ra, rb, rc, rd, n) \
128         enc_g1_2(##ra, ##rb, RX, RY); \
129         \
130         leal (RXd, RYd, 2), RT0d; \
131         addl RYd, RXd; \
132         addl (k + 8 * (n) + 4)(CTX), RT0d; \
133         roll $1, rd ## d; \
134         addl (k + 8 * (n))(CTX), RXd; \
135         xorl RT0d, rd ## d; \
136         xorl RXd, rc ## d; \
137         rorl $1, rc ## d;
138
139 #define decrypt_round(ra, rb, rc, rd, n) \
140         dec_g1_2(##ra, ##rb, RX, RY); \
141         \
142         leal (RXd, RYd, 2), RT0d; \
143         addl RYd, RXd; \
144         addl (k + 8 * (n) + 4)(CTX), RT0d; \
145         roll $1, rc ## d; \
146         addl (k + 8 * (n))(CTX), RXd; \
147         xorl RXd, rc ## d; \
148         xorl RT0d, rd ## d; \
149         rorl $1, rd ## d;
150
151 #define encrypt_cycle(a, b, c, d, nc) \
152         encrypt_round(##a, ##b, ##c, ##d, (nc) * 2); \
153         encrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1);
154
155 #define decrypt_cycle(a, b, c, d, nc) \
156         decrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1); \
157         decrypt_round(##a, ##b, ##c, ##d, (nc) * 2);
158
159 #define inpack(in, n, x, m) \
160         movl (4 * (n))(in), x; \
161         xorl (w + 4 * (m))(CTX), x;
162
163 #define outunpack(out, n, x, m) \
164         xorl (w + 4 * (m))(CTX), x; \
165         movl x, (4 * (n))(out);
166
167 .align 8
168 .globl _gcry_twofish_amd64_encrypt_block
169 .type   _gcry_twofish_amd64_encrypt_block,@function;
170
171 _gcry_twofish_amd64_encrypt_block:
172         /* input:
173          *      %rdi: context, CTX
174          *      %rsi: dst
175          *      %rdx: src
176          */
177         subq $(3 * 8), %rsp;
178         movq %rsi, (0 * 8)(%rsp);
179         movq %rbp, (1 * 8)(%rsp);
180         movq %rbx, (2 * 8)(%rsp);
181
182         movq %rdx, RX;
183         inpack(RX, 0, RAd, 0);
184         inpack(RX, 1, RBd, 1);
185         inpack(RX, 2, RCd, 2);
186         inpack(RX, 3, RDd, 3);
187
188         encrypt_cycle(RA, RB, RC, RD, 0);
189         encrypt_cycle(RA, RB, RC, RD, 1);
190         encrypt_cycle(RA, RB, RC, RD, 2);
191         encrypt_cycle(RA, RB, RC, RD, 3);
192         encrypt_cycle(RA, RB, RC, RD, 4);
193         encrypt_cycle(RA, RB, RC, RD, 5);
194         encrypt_cycle(RA, RB, RC, RD, 6);
195         encrypt_cycle(RA, RB, RC, RD, 7);
196
197         movq (0 * 8)(%rsp), RX; /*dst*/
198         outunpack(RX, 0, RCd, 4);
199         outunpack(RX, 1, RDd, 5);
200         outunpack(RX, 2, RAd, 6);
201         outunpack(RX, 3, RBd, 7);
202
203         movq (2 * 8)(%rsp), %rbx;
204         movq (1 * 8)(%rsp), %rbp;
205         addq $(3 * 8), %rsp;
206
207         ret;
208 .size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;
209
210 .align 8
211 .globl _gcry_twofish_amd64_decrypt_block
212 .type   _gcry_twofish_amd64_decrypt_block,@function;
213
214 _gcry_twofish_amd64_decrypt_block:
215         /* input:
216          *      %rdi: context, CTX
217          *      %rsi: dst
218          *      %rdx: src
219          */
220         subq $(3 * 8), %rsp;
221         movq %rsi, (0 * 8)(%rsp);
222         movq %rbp, (1 * 8)(%rsp);
223         movq %rbx, (2 * 8)(%rsp);
224
225         movq %rdx, RX;
226         inpack(RX, 0, RCd, 4);
227         inpack(RX, 1, RDd, 5);
228         inpack(RX, 2, RAd, 6);
229         inpack(RX, 3, RBd, 7);
230
231         decrypt_cycle(RA, RB, RC, RD, 7);
232         decrypt_cycle(RA, RB, RC, RD, 6);
233         decrypt_cycle(RA, RB, RC, RD, 5);
234         decrypt_cycle(RA, RB, RC, RD, 4);
235         decrypt_cycle(RA, RB, RC, RD, 3);
236         decrypt_cycle(RA, RB, RC, RD, 2);
237         decrypt_cycle(RA, RB, RC, RD, 1);
238         decrypt_cycle(RA, RB, RC, RD, 0);
239
240         movq (0 * 8)(%rsp), RX; /*dst*/
241         outunpack(RX, 0, RAd, 0);
242         outunpack(RX, 1, RBd, 1);
243         outunpack(RX, 2, RCd, 2);
244         outunpack(RX, 3, RDd, 3);
245
246         movq (2 * 8)(%rsp), %rbx;
247         movq (1 * 8)(%rsp), %rbp;
248         addq $(3 * 8), %rsp;
249
250         ret;
251 .size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;
252
253 #undef CTX
254
255 #undef RA
256 #undef RB
257 #undef RC
258 #undef RD
259
260 #undef RAd
261 #undef RBd
262 #undef RCd
263 #undef RDd
264
265 #undef RAbl
266 #undef RBbl
267 #undef RCbl
268 #undef RDbl
269
270 #undef RAbh
271 #undef RBbh
272 #undef RCbh
273 #undef RDbh
274
275 #undef RX
276 #undef RY
277
278 #undef RXd
279 #undef RYd
280
281 #undef RT0
282 #undef RT1
283 #undef RT2
284 #undef RT3
285
286 #undef RT0d
287 #undef RT1d
288 #undef RT2d
289 #undef RT3d
290
291 /***********************************************************************
292  * AMD64 assembly implementation of the Twofish cipher, 3-way parallel
293  ***********************************************************************/
294 #define CTX %rdi
295 #define RIO %rdx
296
297 #define RAB0 %rax
298 #define RAB1 %rbx
299 #define RAB2 %rcx
300
301 #define RAB0d %eax
302 #define RAB1d %ebx
303 #define RAB2d %ecx
304
305 #define RAB0bh %ah
306 #define RAB1bh %bh
307 #define RAB2bh %ch
308
309 #define RAB0bl %al
310 #define RAB1bl %bl
311 #define RAB2bl %cl
312
313 #define RCD0 %r8
314 #define RCD1 %r9
315 #define RCD2 %r10
316
317 #define RCD0d %r8d
318 #define RCD1d %r9d
319 #define RCD2d %r10d
320
321 #define RX0 %rbp
322 #define RX1 %r11
323 #define RX2 %r12
324
325 #define RX0d %ebp
326 #define RX1d %r11d
327 #define RX2d %r12d
328
329 #define RY0 %r13
330 #define RY1 %r14
331 #define RY2 %r15
332
333 #define RY0d %r13d
334 #define RY1d %r14d
335 #define RY2d %r15d
336
337 #define RT0 %rdx
338 #define RT1 %rsi
339
340 #define RT0d %edx
341 #define RT1d %esi
342
343 #define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
344         movzbl ab ## bl,                tmp2 ## d; \
345         movzbl ab ## bh,                tmp1 ## d; \
346         rorq $(rot),                    ab; \
347         op1##l T0(CTX, tmp2, 4),        dst ## d; \
348         op2##l T1(CTX, tmp1, 4),        dst ## d;
349
350 /*
351  * Combined G1 & G2 function. Reordered with help of rotates to have moves
352  * at beginning.
353  */
354 #define g1g2_3(ab, cd, Tx0, Tx1, Tx2, Tx3, Ty0, Ty1, Ty2, Ty3, x, y) \
355         /* G1,1 && G2,1 */ \
356         do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 0, ab ## 0, x ## 0); \
357         do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 0, ab ## 0, y ## 0); \
358         \
359         do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 1, ab ## 1, x ## 1); \
360         do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 1, ab ## 1, y ## 1); \
361         \
362         do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 2, ab ## 2, x ## 2); \
363         do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 2, ab ## 2, y ## 2); \
364         \
365         /* G1,2 && G2,2 */ \
366         do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
367         do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
368         xchgq cd ## 0, ab ## 0; \
369         \
370         do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
371         do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
372         xchgq cd ## 1, ab ## 1; \
373         \
374         do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
375         do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
376         xchgq cd ## 2, ab ## 2;
377
378 #define enc_round_end(ab, x, y, n) \
379         addl y ## d,                    x ## d; \
380         addl x ## d,                    y ## d; \
381         addl k+4*(2*(n))(CTX),          x ## d; \
382         xorl ab ## d,                   x ## d; \
383         addl k+4*(2*(n)+1)(CTX),        y ## d; \
384         shrq $32,                       ab; \
385         roll $1,                        ab ## d; \
386         xorl y ## d,                    ab ## d; \
387         shlq $32,                       ab; \
388         rorl $1,                        x ## d; \
389         orq x,                          ab;
390
391 #define dec_round_end(ba, x, y, n) \
392         addl y ## d,                    x ## d; \
393         addl x ## d,                    y ## d; \
394         addl k+4*(2*(n))(CTX),          x ## d; \
395         addl k+4*(2*(n)+1)(CTX),        y ## d; \
396         xorl ba ## d,                   y ## d; \
397         shrq $32,                       ba; \
398         roll $1,                        ba ## d; \
399         xorl x ## d,                    ba ## d; \
400         shlq $32,                       ba; \
401         rorl $1,                        y ## d; \
402         orq y,                          ba;
403
404 #define encrypt_round3(ab, cd, n) \
405         g1g2_3(ab, cd, s0, s1, s2, s3, s0, s1, s2, s3, RX, RY); \
406         \
407         enc_round_end(ab ## 0, RX0, RY0, n); \
408         enc_round_end(ab ## 1, RX1, RY1, n); \
409         enc_round_end(ab ## 2, RX2, RY2, n);
410
411 #define decrypt_round3(ba, dc, n) \
412         g1g2_3(ba, dc, s1, s2, s3, s0, s3, s0, s1, s2, RY, RX); \
413         \
414         dec_round_end(ba ## 0, RX0, RY0, n); \
415         dec_round_end(ba ## 1, RX1, RY1, n); \
416         dec_round_end(ba ## 2, RX2, RY2, n);
417
418 #define encrypt_cycle3(ab, cd, n) \
419         encrypt_round3(ab, cd, n*2); \
420         encrypt_round3(ab, cd, (n*2)+1);
421
422 #define decrypt_cycle3(ba, dc, n) \
423         decrypt_round3(ba, dc, (n*2)+1); \
424         decrypt_round3(ba, dc, (n*2));
425
426 #define inpack3(xy, m) \
427         xorq w+4*m(CTX),                xy ## 0; \
428         xorq w+4*m(CTX),                xy ## 1; \
429         xorq w+4*m(CTX),                xy ## 2;
430
431 #define outunpack3(xy, m) \
432         xorq w+4*m(CTX),                xy ## 0; \
433         xorq w+4*m(CTX),                xy ## 1; \
434         xorq w+4*m(CTX),                xy ## 2;
435
436 #define inpack_enc3() \
437         inpack3(RAB, 0); \
438         inpack3(RCD, 2);
439
440 #define outunpack_enc3() \
441         outunpack3(RAB, 6); \
442         outunpack3(RCD, 4);
443
444 #define inpack_dec3() \
445         inpack3(RAB, 4); \
446         rorq $32,                       RAB0; \
447         rorq $32,                       RAB1; \
448         rorq $32,                       RAB2; \
449         inpack3(RCD, 6); \
450         rorq $32,                       RCD0; \
451         rorq $32,                       RCD1; \
452         rorq $32,                       RCD2;
453
454 #define outunpack_dec3() \
455         rorq $32,                       RCD0; \
456         rorq $32,                       RCD1; \
457         rorq $32,                       RCD2; \
458         outunpack3(RCD, 0); \
459         rorq $32,                       RAB0; \
460         rorq $32,                       RAB1; \
461         rorq $32,                       RAB2; \
462         outunpack3(RAB, 2);
463
464 .align 8
465 .type __twofish_enc_blk3,@function;
466
467 __twofish_enc_blk3:
468         /* input:
469          *      %rdi: ctx, CTX
470          *      RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three plaintext blocks
471          * output:
472          *      RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three ciphertext blocks
473          */
474         inpack_enc3();
475
476         encrypt_cycle3(RAB, RCD, 0);
477         encrypt_cycle3(RAB, RCD, 1);
478         encrypt_cycle3(RAB, RCD, 2);
479         encrypt_cycle3(RAB, RCD, 3);
480         encrypt_cycle3(RAB, RCD, 4);
481         encrypt_cycle3(RAB, RCD, 5);
482         encrypt_cycle3(RAB, RCD, 6);
483         encrypt_cycle3(RAB, RCD, 7);
484
485         outunpack_enc3();
486
487         ret;
488 .size __twofish_enc_blk3,.-__twofish_enc_blk3;
489
490 .align 8
491 .type  __twofish_dec_blk3,@function;
492
493 __twofish_dec_blk3:
494         /* input:
495          *      %rdi: ctx, CTX
496          *      RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three ciphertext blocks
497          * output:
498          *      RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three plaintext blocks
499          */
500         inpack_dec3();
501
502         decrypt_cycle3(RAB, RCD, 7);
503         decrypt_cycle3(RAB, RCD, 6);
504         decrypt_cycle3(RAB, RCD, 5);
505         decrypt_cycle3(RAB, RCD, 4);
506         decrypt_cycle3(RAB, RCD, 3);
507         decrypt_cycle3(RAB, RCD, 2);
508         decrypt_cycle3(RAB, RCD, 1);
509         decrypt_cycle3(RAB, RCD, 0);
510
511         outunpack_dec3();
512
513         ret;
514 .size __twofish_dec_blk3,.-__twofish_dec_blk3;
515
516 .align 8
517 .globl _gcry_twofish_amd64_ctr_enc
518 .type   _gcry_twofish_amd64_ctr_enc,@function;
519 _gcry_twofish_amd64_ctr_enc:
520         /* input:
521          *      %rdi: ctx, CTX
522          *      %rsi: dst (3 blocks)
523          *      %rdx: src (3 blocks)
524          *      %rcx: iv (big endian, 128bit)
525          */
526         subq $(8 * 8), %rsp;
527         movq %rbp, (0 * 8)(%rsp);
528         movq %rbx, (1 * 8)(%rsp);
529         movq %r12, (2 * 8)(%rsp);
530         movq %r13, (3 * 8)(%rsp);
531         movq %r14, (4 * 8)(%rsp);
532         movq %r15, (5 * 8)(%rsp);
533
534         movq %rsi, (6 * 8)(%rsp);
535         movq %rdx, (7 * 8)(%rsp);
536         movq %rcx, RX0;
537
538         /* load IV and byteswap */
539         movq 8(RX0), RT0;
540         movq 0(RX0), RT1;
541         movq RT0, RCD0;
542         movq RT1, RAB0;
543         bswapq RT0;
544         bswapq RT1;
545
546         /* construct IVs */
547         movq RT0, RCD1;
548         movq RT1, RAB1;
549         movq RT0, RCD2;
550         movq RT1, RAB2;
551         addq $1, RCD1;
552         adcq $0, RAB1;
553         bswapq RCD1;
554         bswapq RAB1;
555         addq $2, RCD2;
556         adcq $0, RAB2;
557         bswapq RCD2;
558         bswapq RAB2;
559         addq $3, RT0;
560         adcq $0, RT1;
561         bswapq RT0;
562         bswapq RT1;
563
564         /* store new IV */
565         movq RT0, 8(RX0);
566         movq RT1, 0(RX0);
567
568         call __twofish_enc_blk3;
569
570         movq (7 * 8)(%rsp), RX0; /*src*/
571         movq (6 * 8)(%rsp), RX1; /*dst*/
572
573         /* XOR key-stream with plaintext */
574         xorq (0 * 8)(RX0), RCD0;
575         xorq (1 * 8)(RX0), RAB0;
576         xorq (2 * 8)(RX0), RCD1;
577         xorq (3 * 8)(RX0), RAB1;
578         xorq (4 * 8)(RX0), RCD2;
579         xorq (5 * 8)(RX0), RAB2;
580         movq RCD0, (0 * 8)(RX1);
581         movq RAB0, (1 * 8)(RX1);
582         movq RCD1, (2 * 8)(RX1);
583         movq RAB1, (3 * 8)(RX1);
584         movq RCD2, (4 * 8)(RX1);
585         movq RAB2, (5 * 8)(RX1);
586
587         movq (0 * 8)(%rsp), %rbp;
588         movq (1 * 8)(%rsp), %rbx;
589         movq (2 * 8)(%rsp), %r12;
590         movq (3 * 8)(%rsp), %r13;
591         movq (4 * 8)(%rsp), %r14;
592         movq (5 * 8)(%rsp), %r15;
593         addq $(8 * 8), %rsp;
594
595         ret;
596 .size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;
597
598 .align 8
599 .globl _gcry_twofish_amd64_cbc_dec
600 .type   _gcry_twofish_amd64_cbc_dec,@function;
601 _gcry_twofish_amd64_cbc_dec:
602         /* input:
603          *      %rdi: ctx, CTX
604          *      %rsi: dst (3 blocks)
605          *      %rdx: src (3 blocks)
606          *      %rcx: iv (128bit)
607          */
608         subq $(9 * 8), %rsp;
609         movq %rbp, (0 * 8)(%rsp);
610         movq %rbx, (1 * 8)(%rsp);
611         movq %r12, (2 * 8)(%rsp);
612         movq %r13, (3 * 8)(%rsp);
613         movq %r14, (4 * 8)(%rsp);
614         movq %r15, (5 * 8)(%rsp);
615
616         movq %rsi, (6 * 8)(%rsp);
617         movq %rdx, (7 * 8)(%rsp);
618         movq %rcx, (8 * 8)(%rsp);
619         movq %rdx, RX0;
620
621         /* load input */
622         movq (0 * 8)(RX0), RAB0;
623         movq (1 * 8)(RX0), RCD0;
624         movq (2 * 8)(RX0), RAB1;
625         movq (3 * 8)(RX0), RCD1;
626         movq (4 * 8)(RX0), RAB2;
627         movq (5 * 8)(RX0), RCD2;
628
629         call __twofish_dec_blk3;
630
631         movq (8 * 8)(%rsp), RT0; /*iv*/
632         movq (7 * 8)(%rsp), RX0; /*src*/
633         movq (6 * 8)(%rsp), RX1; /*dst*/
634
635         movq (4 * 8)(RX0), RY0;
636         movq (5 * 8)(RX0), RY1;
637         xorq (0 * 8)(RT0), RCD0;
638         xorq (1 * 8)(RT0), RAB0;
639         xorq (0 * 8)(RX0), RCD1;
640         xorq (1 * 8)(RX0), RAB1;
641         xorq (2 * 8)(RX0), RCD2;
642         xorq (3 * 8)(RX0), RAB2;
643         movq RY0, (0 * 8)(RT0);
644         movq RY1, (1 * 8)(RT0);
645
646         movq RCD0, (0 * 8)(RX1);
647         movq RAB0, (1 * 8)(RX1);
648         movq RCD1, (2 * 8)(RX1);
649         movq RAB1, (3 * 8)(RX1);
650         movq RCD2, (4 * 8)(RX1);
651         movq RAB2, (5 * 8)(RX1);
652
653         movq (0 * 8)(%rsp), %rbp;
654         movq (1 * 8)(%rsp), %rbx;
655         movq (2 * 8)(%rsp), %r12;
656         movq (3 * 8)(%rsp), %r13;
657         movq (4 * 8)(%rsp), %r14;
658         movq (5 * 8)(%rsp), %r15;
659         addq $(9 * 8), %rsp;
660
661         ret;
662 .size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;
663
664 .align 8
665 .globl _gcry_twofish_amd64_cfb_dec
666 .type   _gcry_twofish_amd64_cfb_dec,@function;
667 _gcry_twofish_amd64_cfb_dec:
668         /* input:
669          *      %rdi: ctx, CTX
670          *      %rsi: dst (3 blocks)
671          *      %rdx: src (3 blocks)
672          *      %rcx: iv (128bit)
673          */
674         subq $(8 * 8), %rsp;
675         movq %rbp, (0 * 8)(%rsp);
676         movq %rbx, (1 * 8)(%rsp);
677         movq %r12, (2 * 8)(%rsp);
678         movq %r13, (3 * 8)(%rsp);
679         movq %r14, (4 * 8)(%rsp);
680         movq %r15, (5 * 8)(%rsp);
681
682         movq %rsi, (6 * 8)(%rsp);
683         movq %rdx, (7 * 8)(%rsp);
684         movq %rdx, RX0;
685         movq %rcx, RX1;
686
687         /* load input */
688         movq (0 * 8)(RX1), RAB0;
689         movq (1 * 8)(RX1), RCD0;
690         movq (0 * 8)(RX0), RAB1;
691         movq (1 * 8)(RX0), RCD1;
692         movq (2 * 8)(RX0), RAB2;
693         movq (3 * 8)(RX0), RCD2;
694
695         /* Update IV */
696         movq (4 * 8)(RX0), RY0;
697         movq (5 * 8)(RX0), RY1;
698         movq RY0, (0 * 8)(RX1);
699         movq RY1, (1 * 8)(RX1);
700
701         call __twofish_enc_blk3;
702
703         movq (7 * 8)(%rsp), RX0; /*src*/
704         movq (6 * 8)(%rsp), RX1; /*dst*/
705
706         xorq (0 * 8)(RX0), RCD0;
707         xorq (1 * 8)(RX0), RAB0;
708         xorq (2 * 8)(RX0), RCD1;
709         xorq (3 * 8)(RX0), RAB1;
710         xorq (4 * 8)(RX0), RCD2;
711         xorq (5 * 8)(RX0), RAB2;
712         movq RCD0, (0 * 8)(RX1);
713         movq RAB0, (1 * 8)(RX1);
714         movq RCD1, (2 * 8)(RX1);
715         movq RAB1, (3 * 8)(RX1);
716         movq RCD2, (4 * 8)(RX1);
717         movq RAB2, (5 * 8)(RX1);
718
719         movq (0 * 8)(%rsp), %rbp;
720         movq (1 * 8)(%rsp), %rbx;
721         movq (2 * 8)(%rsp), %r12;
722         movq (3 * 8)(%rsp), %r13;
723         movq (4 * 8)(%rsp), %r14;
724         movq (5 * 8)(%rsp), %r15;
725         addq $(8 * 8), %rsp;
726
727         ret;
728 .size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;
729
730 #endif /*USE_TWOFISH*/
731 #endif /*__x86_64*/