1b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#!/usr/bin/env perl
2b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
3b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ====================================================================
4b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# project. The module is, however, dual licensed under OpenSSL and
6b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# CRYPTOGAMS licenses depending on where you obtain it. For further
7b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# details see http://www.openssl.org/~appro/cryptogams/.
8b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ====================================================================
9b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
10b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# SHA1 block procedure for MIPS.
11b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
12b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# Performance improvement is 30% on unaligned input. The "secret" is
13b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# to deploy lwl/lwr pair to load unaligned input. One could have
14b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# vectorized Xupdate on MIPSIII/IV, but the goal was to code MIPS32-
15b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# compatible subroutine. There is room for minor optimization on
16b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# little-endian platforms...
17b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
18b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic######################################################################
19b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# There is a number of MIPS ABI in use, O32 and N32/64 are most
20b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# widely used. Then there is a new contender: NUBI. It appears that if
21b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# one picks the latter, it's possible to arrange code in ABI neutral
22b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# manner. Therefore let's stick to NUBI register layout:
23b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
24b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
25b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
26b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
27b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
28b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
29b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# The return value is placed in $a0. Following coding rules facilitate
30b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# interoperability:
31b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
32b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# - never ever touch $tp, "thread pointer", former $gp;
33b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
34b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#   old code];
35b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
36b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
37b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# For reference here is register layout for N32/64 MIPS ABIs:
38b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
39b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
40b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
41b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
42b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
43b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
44b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
45b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
46b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
47b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicif ($flavour =~ /64|n32/i) {
48b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_ADD="dadd";	# incidentally works even on n32
49b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_SUB="dsub";	# incidentally works even on n32
50b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S="sd";
51b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L="ld";
52b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_SLL="dsll";	# incidentally works even on n32
53b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$SZREG=8;
54b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic} else {
55b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_ADD="add";
56b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_SUB="sub";
57b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S="sw";
58b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L="lw";
59b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_SLL="sll";
60b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$SZREG=4;
61b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic}
62b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
63b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# <appro@openssl.org>
64b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#
65b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic######################################################################
66b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
67b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
68b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
69b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicfor (@ARGV) {	$output=$_ if (/^\w[\w\-]*\.\w+$/);   }
70b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicopen STDOUT,">$output";
71b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
72b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicif (!defined($big_endian))
73b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic            {   $big_endian=(unpack('L',pack('N',1))==1);   }
74b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
75b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# offsets of the Most and Least Significant Bytes
76b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$MSB=$big_endian?0:3;
77b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$LSB=3&~$MSB;
78b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
79b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic@X=map("\$$_",(8..23));	# a4-a7,s0-s11
80b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
81b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$ctx=$a0;
82b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$inp=$a1;
83b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$num=$a2;
84b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$A="\$1";
85b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$B="\$2";
86b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$C="\$3";
87b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$D="\$7";
88b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$E="\$24";	@V=($A,$B,$C,$D,$E);
89b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$t0="\$25";
90b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$t1=$num;	# $num is offloaded to stack
91b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$t2="\$30";	# fp
92b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$K="\$31";	# ra
93b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
94b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicsub BODY_00_14 {
95b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy ($i,$a,$b,$c,$d,$e)=@_;
96b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy $j=$i+1;
97b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___	if (!$big_endian);
98b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t0,@X[$i],24	# byte swap($i)
99b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,@X[$i],8
100b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	andi	$t2,@X[$i],0xFF00
101b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	@X[$i],@X[$i],24
102b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	andi	$t1,0xFF00
103b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$t2,8
104b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	@X[$i],$t0
105b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	$t1,$t2
106b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	@X[$i],$t1
107b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
108b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
109b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lwl	@X[$j],$j*4+$MSB($inp)
110b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t0,$a,5	# $i
111b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$K
112b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lwr	@X[$j],$j*4+$LSB($inp)
113b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,$a,27
114b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
115b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$c,$d
116b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t1
117b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$b,30
118b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	and	$t0,$b
119b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$b,$b,2
120b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$d
121b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,@X[$i]
122b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	$b,$t2
123b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
124b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
125b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic}
126b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
127b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicsub BODY_15_19 {
128b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy ($i,$a,$b,$c,$d,$e)=@_;
129b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy $j=$i+1;
130b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
131b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___	if (!$big_endian && $i==15);
132b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t0,@X[$i],24	# byte swap($i)
133b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,@X[$i],8
134b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	andi	$t2,@X[$i],0xFF00
135b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	@X[$i],@X[$i],24
136b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	andi	$t1,0xFF00
137b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$t2,8
138b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	@X[$i],$t0
139b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	@X[$i],$t1
140b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	@X[$i],$t2
141b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
142b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
143b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+2)%16]
144b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t0,$a,5	# $i
145b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$K
146b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,$a,27
147b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
148b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+8)%16]
149b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$c,$d
150b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t1
151b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+13)%16]
152b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$b,30
153b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	and	$t0,$b
154b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 srl	$t1,@X[$j%16],31
155b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 addu	@X[$j%16],@X[$j%16]
156b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$b,$b,2
157b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$d
158b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 or	@X[$j%16],$t1
159b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,@X[$i%16]
160b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	$b,$t2
161b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
162b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
163b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic}
164b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
165b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicsub BODY_20_39 {
166b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy ($i,$a,$b,$c,$d,$e)=@_;
167b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy $j=$i+1;
168b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___ if ($i<79);
169b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+2)%16]
170b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t0,$a,5	# $i
171b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$K
172b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,$a,27
173b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
174b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+8)%16]
175b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$c,$d
176b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t1
177b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+13)%16]
178b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$b,30
179b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$b
180b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 srl	$t1,@X[$j%16],31
181b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 addu	@X[$j%16],@X[$j%16]
182b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$b,$b,2
183b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,@X[$i%16]
184b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 or	@X[$j%16],$t1
185b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	$b,$t2
186b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
187b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
188b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___ if ($i==79);
189b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lw	@X[0],0($ctx)
190b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t0,$a,5	# $i
191b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$K
192b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lw	@X[1],4($ctx)
193b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,$a,27
194b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
195b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lw	@X[2],8($ctx)
196b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$c,$d
197b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t1
198b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lw	@X[3],12($ctx)
199b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$b,30
200b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$b
201b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 lw	@X[4],16($ctx)
202b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$b,$b,2
203b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,@X[$i%16]
204b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	$b,$t2
205b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
206b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
207b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic}
208b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
209b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicsub BODY_40_59 {
210b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy ($i,$a,$b,$c,$d,$e)=@_;
211b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicmy $j=$i+1;
212b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___ if ($i<79);
213b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+2)%16]
214b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t0,$a,5	# $i
215b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$K
216b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$t1,$a,27
217b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
218b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+8)%16]
219b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	and	$t0,$c,$d
220b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t1
221b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 xor	@X[$j%16],@X[($j+13)%16]
222b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sll	$t2,$b,30
223b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
224b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 srl	$t1,@X[$j%16],31
225b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	xor	$t0,$c,$d
226b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 addu	@X[$j%16],@X[$j%16]
227b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	and	$t0,$b
228b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	srl	$b,$b,2
229b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	 or	@X[$j%16],$t1
230b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,@X[$i%16]
231b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	or	$b,$t2
232b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$e,$t0
233b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
234b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic}
235b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
236b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$FRAMESIZE=16;	# large enough to accomodate NUBI saved registers
237b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
238b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
239b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code=<<___;
240b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#ifdef OPENSSL_FIPSCANISTER
241b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic# include <openssl/fipssyms.h>
242b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic#endif
243b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
244b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.text
245b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
246b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.set	noat
247b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.set	noreorder
248b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.align	5
249b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.globl	sha1_block_data_order
250b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.ent	sha1_block_data_order
251b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicsha1_block_data_order:
252b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	.frame	$sp,$FRAMESIZE*$SZREG,$ra
253b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	.mask	$SAVED_REGS_MASK,-$SZREG
254b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	.set	noreorder
255b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_SUB $sp,$FRAMESIZE*$SZREG
256b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$ra,($FRAMESIZE-1)*$SZREG($sp)
257b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$fp,($FRAMESIZE-2)*$SZREG($sp)
258b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s11,($FRAMESIZE-3)*$SZREG($sp)
259b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s10,($FRAMESIZE-4)*$SZREG($sp)
260b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s9,($FRAMESIZE-5)*$SZREG($sp)
261b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s8,($FRAMESIZE-6)*$SZREG($sp)
262b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s7,($FRAMESIZE-7)*$SZREG($sp)
263b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s6,($FRAMESIZE-8)*$SZREG($sp)
264b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s5,($FRAMESIZE-9)*$SZREG($sp)
265b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s4,($FRAMESIZE-10)*$SZREG($sp)
266b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
267b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
268b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s3,($FRAMESIZE-11)*$SZREG($sp)
269b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s2,($FRAMESIZE-12)*$SZREG($sp)
270b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s1,($FRAMESIZE-13)*$SZREG($sp)
271b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$s0,($FRAMESIZE-14)*$SZREG($sp)
272b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$gp,($FRAMESIZE-15)*$SZREG($sp)
273b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
274b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
275b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_SLL $num,6
276b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_ADD $num,$inp
277b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_S	$num,0($sp)
278b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lw	$A,0($ctx)
279b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lw	$B,4($ctx)
280b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lw	$C,8($ctx)
281b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lw	$D,12($ctx)
282b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	b	.Loop
283b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lw	$E,16($ctx)
284b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.align	4
285b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.Loop:
286b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	.set	reorder
287b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lwl	@X[0],$MSB($inp)
288b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lui	$K,0x5a82
289b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lwr	@X[0],$LSB($inp)
290b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	ori	$K,0x7999	# K_00_19
291b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
292b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicfor ($i=0;$i<15;$i++)	{ &BODY_00_14($i,@V); unshift(@V,pop(@V)); }
293b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicfor (;$i<20;$i++)	{ &BODY_15_19($i,@V); unshift(@V,pop(@V)); }
294b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
295b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lui	$K,0x6ed9
296b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	ori	$K,0xeba1	# K_20_39
297b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
298b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicfor (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
299b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
300b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lui	$K,0x8f1b
301b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	ori	$K,0xbcdc	# K_40_59
302b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
303b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicfor (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
304b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
305b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	lui	$K,0xca62
306b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	ori	$K,0xc1d6	# K_60_79
307b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
308b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicfor (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
309b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
310b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_ADD $inp,64
311b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$num,0($sp)
312b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
313b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$A,$X[0]
314b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$B,$X[1]
315b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sw	$A,0($ctx)
316b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$C,$X[2]
317b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$D,$X[3]
318b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sw	$B,4($ctx)
319b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	addu	$E,$X[4]
320b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sw	$C,8($ctx)
321b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sw	$D,12($ctx)
322b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	sw	$E,16($ctx)
323b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	.set	noreorder
324b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	bne	$inp,$num,.Loop
325b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	nop
326b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic
327b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	.set	noreorder
328b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$ra,($FRAMESIZE-1)*$SZREG($sp)
329b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$fp,($FRAMESIZE-2)*$SZREG($sp)
330b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s11,($FRAMESIZE-3)*$SZREG($sp)
331b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s10,($FRAMESIZE-4)*$SZREG($sp)
332b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s9,($FRAMESIZE-5)*$SZREG($sp)
333b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s8,($FRAMESIZE-6)*$SZREG($sp)
334b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s7,($FRAMESIZE-7)*$SZREG($sp)
335b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s6,($FRAMESIZE-8)*$SZREG($sp)
336b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s5,($FRAMESIZE-9)*$SZREG($sp)
337b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s4,($FRAMESIZE-10)*$SZREG($sp)
338b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
339b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___ if ($flavour =~ /nubi/i);
340b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s3,($FRAMESIZE-11)*$SZREG($sp)
341b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s2,($FRAMESIZE-12)*$SZREG($sp)
342b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s1,($FRAMESIZE-13)*$SZREG($sp)
343b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$s0,($FRAMESIZE-14)*$SZREG($sp)
344b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$REG_L	$gp,($FRAMESIZE-15)*$SZREG($sp)
345b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
346b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic$code.=<<___;
347b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	jr	$ra
348b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic	$PTR_ADD $sp,$FRAMESIZE*$SZREG
349b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.end	sha1_block_data_order
350b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.rdata
351b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic.asciiz	"SHA1 for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
352b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovic___
353b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicprint $code;
354b83a02d94f9ba66fc5da46c2e27572674ea17931Petar Jovanovicclose STDOUT;
355