1221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#!/usr/bin/env perl
2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
3221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# ====================================================================
4221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# project. The module is, however, dual licensed under OpenSSL and
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# CRYPTOGAMS licenses depending on where you obtain it. For further
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# details see http://www.openssl.org/~appro/cryptogams/.
8221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# ====================================================================
9221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
10221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# Performance improvement is not really impressive on pre-T1 CPU: +8%
11221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it
12221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and
13221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick.
14221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# X[16] vector is packed to 8 64-bit registers and as result nothing
15221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# is spilled on stack. In addition input data is loaded in compact
16221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# instruction sequence, thus minimizing the window when the code is
17221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# subject to [inter-thread] cache-thrashing hazard. The goal is to
18221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# ensure scalability on UltraSPARC T1, or rather to avoid decay when
19221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# amount of active threads exceeds the number of physical cores.
20221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
21221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$bits=32;
22221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
23221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromif ($bits==64)	{ $bias=2047; $frame=192; }
24221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromelse		{ $bias=0;    $frame=112; }
25221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
26221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$output=shift;
27221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromopen STDOUT,">$output";
28221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
29221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
30221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$rot1m="%g2";
31221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$tmp64="%g3";
32221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$Xi="%g4";
33221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$A="%l0";
34221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$B="%l1";
35221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$C="%l2";
36221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$D="%l3";
37221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$E="%l4";
38221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom@V=($A,$B,$C,$D,$E);
39221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$K_00_19="%l5";
40221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$K_20_39="%l6";
41221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$K_40_59="%l7";
42221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$K_60_79="%g5";
43221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79);
44221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
45221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$ctx="%i0";
46221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$inp="%i1";
47221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$len="%i2";
48221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$tmp0="%i3";
49221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$tmp1="%i4";
50221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$tmp2="%i5";
51221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
52221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub BODY_00_15 {
53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy ($i,$a,$b,$c,$d,$e)=@_;
54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy $xi=($i&1)?@X[($i/2)%8]:$Xi;
55221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
56221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
57221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$a,5,$tmp0		!! $i
58221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	@K[$i/20],$e,$e
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$a,27,$tmp1
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp0,$e,$e
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	and	$c,$b,$tmp0
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$b,30,$tmp2
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	andn	$d,$b,$tmp1
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$b,2,$b
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp1,$tmp0,$tmp1
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp2,$b,$b
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$xi,$e,$e
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromif ($i&1 && $i<15) {
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$code.=
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	"	srlx	@X[(($i+1)/2)%8],32,$Xi\n";
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub Xupdate {
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy ($i,$a,$b,$c,$d,$e)=@_;
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy $j=$i/2;
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromif ($i&1) {
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$a,5,$tmp0		!! $i
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	@K[$i/20],$e,$e
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$a,27,$tmp1
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} else {
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sllx	@X[($j+6)%8],32,$Xi	! Xupdate($i)
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	xor	@X[($j+1)%8],@X[$j%8],@X[$j%8]
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srlx	@X[($j+7)%8],32,$tmp1
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	xor	@X[($j+4)%8],@X[$j%8],@X[$j%8]
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$a,5,$tmp0		!! $i
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp1,$Xi,$Xi
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	@K[$i/20],$e,$e		!!
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	xor	$Xi,@X[$j%8],@X[$j%8]
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srlx	@X[$j%8],31,$Xi
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	@X[$j%8],@X[$j%8],@X[$j%8]
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	and	$Xi,$rot1m,$Xi
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	andn	@X[$j%8],$rot1m,@X[$j%8]
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$a,27,$tmp1		!!
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$Xi,@X[$j%8],@X[$j%8]
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub BODY_16_19 {
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy ($i,$a,$b,$c,$d,$e)=@_;
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	&Xupdate(@_);
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($i&1) {
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$xi=@X[($i/2)%8];
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else {
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$xi=$Xi;
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp0,$e,$e		!!
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	and	$c,$b,$tmp0
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$b,30,$tmp2
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$xi,$e,$e
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	andn	$d,$b,$tmp1
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$b,2,$b
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp1,$tmp0,$tmp1
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp2,$b,$b
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub BODY_20_39 {
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy ($i,$a,$b,$c,$d,$e)=@_;
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy $xi;
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	&Xupdate(@_);
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($i&1) {
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$xi=@X[($i/2)%8];
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else {
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$xi=$Xi;
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp0,$e,$e		!!
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	xor	$c,$b,$tmp0
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$b,30,$tmp2
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	xor	$d,$tmp0,$tmp1
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$b,2,$b
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp2,$b,$b
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$xi,$e,$e
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub BODY_40_59 {
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy ($i,$a,$b,$c,$d,$e)=@_;
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommy $xi;
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	&Xupdate(@_);
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($i&1) {
161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$xi=@X[($i/2)%8];
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else {
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$xi=$Xi;
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp0,$e,$e		!!
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	and	$c,$b,$tmp0
169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$b,30,$tmp2
171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$c,$b,$tmp1
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srl	$b,2,$b
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	and	$d,$tmp1,$tmp1
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$xi,$e,$e
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp1,$tmp0,$tmp1
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp2,$b,$b
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$tmp1,$e,$e
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___ if ($bits==64);
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.register	%g2,#scratch
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.register	%g3,#scratch
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.section	".text",#alloc,#execinstr
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.align	32
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.globl	sha1_block_data_order
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsha1_block_data_order:
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	save	%sp,-$frame,%sp
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sllx	$len,6,$len
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$inp,$len,$len
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	%g0,1,$rot1m
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sllx	$rot1m,32,$rot1m
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$rot1m,1,$rot1m
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+0],$A
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+4],$B
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+8],$C
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+12],$D
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+16],$E
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	andn	$inp,7,$tmp0
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sethi	%hi(0x5a827999),$K_00_19
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$K_00_19,%lo(0x5a827999),$K_00_19
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sethi	%hi(0x6ed9eba1),$K_20_39
209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$K_20_39,%lo(0x6ed9eba1),$K_20_39
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sethi	%hi(0x8f1bbcdc),$K_40_59
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$K_40_59,%lo(0x8f1bbcdc),$K_40_59
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sethi	%hi(0xca62c1d6),$K_60_79
213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$K_60_79,%lo(0xca62c1d6),$K_60_79
214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.Lloop:
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+0],@X[0]
217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+16],@X[2]
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+32],@X[4]
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+48],@X[6]
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	and	$inp,7,$tmp1
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+8],@X[1]
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sll	$tmp1,3,$tmp1
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+24],@X[3]
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	subcc	%g0,$tmp1,$tmp2	! should be 64-$tmp1, but -$tmp1 works too
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+40],@X[5]
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	bz,pt	%icc,.Laligned
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+56],@X[7]
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sllx	@X[0],$tmp1,@X[0]
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ldx	[$tmp0+64],$tmp64
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor($i=0;$i<7;$i++)
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{   $code.=<<___;
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srlx	@X[$i+1],$tmp2,$Xi
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sllx	@X[$i+1],$tmp1,@X[$i+1]
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$Xi,@X[$i],@X[$i]
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srlx	$tmp64,$tmp2,$tmp64
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	or	$tmp64,@X[7],@X[7]
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.Laligned:
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	srlx	@X[0],32,$Xi
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor (;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromfor (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code.=<<___;
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+0],@X[0]
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+4],@X[1]
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+8],@X[2]
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+12],@X[3]
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$inp,64,$inp
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ld	[$ctx+16],@X[4]
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cmp	$inp,$len
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$A,@X[0],$A
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	st	$A,[$ctx+0]
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$B,@X[1],$B
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	st	$B,[$ctx+4]
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$C,@X[2],$C
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	st	$C,[$ctx+8]
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$D,@X[3],$D
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	st	$D,[$ctx+12]
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	add	$E,@X[4],$E
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	st	$E,[$ctx+16]
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	andn	$inp,7,$tmp0
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	restore
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.type	sha1_block_data_order,#function
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.size	sha1_block_data_order,(.-sha1_block_data_order)
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.asciz	"SHA1 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
27943c12e3d4f9bbbbd4a8ba7b149686437514bc6b6Brian Carlstrom.align	4
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$code =~ s/\`([^\`]*)\`/eval $1/gem;
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromprint $code;
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromclose STDOUT;
285