Home | History | Annotate | Download | only in asm
      1 #!/usr/bin/env perl
      2 
      3 # ====================================================================
      4 # Written by Andy Polyakov <appro (at] 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 # SHA2 block procedures for MIPS.
     11 
     12 # October 2010.
     13 #
     14 # SHA256 performance improvement on MIPS R5000 CPU is ~27% over gcc-
     15 # generated code in o32 build and ~55% in n32/64 build. SHA512 [which
     16 # for now can only be compiled for MIPS64 ISA] improvement is modest
     17 # ~17%, but it comes for free, because it's same instruction sequence.
     18 # Improvement coefficients are for aligned input.
     19 
     20 ######################################################################
     21 # There is a number of MIPS ABI in use, O32 and N32/64 are most
     22 # widely used. Then there is a new contender: NUBI. It appears that if
     23 # one picks the latter, it's possible to arrange code in ABI neutral
     24 # manner. Therefore let's stick to NUBI register layout:
     25 #
     26 ($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
     27 ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
     28 ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
     29 ($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
     30 #
     31 # The return value is placed in $a0. Following coding rules facilitate
     32 # interoperability:
     33 #
     34 # - never ever touch $tp, "thread pointer", former $gp [o32 can be
     35 #   excluded from the rule, because it's specified volatile];
     36 # - copy return value to $t0, former $v0 [or to $a0 if you're adapting
     37 #   old code];
     38 # - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
     39 #
     40 # For reference here is register layout for N32/64 MIPS ABIs:
     41 #
     42 # ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
     43 # ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
     44 # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
     45 # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
     46 # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
     47 #
     48 $flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
     49 
     50 if ($flavour =~ /64|n32/i) {
     51 	$PTR_ADD="dadd";	# incidentally works even on n32
     52 	$PTR_SUB="dsub";	# incidentally works even on n32
     53 	$REG_S="sd";
     54 	$REG_L="ld";
     55 	$PTR_SLL="dsll";	# incidentally works even on n32
     56 	$SZREG=8;
     57 } else {
     58 	$PTR_ADD="add";
     59 	$PTR_SUB="sub";
     60 	$REG_S="sw";
     61 	$REG_L="lw";
     62 	$PTR_SLL="sll";
     63 	$SZREG=4;
     64 }
     65 $pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
     66 #
     67 # <appro (at] openssl.org>
     68 #
     69 ######################################################################
     70 
     71 $big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
     72 
     73 for (@ARGV) {	$output=$_ if (/^\w[\w\-]*\.\w+$/);	}
     74 open STDOUT,">$output";
     75 
     76 if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); }
     77 
     78 if ($output =~ /512/) {
     79 	$label="512";
     80 	$SZ=8;
     81 	$LD="ld";		# load from memory
     82 	$ST="sd";		# store to memory
     83 	$SLL="dsll";		# shift left logical
     84 	$SRL="dsrl";		# shift right logical
     85 	$ADDU="daddu";
     86 	@Sigma0=(28,34,39);
     87 	@Sigma1=(14,18,41);
     88 	@sigma0=( 7, 1, 8);	# right shift first
     89 	@sigma1=( 6,19,61);	# right shift first
     90 	$lastK=0x817;
     91 	$rounds=80;
     92 } else {
     93 	$label="256";
     94 	$SZ=4;
     95 	$LD="lw";		# load from memory
     96 	$ST="sw";		# store to memory
     97 	$SLL="sll";		# shift left logical
     98 	$SRL="srl";		# shift right logical
     99 	$ADDU="addu";
    100 	@Sigma0=( 2,13,22);
    101 	@Sigma1=( 6,11,25);
    102 	@sigma0=( 3, 7,18);	# right shift first
    103 	@sigma1=(10,17,19);	# right shift first
    104 	$lastK=0x8f2;
    105 	$rounds=64;
    106 }
    107 
    108 $MSB = $big_endian ? 0 : ($SZ-1);
    109 $LSB = ($SZ-1)&~$MSB;
    110 
    111 @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("\$$_",(1,2,3,7,24,25,30,31));
    112 @X=map("\$$_",(8..23));
    113 
    114 $ctx=$a0;
    115 $inp=$a1;
    116 $len=$a2;	$Ktbl=$len;
    117 
    118 sub BODY_00_15 {
    119 my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
    120 my ($T1,$tmp0,$tmp1,$tmp2)=(@X[4],@X[5],@X[6],@X[7]);
    121 
    122 $code.=<<___ if ($i<15);
    123 	${LD}l	@X[1],`($i+1)*$SZ+$MSB`($inp)
    124 	${LD}r	@X[1],`($i+1)*$SZ+$LSB`($inp)
    125 ___
    126 $code.=<<___	if (!$big_endian && $i<16 && $SZ==4);
    127 	srl	$tmp0,@X[0],24		# byte swap($i)
    128 	srl	$tmp1,@X[0],8
    129 	andi	$tmp2,@X[0],0xFF00
    130 	sll	@X[0],@X[0],24
    131 	andi	$tmp1,0xFF00
    132 	sll	$tmp2,$tmp2,8
    133 	or	@X[0],$tmp0
    134 	or	$tmp1,$tmp2
    135 	or	@X[0],$tmp1
    136 ___
    137 $code.=<<___	if (!$big_endian && $i<16 && $SZ==8);
    138 	ori	$tmp0,$zero,0xFF
    139 	dsll	$tmp2,$tmp0,32
    140 	or	$tmp0,$tmp2		# 0x000000FF000000FF
    141 	and	$tmp1,@X[0],$tmp0	# byte swap($i)
    142 	dsrl	$tmp2,@X[0],24
    143 	dsll	$tmp1,24
    144 	and	$tmp2,$tmp0
    145 	dsll	$tmp0,8			# 0x0000FF000000FF00
    146 	or	$tmp1,$tmp2
    147 	and	$tmp2,@X[0],$tmp0
    148 	dsrl	@X[0],8
    149 	dsll	$tmp2,8
    150 	and	@X[0],$tmp0
    151 	or	$tmp1,$tmp2
    152 	or	@X[0],$tmp1
    153 	dsrl	$tmp1,@X[0],32
    154 	dsll	@X[0],32
    155 	or	@X[0],$tmp1
    156 ___
    157 $code.=<<___;
    158 	$ADDU	$T1,$X[0],$h			# $i
    159 	$SRL	$h,$e,@Sigma1[0]
    160 	xor	$tmp2,$f,$g
    161 	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[2]`
    162 	and	$tmp2,$e
    163 	$SRL	$tmp0,$e,@Sigma1[1]
    164 	xor	$h,$tmp1
    165 	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[1]`
    166 	xor	$h,$tmp0
    167 	$SRL	$tmp0,$e,@Sigma1[2]
    168 	xor	$h,$tmp1
    169 	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[0]`
    170 	xor	$h,$tmp0
    171 	xor	$tmp2,$g			# Ch(e,f,g)
    172 	xor	$tmp0,$tmp1,$h			# Sigma1(e)
    173 
    174 	$SRL	$h,$a,@Sigma0[0]
    175 	$ADDU	$T1,$tmp2
    176 	$LD	$tmp2,`$i*$SZ`($Ktbl)		# K[$i]
    177 	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[2]`
    178 	$ADDU	$T1,$tmp0
    179 	$SRL	$tmp0,$a,@Sigma0[1]
    180 	xor	$h,$tmp1
    181 	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[1]`
    182 	xor	$h,$tmp0
    183 	$SRL	$tmp0,$a,@Sigma0[2]
    184 	xor	$h,$tmp1
    185 	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[0]`
    186 	xor	$h,$tmp0
    187 	$ST	@X[0],`($i%16)*$SZ`($sp)	# offload to ring buffer
    188 	xor	$h,$tmp1			# Sigma0(a)
    189 
    190 	or	$tmp0,$a,$b
    191 	and	$tmp1,$a,$b
    192 	and	$tmp0,$c
    193 	or	$tmp1,$tmp0			# Maj(a,b,c)
    194 	$ADDU	$T1,$tmp2			# +=K[$i]
    195 	$ADDU	$h,$tmp1
    196 
    197 	$ADDU	$d,$T1
    198 	$ADDU	$h,$T1
    199 ___
    200 $code.=<<___ if ($i>=13);
    201 	$LD	@X[3],`(($i+3)%16)*$SZ`($sp)	# prefetch from ring buffer
    202 ___
    203 }
    204 
    205 sub BODY_16_XX {
    206 my $i=@_[0];
    207 my ($tmp0,$tmp1,$tmp2,$tmp3)=(@X[4],@X[5],@X[6],@X[7]);
    208 
    209 $code.=<<___;
    210 	$SRL	$tmp2,@X[1],@sigma0[0]		# Xupdate($i)
    211 	$ADDU	@X[0],@X[9]			# +=X[i+9]
    212 	$SLL	$tmp1,@X[1],`$SZ*8-@sigma0[2]`
    213 	$SRL	$tmp0,@X[1],@sigma0[1]
    214 	xor	$tmp2,$tmp1
    215 	$SLL	$tmp1,`@sigma0[2]-@sigma0[1]`
    216 	xor	$tmp2,$tmp0
    217 	$SRL	$tmp0,@X[1],@sigma0[2]
    218 	xor	$tmp2,$tmp1
    219 
    220 	$SRL	$tmp3,@X[14],@sigma1[0]
    221 	xor	$tmp2,$tmp0			# sigma0(X[i+1])
    222 	$SLL	$tmp1,@X[14],`$SZ*8-@sigma1[2]`
    223 	$ADDU	@X[0],$tmp2
    224 	$SRL	$tmp0,@X[14],@sigma1[1]
    225 	xor	$tmp3,$tmp1
    226 	$SLL	$tmp1,`@sigma1[2]-@sigma1[1]`
    227 	xor	$tmp3,$tmp0
    228 	$SRL	$tmp0,@X[14],@sigma1[2]
    229 	xor	$tmp3,$tmp1
    230 
    231 	xor	$tmp3,$tmp0			# sigma1(X[i+14])
    232 	$ADDU	@X[0],$tmp3
    233 ___
    234 	&BODY_00_15(@_);
    235 }
    236 
    237 $FRAMESIZE=16*$SZ+16*$SZREG;
    238 $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
    239 
    240 $code.=<<___;
    241 #ifdef OPENSSL_FIPSCANISTER
    242 # include <openssl/fipssyms.h>
    243 #endif
    244 
    245 .text
    246 .set	noat
    247 #if !defined(__vxworks) || defined(__pic__)
    248 .option	pic2
    249 #endif
    250 
    251 .align	5
    252 .globl	sha${label}_block_data_order
    253 .ent	sha${label}_block_data_order
    254 sha${label}_block_data_order:
    255 	.frame	$sp,$FRAMESIZE,$ra
    256 	.mask	$SAVED_REGS_MASK,-$SZREG
    257 	.set	noreorder
    258 ___
    259 $code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
    260 	.cpload	$pf
    261 ___
    262 $code.=<<___;
    263 	$PTR_SUB $sp,$FRAMESIZE
    264 	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
    265 	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
    266 	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
    267 	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
    268 	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
    269 	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
    270 	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
    271 	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
    272 	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
    273 	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
    274 ___
    275 $code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
    276 	$REG_S	$s3,$FRAMESIZE-11*$SZREG($sp)
    277 	$REG_S	$s2,$FRAMESIZE-12*$SZREG($sp)
    278 	$REG_S	$s1,$FRAMESIZE-13*$SZREG($sp)
    279 	$REG_S	$s0,$FRAMESIZE-14*$SZREG($sp)
    280 	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
    281 ___
    282 $code.=<<___;
    283 	$PTR_SLL @X[15],$len,`log(16*$SZ)/log(2)`
    284 ___
    285 $code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
    286 	.cplocal	$Ktbl
    287 	.cpsetup	$pf,$zero,sha${label}_block_data_order
    288 ___
    289 $code.=<<___;
    290 	.set	reorder
    291 	la	$Ktbl,K${label}		# PIC-ified 'load address'
    292 
    293 	$LD	$A,0*$SZ($ctx)		# load context
    294 	$LD	$B,1*$SZ($ctx)
    295 	$LD	$C,2*$SZ($ctx)
    296 	$LD	$D,3*$SZ($ctx)
    297 	$LD	$E,4*$SZ($ctx)
    298 	$LD	$F,5*$SZ($ctx)
    299 	$LD	$G,6*$SZ($ctx)
    300 	$LD	$H,7*$SZ($ctx)
    301 
    302 	$PTR_ADD @X[15],$inp		# pointer to the end of input
    303 	$REG_S	@X[15],16*$SZ($sp)
    304 	b	.Loop
    305 
    306 .align	5
    307 .Loop:
    308 	${LD}l	@X[0],$MSB($inp)
    309 	${LD}r	@X[0],$LSB($inp)
    310 ___
    311 for ($i=0;$i<16;$i++)
    312 { &BODY_00_15($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
    313 $code.=<<___;
    314 	b	.L16_xx
    315 .align	4
    316 .L16_xx:
    317 ___
    318 for (;$i<32;$i++)
    319 { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
    320 $code.=<<___;
    321 	and	@X[6],0xfff
    322 	li	@X[7],$lastK
    323 	.set	noreorder
    324 	bne	@X[6],@X[7],.L16_xx
    325 	$PTR_ADD $Ktbl,16*$SZ		# Ktbl+=16
    326 
    327 	$REG_L	@X[15],16*$SZ($sp)	# restore pointer to the end of input
    328 	$LD	@X[0],0*$SZ($ctx)
    329 	$LD	@X[1],1*$SZ($ctx)
    330 	$LD	@X[2],2*$SZ($ctx)
    331 	$PTR_ADD $inp,16*$SZ
    332 	$LD	@X[3],3*$SZ($ctx)
    333 	$ADDU	$A,@X[0]
    334 	$LD	@X[4],4*$SZ($ctx)
    335 	$ADDU	$B,@X[1]
    336 	$LD	@X[5],5*$SZ($ctx)
    337 	$ADDU	$C,@X[2]
    338 	$LD	@X[6],6*$SZ($ctx)
    339 	$ADDU	$D,@X[3]
    340 	$LD	@X[7],7*$SZ($ctx)
    341 	$ADDU	$E,@X[4]
    342 	$ST	$A,0*$SZ($ctx)
    343 	$ADDU	$F,@X[5]
    344 	$ST	$B,1*$SZ($ctx)
    345 	$ADDU	$G,@X[6]
    346 	$ST	$C,2*$SZ($ctx)
    347 	$ADDU	$H,@X[7]
    348 	$ST	$D,3*$SZ($ctx)
    349 	$ST	$E,4*$SZ($ctx)
    350 	$ST	$F,5*$SZ($ctx)
    351 	$ST	$G,6*$SZ($ctx)
    352 	$ST	$H,7*$SZ($ctx)
    353 
    354 	bnel	$inp,@X[15],.Loop
    355 	$PTR_SUB $Ktbl,`($rounds-16)*$SZ`	# rewind $Ktbl
    356 
    357 	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
    358 	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
    359 	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
    360 	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
    361 	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
    362 	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
    363 	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
    364 	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
    365 	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
    366 	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
    367 ___
    368 $code.=<<___ if ($flavour =~ /nubi/i);
    369 	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
    370 	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
    371 	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
    372 	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
    373 	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
    374 ___
    375 $code.=<<___;
    376 	jr	$ra
    377 	$PTR_ADD $sp,$FRAMESIZE
    378 .end	sha${label}_block_data_order
    379 
    380 .rdata
    381 .align	5
    382 K${label}:
    383 ___
    384 if ($SZ==4) {
    385 $code.=<<___;
    386 	.word	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
    387 	.word	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
    388 	.word	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
    389 	.word	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
    390 	.word	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
    391 	.word	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
    392 	.word	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
    393 	.word	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
    394 	.word	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
    395 	.word	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
    396 	.word	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
    397 	.word	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
    398 	.word	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
    399 	.word	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
    400 	.word	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
    401 	.word	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
    402 ___
    403 } else {
    404 $code.=<<___;
    405 	.dword	0x428a2f98d728ae22, 0x7137449123ef65cd
    406 	.dword	0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc
    407 	.dword	0x3956c25bf348b538, 0x59f111f1b605d019
    408 	.dword	0x923f82a4af194f9b, 0xab1c5ed5da6d8118
    409 	.dword	0xd807aa98a3030242, 0x12835b0145706fbe
    410 	.dword	0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2
    411 	.dword	0x72be5d74f27b896f, 0x80deb1fe3b1696b1
    412 	.dword	0x9bdc06a725c71235, 0xc19bf174cf692694
    413 	.dword	0xe49b69c19ef14ad2, 0xefbe4786384f25e3
    414 	.dword	0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65
    415 	.dword	0x2de92c6f592b0275, 0x4a7484aa6ea6e483
    416 	.dword	0x5cb0a9dcbd41fbd4, 0x76f988da831153b5
    417 	.dword	0x983e5152ee66dfab, 0xa831c66d2db43210
    418 	.dword	0xb00327c898fb213f, 0xbf597fc7beef0ee4
    419 	.dword	0xc6e00bf33da88fc2, 0xd5a79147930aa725
    420 	.dword	0x06ca6351e003826f, 0x142929670a0e6e70
    421 	.dword	0x27b70a8546d22ffc, 0x2e1b21385c26c926
    422 	.dword	0x4d2c6dfc5ac42aed, 0x53380d139d95b3df
    423 	.dword	0x650a73548baf63de, 0x766a0abb3c77b2a8
    424 	.dword	0x81c2c92e47edaee6, 0x92722c851482353b
    425 	.dword	0xa2bfe8a14cf10364, 0xa81a664bbc423001
    426 	.dword	0xc24b8b70d0f89791, 0xc76c51a30654be30
    427 	.dword	0xd192e819d6ef5218, 0xd69906245565a910
    428 	.dword	0xf40e35855771202a, 0x106aa07032bbd1b8
    429 	.dword	0x19a4c116b8d2d0c8, 0x1e376c085141ab53
    430 	.dword	0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8
    431 	.dword	0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb
    432 	.dword	0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3
    433 	.dword	0x748f82ee5defb2fc, 0x78a5636f43172f60
    434 	.dword	0x84c87814a1f0ab72, 0x8cc702081a6439ec
    435 	.dword	0x90befffa23631e28, 0xa4506cebde82bde9
    436 	.dword	0xbef9a3f7b2c67915, 0xc67178f2e372532b
    437 	.dword	0xca273eceea26619c, 0xd186b8c721c0c207
    438 	.dword	0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178
    439 	.dword	0x06f067aa72176fba, 0x0a637dc5a2c898a6
    440 	.dword	0x113f9804bef90dae, 0x1b710b35131c471b
    441 	.dword	0x28db77f523047d84, 0x32caab7b40c72493
    442 	.dword	0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c
    443 	.dword	0x4cc5d4becb3e42b6, 0x597f299cfc657e2a
    444 	.dword	0x5fcb6fab3ad6faec, 0x6c44198c4a475817
    445 ___
    446 }
    447 $code.=<<___;
    448 .asciiz	"SHA${label} for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
    449 .align	5
    450 
    451 ___
    452 
    453 $code =~ s/\`([^\`]*)\`/eval $1/gem;
    454 print $code;
    455 close STDOUT;
    456