Detect UltraSPARC T1 in ./config.
[openssl.git] / crypto / sha / asm / sha512-sparcv9.pl
1 #!/usr/bin/env perl
2
3 # ====================================================================
4 # Written by Andy Polyakov <appro@fy.chalmers.se> 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 # SHA256 performance improvement over compiler generated code varies
11 # from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit
12 # build]. Just like in SHA1 module I aim to ensure scalability on
13 # UltraSPARC T1 by packing X[16] to 8 64-bit registers.
14
15 # SHA512 on pre-T1 UltraSPARC.
16 #
17 # Performance is >75% better than 64-bit code generated by Sun C and
18 # over 2x than 32-bit code. X[16] resides on stack, but access to it
19 # is scheduled for L2 latency and staged through 32 least significant
20 # bits of %l0-%l7. The latter is done to achieve 32-/64-bit bit ABI
21 # duality. Nevetheless it's ~40% faster than SHA256, which is pretty
22 # good [optimal coefficient is 50%].
23 #
24 # SHA512 on UltraSPARC T1.
25 #
26 # ...
27
28 $bits=32;
29 for (@ARGV)     { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
30 if ($bits==64)  { $bias=2047; $frame=192; }
31 else            { $bias=0;    $frame=112; }
32
33 $output=shift;
34 open STDOUT,">$output";
35
36 if ($output =~ /512/) {
37         $label="512";
38         $SZ=8;
39         $LD="ldx";              # load from memory
40         $ST="stx";              # store to memory
41         $SLL="sllx";            # shift left logical
42         $SRL="srlx";            # shift right logical
43         @Sigma0=(28,34,39);
44         @Sigma1=(14,18,41);
45         @sigma0=( 7, 1, 8);     # right shift first
46         @sigma1=( 6,19,61);     # right shift first
47         $lastK=0x817;
48         $rounds=80;
49         $align=4;
50
51         $locals=16*$SZ;         # X[16]
52
53         $A="%o0";
54         $B="%o1";
55         $C="%o2";
56         $D="%o3";
57         $E="%o4";
58         $F="%o5";
59         $G="%g1";
60         $H="%o7";
61         @V=($A,$B,$C,$D,$E,$F,$G,$H);
62 } else {
63         $label="256";
64         $SZ=4;
65         $LD="ld";               # load from memory
66         $ST="st";               # store to memory
67         $SLL="sll";             # shift left logical
68         $SRL="srl";             # shift right logical
69         @Sigma0=( 2,13,22);
70         @Sigma1=( 6,11,25);
71         @sigma0=( 3, 7,18);     # right shift first
72         @sigma1=(10,17,19);     # right shift first
73         $lastK=0x8f2;
74         $rounds=64;
75         $align=8;
76
77         $locals=0;              # X[16] is register resident
78         @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
79         
80         $A="%l0";
81         $B="%l1";
82         $C="%l2";
83         $D="%l3";
84         $E="%l4";
85         $F="%l5";
86         $G="%l6";
87         $H="%l7";
88         @V=($A,$B,$C,$D,$E,$F,$G,$H);
89 }
90 $T1="%g2";
91 $tmp0="%g3";
92 $tmp1="%g4";
93 $tmp2="%g5";
94
95 $ctx="%i0";
96 $inp="%i1";
97 $len="%i2";
98 $Ktbl="%i3";
99 $tmp31="%i4";
100 $tmp32="%i5";
101
102 ########### SHA256
103 $Xload = sub {
104 my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
105
106     if ($i==0) {
107 $code.=<<___;
108         ldx     [$inp+0],@X[0]
109         ldx     [$inp+16],@X[2]
110         ldx     [$inp+32],@X[4]
111         ldx     [$inp+48],@X[6]
112         ldx     [$inp+8],@X[1]
113         ldx     [$inp+24],@X[3]
114         subcc   %g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too
115         ldx     [$inp+40],@X[5]
116         bz,pt   %icc,.Laligned
117         ldx     [$inp+56],@X[7]
118
119         sllx    @X[0],$tmp31,@X[0]
120         ldx     [$inp+64],$T1
121 ___
122 for($j=0;$j<7;$j++)
123 {   $code.=<<___;
124         srlx    @X[$j+1],$tmp32,$tmp1
125         sllx    @X[$j+1],$tmp31,@X[$j+1]
126         or      $tmp1,@X[$j],@X[$j]
127 ___
128 }
129 $code.=<<___;
130         srlx    $T1,$tmp32,$T1
131         or      $T1,@X[7],@X[7]
132 .Laligned:
133 ___
134     }
135
136     if ($i&1) {
137         $code.="\tadd   @X[$i/2],$h,$T1\n";
138     } else {
139         $code.="\tsrlx  @X[$i/2],32,$T1\n\tadd  $h,$T1,$T1\n";
140     }
141 } if ($SZ==4);
142
143 ########### SHA512
144 $Xload = sub {
145 my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
146 my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8));
147
148 $code.=<<___ if ($i==0);
149         ld      [$inp+0],%l0
150         ld      [$inp+4],%l1
151         ld      [$inp+8],%l2
152         ld      [$inp+12],%l3
153         ld      [$inp+16],%l4
154         ld      [$inp+20],%l5
155         ld      [$inp+24],%l6
156         ld      [$inp+28],%l7
157 ___
158 $code.=<<___ if ($i<15);
159         sllx    @pair[1],$tmp31,$tmp2   ! Xload($i)
160         add     $tmp31,32,$tmp0
161         sllx    @pair[0],$tmp0,$tmp1
162         `"ld    [$inp+".eval(32+0+$i*8)."],@pair[0]"    if ($i<12)`
163         srlx    @pair[2],$tmp32,@pair[1]
164         or      $tmp1,$tmp2,$tmp2
165         or      @pair[1],$tmp2,$tmp2
166         `"ld    [$inp+".eval(32+4+$i*8)."],@pair[1]"    if ($i<12)`
167         add     $h,$tmp2,$T1
168         $ST     $tmp2,[%sp+`$bias+$frame+$i*$SZ`]
169 ___
170 $code.=<<___ if ($i==12);
171         brnz,a  $tmp31,.+8
172         ld      [$inp+128],%l0
173 ___
174 $code.=<<___ if ($i==15);
175         ld      [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
176         sllx    @pair[1],$tmp31,$tmp2   ! Xload($i)
177         add     $tmp31,32,$tmp0
178         ld      [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
179         sllx    @pair[0],$tmp0,$tmp1
180         ld      [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
181         srlx    @pair[2],$tmp32,@pair[1]
182         or      $tmp1,$tmp2,$tmp2
183         ld      [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
184         or      @pair[1],$tmp2,$tmp2
185         ld      [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
186         add     $h,$tmp2,$T1
187         $ST     $tmp2,[%sp+`$bias+$frame+$i*$SZ`]
188         ld      [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
189         ld      [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
190         ld      [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
191 ___
192 } if ($SZ==8);
193
194 ########### common
195 sub BODY_00_15 {
196 my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
197
198     if ($i<16) {
199         &$Xload(@_);
200     } else {
201         $code.="\tadd   $h,$T1,$T1\n";
202     }
203
204 $code.=<<___;
205         $SRL    $e,@Sigma1[0],$h        !! $i
206         xor     $f,$g,$tmp2
207         $SLL    $e,`$SZ*8-@Sigma1[2]`,$tmp1
208         and     $e,$tmp2,$tmp2
209         $SRL    $e,@Sigma1[1],$tmp0
210         xor     $tmp1,$h,$h
211         $SLL    $e,`$SZ*8-@Sigma1[1]`,$tmp1
212         xor     $tmp0,$h,$h
213         $SRL    $e,@Sigma1[2],$tmp0
214         xor     $tmp1,$h,$h
215         $SLL    $e,`$SZ*8-@Sigma1[0]`,$tmp1
216         xor     $tmp0,$h,$h
217         xor     $g,$tmp2,$tmp2          ! Ch(e,f,g)
218         xor     $tmp1,$h,$tmp0          ! Sigma1(e)
219
220         $SRL    $a,@Sigma0[0],$h
221         add     $tmp2,$T1,$T1
222         $LD     [$Ktbl+`$i*$SZ`],$tmp2  ! K[$i]
223         $SLL    $a,`$SZ*8-@Sigma0[2]`,$tmp1
224         add     $tmp0,$T1,$T1
225         $SRL    $a,@Sigma0[1],$tmp0
226         xor     $tmp1,$h,$h
227         $SLL    $a,`$SZ*8-@Sigma0[1]`,$tmp1
228         xor     $tmp0,$h,$h
229         $SRL    $a,@Sigma0[2],$tmp0
230         xor     $tmp1,$h,$h     
231         $SLL    $a,`$SZ*8-@Sigma0[0]`,$tmp1
232         xor     $tmp0,$h,$h
233         xor     $tmp1,$h,$h             ! Sigma0(a)
234
235         or      $a,$b,$tmp0
236         and     $a,$b,$tmp1
237         and     $c,$tmp0,$tmp0
238         or      $tmp0,$tmp1,$tmp1       ! Maj(a,b,c)
239         add     $tmp2,$T1,$T1           ! +=K[$i]
240         add     $tmp1,$h,$h
241
242         add     $T1,$d,$d
243         add     $T1,$h,$h
244 ___
245 }
246
247 ########### SHA256
248 $BODY_16_XX = sub {
249 my $i=@_[0];
250 my $xi;
251
252     if ($i&1) {
253         $xi=$tmp32;
254         $code.="\tsrlx  @X[(($i+1)/2)%8],32,$xi\n";
255     } else {
256         $xi=@X[(($i+1)/2)%8];
257     }
258 $code.=<<___;
259         srl     $xi,@sigma0[0],$T1              !! Xupdate($i)
260         sll     $xi,`32-@sigma0[2]`,$tmp1
261         srl     $xi,@sigma0[1],$tmp0
262         xor     $tmp1,$T1,$T1
263         sll     $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
264         xor     $tmp0,$T1,$T1
265         srl     $xi,@sigma0[2],$tmp0
266         xor     $tmp1,$T1,$T1
267 ___
268     if ($i&1) {
269         $xi=@X[(($i+14)/2)%8];
270     } else {
271         $xi=$tmp32;
272         $code.="\tsrlx  @X[(($i+14)/2)%8],32,$xi\n";
273     }
274 $code.=<<___;
275         srl     $xi,@sigma1[0],$tmp2
276         xor     $tmp0,$T1,$T1                   ! T1=sigma0(X[i+1])
277         sll     $xi,`32-@sigma1[2]`,$tmp1
278         srl     $xi,@sigma1[1],$tmp0
279         xor     $tmp1,$tmp2,$tmp2
280         sll     $tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1
281         xor     $tmp0,$tmp2,$tmp2
282         srl     $xi,@sigma1[2],$tmp0
283         xor     $tmp1,$tmp2,$tmp2
284 ___
285     if ($i&1) {
286         $xi=@X[($i/2)%8];
287 $code.=<<___;
288         srlx    @X[(($i+9)/2)%8],32,$tmp1       ! X[i+9]
289         xor     $tmp0,$tmp2,$tmp2               ! sigma1(X[i+14])
290         srl     @X[($i/2)%8],0,$tmp0
291         add     $xi,$T1,$T1                     ! +=X[i]
292         xor     $tmp0,@X[($i/2)%8],@X[($i/2)%8]
293         add     $tmp2,$T1,$T1
294         add     $tmp1,$T1,$T1
295
296         srl     $T1,0,$T1
297         or      $T1,@X[($i/2)%8],@X[($i/2)%8]
298 ___
299     } else {
300         $xi=@X[(($i+9)/2)%8];
301 $code.=<<___;
302         srlx    @X[($i/2)%8],32,$tmp1           ! X[i]
303         xor     $tmp0,$tmp2,$tmp2               ! sigma1(X[i+14])
304         srl     @X[($i/2)%8],0,@X[($i/2)%8]
305         add     $xi,$T1,$T1                     ! +=X[i+9]
306         add     $tmp2,$T1,$T1
307         add     $tmp1,$T1,$T1
308
309         sllx    $T1,32,$tmp0
310         or      $tmp0,@X[($i/2)%8],@X[($i/2)%8]
311 ___
312     }
313     &BODY_00_15(@_);
314 } if ($SZ==4);
315
316 ########### SHA512
317 $BODY_16_XX = sub {
318 my $i=@_[0];
319 my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1));
320
321 $code.=<<___;
322         sllx    %l2,32,$tmp0            !! Xupdate($i)
323         or      %l3,$tmp0,$tmp0
324
325         srlx    $tmp0,@sigma0[0],$T1
326         ld      [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
327         sllx    $tmp0,`64-@sigma0[2]`,$tmp1
328         ld      [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
329         srlx    $tmp0,@sigma0[1],$tmp0
330         xor     $tmp1,$T1,$T1
331         sllx    $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
332         xor     $tmp0,$T1,$T1
333         srlx    $tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0
334         xor     $tmp1,$T1,$T1
335         sllx    %l6,32,$tmp2
336         xor     $tmp0,$T1,$T1           ! sigma0(X[$i+1])
337         or      %l7,$tmp2,$tmp2
338
339         srlx    $tmp2,@sigma1[0],$tmp1
340         ld      [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
341         sllx    $tmp2,`64-@sigma1[2]`,$tmp0
342         ld      [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
343         srlx    $tmp2,@sigma1[1],$tmp2
344         xor     $tmp0,$tmp1,$tmp1
345         sllx    $tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0
346         xor     $tmp2,$tmp1,$tmp1
347         srlx    $tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2
348         xor     $tmp0,$tmp1,$tmp1
349         sllx    %l4,32,$tmp0
350         xor     $tmp2,$tmp1,$tmp1       ! sigma1(X[$i+14])
351         ld      [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
352         or      %l5,$tmp0,$tmp0
353         ld      [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
354
355         sllx    %l0,32,$tmp2
356         add     $tmp1,$T1,$T1
357         ld      [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
358         or      %l1,$tmp2,$tmp2
359         add     $tmp0,$T1,$T1           ! +=X[$i+9]
360         ld      [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
361         add     $tmp2,$T1,$T1           ! +=X[$i]
362         $ST     $T1,[%sp+`$bias+$frame+($i%16)*$SZ`]
363 ___
364     &BODY_00_15(@_);
365 } if ($SZ==8);
366
367 $code.=<<___ if ($bits==64);
368 .register       %g2,#scratch
369 .register       %g3,#scratch
370 ___
371 $code.=<<___;
372 .section        ".text",#alloc,#execinstr
373
374 .align  64
375 K${label}:
376 .type   K${label},#object
377 ___
378 if ($SZ==4) {
379 $code.=<<___;
380         .long   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
381         .long   0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
382         .long   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
383         .long   0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
384         .long   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
385         .long   0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
386         .long   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
387         .long   0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
388         .long   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
389         .long   0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
390         .long   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
391         .long   0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
392         .long   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
393         .long   0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
394         .long   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
395         .long   0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
396 ___
397 } else {
398 $code.=<<___;
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 }
441 $code.=<<___;
442 .size   K${label},.-K${label}
443 .globl  sha${label}_block_data_order
444 sha${label}_block_data_order:
445         save    %sp,`-$frame-$locals`,%sp
446         and     $inp,`$align-1`,$tmp31
447         sllx    $len,`log(16*$SZ)/log(2)`,$len
448         andn    $inp,`$align-1`,$inp
449         sll     $tmp31,3,$tmp31
450         add     $inp,$len,$len
451 ___
452 $code.=<<___ if ($SZ==8); # SHA512
453         mov     32,$tmp32
454         sub     $tmp32,$tmp31,$tmp32
455 ___
456 $code.=<<___;
457 .Lpic:  call    .+8
458         sub     %o7,.Lpic-K${label},$Ktbl
459
460         $LD     [$ctx+`0*$SZ`],$A
461         $LD     [$ctx+`1*$SZ`],$B
462         $LD     [$ctx+`2*$SZ`],$C
463         $LD     [$ctx+`3*$SZ`],$D
464         $LD     [$ctx+`4*$SZ`],$E
465         $LD     [$ctx+`5*$SZ`],$F
466         $LD     [$ctx+`6*$SZ`],$G
467         $LD     [$ctx+`7*$SZ`],$H
468
469 .Lloop:
470 ___
471 for ($i=0;$i<16;$i++)   { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
472 $code.=".L16_xx:\n";
473 for (;$i<32;$i++)       { &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
474 $code.=<<___;
475         and     $tmp2,0xfff,$tmp2
476         cmp     $tmp2,$lastK
477         bne     .L16_xx
478         add     $Ktbl,`16*$SZ`,$Ktbl    ! Ktbl+=16
479
480 ___
481 $code.=<<___ if ($SZ==4); # SHA256
482         $LD     [$ctx+`0*$SZ`],@X[0]
483         $LD     [$ctx+`1*$SZ`],@X[1]
484         $LD     [$ctx+`2*$SZ`],@X[2]
485         $LD     [$ctx+`3*$SZ`],@X[3]
486         $LD     [$ctx+`4*$SZ`],@X[4]
487         $LD     [$ctx+`5*$SZ`],@X[5]
488         $LD     [$ctx+`6*$SZ`],@X[6]
489         $LD     [$ctx+`7*$SZ`],@X[7]
490
491         add     $A,@X[0],$A
492         $ST     $A,[$ctx+`0*$SZ`]
493         add     $B,@X[1],$B
494         $ST     $B,[$ctx+`1*$SZ`]
495         add     $C,@X[2],$C
496         $ST     $C,[$ctx+`2*$SZ`]
497         add     $D,@X[3],$D
498         $ST     $D,[$ctx+`3*$SZ`]
499         add     $E,@X[4],$E
500         $ST     $E,[$ctx+`4*$SZ`]
501         add     $F,@X[5],$F
502         $ST     $F,[$ctx+`5*$SZ`]
503         add     $G,@X[6],$G
504         $ST     $G,[$ctx+`6*$SZ`]
505         add     $H,@X[7],$H
506         $ST     $H,[$ctx+`7*$SZ`]
507 ___
508 $code.=<<___ if ($SZ==8); # SHA512
509         ld      [$ctx+`0*$SZ+0`],%l0
510         ld      [$ctx+`0*$SZ+4`],%l1
511         ld      [$ctx+`1*$SZ+0`],%l2
512         ld      [$ctx+`1*$SZ+4`],%l3
513         ld      [$ctx+`2*$SZ+0`],%l4
514         ld      [$ctx+`2*$SZ+4`],%l5
515         ld      [$ctx+`3*$SZ+0`],%l6
516
517         sllx    %l0,32,$tmp0
518         ld      [$ctx+`3*$SZ+4`],%l7
519         sllx    %l2,32,$tmp1
520         or      %l1,$tmp0,$tmp0
521         or      %l3,$tmp1,$tmp1
522         add     $tmp0,$A,$A
523         add     $tmp1,$B,$B
524         $ST     $A,[$ctx+`0*$SZ`]
525         sllx    %l4,32,$tmp2
526         $ST     $B,[$ctx+`1*$SZ`]
527         sllx    %l6,32,$T1
528         or      %l5,$tmp2,$tmp2
529         or      %l7,$T1,$T1
530         add     $tmp2,$C,$C
531         $ST     $C,[$ctx+`2*$SZ`]
532         add     $T1,$D,$D
533         $ST     $D,[$ctx+`3*$SZ`]
534
535         ld      [$ctx+`4*$SZ+0`],%l0
536         ld      [$ctx+`4*$SZ+4`],%l1
537         ld      [$ctx+`5*$SZ+0`],%l2
538         ld      [$ctx+`5*$SZ+4`],%l3
539         ld      [$ctx+`6*$SZ+0`],%l4
540         ld      [$ctx+`6*$SZ+4`],%l5
541         ld      [$ctx+`7*$SZ+0`],%l6
542
543         sllx    %l0,32,$tmp0
544         ld      [$ctx+`7*$SZ+4`],%l7
545         sllx    %l2,32,$tmp1
546         or      %l1,$tmp0,$tmp0
547         or      %l3,$tmp1,$tmp1
548         add     $tmp0,$E,$E
549         add     $tmp1,$F,$F
550         $ST     $E,[$ctx+`4*$SZ`]
551         sllx    %l4,32,$tmp2
552         $ST     $F,[$ctx+`5*$SZ`]
553         sllx    %l6,32,$T1
554         or      %l5,$tmp2,$tmp2
555         or      %l7,$T1,$T1
556         add     $tmp2,$G,$G
557         $ST     $G,[$ctx+`6*$SZ`]
558         add     $T1,$H,$H
559         $ST     $H,[$ctx+`7*$SZ`]
560 ___
561 $code.=<<___;
562         add     $inp,`16*$SZ`,$inp              ! advance inp
563         cmp     $inp,$len
564         bne     `$bits==64?"%xcc":"%icc"`,.Lloop
565         sub     $Ktbl,`($rounds-16)*$SZ`,$Ktbl  ! rewind Ktbl
566
567         ret
568         restore
569 .type   sha${label}_block_data_order,#function
570 .size   sha${label}_block_data_order,(.-sha${label}_block_data_order)
571 .asciz  "SHA${label} block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
572 ___
573
574 $code =~ s/\`([^\`]*)\`/eval $1/gem;
575 print $code;
576 close STDOUT;