Consistently use arm_arch.h constants in armcap assembly code.
[openssl.git] / crypto / poly1305 / asm / poly1305-ppc.pl
1 #!/usr/bin/env perl
2 #
3 # ====================================================================
4 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
5 # project. The module is, however, dual licensed under OpenSSL and
6 # CRYPTOGAMS licenses depending on where you obtain it. For further
7 # details see http://www.openssl.org/~appro/cryptogams/.
8 # ====================================================================
9 #
10 # This module implements Poly1305 hash for PowerPC.
11 #
12 # June 2015
13 #
14 # Numbers are cycles per processed byte with poly1305_blocks alone,
15 # and improvement coefficients relative to gcc-generated code.
16 #
17 #                       -m32            -m64
18 #
19 # Freescale e300        14.8/+80%       -
20 # PPC74x0               7.40/+60%       -
21 # PPC970                7.20/+114%      3.51/+205%
22 # POWER6                3.96/+250%      2.02/+170%
23 # POWER7                3.67/+260%      1.87/+100%
24 # POWER8                -               2.13/+200%
25 #
26 # Do we need floating-point implementation for PPC? Results presented
27 # in poly1305_ieee754.c are tricky to compare to, because they are for
28 # compiler-generated code. On the other hand it's known that floating-
29 # point performance can be dominated by FPU latency, which means that
30 # there is limit even for ideally optimized (and even vectorized) code.
31 # And this limit is estimated to be higher than above -m64 results. Or
32 # in other words floating-point implementation can be meaningful to
33 # consider only in 32-bit application context. We probably have to
34 # recognize that 32-bit builds are getting less popular on high-end
35 # systems and therefore tend to target embedded ones, which might not
36 # even have FPU...
37 #
38 # On side note, Power ISA 2.07 enables vector base 2^26 implementation,
39 # and POWER8 might have capacity to break 1.0 cycle per byte barrier...
40
41 $flavour = shift;
42
43 if ($flavour =~ /64/) {
44         $SIZE_T =8;
45         $LRSAVE =2*$SIZE_T;
46         $UCMP   ="cmpld";
47         $STU    ="stdu";
48         $POP    ="ld";
49         $PUSH   ="std";
50 } elsif ($flavour =~ /32/) {
51         $SIZE_T =4;
52         $LRSAVE =$SIZE_T;
53         $UCMP   ="cmplw";
54         $STU    ="stwu";
55         $POP    ="lwz";
56         $PUSH   ="stw";
57 } else { die "nonsense $flavour"; }
58
59 # Define endianess based on flavour
60 # i.e.: linux64le
61 $LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
62
63 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
64 ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
65 ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
66 die "can't locate ppc-xlate.pl";
67
68 open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
69
70 $FRAME=24*$SIZE_T;
71
72 $sp="r1";
73 my ($ctx,$inp,$len,$padbit) = map("r$_",(3..6));
74 my ($mac,$nonce)=($inp,$len);
75 my $mask = "r0";
76
77 $code=<<___;
78 .machine        "any"
79 .text
80 ___
81                                                         if ($flavour =~ /64/) {
82 ###############################################################################
83 # base 2^64 implementation
84
85 my ($h0,$h1,$h2,$d0,$d1,$d2, $r0,$r1,$s1, $t0,$t1) = map("r$_",(7..12,27..31));
86
87 $code.=<<___;
88 .globl  .poly1305_init_int
89 .align  4
90 .poly1305_init_int:
91         xor     r0,r0,r0
92         std     r0,0($ctx)              # zero hash value
93         std     r0,8($ctx)
94         std     r0,16($ctx)
95
96         $UCMP   $inp,r0
97         beq-    Lno_key
98 ___
99 $code.=<<___    if ($LITTLE_ENDIAN);
100         ld      $d0,0($inp)             # load key material
101         ld      $d1,8($inp)
102 ___
103 $code.=<<___    if (!$LITTLE_ENDIAN);
104         li      $h0,4
105         lwbrx   $d0,0,$inp              # load key material
106         li      $d1,8
107         lwbrx   $h0,$h0,$inp
108         li      $h1,12
109         lwbrx   $d1,$d1,$inp
110         lwbrx   $h1,$h1,$inp
111         insrdi  $d0,$h0,32,0
112         insrdi  $d1,$h1,32,0
113 ___
114 $code.=<<___;
115         lis     $h1,0xfff               # 0x0fff0000
116         ori     $h1,$h1,0xfffc          # 0x0ffffffc
117         insrdi  $h1,$h1,32,0            # 0x0ffffffc0ffffffc
118         ori     $h0,$h1,3               # 0x0ffffffc0fffffff
119
120         and     $d0,$d0,$h0
121         and     $d1,$d1,$h1
122
123         std     $d0,32($ctx)            # store key
124         std     $d1,40($ctx)
125
126 Lno_key:
127         xor     r3,r3,r3
128         blr
129         .long   0
130         .byte   0,12,0x14,0,0,0,2,0
131 .size   .poly1305_init_int,.-.poly1305_init_int
132
133 .globl  .poly1305_blocks
134 .align  4
135 .poly1305_blocks:
136         srdi.   $len,$len,4
137         beq-    Labort
138
139         $STU    $sp,-$FRAME($sp)
140         mflr    r0
141         $PUSH   r27,`$FRAME-$SIZE_T*5`($sp)
142         $PUSH   r28,`$FRAME-$SIZE_T*4`($sp)
143         $PUSH   r29,`$FRAME-$SIZE_T*3`($sp)
144         $PUSH   r30,`$FRAME-$SIZE_T*2`($sp)
145         $PUSH   r31,`$FRAME-$SIZE_T*1`($sp)
146         $PUSH   r0,`$FRAME+$LRSAVE`($sp)
147
148         ld      $r0,32($ctx)            # load key
149         ld      $r1,40($ctx)
150
151         ld      $h0,0($ctx)             # load hash value
152         ld      $h1,8($ctx)
153         ld      $h2,16($ctx)
154
155         srdi    $s1,$r1,2
156         mtctr   $len
157         add     $s1,$s1,$r1             # s1 = r1 + r1>>2
158         li      $mask,3
159         b       Loop
160
161 .align  4
162 Loop:
163 ___
164 $code.=<<___    if ($LITTLE_ENDIAN);
165         ld      $t0,0($inp)             # load input
166         ld      $t1,8($inp)
167 ___
168 $code.=<<___    if (!$LITTLE_ENDIAN);
169         li      $d0,4
170         lwbrx   $t0,0,$inp              # load input
171         li      $t1,8
172         lwbrx   $d0,$d0,$inp
173         li      $d1,12
174         lwbrx   $t1,$t1,$inp
175         lwbrx   $d1,$d1,$inp
176         insrdi  $t0,$d0,32,0
177         insrdi  $t1,$d1,32,0
178 ___
179 $code.=<<___;
180         addi    $inp,$inp,16
181
182         addc    $h0,$h0,$t0             # accumulate input
183         adde    $h1,$h1,$t1
184
185         mulld   $d0,$h0,$r0             # h0*r0
186         mulhdu  $d1,$h0,$r0
187         adde    $h2,$h2,$padbit
188
189         mulld   $t0,$h1,$s1             # h1*5*r1
190         mulhdu  $t1,$h1,$s1
191         addc    $d0,$d0,$t0
192         adde    $d1,$d1,$t1
193
194         mulld   $t0,$h0,$r1             # h0*r1
195         mulhdu  $d2,$h0,$r1
196         addc    $d1,$d1,$t0
197         addze   $d2,$d2
198
199         mulld   $t0,$h1,$r0             # h1*r0
200         mulhdu  $t1,$h1,$r0
201         addc    $d1,$d1,$t0
202         adde    $d2,$d2,$t1
203
204         mulld   $t0,$h2,$s1             # h2*5*r1
205         mulld   $t1,$h2,$r0             # h2*r0
206         addc    $d1,$d1,$t0
207         adde    $d2,$d2,$t1
208
209         andc    $t0,$d2,$mask           # final reduction step
210         and     $h2,$d2,$mask
211         srdi    $t1,$t0,2
212         add     $t0,$t0,$t1
213         addc    $h0,$d0,$t0
214         addze   $h1,$d1
215
216         bdnz    Loop
217
218         std     $h0,0($ctx)             # store hash value
219         std     $h1,8($ctx)
220         std     $h2,16($ctx)
221
222         $POP    r27,`$FRAME-$SIZE_T*5`($sp)
223         $POP    r28,`$FRAME-$SIZE_T*4`($sp)
224         $POP    r29,`$FRAME-$SIZE_T*3`($sp)
225         $POP    r30,`$FRAME-$SIZE_T*2`($sp)
226         $POP    r31,`$FRAME-$SIZE_T*1`($sp)
227         addi    $sp,$sp,$FRAME
228 Labort:
229         blr
230         .long   0
231         .byte   0,12,4,1,0x80,5,4,0
232 .size   .poly1305_blocks,.-.poly1305_blocks
233
234 .globl  .poly1305_emit
235 .align  4
236 .poly1305_emit:
237         ld      $h0,0($ctx)             # load hash
238         ld      $h1,8($ctx)
239         ld      $h2,16($ctx)
240         ld      $padbit,0($nonce)       # load nonce
241         ld      $nonce,8($nonce)
242
243         addic   $d0,$h0,5               # compare to modulus
244         addze   $d1,$h1
245         addze   $d2,$h2
246
247         srdi    $mask,$d2,2             # did it carry/borrow?
248         neg     $mask,$mask
249
250         andc    $h0,$h0,$mask
251         and     $d0,$d0,$mask
252         andc    $h1,$h1,$mask
253         and     $d1,$d1,$mask
254         or      $h0,$h0,$d0
255         or      $h1,$h1,$d1
256 ___
257 $code.=<<___    if (!$LITTLE_ENDIAN);
258         rotldi  $padbit,$padbit,32      # flip nonce words
259         rotldi  $nonce,$nonce,32
260 ___
261 $code.=<<___;
262         addc    $h0,$h0,$padbit         # accumulate nonce
263         adde    $h1,$h1,$nonce
264 ___
265 $code.=<<___    if ($LITTLE_ENDIAN);
266         std     $h0,0($mac)             # write result
267         std     $h1,8($mac)
268 ___
269 $code.=<<___    if (!$LITTLE_ENDIAN);
270         extrdi  r0,$h0,32,0
271         li      $d0,4
272         stwbrx  $h0,0,$mac              # write result
273         extrdi  $h0,$h1,32,0
274         li      $d1,8
275         stwbrx  r0,$d0,$mac
276         li      $d2,12
277         stwbrx  $h1,$d1,$mac
278         stwbrx  $h0,$d2,$mac
279 ___
280 $code.=<<___;
281         blr
282         .long   0
283         .byte   0,12,0x14,0,0,0,3,0
284 .size   .poly1305_emit,.-.poly1305_emit
285 ___
286                                                         } else {
287 ###############################################################################
288 # base 2^32 implementation
289
290 my ($h0,$h1,$h2,$h3,$h4, $r0,$r1,$r2,$r3, $s1,$s2,$s3,
291     $t0,$t1,$t2,$t3, $D0,$D1,$D2,$D3, $d0,$d1,$d2,$d3
292    ) = map("r$_",(7..12,14..31));
293
294 $code.=<<___;
295 .globl  .poly1305_init_int
296 .align  4
297 .poly1305_init_int:
298         xor     r0,r0,r0
299         stw     r0,0($ctx)              # zero hash value
300         stw     r0,4($ctx)
301         stw     r0,8($ctx)
302         stw     r0,12($ctx)
303         stw     r0,16($ctx)
304
305         $UCMP   $inp,r0
306         beq-    Lno_key
307 ___
308 $code.=<<___    if ($LITTLE_ENDIAN);
309         lw      $h0,0($inp)             # load key material
310         lw      $h1,4($inp)
311         lw      $h2,8($inp)
312         lw      $h3,12($inp)
313 ___
314 $code.=<<___    if (!$LITTLE_ENDIAN);
315         li      $h1,4
316         lwbrx   $h0,0,$inp              # load key material
317         li      $h2,8
318         lwbrx   $h1,$h1,$inp
319         li      $h3,12
320         lwbrx   $h2,$h2,$inp
321         lwbrx   $h3,$h3,$inp
322 ___
323 $code.=<<___;
324         lis     $mask,0xf000            # 0xf0000000
325         li      $r0,-4
326         andc    $r0,$r0,$mask           # 0x0ffffffc
327
328         andc    $h0,$h0,$mask
329         and     $h1,$h1,$r0
330         and     $h2,$h2,$r0
331         and     $h3,$h3,$r0
332
333         stw     $h0,32($ctx)            # store key
334         stw     $h1,36($ctx)
335         stw     $h2,40($ctx)
336         stw     $h3,44($ctx)
337
338 Lno_key:
339         xor     r3,r3,r3
340         blr
341         .long   0
342         .byte   0,12,0x14,0,0,0,2,0
343 .size   .poly1305_init_int,.-.poly1305_init_int
344
345 .globl  .poly1305_blocks
346 .align  4
347 .poly1305_blocks:
348         srwi.   $len,$len,4
349         beq-    Labort
350
351         $STU    $sp,-$FRAME($sp)
352         mflr    r0
353         $PUSH   r14,`$FRAME-$SIZE_T*18`($sp)
354         $PUSH   r15,`$FRAME-$SIZE_T*17`($sp)
355         $PUSH   r16,`$FRAME-$SIZE_T*16`($sp)
356         $PUSH   r17,`$FRAME-$SIZE_T*15`($sp)
357         $PUSH   r18,`$FRAME-$SIZE_T*14`($sp)
358         $PUSH   r19,`$FRAME-$SIZE_T*13`($sp)
359         $PUSH   r20,`$FRAME-$SIZE_T*12`($sp)
360         $PUSH   r21,`$FRAME-$SIZE_T*11`($sp)
361         $PUSH   r22,`$FRAME-$SIZE_T*10`($sp)
362         $PUSH   r23,`$FRAME-$SIZE_T*9`($sp)
363         $PUSH   r24,`$FRAME-$SIZE_T*8`($sp)
364         $PUSH   r25,`$FRAME-$SIZE_T*7`($sp)
365         $PUSH   r26,`$FRAME-$SIZE_T*6`($sp)
366         $PUSH   r27,`$FRAME-$SIZE_T*5`($sp)
367         $PUSH   r28,`$FRAME-$SIZE_T*4`($sp)
368         $PUSH   r29,`$FRAME-$SIZE_T*3`($sp)
369         $PUSH   r30,`$FRAME-$SIZE_T*2`($sp)
370         $PUSH   r31,`$FRAME-$SIZE_T*1`($sp)
371         $PUSH   r0,`$FRAME+$LRSAVE`($sp)
372
373         lwz     $r0,32($ctx)            # load key
374         lwz     $r1,36($ctx)
375         lwz     $r2,40($ctx)
376         lwz     $r3,44($ctx)
377
378         lwz     $h0,0($ctx)             # load hash value
379         lwz     $h1,4($ctx)
380         lwz     $h2,8($ctx)
381         lwz     $h3,12($ctx)
382         lwz     $h4,16($ctx)
383
384         srwi    $s1,$r1,2
385         srwi    $s2,$r2,2
386         srwi    $s3,$r3,2
387         add     $s1,$s1,$r1             # si = ri + ri>>2
388         add     $s2,$s2,$r2
389         add     $s3,$s3,$r3
390         mtctr   $len
391         li      $mask,3
392         b       Loop
393
394 .align  4
395 Loop:
396 ___
397 $code.=<<___    if ($LITTLE_ENDIAN);
398         lwz     $d0,0($inp)             # load input
399         lwz     $d1,4($inp)
400         lwz     $d2,8($inp)
401         lwz     $d3,12($inp)
402 ___
403 $code.=<<___    if (!$LITTLE_ENDIAN);
404         li      $d1,4
405         lwbrx   $d0,0,$inp              # load input
406         li      $d2,8
407         lwbrx   $d1,$d1,$inp
408         li      $d3,12
409         lwbrx   $d2,$d2,$inp
410         lwbrx   $d3,$d3,$inp
411 ___
412 $code.=<<___;
413         addi    $inp,$inp,16
414
415         addc    $h0,$h0,$d0             # accumulate input
416         adde    $h1,$h1,$d1
417         adde    $h2,$h2,$d2
418
419         mullw   $d0,$h0,$r0             # h0*r0
420         mulhwu  $D0,$h0,$r0
421
422         mullw   $d1,$h0,$r1             # h0*r1
423         mulhwu  $D1,$h0,$r1
424
425         mullw   $d2,$h0,$r2             # h0*r2
426         mulhwu  $D2,$h0,$r2
427
428          adde   $h3,$h3,$d3
429          adde   $h4,$h4,$padbit
430
431         mullw   $d3,$h0,$r3             # h0*r3
432         mulhwu  $D3,$h0,$r3
433
434         mullw   $t0,$h1,$s3             # h1*s3
435         mulhwu  $t1,$h1,$s3
436
437         mullw   $t2,$h1,$r0             # h1*r0
438         mulhwu  $t3,$h1,$r0
439          addc   $d0,$d0,$t0
440          adde   $D0,$D0,$t1
441
442         mullw   $t0,$h1,$r1             # h1*r1
443         mulhwu  $t1,$h1,$r1
444          addc   $d1,$d1,$t2
445          adde   $D1,$D1,$t3
446
447         mullw   $t2,$h1,$r2             # h1*r2
448         mulhwu  $t3,$h1,$r2
449          addc   $d2,$d2,$t0
450          adde   $D2,$D2,$t1
451
452         mullw   $t0,$h2,$s2             # h2*s2
453         mulhwu  $t1,$h2,$s2
454          addc   $d3,$d3,$t2
455          adde   $D3,$D3,$t3
456
457         mullw   $t2,$h2,$s3             # h2*s3
458         mulhwu  $t3,$h2,$s3
459          addc   $d0,$d0,$t0
460          adde   $D0,$D0,$t1
461
462         mullw   $t0,$h2,$r0             # h2*r0
463         mulhwu  $t1,$h2,$r0
464          addc   $d1,$d1,$t2
465          adde   $D1,$D1,$t3
466
467         mullw   $t2,$h2,$r1             # h2*r1
468         mulhwu  $t3,$h2,$r1
469          addc   $d2,$d2,$t0
470          adde   $D2,$D2,$t1
471
472         mullw   $t0,$h3,$s1             # h3*s1
473         mulhwu  $t1,$h3,$s1
474          addc   $d3,$d3,$t2
475          adde   $D3,$D3,$t3
476
477         mullw   $t2,$h3,$s2             # h3*s2
478         mulhwu  $t3,$h3,$s2
479          addc   $d0,$d0,$t0
480          adde   $D0,$D0,$t1
481
482         mullw   $t0,$h3,$s3             # h3*s3
483         mulhwu  $t1,$h3,$s3
484          addc   $d1,$d1,$t2
485          adde   $D1,$D1,$t3
486
487         mullw   $t2,$h3,$r0             # h3*r0
488         mulhwu  $t3,$h3,$r0
489          addc   $d2,$d2,$t0
490          adde   $D2,$D2,$t1
491
492         mullw   $t0,$h4,$s1             # h4*s1
493          addc   $d3,$d3,$t2
494          adde   $D3,$D3,$t3
495         addc    $d1,$d1,$t0
496
497         mullw   $t1,$h4,$s2             # h4*s2
498          addze  $D1,$D1
499         addc    $d2,$d2,$t1
500         addze   $D2,$D2
501
502         mullw   $t2,$h4,$s3             # h4*s3
503         addc    $d3,$d3,$t2
504         addze   $D3,$D3
505
506         mullw   $h4,$h4,$r0             # h4*r0
507
508         addc    $h1,$d1,$D0
509         adde    $h2,$d2,$D1
510         adde    $h3,$d3,$D2
511         adde    $h4,$h4,$D3
512
513         andc    $D0,$h4,$mask           # final reduction step
514         and     $h4,$h4,$mask
515         srwi    $D1,$D0,2
516         add     $D0,$D0,$D1
517         addc    $h0,$d0,$D0
518         addze   $h1,$h1
519         addze   $h2,$h2
520         addze   $h3,$h3
521
522         bdnz    Loop
523
524         stw     $h0,0($ctx)             # store hash value
525         stw     $h1,4($ctx)
526         stw     $h2,8($ctx)
527         stw     $h3,12($ctx)
528         stw     $h4,16($ctx)
529
530         $POP    r14,`$FRAME-$SIZE_T*18`($sp)
531         $POP    r15,`$FRAME-$SIZE_T*17`($sp)
532         $POP    r16,`$FRAME-$SIZE_T*16`($sp)
533         $POP    r17,`$FRAME-$SIZE_T*15`($sp)
534         $POP    r18,`$FRAME-$SIZE_T*14`($sp)
535         $POP    r19,`$FRAME-$SIZE_T*13`($sp)
536         $POP    r20,`$FRAME-$SIZE_T*12`($sp)
537         $POP    r21,`$FRAME-$SIZE_T*11`($sp)
538         $POP    r22,`$FRAME-$SIZE_T*10`($sp)
539         $POP    r23,`$FRAME-$SIZE_T*9`($sp)
540         $POP    r24,`$FRAME-$SIZE_T*8`($sp)
541         $POP    r25,`$FRAME-$SIZE_T*7`($sp)
542         $POP    r26,`$FRAME-$SIZE_T*6`($sp)
543         $POP    r27,`$FRAME-$SIZE_T*5`($sp)
544         $POP    r28,`$FRAME-$SIZE_T*4`($sp)
545         $POP    r29,`$FRAME-$SIZE_T*3`($sp)
546         $POP    r30,`$FRAME-$SIZE_T*2`($sp)
547         $POP    r31,`$FRAME-$SIZE_T*1`($sp)
548         addi    $sp,$sp,$FRAME
549 Labort:
550         blr
551         .long   0
552         .byte   0,12,4,1,0x80,18,4,0
553 .size   .poly1305_blocks,.-.poly1305_blocks
554
555 .globl  .poly1305_emit
556 .align  4
557 .poly1305_emit:
558         $STU    $sp,-$FRAME($sp)
559         mflr    r0
560         $PUSH   r28,`$FRAME-$SIZE_T*4`($sp)
561         $PUSH   r29,`$FRAME-$SIZE_T*3`($sp)
562         $PUSH   r30,`$FRAME-$SIZE_T*2`($sp)
563         $PUSH   r31,`$FRAME-$SIZE_T*1`($sp)
564         $PUSH   r0,`$FRAME+$LRSAVE`($sp)
565
566         lwz     $h0,0($ctx)             # load hash
567         lwz     $h1,4($ctx)
568         lwz     $h2,8($ctx)
569         lwz     $h3,12($ctx)
570         lwz     $h4,16($ctx)
571
572         addic   $d0,$h0,5               # compare to modulus
573         addze   $d1,$h1
574         addze   $d2,$h2
575         addze   $d3,$h3
576         addze   $mask,$h4
577
578         srwi    $mask,$mask,2           # did it carry/borrow?
579         neg     $mask,$mask
580
581         andc    $h0,$h0,$mask
582         and     $d0,$d0,$mask
583         andc    $h1,$h1,$mask
584         and     $d1,$d1,$mask
585         or      $h0,$h0,$d0
586         lwz     $d0,0($nonce)           # load nonce
587         andc    $h2,$h2,$mask
588         and     $d2,$d2,$mask
589         or      $h1,$h1,$d1
590         lwz     $d1,4($nonce)
591         andc    $h3,$h3,$mask
592         and     $d3,$d3,$mask
593         or      $h2,$h2,$d2
594         lwz     $d2,8($nonce)
595         or      $h3,$h3,$d3
596         lwz     $d3,12($nonce)
597
598         addc    $h0,$h0,$d0             # accumulate nonce
599         adde    $h1,$h1,$d1
600         adde    $h2,$h2,$d2
601         adde    $h3,$h3,$d3
602 ___
603 $code.=<<___    if ($LITTLE_ENDIAN);
604         stw     $h0,0($mac)             # write result
605         stw     $h1,4($mac)
606         stw     $h2,8($mac)
607         stw     $h3,12($mac)
608 ___
609 $code.=<<___    if (!$LITTLE_ENDIAN);
610         li      $d1,4
611         stwbrx  $h0,0,$mac              # write result
612         li      $d2,8
613         stwbrx  $h1,$d1,$mac
614         li      $d3,12
615         stwbrx  $h2,$d2,$mac
616         stwbrx  $h3,$d3,$mac
617 ___
618 $code.=<<___;
619         $POP    r28,`$FRAME-$SIZE_T*4`($sp)
620         $POP    r29,`$FRAME-$SIZE_T*3`($sp)
621         $POP    r30,`$FRAME-$SIZE_T*2`($sp)
622         $POP    r31,`$FRAME-$SIZE_T*1`($sp)
623         addi    $sp,$sp,$FRAME
624         blr
625         .long   0
626         .byte   0,12,4,1,0x80,4,3,0
627 .size   .poly1305_emit,.-.poly1305_emit
628 ___
629                                                         }
630 $code.=<<___;
631 .asciz  "Poly1305 for PPC, CRYPTOGAMS by <appro\@openssl.org>"
632 ___
633
634 $code =~ s/\`([^\`]*)\`/eval $1/gem;
635 print $code;
636 close STDOUT;