1238384Sjkim#!/usr/bin/env perl
2238384Sjkim
3238384Sjkim# ====================================================================
4238384Sjkim# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5238384Sjkim# project. The module is, however, dual licensed under OpenSSL and
6238384Sjkim# CRYPTOGAMS licenses depending on where you obtain it. For further
7238384Sjkim# details see http://www.openssl.org/~appro/cryptogams/.
8238384Sjkim# ====================================================================
9238384Sjkim
10238384Sjkim# SHA1 block procedure for MIPS.
11238384Sjkim
12238384Sjkim# Performance improvement is 30% on unaligned input. The "secret" is
13238384Sjkim# to deploy lwl/lwr pair to load unaligned input. One could have
14238384Sjkim# vectorized Xupdate on MIPSIII/IV, but the goal was to code MIPS32-
15238384Sjkim# compatible subroutine. There is room for minor optimization on
16238384Sjkim# little-endian platforms...
17238384Sjkim
18290207Sjkim# September 2012.
19290207Sjkim#
20290207Sjkim# Add MIPS32r2 code (>25% less instructions).
21290207Sjkim
22238384Sjkim######################################################################
23238384Sjkim# There is a number of MIPS ABI in use, O32 and N32/64 are most
24238384Sjkim# widely used. Then there is a new contender: NUBI. It appears that if
25238384Sjkim# one picks the latter, it's possible to arrange code in ABI neutral
26238384Sjkim# manner. Therefore let's stick to NUBI register layout:
27238384Sjkim#
28238384Sjkim($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
29238384Sjkim($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
30238384Sjkim($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
31238384Sjkim($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
32238384Sjkim#
33238384Sjkim# The return value is placed in $a0. Following coding rules facilitate
34238384Sjkim# interoperability:
35238384Sjkim#
36238384Sjkim# - never ever touch $tp, "thread pointer", former $gp;
37238384Sjkim# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
38238384Sjkim#   old code];
39238384Sjkim# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
40238384Sjkim#
41238384Sjkim# For reference here is register layout for N32/64 MIPS ABIs:
42238384Sjkim#
43238384Sjkim# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
44238384Sjkim# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
45238384Sjkim# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
46238384Sjkim# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
47238384Sjkim# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
48238384Sjkim#
49290207Sjkim$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
50238384Sjkim
51238384Sjkimif ($flavour =~ /64|n32/i) {
52238384Sjkim	$PTR_ADD="dadd";	# incidentally works even on n32
53238384Sjkim	$PTR_SUB="dsub";	# incidentally works even on n32
54238384Sjkim	$REG_S="sd";
55238384Sjkim	$REG_L="ld";
56238384Sjkim	$PTR_SLL="dsll";	# incidentally works even on n32
57238384Sjkim	$SZREG=8;
58238384Sjkim} else {
59238384Sjkim	$PTR_ADD="add";
60238384Sjkim	$PTR_SUB="sub";
61238384Sjkim	$REG_S="sw";
62238384Sjkim	$REG_L="lw";
63238384Sjkim	$PTR_SLL="sll";
64238384Sjkim	$SZREG=4;
65238384Sjkim}
66238384Sjkim#
67238384Sjkim# <appro@openssl.org>
68238384Sjkim#
69238384Sjkim######################################################################
70238384Sjkim
71276861Sjkim$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
72238384Sjkim
73238384Sjkimfor (@ARGV) {	$output=$_ if (/^\w[\w\-]*\.\w+$/);   }
74238384Sjkimopen STDOUT,">$output";
75238384Sjkim
76238384Sjkimif (!defined($big_endian))
77238384Sjkim            {   $big_endian=(unpack('L',pack('N',1))==1);   }
78238384Sjkim
79238384Sjkim# offsets of the Most and Least Significant Bytes
80238384Sjkim$MSB=$big_endian?0:3;
81238384Sjkim$LSB=3&~$MSB;
82238384Sjkim
83238384Sjkim@X=map("\$$_",(8..23));	# a4-a7,s0-s11
84238384Sjkim
85238384Sjkim$ctx=$a0;
86238384Sjkim$inp=$a1;
87238384Sjkim$num=$a2;
88238384Sjkim$A="\$1";
89238384Sjkim$B="\$2";
90238384Sjkim$C="\$3";
91238384Sjkim$D="\$7";
92238384Sjkim$E="\$24";	@V=($A,$B,$C,$D,$E);
93238384Sjkim$t0="\$25";
94238384Sjkim$t1=$num;	# $num is offloaded to stack
95238384Sjkim$t2="\$30";	# fp
96238384Sjkim$K="\$31";	# ra
97238384Sjkim
98238384Sjkimsub BODY_00_14 {
99238384Sjkimmy ($i,$a,$b,$c,$d,$e)=@_;
100238384Sjkimmy $j=$i+1;
101238384Sjkim$code.=<<___	if (!$big_endian);
102290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
103290207Sjkim	wsbh	@X[$i],@X[$i]	# byte swap($i)
104290207Sjkim	rotr	@X[$i],@X[$i],16
105290207Sjkim#else
106238384Sjkim	srl	$t0,@X[$i],24	# byte swap($i)
107238384Sjkim	srl	$t1,@X[$i],8
108238384Sjkim	andi	$t2,@X[$i],0xFF00
109238384Sjkim	sll	@X[$i],@X[$i],24
110238384Sjkim	andi	$t1,0xFF00
111238384Sjkim	sll	$t2,$t2,8
112238384Sjkim	or	@X[$i],$t0
113238384Sjkim	or	$t1,$t2
114238384Sjkim	or	@X[$i],$t1
115290207Sjkim#endif
116238384Sjkim___
117238384Sjkim$code.=<<___;
118290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
119290207Sjkim	addu	$e,$K		# $i
120290207Sjkim	xor	$t0,$c,$d
121290207Sjkim	rotr	$t1,$a,27
122238384Sjkim	 lwl	@X[$j],$j*4+$MSB($inp)
123290207Sjkim	and	$t0,$b
124290207Sjkim	addu	$e,$t1
125290207Sjkim	 lwr	@X[$j],$j*4+$LSB($inp)
126290207Sjkim	xor	$t0,$d
127290207Sjkim	addu	$e,@X[$i]
128290207Sjkim	rotr	$b,$b,2
129290207Sjkim	addu	$e,$t0
130290207Sjkim#else
131290207Sjkim	 lwl	@X[$j],$j*4+$MSB($inp)
132238384Sjkim	sll	$t0,$a,5	# $i
133238384Sjkim	addu	$e,$K
134238384Sjkim	 lwr	@X[$j],$j*4+$LSB($inp)
135238384Sjkim	srl	$t1,$a,27
136238384Sjkim	addu	$e,$t0
137238384Sjkim	xor	$t0,$c,$d
138238384Sjkim	addu	$e,$t1
139238384Sjkim	sll	$t2,$b,30
140238384Sjkim	and	$t0,$b
141238384Sjkim	srl	$b,$b,2
142238384Sjkim	xor	$t0,$d
143238384Sjkim	addu	$e,@X[$i]
144238384Sjkim	or	$b,$t2
145238384Sjkim	addu	$e,$t0
146290207Sjkim#endif
147238384Sjkim___
148238384Sjkim}
149238384Sjkim
150238384Sjkimsub BODY_15_19 {
151238384Sjkimmy ($i,$a,$b,$c,$d,$e)=@_;
152238384Sjkimmy $j=$i+1;
153238384Sjkim
154238384Sjkim$code.=<<___	if (!$big_endian && $i==15);
155290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
156290207Sjkim	wsbh	@X[$i],@X[$i]	# byte swap($i)
157290207Sjkim	rotr	@X[$i],@X[$i],16
158290207Sjkim#else
159238384Sjkim	srl	$t0,@X[$i],24	# byte swap($i)
160238384Sjkim	srl	$t1,@X[$i],8
161238384Sjkim	andi	$t2,@X[$i],0xFF00
162238384Sjkim	sll	@X[$i],@X[$i],24
163238384Sjkim	andi	$t1,0xFF00
164238384Sjkim	sll	$t2,$t2,8
165238384Sjkim	or	@X[$i],$t0
166238384Sjkim	or	@X[$i],$t1
167238384Sjkim	or	@X[$i],$t2
168290207Sjkim#endif
169238384Sjkim___
170238384Sjkim$code.=<<___;
171290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
172290207Sjkim	addu	$e,$K		# $i
173238384Sjkim	 xor	@X[$j%16],@X[($j+2)%16]
174290207Sjkim	xor	$t0,$c,$d
175290207Sjkim	rotr	$t1,$a,27
176290207Sjkim	 xor	@X[$j%16],@X[($j+8)%16]
177290207Sjkim	and	$t0,$b
178290207Sjkim	addu	$e,$t1
179290207Sjkim	 xor	@X[$j%16],@X[($j+13)%16]
180290207Sjkim	xor	$t0,$d
181290207Sjkim	addu	$e,@X[$i%16]
182290207Sjkim	 rotr	@X[$j%16],@X[$j%16],31
183290207Sjkim	rotr	$b,$b,2
184290207Sjkim	addu	$e,$t0
185290207Sjkim#else
186290207Sjkim	 xor	@X[$j%16],@X[($j+2)%16]
187238384Sjkim	sll	$t0,$a,5	# $i
188238384Sjkim	addu	$e,$K
189238384Sjkim	srl	$t1,$a,27
190238384Sjkim	addu	$e,$t0
191238384Sjkim	 xor	@X[$j%16],@X[($j+8)%16]
192238384Sjkim	xor	$t0,$c,$d
193238384Sjkim	addu	$e,$t1
194238384Sjkim	 xor	@X[$j%16],@X[($j+13)%16]
195238384Sjkim	sll	$t2,$b,30
196238384Sjkim	and	$t0,$b
197238384Sjkim	 srl	$t1,@X[$j%16],31
198238384Sjkim	 addu	@X[$j%16],@X[$j%16]
199238384Sjkim	srl	$b,$b,2
200238384Sjkim	xor	$t0,$d
201238384Sjkim	 or	@X[$j%16],$t1
202238384Sjkim	addu	$e,@X[$i%16]
203238384Sjkim	or	$b,$t2
204238384Sjkim	addu	$e,$t0
205290207Sjkim#endif
206238384Sjkim___
207238384Sjkim}
208238384Sjkim
209238384Sjkimsub BODY_20_39 {
210238384Sjkimmy ($i,$a,$b,$c,$d,$e)=@_;
211238384Sjkimmy $j=$i+1;
212238384Sjkim$code.=<<___ if ($i<79);
213290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
214238384Sjkim	 xor	@X[$j%16],@X[($j+2)%16]
215290207Sjkim	addu	$e,$K		# $i
216290207Sjkim	rotr	$t1,$a,27
217290207Sjkim	 xor	@X[$j%16],@X[($j+8)%16]
218290207Sjkim	xor	$t0,$c,$d
219290207Sjkim	addu	$e,$t1
220290207Sjkim	 xor	@X[$j%16],@X[($j+13)%16]
221290207Sjkim	xor	$t0,$b
222290207Sjkim	addu	$e,@X[$i%16]
223290207Sjkim	 rotr	@X[$j%16],@X[$j%16],31
224290207Sjkim	rotr	$b,$b,2
225290207Sjkim	addu	$e,$t0
226290207Sjkim#else
227290207Sjkim	 xor	@X[$j%16],@X[($j+2)%16]
228238384Sjkim	sll	$t0,$a,5	# $i
229238384Sjkim	addu	$e,$K
230238384Sjkim	srl	$t1,$a,27
231238384Sjkim	addu	$e,$t0
232238384Sjkim	 xor	@X[$j%16],@X[($j+8)%16]
233238384Sjkim	xor	$t0,$c,$d
234238384Sjkim	addu	$e,$t1
235238384Sjkim	 xor	@X[$j%16],@X[($j+13)%16]
236238384Sjkim	sll	$t2,$b,30
237238384Sjkim	xor	$t0,$b
238238384Sjkim	 srl	$t1,@X[$j%16],31
239238384Sjkim	 addu	@X[$j%16],@X[$j%16]
240238384Sjkim	srl	$b,$b,2
241238384Sjkim	addu	$e,@X[$i%16]
242238384Sjkim	 or	@X[$j%16],$t1
243238384Sjkim	or	$b,$t2
244238384Sjkim	addu	$e,$t0
245290207Sjkim#endif
246238384Sjkim___
247238384Sjkim$code.=<<___ if ($i==79);
248290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
249238384Sjkim	 lw	@X[0],0($ctx)
250290207Sjkim	addu	$e,$K		# $i
251290207Sjkim	 lw	@X[1],4($ctx)
252290207Sjkim	rotr	$t1,$a,27
253290207Sjkim	 lw	@X[2],8($ctx)
254290207Sjkim	xor	$t0,$c,$d
255290207Sjkim	addu	$e,$t1
256290207Sjkim	 lw	@X[3],12($ctx)
257290207Sjkim	xor	$t0,$b
258290207Sjkim	addu	$e,@X[$i%16]
259290207Sjkim	 lw	@X[4],16($ctx)
260290207Sjkim	rotr	$b,$b,2
261290207Sjkim	addu	$e,$t0
262290207Sjkim#else
263290207Sjkim	 lw	@X[0],0($ctx)
264238384Sjkim	sll	$t0,$a,5	# $i
265238384Sjkim	addu	$e,$K
266238384Sjkim	 lw	@X[1],4($ctx)
267238384Sjkim	srl	$t1,$a,27
268238384Sjkim	addu	$e,$t0
269238384Sjkim	 lw	@X[2],8($ctx)
270238384Sjkim	xor	$t0,$c,$d
271238384Sjkim	addu	$e,$t1
272238384Sjkim	 lw	@X[3],12($ctx)
273238384Sjkim	sll	$t2,$b,30
274238384Sjkim	xor	$t0,$b
275238384Sjkim	 lw	@X[4],16($ctx)
276238384Sjkim	srl	$b,$b,2
277238384Sjkim	addu	$e,@X[$i%16]
278238384Sjkim	or	$b,$t2
279238384Sjkim	addu	$e,$t0
280290207Sjkim#endif
281238384Sjkim___
282238384Sjkim}
283238384Sjkim
284238384Sjkimsub BODY_40_59 {
285238384Sjkimmy ($i,$a,$b,$c,$d,$e)=@_;
286238384Sjkimmy $j=$i+1;
287238384Sjkim$code.=<<___ if ($i<79);
288290207Sjkim#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
289290207Sjkim	addu	$e,$K		# $i
290290207Sjkim	and	$t0,$c,$d
291238384Sjkim	 xor	@X[$j%16],@X[($j+2)%16]
292290207Sjkim	rotr	$t1,$a,27
293290207Sjkim	addu	$e,$t0
294290207Sjkim	 xor	@X[$j%16],@X[($j+8)%16]
295290207Sjkim	xor	$t0,$c,$d
296290207Sjkim	addu	$e,$t1
297290207Sjkim	 xor	@X[$j%16],@X[($j+13)%16]
298290207Sjkim	and	$t0,$b
299290207Sjkim	addu	$e,@X[$i%16]
300290207Sjkim	 rotr	@X[$j%16],@X[$j%16],31
301290207Sjkim	rotr	$b,$b,2
302290207Sjkim	addu	$e,$t0
303290207Sjkim#else
304290207Sjkim	 xor	@X[$j%16],@X[($j+2)%16]
305238384Sjkim	sll	$t0,$a,5	# $i
306238384Sjkim	addu	$e,$K
307238384Sjkim	srl	$t1,$a,27
308238384Sjkim	addu	$e,$t0
309238384Sjkim	 xor	@X[$j%16],@X[($j+8)%16]
310238384Sjkim	and	$t0,$c,$d
311238384Sjkim	addu	$e,$t1
312238384Sjkim	 xor	@X[$j%16],@X[($j+13)%16]
313238384Sjkim	sll	$t2,$b,30
314238384Sjkim	addu	$e,$t0
315238384Sjkim	 srl	$t1,@X[$j%16],31
316238384Sjkim	xor	$t0,$c,$d
317238384Sjkim	 addu	@X[$j%16],@X[$j%16]
318238384Sjkim	and	$t0,$b
319238384Sjkim	srl	$b,$b,2
320238384Sjkim	 or	@X[$j%16],$t1
321238384Sjkim	addu	$e,@X[$i%16]
322238384Sjkim	or	$b,$t2
323238384Sjkim	addu	$e,$t0
324290207Sjkim#endif
325238384Sjkim___
326238384Sjkim}
327238384Sjkim
328238384Sjkim$FRAMESIZE=16;	# large enough to accomodate NUBI saved registers
329238384Sjkim$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
330238384Sjkim
331238384Sjkim$code=<<___;
332238384Sjkim#ifdef OPENSSL_FIPSCANISTER
333238384Sjkim# include <openssl/fipssyms.h>
334238384Sjkim#endif
335238384Sjkim
336290207Sjkim#if defined(__mips_smartmips) && !defined(_MIPS_ARCH_MIPS32R2)
337290207Sjkim#define _MIPS_ARCH_MIPS32R2
338290207Sjkim#endif
339290207Sjkim
340238384Sjkim.text
341238384Sjkim
342238384Sjkim.set	noat
343238384Sjkim.set	noreorder
344238384Sjkim.align	5
345238384Sjkim.globl	sha1_block_data_order
346238384Sjkim.ent	sha1_block_data_order
347238384Sjkimsha1_block_data_order:
348238384Sjkim	.frame	$sp,$FRAMESIZE*$SZREG,$ra
349238384Sjkim	.mask	$SAVED_REGS_MASK,-$SZREG
350238384Sjkim	.set	noreorder
351238384Sjkim	$PTR_SUB $sp,$FRAMESIZE*$SZREG
352238384Sjkim	$REG_S	$ra,($FRAMESIZE-1)*$SZREG($sp)
353238384Sjkim	$REG_S	$fp,($FRAMESIZE-2)*$SZREG($sp)
354238384Sjkim	$REG_S	$s11,($FRAMESIZE-3)*$SZREG($sp)
355238384Sjkim	$REG_S	$s10,($FRAMESIZE-4)*$SZREG($sp)
356238384Sjkim	$REG_S	$s9,($FRAMESIZE-5)*$SZREG($sp)
357238384Sjkim	$REG_S	$s8,($FRAMESIZE-6)*$SZREG($sp)
358238384Sjkim	$REG_S	$s7,($FRAMESIZE-7)*$SZREG($sp)
359238384Sjkim	$REG_S	$s6,($FRAMESIZE-8)*$SZREG($sp)
360238384Sjkim	$REG_S	$s5,($FRAMESIZE-9)*$SZREG($sp)
361238384Sjkim	$REG_S	$s4,($FRAMESIZE-10)*$SZREG($sp)
362238384Sjkim___
363238384Sjkim$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
364238384Sjkim	$REG_S	$s3,($FRAMESIZE-11)*$SZREG($sp)
365238384Sjkim	$REG_S	$s2,($FRAMESIZE-12)*$SZREG($sp)
366238384Sjkim	$REG_S	$s1,($FRAMESIZE-13)*$SZREG($sp)
367238384Sjkim	$REG_S	$s0,($FRAMESIZE-14)*$SZREG($sp)
368238384Sjkim	$REG_S	$gp,($FRAMESIZE-15)*$SZREG($sp)
369238384Sjkim___
370238384Sjkim$code.=<<___;
371238384Sjkim	$PTR_SLL $num,6
372238384Sjkim	$PTR_ADD $num,$inp
373238384Sjkim	$REG_S	$num,0($sp)
374238384Sjkim	lw	$A,0($ctx)
375238384Sjkim	lw	$B,4($ctx)
376238384Sjkim	lw	$C,8($ctx)
377238384Sjkim	lw	$D,12($ctx)
378238384Sjkim	b	.Loop
379238384Sjkim	lw	$E,16($ctx)
380238384Sjkim.align	4
381238384Sjkim.Loop:
382238384Sjkim	.set	reorder
383238384Sjkim	lwl	@X[0],$MSB($inp)
384238384Sjkim	lui	$K,0x5a82
385238384Sjkim	lwr	@X[0],$LSB($inp)
386238384Sjkim	ori	$K,0x7999	# K_00_19
387238384Sjkim___
388238384Sjkimfor ($i=0;$i<15;$i++)	{ &BODY_00_14($i,@V); unshift(@V,pop(@V)); }
389238384Sjkimfor (;$i<20;$i++)	{ &BODY_15_19($i,@V); unshift(@V,pop(@V)); }
390238384Sjkim$code.=<<___;
391238384Sjkim	lui	$K,0x6ed9
392238384Sjkim	ori	$K,0xeba1	# K_20_39
393238384Sjkim___
394238384Sjkimfor (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
395238384Sjkim$code.=<<___;
396238384Sjkim	lui	$K,0x8f1b
397238384Sjkim	ori	$K,0xbcdc	# K_40_59
398238384Sjkim___
399238384Sjkimfor (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
400238384Sjkim$code.=<<___;
401238384Sjkim	lui	$K,0xca62
402238384Sjkim	ori	$K,0xc1d6	# K_60_79
403238384Sjkim___
404238384Sjkimfor (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
405238384Sjkim$code.=<<___;
406238384Sjkim	$PTR_ADD $inp,64
407238384Sjkim	$REG_L	$num,0($sp)
408238384Sjkim
409238384Sjkim	addu	$A,$X[0]
410238384Sjkim	addu	$B,$X[1]
411238384Sjkim	sw	$A,0($ctx)
412238384Sjkim	addu	$C,$X[2]
413238384Sjkim	addu	$D,$X[3]
414238384Sjkim	sw	$B,4($ctx)
415238384Sjkim	addu	$E,$X[4]
416238384Sjkim	sw	$C,8($ctx)
417238384Sjkim	sw	$D,12($ctx)
418238384Sjkim	sw	$E,16($ctx)
419238384Sjkim	.set	noreorder
420238384Sjkim	bne	$inp,$num,.Loop
421238384Sjkim	nop
422238384Sjkim
423238384Sjkim	.set	noreorder
424238384Sjkim	$REG_L	$ra,($FRAMESIZE-1)*$SZREG($sp)
425238384Sjkim	$REG_L	$fp,($FRAMESIZE-2)*$SZREG($sp)
426238384Sjkim	$REG_L	$s11,($FRAMESIZE-3)*$SZREG($sp)
427238384Sjkim	$REG_L	$s10,($FRAMESIZE-4)*$SZREG($sp)
428238384Sjkim	$REG_L	$s9,($FRAMESIZE-5)*$SZREG($sp)
429238384Sjkim	$REG_L	$s8,($FRAMESIZE-6)*$SZREG($sp)
430238384Sjkim	$REG_L	$s7,($FRAMESIZE-7)*$SZREG($sp)
431238384Sjkim	$REG_L	$s6,($FRAMESIZE-8)*$SZREG($sp)
432238384Sjkim	$REG_L	$s5,($FRAMESIZE-9)*$SZREG($sp)
433238384Sjkim	$REG_L	$s4,($FRAMESIZE-10)*$SZREG($sp)
434238384Sjkim___
435238384Sjkim$code.=<<___ if ($flavour =~ /nubi/i);
436238384Sjkim	$REG_L	$s3,($FRAMESIZE-11)*$SZREG($sp)
437238384Sjkim	$REG_L	$s2,($FRAMESIZE-12)*$SZREG($sp)
438238384Sjkim	$REG_L	$s1,($FRAMESIZE-13)*$SZREG($sp)
439238384Sjkim	$REG_L	$s0,($FRAMESIZE-14)*$SZREG($sp)
440238384Sjkim	$REG_L	$gp,($FRAMESIZE-15)*$SZREG($sp)
441238384Sjkim___
442238384Sjkim$code.=<<___;
443238384Sjkim	jr	$ra
444238384Sjkim	$PTR_ADD $sp,$FRAMESIZE*$SZREG
445238384Sjkim.end	sha1_block_data_order
446238384Sjkim.rdata
447238384Sjkim.asciiz	"SHA1 for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
448238384Sjkim___
449238384Sjkimprint $code;
450238384Sjkimclose STDOUT;
451