]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/sha/asm/sha512-ppc.pl
Unify ppc assembler make rules.
[thirdparty/openssl.git] / crypto / sha / asm / sha512-ppc.pl
CommitLineData
17478fde
AP
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
7af57261
AP
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/.
17478fde
AP
8# ====================================================================
9
10# I let hardware handle unaligned input, except on page boundaries
11# (see below for details). Otherwise straightforward implementation
12# with X vector in register bank. The module is big-endian [which is
13# not big deal as there're no little-endian targets left around].
14
15# sha256 | sha512
16# -m64 -m32 | -m64 -m32
17# --------------------------------------+-----------------------
18# PPC970,gcc-4.0.0 +50% +38% | +40% +410%(*)
399f94bf 19# Power6,xlc-7 +150% +90% | +100% +430%(*)
17478fde
AP
20#
21# (*) 64-bit code in 32-bit application context, which actually is
7af57261
AP
22# on TODO list. It should be noted that for safe deployment in
23# 32-bit *mutli-threaded* context asyncronous signals should be
24# blocked upon entry to SHA512 block routine. This is because
25# 32-bit signaling procedure invalidates upper halves of GPRs.
26# Context switch procedure preserves them, but not signaling:-(
27
28# Second version is true multi-thread safe. Trouble with the original
29# version was that it was using thread local storage pointer register.
30# Well, it scrupulously preserved it, but the problem would arise the
31# moment asynchronous signal was delivered and signal handler would
32# dereference the TLS pointer. While it's never the case in openssl
33# application or test suite, we have to respect this scenario and not
34# use TLS pointer register. Alternative would be to require caller to
35# block signals prior calling this routine. For the record, in 32-bit
36# context R2 serves as TLS pointer, while in 64-bit context - R13.
17478fde 37
addd641f
AP
38$flavour=shift;
39$output =shift;
17478fde 40
addd641f 41if ($flavour =~ /64/) {
17478fde
AP
42 $SIZE_T=8;
43 $STU="stdu";
44 $UCMP="cmpld";
45 $SHL="sldi";
46 $POP="ld";
47 $PUSH="std";
addd641f 48} elsif ($flavour =~ /32/) {
17478fde
AP
49 $SIZE_T=4;
50 $STU="stwu";
51 $UCMP="cmplw";
52 $SHL="slwi";
53 $POP="lwz";
54 $PUSH="stw";
addd641f 55} else { die "nonsense $flavour"; }
17478fde 56
addd641f
AP
57$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
58( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
59( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
60die "can't locate ppc-xlate.pl";
61
62open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
17478fde
AP
63
64if ($output =~ /512/) {
c5f17d45 65 $func="sha512_block_data_order";
17478fde
AP
66 $SZ=8;
67 @Sigma0=(28,34,39);
68 @Sigma1=(14,18,41);
69 @sigma0=(1, 8, 7);
70 @sigma1=(19,61, 6);
71 $rounds=80;
72 $LD="ld";
73 $ST="std";
74 $ROR="rotrdi";
75 $SHR="srdi";
76} else {
c5f17d45 77 $func="sha256_block_data_order";
17478fde
AP
78 $SZ=4;
79 @Sigma0=( 2,13,22);
80 @Sigma1=( 6,11,25);
81 @sigma0=( 7,18, 3);
82 @sigma1=(17,19,10);
83 $rounds=64;
84 $LD="lwz";
85 $ST="stw";
86 $ROR="rotrwi";
87 $SHR="srwi";
88}
89
90$FRAME=32*$SIZE_T;
91
92$sp ="r1";
7af57261 93$toc="r2";
17478fde 94$ctx="r3"; # zapped by $a0
7af57261
AP
95$inp="r4"; # zapped by $a1
96$num="r5"; # zapped by $t0
17478fde
AP
97
98$T ="r0";
17478fde 99$a0 ="r3";
7af57261
AP
100$a1 ="r4";
101$t0 ="r5";
102$t1 ="r6";
103$Tbl="r7";
17478fde
AP
104
105$A ="r8";
106$B ="r9";
107$C ="r10";
108$D ="r11";
109$E ="r12";
7af57261 110$F ="r13"; $F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer
17478fde
AP
111$G ="r14";
112$H ="r15";
113
114@V=($A,$B,$C,$D,$E,$F,$G,$H);
115@X=("r16","r17","r18","r19","r20","r21","r22","r23",
116 "r24","r25","r26","r27","r28","r29","r30","r31");
117
7af57261
AP
118$inp="r31"; # reassigned $inp! aliases with @X[15]
119
17478fde
AP
120sub ROUND_00_15 {
121my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
122$code.=<<___;
123 $LD $T,`$i*$SZ`($Tbl)
124 $ROR $a0,$e,$Sigma1[0]
125 $ROR $a1,$e,$Sigma1[1]
126 and $t0,$f,$e
127 andc $t1,$g,$e
128 add $T,$T,$h
129 xor $a0,$a0,$a1
130 $ROR $a1,$a1,`$Sigma1[2]-$Sigma1[1]`
131 or $t0,$t0,$t1 ; Ch(e,f,g)
132 add $T,$T,@X[$i]
133 xor $a0,$a0,$a1 ; Sigma1(e)
134 add $T,$T,$t0
135 add $T,$T,$a0
136
137 $ROR $a0,$a,$Sigma0[0]
138 $ROR $a1,$a,$Sigma0[1]
139 and $t0,$a,$b
140 and $t1,$a,$c
141 xor $a0,$a0,$a1
142 $ROR $a1,$a1,`$Sigma0[2]-$Sigma0[1]`
143 xor $t0,$t0,$t1
144 and $t1,$b,$c
145 xor $a0,$a0,$a1 ; Sigma0(a)
146 add $d,$d,$T
147 xor $t0,$t0,$t1 ; Maj(a,b,c)
148 add $h,$T,$a0
149 add $h,$h,$t0
150
151___
152}
153
154sub ROUND_16_xx {
155my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
156$i-=16;
157$code.=<<___;
158 $ROR $a0,@X[($i+1)%16],$sigma0[0]
159 $ROR $a1,@X[($i+1)%16],$sigma0[1]
160 $ROR $t0,@X[($i+14)%16],$sigma1[0]
161 $ROR $t1,@X[($i+14)%16],$sigma1[1]
162 xor $a0,$a0,$a1
163 $SHR $a1,@X[($i+1)%16],$sigma0[2]
164 xor $t0,$t0,$t1
165 $SHR $t1,@X[($i+14)%16],$sigma1[2]
166 add @X[$i],@X[$i],@X[($i+9)%16]
167 xor $a0,$a0,$a1 ; sigma0(X[(i+1)&0x0f])
168 xor $t0,$t0,$t1 ; sigma1(X[(i+14)&0x0f])
169 add @X[$i],@X[$i],$a0
170 add @X[$i],@X[$i],$t0
171___
172&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h);
173}
174
175$code=<<___;
176.text
177
178.globl $func
179.align 6
180$func:
181 mflr r0
182 $STU $sp,`-($FRAME+16*$SZ)`($sp)
183 $SHL $num,$num,`log(16*$SZ)/log(2)`
184
185 $PUSH $ctx,`$FRAME-$SIZE_T*22`($sp)
186
187 $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
188 $PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
189 $PUSH r13,`$FRAME-$SIZE_T*19`($sp)
190 $PUSH r14,`$FRAME-$SIZE_T*18`($sp)
191 $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
192 $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
193 $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
194 $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
195 $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
196 $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
197 $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
198 $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
199 $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
200 $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
201 $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
202 $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
203 $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
204 $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
205 $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
206 $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
207 $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
208
209 $LD $A,`0*$SZ`($ctx)
7af57261 210 mr $inp,r4 ; incarnate $inp
17478fde
AP
211 $LD $B,`1*$SZ`($ctx)
212 $LD $C,`2*$SZ`($ctx)
213 $LD $D,`3*$SZ`($ctx)
214 $LD $E,`4*$SZ`($ctx)
215 $LD $F,`5*$SZ`($ctx)
216 $LD $G,`6*$SZ`($ctx)
217 $LD $H,`7*$SZ`($ctx)
218
219 b LPICmeup
220LPICedup:
221 andi. r0,$inp,3
222 bne Lunaligned
223Laligned:
7af57261
AP
224 add $num,$inp,$num
225 $PUSH $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer
226 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
17478fde
AP
227 bl Lsha2_block_private
228Ldone:
229 $POP r0,`$FRAME-$SIZE_T*21`($sp)
230 $POP $toc,`$FRAME-$SIZE_T*20`($sp)
231 $POP r13,`$FRAME-$SIZE_T*19`($sp)
232 $POP r14,`$FRAME-$SIZE_T*18`($sp)
233 $POP r15,`$FRAME-$SIZE_T*17`($sp)
234 $POP r16,`$FRAME-$SIZE_T*16`($sp)
235 $POP r17,`$FRAME-$SIZE_T*15`($sp)
236 $POP r18,`$FRAME-$SIZE_T*14`($sp)
237 $POP r19,`$FRAME-$SIZE_T*13`($sp)
238 $POP r20,`$FRAME-$SIZE_T*12`($sp)
239 $POP r21,`$FRAME-$SIZE_T*11`($sp)
240 $POP r22,`$FRAME-$SIZE_T*10`($sp)
241 $POP r23,`$FRAME-$SIZE_T*9`($sp)
242 $POP r24,`$FRAME-$SIZE_T*8`($sp)
243 $POP r25,`$FRAME-$SIZE_T*7`($sp)
244 $POP r26,`$FRAME-$SIZE_T*6`($sp)
245 $POP r27,`$FRAME-$SIZE_T*5`($sp)
246 $POP r28,`$FRAME-$SIZE_T*4`($sp)
247 $POP r29,`$FRAME-$SIZE_T*3`($sp)
248 $POP r30,`$FRAME-$SIZE_T*2`($sp)
249 $POP r31,`$FRAME-$SIZE_T*1`($sp)
250 mtlr r0
251 addi $sp,$sp,`$FRAME+16*$SZ`
252 blr
253___
254
255# PowerPC specification allows an implementation to be ill-behaved
256# upon unaligned access which crosses page boundary. "Better safe
257# than sorry" principle makes me treat it specially. But I don't
258# look for particular offending word, but rather for the input
259# block which crosses the boundary. Once found that block is aligned
260# and hashed separately...
261$code.=<<___;
262.align 4
263Lunaligned:
264 subfic $t1,$inp,4096
265 andi. $t1,$t1,`4096-16*$SZ` ; distance to closest page boundary
266 beq Lcross_page
267 $UCMP $num,$t1
268 ble- Laligned ; didn't cross the page boundary
269 subfc $num,$t1,$num
7af57261
AP
270 add $t1,$inp,$t1
271 $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real remaining num
272 $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; intermediate end pointer
273 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
17478fde 274 bl Lsha2_block_private
7af57261
AP
275 ; $inp equals to the intermediate end pointer here
276 $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real remaining num
17478fde
AP
277Lcross_page:
278 li $t1,`16*$SZ/4`
279 mtctr $t1
7af57261 280 addi r20,$sp,$FRAME ; aligned spot below the frame
17478fde
AP
281Lmemcpy:
282 lbz r16,0($inp)
283 lbz r17,1($inp)
284 lbz r18,2($inp)
285 lbz r19,3($inp)
286 addi $inp,$inp,4
287 stb r16,0(r20)
288 stb r17,1(r20)
289 stb r18,2(r20)
290 stb r19,3(r20)
291 addi r20,r20,4
292 bdnz Lmemcpy
293
7af57261
AP
294 $PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp
295 addi $t1,$sp,`$FRAME+16*$SZ` ; fictitious end pointer
296 addi $inp,$sp,$FRAME ; fictitious inp pointer
297 $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real num
298 $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; end pointer
299 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
17478fde 300 bl Lsha2_block_private
7af57261
AP
301 $POP $inp,`$FRAME-$SIZE_T*26`($sp) ; restore real inp
302 $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real num
303 addic. $num,$num,`-16*$SZ` ; num--
17478fde
AP
304 bne- Lunaligned
305 b Ldone
306___
307
308$code.=<<___;
309.align 4
310Lsha2_block_private:
311___
312for($i=0;$i<16;$i++) {
313$code.=<<___ if ($SZ==4);
314 lwz @X[$i],`$i*$SZ`($inp)
315___
316# 64-bit loads are split to 2x32-bit ones, as CPU can't handle
317# unaligned 64-bit loads, only 32-bit ones...
318$code.=<<___ if ($SZ==8);
319 lwz $t0,`$i*$SZ`($inp)
320 lwz @X[$i],`$i*$SZ+4`($inp)
321 insrdi @X[$i],$t0,32,0
322___
323 &ROUND_00_15($i,@V);
324 unshift(@V,pop(@V));
325}
326$code.=<<___;
327 li $T,`$rounds/16-1`
328 mtctr $T
329.align 4
330Lrounds:
331 addi $Tbl,$Tbl,`16*$SZ`
332___
333for(;$i<32;$i++) {
334 &ROUND_16_xx($i,@V);
335 unshift(@V,pop(@V));
336}
337$code.=<<___;
338 bdnz- Lrounds
339
17478fde 340 $POP $ctx,`$FRAME-$SIZE_T*22`($sp)
7af57261
AP
341 $POP $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
342 $POP $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer
343 subi $Tbl,$Tbl,`($rounds-16)*$SZ` ; rewind Tbl
17478fde
AP
344
345 $LD r16,`0*$SZ`($ctx)
346 $LD r17,`1*$SZ`($ctx)
347 $LD r18,`2*$SZ`($ctx)
348 $LD r19,`3*$SZ`($ctx)
349 $LD r20,`4*$SZ`($ctx)
350 $LD r21,`5*$SZ`($ctx)
351 $LD r22,`6*$SZ`($ctx)
7af57261 352 addi $inp,$inp,`16*$SZ` ; advance inp
17478fde
AP
353 $LD r23,`7*$SZ`($ctx)
354 add $A,$A,r16
355 add $B,$B,r17
7af57261 356 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp)
17478fde
AP
357 add $C,$C,r18
358 $ST $A,`0*$SZ`($ctx)
359 add $D,$D,r19
360 $ST $B,`1*$SZ`($ctx)
361 add $E,$E,r20
362 $ST $C,`2*$SZ`($ctx)
363 add $F,$F,r21
364 $ST $D,`3*$SZ`($ctx)
365 add $G,$G,r22
366 $ST $E,`4*$SZ`($ctx)
367 add $H,$H,r23
368 $ST $F,`5*$SZ`($ctx)
17478fde
AP
369 $ST $G,`6*$SZ`($ctx)
370 $UCMP $inp,$num
371 $ST $H,`7*$SZ`($ctx)
372 bne Lsha2_block_private
373 blr
374___
375
376# Ugly hack here, because PPC assembler syntax seem to vary too
377# much from platforms to platform...
378$code.=<<___;
379.align 6
380LPICmeup:
381 bl LPIC
7af57261 382 addi $Tbl,$Tbl,`64-4` ; "distance" between . and last nop
17478fde
AP
383 b LPICedup
384 nop
385 nop
386 nop
387 nop
388 nop
17478fde 389LPIC: mflr $Tbl
17478fde
AP
390 blr
391 nop
392 nop
393 nop
394 nop
395 nop
7af57261 396 nop
17478fde
AP
397___
398$code.=<<___ if ($SZ==8);
399 .long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
400 .long 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
401 .long 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
402 .long 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
403 .long 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
404 .long 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
405 .long 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
406 .long 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
407 .long 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
408 .long 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
409 .long 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
410 .long 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
411 .long 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
412 .long 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
413 .long 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
414 .long 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
415 .long 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
416 .long 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
417 .long 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
418 .long 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
419 .long 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
420 .long 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
421 .long 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
422 .long 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
423 .long 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
424 .long 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
425 .long 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
426 .long 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
427 .long 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
428 .long 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
429 .long 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
430 .long 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
431 .long 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
432 .long 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
433 .long 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
434 .long 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
435 .long 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
436 .long 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
437 .long 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
438 .long 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
439___
440$code.=<<___ if ($SZ==4);
441 .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
442 .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
443 .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
444 .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
445 .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
446 .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
447 .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
448 .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
449 .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
450 .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
451 .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
452 .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
453 .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
454 .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
455 .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
456 .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
457___
458
459$code =~ s/\`([^\`]*)\`/eval $1/gem;
460print $code;
461close STDOUT;