da7e951836f07f7e3a3df03833ff2bf4aff754dd
[openssl.git] / crypto / aes / asm / bsaes-x86_64.pl
1 #!/usr/bin/env perl
2
3 ###################################################################
4 ### AES-128 [originally in CTR mode]                            ###
5 ### bitsliced implementation for Intel Core 2 processors        ###
6 ### requires support of SSE extensions up to SSSE3              ###
7 ### Author: Emilia Käsper and Peter Schwabe                    ###
8 ### Date: 2009-03-19                                            ###
9 ### Public domain                                               ###
10 ###                                                             ###
11 ### See http://homes.esat.kuleuven.be/~ekasper/#software for    ###
12 ### further information.                                        ###
13 ###################################################################
14 #
15 # September 2011.
16 #
17 # Started as transliteration to "perlasm" the original code has
18 # undergone following changes:
19 #
20 # - code was made position-independent;
21 # - rounds were folded into a loop resulting in >5x size reduction
22 #   from 12.5KB to 2.2KB;
23 # - above was possibile thanks to mixcolumns() modification that
24 #   allowed to feed its output back to aesenc[last], this was
25 #   achieved at cost of two additional inter-registers moves;
26 # - some instruction reordering and interleaving;
27 # - this module doesn't implement key setup subroutine, instead it
28 #   relies on conversion of "conventional" key schedule as returned
29 #   by AES_set_encrypt_key (see discussion below);
30 # - first and last round keys are treated differently, which allowed
31 #   to skip one shiftrows(), reduce bit-sliced key schedule and
32 #   speed-up conversion by 22%;
33 # - support for 192- and 256-bit keys was added;
34 #
35 # Resulting performance in CPU cycles spent to encrypt one byte out
36 # of 4096-byte buffer with 128-bit key is:
37 #
38 #               Emilia's        this(*)         difference
39 #
40 # Core 2        9.30            8.69            +7%
41 # Nehalem(**)   7.63            6.98            +9%
42 # Atom          17.1            17.4            -2%(***)
43 #
44 # (*)   Comparison is not completely fair, because "this" is ECB,
45 #       i.e. no extra processing such as counter values calculation
46 #       and xor-ing input as in Emilia's CTR implementation is
47 #       performed. However, the CTR calculations stand for not more
48 #       than 1% of total time, so comparison is *rather* fair.
49 #
50 # (**)  Results were collected on Westmere, which is considered to
51 #       be equivalent to Nehalem for this code.
52 #
53 # (***) Slowdown on Atom is rather strange per se, because original
54 #       implementation has a number of 9+-bytes instructions, which
55 #       are bad for Atom front-end, and which I eliminated completely.
56 #       In attempt to address deterioration sbox() was tested in FP
57 #       SIMD "domain" (movaps instead of movdqa, xorps instead of
58 #       pxor, etc.). While it resulted in nominal 4% improvement on
59 #       Atom, it hurted Westmere by more than 2x factor.
60 #
61 # As for key schedule conversion subroutine. Interface to OpenSSL
62 # relies on per-invocation on-the-fly conversion. This naturally
63 # has impact on performance, especially for short inputs. Conversion
64 # time in CPU cycles and its ratio to CPU cycles spent in 8x block
65 # function is:
66 #
67 #               conversion      conversion/8x block
68 # Core 2        410             0.37
69 # Nehalem       310             0.35
70 # Atom          570             0.26
71 #
72 # The ratio values mean that 128-byte blocks will be processed
73 # 21-27% slower, 256-byte blocks - 12-16%, 382-byte blocks - 8-11%,
74 # etc. Then keep in mind that input sizes not divisible by 128 are
75 # *effectively* slower, especially shortest ones, e.g. consecutive
76 # 144-byte blocks are processed 44% slower than one would expect,
77 # 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings"
78 # it's still faster than ["hyper-threading-safe" code path in]
79 # aes-x86_64.pl on all lengths above 64 bytes...
80 #
81 #                                               <appro@openssl.org>
82
83 $flavour = shift;
84 $output  = shift;
85 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
86
87 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
88
89 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
90 ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
91 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
92 die "can't locate x86_64-xlate.pl";
93
94 open STDOUT,"| $^X $xlate $flavour $output";
95
96 my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
97 my @XMM=map("%xmm$_",(15,0..14));       # best on Atom, +10% over (0..15)
98
99 {
100 my ($key,$rounds,$const)=("%rax","%r10d","%r11");
101
102 sub sbox {
103 # input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
104 # output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
105 my @b=@_[0..7];
106 my @t=@_[8..11];
107 my @s=@_[12..15];
108         &InBasisChange  (@b);
109         &Inv_GF256      (@b[6,5,0,3,7,1,4,2],@t,@s);
110         &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
111 }
112
113 sub InBasisChange {
114 # input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
115 # output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 
116 my @b=@_[0..7];
117 $code.=<<___;
118         pxor    @b[6], @b[5]
119         pxor    @b[1], @b[2]
120         pxor    @b[0], @b[5]
121         pxor    @b[2], @b[6]
122         pxor    @b[0], @b[3]
123
124         pxor    @b[3], @b[6]
125         pxor    @b[7], @b[3]
126         pxor    @b[5], @b[7]
127         pxor    @b[4], @b[3]
128         pxor    @b[5], @b[4]
129         pxor    @b[1], @b[3]
130
131         pxor    @b[7], @b[2]
132         pxor    @b[5], @b[1]
133 ___
134 }
135
136 sub OutBasisChange {
137 # input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
138 # output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
139 my @b=@_[0..7];
140 $code.=<<___;
141         pxor    @b[6], @b[0]
142         pxor    @b[4], @b[1]
143         pxor    @b[0], @b[2]
144         pxor    @b[6], @b[4]
145         pxor    @b[1], @b[6]
146
147         pxor    @b[5], @b[1]
148         pxor    @b[3], @b[5]
149         pxor    @b[7], @b[3]
150         pxor    @b[5], @b[7]
151         pxor    @b[5], @b[2]
152
153         pxor    @b[7], @b[4]
154 ___
155 }
156
157 sub Mul_GF4 {
158 #;*************************************************************
159 #;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
160 #;*************************************************************
161 my ($x0,$x1,$y0,$y1,$t0)=@_;
162 $code.=<<___;
163         movdqa  $y0, $t0
164         pxor    $y1, $t0
165         pand    $x0, $t0
166         pxor    $x1, $x0
167         pand    $y0, $x1
168         pand    $y1, $x0
169         pxor    $x1, $x0
170         pxor    $t0, $x1
171 ___
172 }
173
174 sub Mul_GF4_N {                         # not used, see next subroutine
175 # multiply and scale by N
176 my ($x0,$x1,$y0,$y1,$t0)=@_;
177 $code.=<<___;
178         movdqa  $y0, $t0
179         pxor    $y1, $t0
180         pand    $x0, $t0
181         pxor    $x1, $x0
182         pand    $y0, $x1
183         pand    $y1, $x0
184         pxor    $x0, $x1
185         pxor    $t0, $x0
186 ___
187 }
188
189 sub Mul_GF4_N_GF4 {
190 # interleaved Mul_GF4_N and Mul_GF4
191 my ($x0,$x1,$y0,$y1,$t0,
192     $x2,$x3,$y2,$y3,$t1)=@_;
193 $code.=<<___;
194         movdqa  $y0, $t0
195          movdqa $y2, $t1
196         pxor    $y1, $t0
197          pxor   $y3, $t1
198         pand    $x0, $t0
199          pand   $x2, $t1
200         pxor    $x1, $x0
201          pxor   $x3, $x2
202         pand    $y0, $x1
203          pand   $y2, $x3
204         pand    $y1, $x0
205          pand   $y3, $x2
206         pxor    $x0, $x1
207          pxor   $x3, $x2
208         pxor    $t0, $x0
209          pxor   $t1, $x3
210 ___
211 }
212 sub Mul_GF16_2 {
213 my @x=@_[0..7];
214 my @y=@_[8..11];
215 my @t=@_[12..15];
216 $code.=<<___;
217         movdqa  @x[0], @t[0]
218         movdqa  @x[1], @t[1]
219 ___
220         &Mul_GF4        (@x[0], @x[1], @y[0], @y[1], @t[2]);
221 $code.=<<___;
222         pxor    @x[2], @t[0]
223         pxor    @x[3], @t[1]
224         pxor    @y[2], @y[0]
225         pxor    @y[3], @y[1]
226 ___
227         Mul_GF4_N_GF4   (@t[0], @t[1], @y[0], @y[1], @t[3],
228                          @x[2], @x[3], @y[2], @y[3], @t[2]);
229 $code.=<<___;
230         pxor    @t[0], @x[0]
231         pxor    @t[0], @x[2]
232         pxor    @t[1], @x[1]
233         pxor    @t[1], @x[3]
234
235         movdqa  @x[4], @t[0]
236         movdqa  @x[5], @t[1]
237         pxor    @x[6], @t[0]
238         pxor    @x[7], @t[1]
239 ___
240         &Mul_GF4_N_GF4  (@t[0], @t[1], @y[0], @y[1], @t[3],
241                          @x[6], @x[7], @y[2], @y[3], @t[2]);
242 $code.=<<___;
243         pxor    @y[2], @y[0]
244         pxor    @y[3], @y[1]
245 ___
246         &Mul_GF4        (@x[4], @x[5], @y[0], @y[1], @t[3]);
247 $code.=<<___;
248         pxor    @t[0], @x[4]
249         pxor    @t[0], @x[6]
250         pxor    @t[1], @x[5]
251         pxor    @t[1], @x[7]
252 ___
253 }
254 sub Inv_GF256 {
255 #;********************************************************************
256 #;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
257 #;********************************************************************
258 my @x=@_[0..7];
259 my @t=@_[8..11];
260 my @s=@_[12..15];
261 # direct optimizations from hardware
262 $code.=<<___;
263         movdqa  @x[4], @t[3]
264         movdqa  @x[5], @t[2]
265         movdqa  @x[1], @t[1]
266         movdqa  @x[7], @s[1]
267         movdqa  @x[0], @s[0]
268
269         pxor    @x[6], @t[3]
270         pxor    @x[7], @t[2]
271         pxor    @x[3], @t[1]
272          movdqa @t[3], @s[2]
273         pxor    @x[6], @s[1]
274          movdqa @t[2], @t[0]
275         pxor    @x[2], @s[0]
276          movdqa @t[3], @s[3]
277
278         por     @t[1], @t[2]
279         por     @s[0], @t[3]
280         pxor    @t[0], @s[3]
281         pand    @s[0], @s[2]
282         pxor    @t[1], @s[0]
283         pand    @t[1], @t[0]
284         pand    @s[0], @s[3]
285         movdqa  @x[3], @s[0]
286         pxor    @x[2], @s[0]
287         pand    @s[0], @s[1]
288         pxor    @s[1], @t[3]
289         pxor    @s[1], @t[2]
290         movdqa  @x[4], @s[1]
291         movdqa  @x[1], @s[0]
292         pxor    @x[5], @s[1]
293         pxor    @x[0], @s[0]
294         movdqa  @s[1], @t[1]
295         pand    @s[0], @s[1]
296         por     @s[0], @t[1]
297         pxor    @s[1], @t[0]
298         pxor    @s[3], @t[3]
299         pxor    @s[2], @t[2]
300         pxor    @s[3], @t[1]
301         movdqa  @x[7], @s[0]
302         pxor    @s[2], @t[0]
303         movdqa  @x[6], @s[1]
304         pxor    @s[2], @t[1]
305         movdqa  @x[5], @s[2]
306         pand    @x[3], @s[0]
307         movdqa  @x[4], @s[3]
308         pand    @x[2], @s[1]
309         pand    @x[1], @s[2]
310         por     @x[0], @s[3]
311         pxor    @s[0], @t[3]
312         pxor    @s[1], @t[2]
313         pxor    @s[2], @t[1]
314         pxor    @s[3], @t[0] 
315
316         #Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
317
318         # new smaller inversion
319
320         movdqa  @t[3], @s[0]
321         pand    @t[1], @t[3]
322         pxor    @t[2], @s[0]
323
324         movdqa  @t[0], @s[2]
325         movdqa  @s[0], @s[3]
326         pxor    @t[3], @s[2]
327         pand    @s[2], @s[3]
328
329         movdqa  @t[1], @s[1]
330         pxor    @t[2], @s[3]
331         pxor    @t[0], @s[1]
332
333         pxor    @t[2], @t[3]
334
335         pand    @t[3], @s[1]
336
337         movdqa  @s[2], @t[2]
338         pxor    @t[0], @s[1]
339
340         pxor    @s[1], @t[2]
341         pxor    @s[1], @t[1]
342
343         pand    @t[0], @t[2]
344
345         pxor    @t[2], @s[2]
346         pxor    @t[2], @t[1]
347
348         pand    @s[3], @s[2]
349
350         pxor    @s[0], @s[2]
351 ___
352 # output in s3, s2, s1, t1
353
354 # Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
355
356 # Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
357         &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
358
359 ### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
360 }
361
362 # AES linear components
363
364 sub shiftrows {
365 my @x=@_[0..7];
366 my $mask=pop;
367 $code.=<<___;
368         pxor    0x00($key),@x[0]
369         pxor    0x10($key),@x[1]
370         pshufb  $mask,@x[0]
371         pxor    0x20($key),@x[2]
372         pshufb  $mask,@x[1]
373         pxor    0x30($key),@x[3]
374         pshufb  $mask,@x[2]
375         pxor    0x40($key),@x[4]
376         pshufb  $mask,@x[3]
377         pxor    0x50($key),@x[5]
378         pshufb  $mask,@x[4]
379         pxor    0x60($key),@x[6]
380         pshufb  $mask,@x[5]
381         pxor    0x70($key),@x[7]
382         pshufb  $mask,@x[6]
383         lea     0x80($key),$key
384         pshufb  $mask,@x[7]
385 ___
386 }
387
388 sub mixcolumns {
389 # modified to emit output in order suitable for feeding back to aesenc[last]
390 my @x=@_[0..7];
391 my @t=@_[8..15];
392 $code.=<<___;
393         pshufd  \$0x93, @x[0], @t[0]    # x0 <<< 32
394         pshufd  \$0x93, @x[1], @t[1]
395          pxor   @t[0], @x[0]            # x0 ^ (x0 <<< 32)
396         pshufd  \$0x93, @x[2], @t[2]
397          pxor   @t[1], @x[1]
398         pshufd  \$0x93, @x[3], @t[3]
399          pxor   @t[2], @x[2]
400         pshufd  \$0x93, @x[4], @t[4]
401          pxor   @t[3], @x[3]
402         pshufd  \$0x93, @x[5], @t[5]
403          pxor   @t[4], @x[4]
404         pshufd  \$0x93, @x[6], @t[6]
405          pxor   @t[5], @x[5]
406         pshufd  \$0x93, @x[7], @t[7]
407          pxor   @t[6], @x[6]
408          pxor   @t[7], @x[7]
409
410         pxor    @x[0], @t[1]
411         pxor    @x[7], @t[0]
412         pxor    @x[7], @t[1]
413          pshufd \$0x4E, @x[0], @x[0]    # (x0 ^ (x0 <<< 32)) <<< 64)
414         pxor    @x[1], @t[2]
415          pshufd \$0x4E, @x[1], @x[1]
416         pxor    @x[4], @t[5]
417          pxor   @t[0], @x[0]
418         pxor    @x[5], @t[6]
419          pxor   @t[1], @x[1]
420         pxor    @x[3], @t[4]
421          pshufd \$0x4E, @x[4], @t[0]
422         pxor    @x[6], @t[7]
423          pshufd \$0x4E, @x[5], @t[1]
424         pxor    @x[2], @t[3]
425          pshufd \$0x4E, @x[3], @x[4]
426         pxor    @x[7], @t[3]
427          pshufd \$0x4E, @x[7], @x[5]
428         pxor    @x[7], @t[4]
429          pshufd \$0x4E, @x[6], @x[3]
430         pxor    @t[4], @t[0]
431          pshufd \$0x4E, @x[2], @x[6]
432         pxor    @t[5], @t[1]
433
434         pxor    @t[3], @x[4]
435         pxor    @t[7], @x[5]
436         pxor    @t[6], @x[3]
437          movdqa @t[0], @x[2]
438         pxor    @t[2], @x[6]
439          movdqa @t[1], @x[7]
440 ___
441 }
442
443 sub aesenc {                            # not used
444 my @b=@_[0..7];
445 my @t=@_[8..15];
446 $code.=<<___;
447         movdqa  0x30($const),@t[0]      # .LSR
448 ___
449         &shiftrows      (@b,@t[0]);
450         &sbox           (@b,@t);
451         &mixcolumns     (@b[0,1,4,6,3,7,2,5],@t);
452 }
453
454 sub aesenclast {                        # not used
455 my @b=@_[0..7];
456 my @t=@_[8..15];
457 $code.=<<___;
458         movdqa  0x40($const),@t[0]      # .LSRM0
459 ___
460         &shiftrows      (@b,@t[0]);
461         &sbox           (@b,@t);
462 $code.=<<___
463         pxor    0x00($key),@b[0]
464         pxor    0x10($key),@b[1]
465         pxor    0x20($key),@b[4]
466         pxor    0x30($key),@b[6]
467         pxor    0x40($key),@b[3]
468         pxor    0x50($key),@b[7]
469         pxor    0x60($key),@b[2]
470         pxor    0x70($key),@b[5]
471 ___
472 }
473
474 sub swapmove {
475 my ($a,$b,$n,$mask,$t)=@_;
476 $code.=<<___;
477         movdqa  $b,$t
478         psrlq   \$$n,$b
479         pxor    $a,$b
480         pand    $mask,$b
481         pxor    $b,$a
482         psllq   \$$n,$b
483         pxor    $t,$b
484 ___
485 }
486 sub swapmove2x {
487 my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
488 $code.=<<___;
489         movdqa  $b0,$t0
490         psrlq   \$$n,$b0
491          movdqa $b1,$t1
492          psrlq  \$$n,$b1
493         pxor    $a0,$b0
494          pxor   $a1,$b1
495         pand    $mask,$b0
496          pand   $mask,$b1
497         pxor    $b0,$a0
498         psllq   \$$n,$b0
499          pxor   $b1,$a1
500          psllq  \$$n,$b1
501         pxor    $t0,$b0
502          pxor   $t1,$b1
503 ___
504 }
505
506 sub bitslice {
507 my @x=reverse(@_[0..7]);
508 my ($t0,$t1,$t2,$t3)=@_[8..11];
509 $code.=<<___;
510         movdqa  0x00($const),$t0        # .LBS0
511         movdqa  0x10($const),$t1        # .LBS1
512 ___
513         &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
514         &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
515 $code.=<<___;
516         movdqa  0x20($const),$t0        # .LBS2
517 ___
518         &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
519         &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
520
521         &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
522         &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
523 }
524
525 $code.=<<___;
526 .text
527
528 .extern AES_encrypt
529
530 .type   _bsaes_encrypt8,\@abi-omnipotent
531 .align  64
532 _bsaes_encrypt8:
533         lea     .LBS0(%rip), $const     # constants table
534
535         movdqa  ($key), @XMM[9]         # round 0 key
536         lea     0x10($key), $key
537         movdqa  0x60($const), @XMM[8]   # .LM0SR
538         pxor    @XMM[9], @XMM[0]        # xor with round0 key
539         pxor    @XMM[9], @XMM[1]
540          pshufb @XMM[8], @XMM[0]
541         pxor    @XMM[9], @XMM[2]
542          pshufb @XMM[8], @XMM[1]
543         pxor    @XMM[9], @XMM[3]
544          pshufb @XMM[8], @XMM[2]
545         pxor    @XMM[9], @XMM[4]
546          pshufb @XMM[8], @XMM[3]
547         pxor    @XMM[9], @XMM[5]
548          pshufb @XMM[8], @XMM[4]
549         pxor    @XMM[9], @XMM[6]
550          pshufb @XMM[8], @XMM[5]
551         pxor    @XMM[9], @XMM[7]
552          pshufb @XMM[8], @XMM[6]
553          pshufb @XMM[8], @XMM[7]
554 _bsaes_encrypt8_bitslice:
555 ___
556         &bitslice       (@XMM[0..7, 8..11]);
557 $code.=<<___;
558         dec     $rounds
559         jmp     .Lenc_sbox
560 .align  16
561 .Lenc_loop:
562 ___
563         &shiftrows      (@XMM[0..7, 8]);
564 $code.=".Lenc_sbox:\n";
565         &sbox           (@XMM[0..7, 8..15]);
566 $code.=<<___;
567         dec     $rounds
568         jl      .Lenc_done
569 ___
570         &mixcolumns     (@XMM[0,1,4,6,3,7,2,5, 8..15]);
571 $code.=<<___;
572         movdqa  0x30($const), @XMM[8]   # .LSR
573         jnz     .Lenc_loop
574         movdqa  0x40($const), @XMM[8]   # .LSRM0
575         jmp     .Lenc_loop
576 .align  16
577 .Lenc_done:
578 ___
579         # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
580         &bitslice       (@XMM[0,1,4,6,3,7,2,5, 8..11]);
581 $code.=<<___;
582         movdqa  ($key), @XMM[8]         # last round key
583         pxor    @XMM[8], @XMM[0]
584         pxor    @XMM[8], @XMM[1]
585         pxor    @XMM[8], @XMM[4]
586         pxor    @XMM[8], @XMM[6]
587         pxor    @XMM[8], @XMM[3]
588         pxor    @XMM[8], @XMM[7]
589         pxor    @XMM[8], @XMM[2]
590         pxor    @XMM[8], @XMM[5]
591         ret
592 .size   _bsaes_encrypt8,.-_bsaes_encrypt8
593 ___
594 }
595 {
596 my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11");
597
598 sub bitslice_key {
599 my @x=reverse(@_[0..7]);
600 my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
601
602         &swapmove       (@x[0,1],1,$bs0,$t2,$t3);
603 $code.=<<___;
604         #&swapmove(@x[2,3],1,$t0,$t2,$t3);
605         movdqa  @x[0], @x[2]
606         movdqa  @x[1], @x[3]
607 ___
608         #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
609
610         &swapmove2x     (@x[0,2,1,3],2,$bs1,$t2,$t3);
611 $code.=<<___;
612         #&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
613         movdqa  @x[0], @x[4]
614         movdqa  @x[2], @x[6]
615         movdqa  @x[1], @x[5]
616         movdqa  @x[3], @x[7]
617 ___
618         &swapmove2x     (@x[0,4,1,5],4,$bs2,$t2,$t3);
619         &swapmove2x     (@x[2,6,3,7],4,$bs2,$t2,$t3);
620 }
621
622 $code.=<<___;
623 .type   _bsaes_enc_key_convert,\@abi-omnipotent
624 .align  16
625 _bsaes_enc_key_convert:
626         lea     .LBS1(%rip), $const
627         movdqu  ($inp), %xmm7           # load round 0 key
628         movdqa  -0x10($const), %xmm8    # .LBS0
629         movdqa  0x00($const), %xmm9     # .LBS1
630         movdqa  0x10($const), %xmm10    # .LBS2
631         movdqa  0x40($const), %xmm13    # .LM0
632         movdqa  0x60($const),%xmm14     # .LNOT
633
634         movdqu  0x10($inp), %xmm6       # load round 1 key
635         lea     0x10($inp), $inp
636         movdqa  %xmm7, ($out)           # save round 0 key
637         lea     0x10($out), $out
638         dec     $rounds
639         jmp     .Lkey_loop
640 .align  16
641 .Lkey_loop:
642         pshufb  %xmm13, %xmm6
643         movdqa  %xmm6, %xmm7
644 ___
645         &bitslice_key   (map("%xmm$_",(0..7, 8..12)));
646 $code.=<<___;
647         pxor    %xmm14, %xmm5           # "pnot"
648         pxor    %xmm14, %xmm6
649         pxor    %xmm14, %xmm0
650         pxor    %xmm14, %xmm1
651         lea     0x10($inp), $inp
652         movdqa  %xmm0, 0x00($out)       # write bit-sliced round key
653         movdqa  %xmm1, 0x10($out)
654         movdqa  %xmm2, 0x20($out)
655         movdqa  %xmm3, 0x30($out)
656         movdqa  %xmm4, 0x40($out)
657         movdqa  %xmm5, 0x50($out)
658         movdqa  %xmm6, 0x60($out)
659         movdqa  %xmm7, 0x70($out)
660         lea     0x80($out),$out
661         movdqu  ($inp), %xmm6           # load next round key
662         dec     $rounds
663         jnz     .Lkey_loop
664
665         pxor    0x70($const), %xmm6     # .L63
666         movdqa  %xmm6, ($out)           # save last round key
667         ret
668 .size   _bsaes_enc_key_convert,.-_bsaes_enc_key_convert
669 ___
670 }
671
672 if (1 && !$win64) {     # following two functions are unsupported interface
673                         # used for benchmarking...
674 $code.=<<___;
675 .globl  bsaes_enc_key_convert
676 .type   bsaes_enc_key_convert,\@function,2
677 .align  16
678 bsaes_enc_key_convert:
679         mov     240($inp),%r10d         # pass rounds
680         mov     $inp,%rcx               # pass key
681         mov     $out,%rax               # pass key schedule
682         call    _bsaes_enc_key_convert
683         ret
684 .size   bsaes_enc_key_convert,.-bsaes_enc_key_convert
685
686 .globl  bsaes_encrypt_128
687 .type   bsaes_encrypt_128,\@function,4
688 .align  16
689 bsaes_encrypt_128:
690 .Lenc128_loop:
691         movdqu  0x00($inp), @XMM[0]     # load input
692         movdqu  0x10($inp), @XMM[1]
693         movdqu  0x20($inp), @XMM[2]
694         movdqu  0x30($inp), @XMM[3]
695         movdqu  0x40($inp), @XMM[4]
696         movdqu  0x50($inp), @XMM[5]
697         movdqu  0x60($inp), @XMM[6]
698         movdqu  0x70($inp), @XMM[7]
699         mov     $key, %rax              # pass the $key
700         lea     0x80($inp), $inp
701         mov     \$10,%r10d
702
703         call    _bsaes_encrypt8
704
705         movdqu  @XMM[0], 0x00($out)     # write output
706         movdqu  @XMM[1], 0x10($out)
707         movdqu  @XMM[4], 0x20($out)
708         movdqu  @XMM[6], 0x30($out)
709         movdqu  @XMM[3], 0x40($out)
710         movdqu  @XMM[7], 0x50($out)
711         movdqu  @XMM[2], 0x60($out)
712         movdqu  @XMM[5], 0x70($out)
713         lea     0x80($out), $out
714         sub     \$0x80,$len
715         ja      .Lenc128_loop
716         ret
717 .size   bsaes_encrypt_128,.-bsaes_encrypt_128
718 ___
719 }
720 {
721 ######################################################################
722 #
723 # OpenSSL interface
724 #
725 my ($arg1,$arg2,$arg3,$arg4,$arg5) = $win64     ? ("%rcx","%rdx","%r8","%r9","%r10")
726                                                 : ("%rdi","%rsi","%rdx","%rcx","%r8");
727 my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15");
728
729 $code.=<<___;
730 .globl  bsaes_ecb_encrypt_blocks
731 .type   bsaes_ecb_encrypt_blocks,\@abi-omnipotent
732 .align  16
733 bsaes_ecb_encrypt_blocks:
734         push    %rbp
735         push    %rbx
736         push    %r12
737         push    %r13
738         push    %r14
739         push    %r15
740         lea     -0x48(%rsp),%rsp
741 ___
742 $code.=<<___ if ($win64);
743         lea     -0xa0(%rsp), %rsp
744         movaps  %xmm6, 0x40(%rsp)
745         movaps  %xmm7, 0x50(%rsp)
746         movaps  %xmm8, 0x60(%rsp)
747         movaps  %xmm9, 0x70(%rsp)
748         movaps  %xmm10, 0x80(%rsp)
749         movaps  %xmm11, 0x90(%rsp)
750         movaps  %xmm12, 0xa0(%rsp)
751         movaps  %xmm13, 0xb0(%rsp)
752         movaps  %xmm14, 0xc0(%rsp)
753         movaps  %xmm15, 0xd0(%rsp)
754 .Lecb_enc_body:
755 ___
756 $code.=<<___;
757         mov     %rsp,%rbp               # backup %rsp
758         mov     240($arg4),%eax         # rounds
759         mov     $arg1,$inp              # backup arguments
760         mov     $arg2,$out
761         mov     $arg3,$len
762         mov     $arg4,$key
763         cmp     \$8,$arg3
764         jb      .Lecb_enc_short
765
766         mov     %eax,%ebx               # backup rounds
767         shl     \$7,%rax                # 128 bytes per inner round key
768         sub     \$`128-32`,%rax         # size of bit-sliced key schedule
769         sub     %rax,%rsp
770         mov     %rsp,%rax               # pass key schedule
771         mov     $key,%rcx               # pass key
772         mov     %ebx,%r10d              # pass rounds
773         call    _bsaes_enc_key_convert
774
775         sub     \$8,$len
776 .Lecb_enc_loop:
777         movdqu  0x00($inp), @XMM[0]     # load input
778         movdqu  0x10($inp), @XMM[1]
779         movdqu  0x20($inp), @XMM[2]
780         movdqu  0x30($inp), @XMM[3]
781         movdqu  0x40($inp), @XMM[4]
782         movdqu  0x50($inp), @XMM[5]
783         mov     %rsp, %rax              # pass key schedule
784         movdqu  0x60($inp), @XMM[6]
785         mov     %ebx,%r10d              # pass rounds
786         movdqu  0x70($inp), @XMM[7]
787         lea     0x80($inp), $inp
788
789         call    _bsaes_encrypt8
790
791         movdqu  @XMM[0], 0x00($out)     # write output
792         movdqu  @XMM[1], 0x10($out)
793         movdqu  @XMM[4], 0x20($out)
794         movdqu  @XMM[6], 0x30($out)
795         movdqu  @XMM[3], 0x40($out)
796         movdqu  @XMM[7], 0x50($out)
797         movdqu  @XMM[2], 0x60($out)
798         movdqu  @XMM[5], 0x70($out)
799         lea     0x80($out), $out
800         sub     \$8,$len
801         jnc     .Lecb_enc_loop
802
803         add     \$8,$len
804         jz      .Lecb_enc_done
805
806         movdqu  0x00($inp), @XMM[0]     # load input
807         mov     %rsp, %rax              # pass key schedule
808         mov     %ebx,%r10d              # pass rounds
809         cmp     \$2,$len
810         jb      .Lecb_enc_one
811         movdqu  0x10($inp), @XMM[1]
812         je      .Lecb_enc_two
813         movdqu  0x20($inp), @XMM[2]
814         cmp     \$4,$len
815         jb      .Lecb_enc_three
816         movdqu  0x30($inp), @XMM[3]
817         je      .Lecb_enc_four
818         movdqu  0x40($inp), @XMM[4]
819         cmp     \$6,$len
820         jb      .Lecb_enc_five
821         movdqu  0x50($inp), @XMM[5]
822         je      .Lecb_enc_six
823         movdqu  0x60($inp), @XMM[6]
824         call    _bsaes_encrypt8
825         movdqu  @XMM[0], 0x00($out)     # write output
826         movdqu  @XMM[1], 0x10($out)
827         movdqu  @XMM[4], 0x20($out)
828         movdqu  @XMM[6], 0x30($out)
829         movdqu  @XMM[3], 0x40($out)
830         movdqu  @XMM[7], 0x50($out)
831         movdqu  @XMM[2], 0x60($out)
832         jmp     .Lecb_enc_done
833 .align  16
834 .Lecb_enc_six:
835         call    _bsaes_encrypt8
836         movdqu  @XMM[0], 0x00($out)     # write output
837         movdqu  @XMM[1], 0x10($out)
838         movdqu  @XMM[4], 0x20($out)
839         movdqu  @XMM[6], 0x30($out)
840         movdqu  @XMM[3], 0x40($out)
841         movdqu  @XMM[7], 0x50($out)
842         jmp     .Lecb_enc_done
843 .align  16
844 .Lecb_enc_five:
845         call    _bsaes_encrypt8
846         movdqu  @XMM[0], 0x00($out)     # write output
847         movdqu  @XMM[1], 0x10($out)
848         movdqu  @XMM[4], 0x20($out)
849         movdqu  @XMM[6], 0x30($out)
850         movdqu  @XMM[3], 0x40($out)
851         jmp     .Lecb_enc_done
852 .align  16
853 .Lecb_enc_four:
854         call    _bsaes_encrypt8
855         movdqu  @XMM[0], 0x00($out)     # write output
856         movdqu  @XMM[1], 0x10($out)
857         movdqu  @XMM[4], 0x20($out)
858         movdqu  @XMM[6], 0x30($out)
859         jmp     .Lecb_enc_done
860 .align  16
861 .Lecb_enc_three:
862         call    _bsaes_encrypt8
863         movdqu  @XMM[0], 0x00($out)     # write output
864         movdqu  @XMM[1], 0x10($out)
865         movdqu  @XMM[4], 0x20($out)
866         jmp     .Lecb_enc_done
867 .align  16
868 .Lecb_enc_two:
869         call    _bsaes_encrypt8
870         movdqu  @XMM[0], 0x00($out)     # write output
871         movdqu  @XMM[1], 0x10($out)
872         jmp     .Lecb_enc_done
873 .align  16
874 .Lecb_enc_one:
875         call    _bsaes_encrypt8
876         movdqu  @XMM[0], 0x00($out)     # write output
877         jmp     .Lecb_enc_done
878 .align  16
879 .Lecb_enc_short:
880         lea     ($inp), $arg1
881         lea     ($out), $arg2
882         lea     ($key), $arg3
883         call    AES_encrypt
884         lea     16($inp), $inp
885         lea     16($out), $out
886         dec     $len
887         jnz     .Lecb_enc_short
888
889 .Lecb_enc_done:
890         lea     (%rsp),%rax
891         pxor    %xmm0, %xmm0
892 .Lecb_enc_bzero:                        # wipe key schedule [if any]
893         movdqa  %xmm0, 0x00(%rax)
894         movdqa  %xmm0, 0x10(%rax)
895         lea     0x20(%rax), %rax
896         cmp     %rax, %rbp
897         jb      .Lecb_enc_bzero
898
899         lea     (%rbp),%rsp             # restore %rsp
900 ___
901 $code.=<<___ if ($win64);
902         movaps  0x40(%rbp), %xmm6
903         movaps  0x50(%rbp), %xmm7
904         movaps  0x60(%rbp), %xmm8
905         movaps  0x70(%rbp), %xmm9
906         movaps  0x80(%rbp), %xmm10
907         movaps  0x90(%rbp), %xmm11
908         movaps  0xa0(%rbp), %xmm12
909         movaps  0xb0(%rbp), %xmm13
910         movaps  0xc0(%rbp), %xmm14
911         movaps  0xd0(%rbp), %xmm15
912         lea     0xa0(%rbp), %rsp
913 ___
914 $code.=<<___;
915         mov     0x48(%rsp), %r15
916         mov     0x50(%rsp), %r14
917         mov     0x58(%rsp), %r13
918         mov     0x60(%rsp), %r12
919         mov     0x68(%rsp), %rbx
920         mov     0x70(%rsp), %rbp
921         lea     0x78(%rsp), %rsp
922 .Lecb_enc_epilogue:
923         ret
924 .size   bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
925
926 .globl  bsaes_ctr32_encrypt_blocks
927 .type   bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
928 .align  16
929 bsaes_ctr32_encrypt_blocks:
930         push    %rbp
931         push    %rbx
932         push    %r12
933         push    %r13
934         push    %r14
935         push    %r15
936         lea     -0x48(%rsp), %rsp
937 ___
938 $code.=<<___ if ($win64);
939         mov     0xa0(%rsp),$arg5        # pull ivp
940         lea     -0xa0(%rsp), %rsp
941         movaps  %xmm6, 0x40(%rsp)
942         movaps  %xmm7, 0x50(%rsp)
943         movaps  %xmm8, 0x60(%rsp)
944         movaps  %xmm9, 0x70(%rsp)
945         movaps  %xmm10, 0x80(%rsp)
946         movaps  %xmm11, 0x90(%rsp)
947         movaps  %xmm12, 0xa0(%rsp)
948         movaps  %xmm13, 0xb0(%rsp)
949         movaps  %xmm14, 0xc0(%rsp)
950         movaps  %xmm15, 0xd0(%rsp)
951 .Lctr_enc_body:
952 ___
953 $code.=<<___;
954         mov     %rsp, %rbp              # backup %rsp
955         movdqu  ($arg5), %xmm0          # load counter
956         mov     240($arg4), %eax        # rounds
957         mov     $arg1, $inp             # backup arguments
958         mov     $arg2, $out
959         mov     $arg3, $len
960         mov     $arg4, $key
961         movdqa  %xmm0, 0x20(%rbp)       # copy counter
962         cmp     \$8, $arg3
963         jb      .Lctr_enc_short
964
965         mov     %eax, %ebx              # rounds
966         shl     \$7, %rax               # 128 bytes per inner round key
967         sub     \$`128-32`, %rax        # size of bit-sliced key schedule
968         sub     %rax, %rsp
969
970         mov     %rsp, %rax              # pass key schedule
971         mov     $key, %rcx              # pass key
972         mov     %ebx, %r10d             # pass rounds
973         call    _bsaes_enc_key_convert
974
975         movdqa  (%rsp), @XMM[9]         # load round0 key
976         lea     .LADD1(%rip), %r11
977         movdqa  0x20(%rbp), @XMM[0]     # counter copy
978         movdqa  -0x20(%r11), @XMM[8]    # .LSWPUP
979         pshufb  @XMM[8], @XMM[9]        # byte swap upper part
980         pshufb  @XMM[8], @XMM[0]
981         movdqa  @XMM[9], (%rsp)         # save adjusted round0 key
982         jmp     .Lctr_enc_loop
983 .align  16
984 .Lctr_enc_loop:
985         movdqa  @XMM[0], 0x20(%rbp)     # save counter
986         movdqa  @XMM[0], @XMM[1]        # prepare 8 counter values
987         movdqa  @XMM[0], @XMM[2]
988         paddd   0x00(%r11), @XMM[1]     # .LADD1
989         movdqa  @XMM[0], @XMM[3]
990         paddd   0x10(%r11), @XMM[2]     # .LADD2
991         movdqa  @XMM[0], @XMM[4]
992         paddd   0x20(%r11), @XMM[3]     # .LADD3
993         movdqa  @XMM[0], @XMM[5]
994         paddd   0x30(%r11), @XMM[4]     # .LADD4
995         movdqa  @XMM[0], @XMM[6]
996         paddd   0x40(%r11), @XMM[5]     # .LADD5
997         movdqa  @XMM[0], @XMM[7]
998         paddd   0x50(%r11), @XMM[6]     # .LADD6
999         paddd   0x60(%r11), @XMM[7]     # .LADD7
1000
1001         # Borrow prologue from _bsaes_encrypt8 to use the opportunity
1002         # to flip byte order in 32-bit counter
1003         movdqa  (%rsp), @XMM[9]         # round 0 key
1004         lea     0x10(%rsp), %rax        # pass key schedule
1005         movdqa  -0x10(%r11), @XMM[8]    # .LSWPUPM0SR
1006         pxor    @XMM[9], @XMM[0]        # xor with round0 key
1007         pxor    @XMM[9], @XMM[1]
1008          pshufb @XMM[8], @XMM[0]
1009         pxor    @XMM[9], @XMM[2]
1010          pshufb @XMM[8], @XMM[1]
1011         pxor    @XMM[9], @XMM[3]
1012          pshufb @XMM[8], @XMM[2]
1013         pxor    @XMM[9], @XMM[4]
1014          pshufb @XMM[8], @XMM[3]
1015         pxor    @XMM[9], @XMM[5]
1016          pshufb @XMM[8], @XMM[4]
1017         pxor    @XMM[9], @XMM[6]
1018          pshufb @XMM[8], @XMM[5]
1019         pxor    @XMM[9], @XMM[7]
1020          pshufb @XMM[8], @XMM[6]
1021         lea     .LBS0(%rip), %r11       # constants table
1022          pshufb @XMM[8], @XMM[7]
1023         mov     %ebx,%r10d              # pass rounds
1024
1025         call    _bsaes_encrypt8_bitslice
1026
1027         sub     \$8,$len
1028         jc      .Lctr_enc_loop_done
1029
1030         movdqu  0x00($inp), @XMM[8]     # load input
1031         movdqu  0x10($inp), @XMM[9]
1032         movdqu  0x20($inp), @XMM[10]
1033         movdqu  0x30($inp), @XMM[11]
1034         movdqu  0x40($inp), @XMM[12]
1035         movdqu  0x50($inp), @XMM[13]
1036         movdqu  0x60($inp), @XMM[14]
1037         movdqu  0x70($inp), @XMM[15]
1038         lea     0x80($inp),$inp
1039         pxor    @XMM[0], @XMM[8]
1040         movdqa  0x20(%rbp), @XMM[0]     # load counter
1041         pxor    @XMM[9], @XMM[1]
1042         movdqu  @XMM[8], 0x00($out)     # write output
1043         pxor    @XMM[10], @XMM[4]
1044         movdqu  @XMM[1], 0x10($out)
1045         pxor    @XMM[11], @XMM[6]
1046         movdqu  @XMM[4], 0x20($out)
1047         pxor    @XMM[12], @XMM[3]
1048         movdqu  @XMM[6], 0x30($out)
1049         pxor    @XMM[13], @XMM[7]
1050         movdqu  @XMM[3], 0x40($out)
1051         pxor    @XMM[14], @XMM[2]
1052         movdqu  @XMM[7], 0x50($out)
1053         pxor    @XMM[15], @XMM[5]
1054         movdqu  @XMM[2], 0x60($out)
1055         lea     .LADD1(%rip), %r11
1056         movdqu  @XMM[5], 0x70($out)
1057         lea     0x80($out), $out
1058         paddd   0x70(%r11), @XMM[0]     # .LADD8
1059         jnz     .Lctr_enc_loop
1060
1061         jmp     .Lctr_enc_done
1062 .align  16
1063 .Lctr_enc_loop_done:
1064         movdqu  0x00($inp), @XMM[8]     # load input
1065         pxor    @XMM[8], @XMM[0]
1066         movdqu  @XMM[0], 0x00($out)     # write output
1067         cmp     \$2,$len
1068         jb      .Lctr_enc_done
1069         movdqu  0x10($inp), @XMM[9]
1070         pxor    @XMM[9], @XMM[1]
1071         movdqu  @XMM[1], 0x10($out)
1072         je      .Lctr_enc_done
1073         movdqu  0x20($inp), @XMM[10]
1074         pxor    @XMM[10], @XMM[4]
1075         movdqu  @XMM[4], 0x20($out)
1076         cmp     \$4,$len
1077         jb      .Lctr_enc_done
1078         movdqu  0x30($inp), @XMM[11]
1079         pxor    @XMM[11], @XMM[6]
1080         movdqu  @XMM[6], 0x30($out)
1081         je      .Lctr_enc_done
1082         movdqu  0x40($inp), @XMM[12]
1083         pxor    @XMM[12], @XMM[3]
1084         movdqu  @XMM[3], 0x40($out)
1085         cmp     \$6,$len
1086         jb      .Lctr_enc_done
1087         movdqu  0x50($inp), @XMM[13]
1088         pxor    @XMM[13], @XMM[7]
1089         movdqu  @XMM[7], 0x50($out)
1090         je      .Lctr_enc_done
1091         movdqu  0x60($inp), @XMM[14]
1092         pxor    @XMM[14], @XMM[2]
1093         movdqu  @XMM[2], 0x60($out)
1094         jmp     .Lctr_enc_done
1095
1096 .align  16
1097 .Lctr_enc_short:
1098         lea     0x20(%rbp), $arg1
1099         lea     0x30(%rbp), $arg2
1100         lea     ($key), $arg3
1101         call    AES_encrypt
1102         movdqu  ($inp), @XMM[1]
1103         lea     16($inp), $inp
1104         mov     0x2c(%rbp), %eax        # load 32-bit counter
1105         bswap   %eax
1106         pxor    0x30(%rbp), @XMM[1]
1107         inc     %eax                    # increment
1108         movdqu  @XMM[1], ($out)
1109         bswap   %eax
1110         lea     16($out), $out
1111         mov     %eax, 0x2c(%rsp)        # save 32-bit counter
1112         dec     $len
1113         jnz     .Lctr_enc_short
1114
1115 .Lctr_enc_done:
1116         lea     (%rsp), %rax
1117         pxor    %xmm0, %xmm0
1118 .Lctr_enc_bzero:                        # wipe key schedule [if any]
1119         movdqa  %xmm0, 0x00(%rax)
1120         movdqa  %xmm0, 0x10(%rax)
1121         lea     0x20(%rax), %rax
1122         cmp     %rax, %rbp
1123         ja      .Lctr_enc_bzero
1124
1125         lea     (%rbp),%rsp             # restore %rsp
1126 ___
1127 $code.=<<___ if ($win64);
1128         movaps  0x40(%rbp), %xmm6
1129         movaps  0x50(%rbp), %xmm7
1130         movaps  0x60(%rbp), %xmm8
1131         movaps  0x70(%rbp), %xmm9
1132         movaps  0x80(%rbp), %xmm10
1133         movaps  0x90(%rbp), %xmm11
1134         movaps  0xa0(%rbp), %xmm12
1135         movaps  0xb0(%rbp), %xmm13
1136         movaps  0xc0(%rbp), %xmm14
1137         movaps  0xd0(%rbp), %xmm15
1138         lea     0xa0(%rbp), %rsp
1139 ___
1140 $code.=<<___;
1141         mov     0x48(%rsp), %r15
1142         mov     0x50(%rsp), %r14
1143         mov     0x58(%rsp), %r13
1144         mov     0x60(%rsp), %r12
1145         mov     0x68(%rsp), %rbx
1146         mov     0x70(%rsp), %rbp
1147         lea     0x78(%rsp), %rsp
1148 .Lctr_enc_epilogue:
1149         ret
1150 .size   bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
1151 ___
1152 }
1153 $code.=<<___;
1154 .align  64
1155 .LBS0:  .quad   0x5555555555555555, 0x5555555555555555
1156 .LBS1:  .quad   0x3333333333333333, 0x3333333333333333
1157 .LBS2:  .quad   0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
1158 .LSR:   .quad   0x0504070600030201, 0x0f0e0d0c0a09080b
1159 .LSRM0: .quad   0x0304090e00050a0f, 0x01060b0c0207080d
1160 .LM0:   .quad   0x02060a0e03070b0f, 0x0004080c0105090d
1161 .LM0SR: .quad   0x0a0e02060f03070b, 0x0004080c05090d01
1162 .LNOT:  .quad   0xffffffffffffffff, 0xffffffffffffffff
1163 .L63:   .quad   0x6363636363636363, 0x6363636363636363
1164 .LSWPUP:
1165         .quad   0x0706050403020100, 0x0c0d0e0f0b0a0908
1166 .LSWPUPM0SR:
1167         .quad   0x0a0d02060c03070b, 0x0004080f05090e01
1168 .LADD1: .quad   0x0000000000000000, 0x0000000100000000
1169 .LADD2: .quad   0x0000000000000000, 0x0000000200000000
1170 .LADD3: .quad   0x0000000000000000, 0x0000000300000000
1171 .LADD4: .quad   0x0000000000000000, 0x0000000400000000
1172 .LADD5: .quad   0x0000000000000000, 0x0000000500000000
1173 .LADD6: .quad   0x0000000000000000, 0x0000000600000000
1174 .LADD7: .quad   0x0000000000000000, 0x0000000700000000
1175 .LADD8: .quad   0x0000000000000000, 0x0000000800000000
1176 .asciz  "Bit-sliced AES for x86_64/SSSE3, Emilia Käsper and Peter Schwabe"
1177 .align  64
1178 ___
1179
1180 $code =~ s/\`([^\`]*)\`/eval($1)/gem;
1181
1182 print $code;
1183
1184 close STDOUT;