1#! /usr/bin/env perl 2# Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License 2.0 (the "License"). You may not use 5# this file except in compliance with the License. You can obtain a copy 6# in the file LICENSE in the source distribution or at 7# https://www.openssl.org/source/license.html 8 9 10# ==================================================================== 11# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 12# project. The module is, however, dual licensed under OpenSSL and 13# CRYPTOGAMS licenses depending on where you obtain it. For further 14# details see http://www.openssl.org/~appro/cryptogams/. 15# ==================================================================== 16 17# SHA1 block procedure for PA-RISC. 18 19# June 2009. 20# 21# On PA-7100LC performance is >30% better than gcc 3.2 generated code 22# for aligned input and >50% better for unaligned. Compared to vendor 23# compiler on PA-8600 it's almost 60% faster in 64-bit build and just 24# few percent faster in 32-bit one (this for aligned input, data for 25# unaligned input is not available). 26# 27# Special thanks to polarhome.com for providing HP-UX account. 28 29# $output is the last argument if it looks like a file (it has an extension) 30# $flavour is the first argument if it doesn't look like a file 31$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; 32$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; 33 34$output and open STDOUT,">$output"; 35 36if ($flavour =~ /64/) { 37 $LEVEL ="2.0W"; 38 $SIZE_T =8; 39 $FRAME_MARKER =80; 40 $SAVED_RP =16; 41 $PUSH ="std"; 42 $PUSHMA ="std,ma"; 43 $POP ="ldd"; 44 $POPMB ="ldd,mb"; 45} else { 46 $LEVEL ="1.0"; 47 $SIZE_T =4; 48 $FRAME_MARKER =48; 49 $SAVED_RP =20; 50 $PUSH ="stw"; 51 $PUSHMA ="stwm"; 52 $POP ="ldw"; 53 $POPMB ="ldwm"; 54} 55 56$FRAME=14*$SIZE_T+$FRAME_MARKER;# 14 saved regs + frame marker 57 # [+ argument transfer] 58$ctx="%r26"; # arg0 59$inp="%r25"; # arg1 60$num="%r24"; # arg2 61 62$t0="%r28"; 63$t1="%r29"; 64$K="%r31"; 65 66@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8", 67 "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$t0); 68 69@V=($A,$B,$C,$D,$E)=("%r19","%r20","%r21","%r22","%r23"); 70 71sub BODY_00_19 { 72my ($i,$a,$b,$c,$d,$e)=@_; 73my $j=$i+1; 74$code.=<<___ if ($i<15); 75 addl $K,$e,$e ; $i 76 shd $a,$a,27,$t1 77 addl @X[$i],$e,$e 78 and $c,$b,$t0 79 addl $t1,$e,$e 80 andcm $d,$b,$t1 81 shd $b,$b,2,$b 82 or $t1,$t0,$t0 83 addl $t0,$e,$e 84___ 85$code.=<<___ if ($i>=15); # with forward Xupdate 86 addl $K,$e,$e ; $i 87 shd $a,$a,27,$t1 88 xor @X[($j+2)%16],@X[$j%16],@X[$j%16] 89 addl @X[$i%16],$e,$e 90 and $c,$b,$t0 91 xor @X[($j+8)%16],@X[$j%16],@X[$j%16] 92 addl $t1,$e,$e 93 andcm $d,$b,$t1 94 shd $b,$b,2,$b 95 or $t1,$t0,$t0 96 xor @X[($j+13)%16],@X[$j%16],@X[$j%16] 97 add $t0,$e,$e 98 shd @X[$j%16],@X[$j%16],31,@X[$j%16] 99___ 100} 101 102sub BODY_20_39 { 103my ($i,$a,$b,$c,$d,$e)=@_; 104my $j=$i+1; 105$code.=<<___ if ($i<79); 106 xor @X[($j+2)%16],@X[$j%16],@X[$j%16] ; $i 107 addl $K,$e,$e 108 shd $a,$a,27,$t1 109 xor @X[($j+8)%16],@X[$j%16],@X[$j%16] 110 addl @X[$i%16],$e,$e 111 xor $b,$c,$t0 112 xor @X[($j+13)%16],@X[$j%16],@X[$j%16] 113 addl $t1,$e,$e 114 shd $b,$b,2,$b 115 xor $d,$t0,$t0 116 shd @X[$j%16],@X[$j%16],31,@X[$j%16] 117 addl $t0,$e,$e 118___ 119$code.=<<___ if ($i==79); # with context load 120 ldw 0($ctx),@X[0] ; $i 121 addl $K,$e,$e 122 shd $a,$a,27,$t1 123 ldw 4($ctx),@X[1] 124 addl @X[$i%16],$e,$e 125 xor $b,$c,$t0 126 ldw 8($ctx),@X[2] 127 addl $t1,$e,$e 128 shd $b,$b,2,$b 129 xor $d,$t0,$t0 130 ldw 12($ctx),@X[3] 131 addl $t0,$e,$e 132 ldw 16($ctx),@X[4] 133___ 134} 135 136sub BODY_40_59 { 137my ($i,$a,$b,$c,$d,$e)=@_; 138my $j=$i+1; 139$code.=<<___; 140 shd $a,$a,27,$t1 ; $i 141 addl $K,$e,$e 142 xor @X[($j+2)%16],@X[$j%16],@X[$j%16] 143 xor $d,$c,$t0 144 addl @X[$i%16],$e,$e 145 xor @X[($j+8)%16],@X[$j%16],@X[$j%16] 146 and $b,$t0,$t0 147 addl $t1,$e,$e 148 shd $b,$b,2,$b 149 xor @X[($j+13)%16],@X[$j%16],@X[$j%16] 150 addl $t0,$e,$e 151 and $d,$c,$t1 152 shd @X[$j%16],@X[$j%16],31,@X[$j%16] 153 addl $t1,$e,$e 154___ 155} 156 157$code=<<___; 158 .LEVEL $LEVEL 159 .SPACE \$TEXT\$ 160 .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY 161 162 .EXPORT sha1_block_data_order,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR 163sha1_block_data_order 164 .PROC 165 .CALLINFO FRAME=`$FRAME-14*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=16 166 .ENTRY 167 $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue 168 $PUSHMA %r3,$FRAME(%sp) 169 $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) 170 $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) 171 $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) 172 $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) 173 $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) 174 $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) 175 $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) 176 $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) 177 $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp) 178 $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp) 179 $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp) 180 $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp) 181 $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp) 182 183 ldw 0($ctx),$A 184 ldw 4($ctx),$B 185 ldw 8($ctx),$C 186 ldw 12($ctx),$D 187 ldw 16($ctx),$E 188 189 extru $inp,31,2,$t0 ; t0=inp&3; 190 sh3addl $t0,%r0,$t0 ; t0*=8; 191 subi 32,$t0,$t0 ; t0=32-t0; 192 mtctl $t0,%cr11 ; %sar=t0; 193 194L\$oop 195 ldi 3,$t0 196 andcm $inp,$t0,$t0 ; 64-bit neutral 197___ 198 for ($i=0;$i<15;$i++) { # load input block 199 $code.="\tldw `4*$i`($t0),@X[$i]\n"; } 200$code.=<<___; 201 cmpb,*= $inp,$t0,L\$aligned 202 ldw 60($t0),@X[15] 203 ldw 64($t0),@X[16] 204___ 205 for ($i=0;$i<16;$i++) { # align input 206 $code.="\tvshd @X[$i],@X[$i+1],@X[$i]\n"; } 207$code.=<<___; 208L\$aligned 209 ldil L'0x5a827000,$K ; K_00_19 210 ldo 0x999($K),$K 211___ 212for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } 213$code.=<<___; 214 ldil L'0x6ed9e000,$K ; K_20_39 215 ldo 0xba1($K),$K 216___ 217 218for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } 219$code.=<<___; 220 ldil L'0x8f1bb000,$K ; K_40_59 221 ldo 0xcdc($K),$K 222___ 223 224for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } 225$code.=<<___; 226 ldil L'0xca62c000,$K ; K_60_79 227 ldo 0x1d6($K),$K 228___ 229for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } 230 231$code.=<<___; 232 addl @X[0],$A,$A 233 addl @X[1],$B,$B 234 addl @X[2],$C,$C 235 addl @X[3],$D,$D 236 addl @X[4],$E,$E 237 stw $A,0($ctx) 238 stw $B,4($ctx) 239 stw $C,8($ctx) 240 stw $D,12($ctx) 241 stw $E,16($ctx) 242 addib,*<> -1,$num,L\$oop 243 ldo 64($inp),$inp 244 245 $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue 246 $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 247 $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 248 $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 249 $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 250 $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 251 $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 252 $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 253 $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 254 $POP `-$FRAME+9*$SIZE_T`(%sp),%r12 255 $POP `-$FRAME+10*$SIZE_T`(%sp),%r13 256 $POP `-$FRAME+11*$SIZE_T`(%sp),%r14 257 $POP `-$FRAME+12*$SIZE_T`(%sp),%r15 258 $POP `-$FRAME+13*$SIZE_T`(%sp),%r16 259 bv (%r2) 260 .EXIT 261 $POPMB -$FRAME(%sp),%r3 262 .PROCEND 263 .STRINGZ "SHA1 block transform for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>" 264___ 265 266if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` 267 =~ /GNU assembler/) { 268 $gnuas = 1; 269} 270 271foreach(split("\n",$code)) { 272 s/\`([^\`]*)\`/eval $1/ge; 273 274 s/(\.LEVEL\s+2\.0)W/$1w/ if ($gnuas && $SIZE_T==8); 275 s/\.SPACE\s+\$TEXT\$/.text/ if ($gnuas && $SIZE_T==8); 276 s/\.SUBSPA.*// if ($gnuas && $SIZE_T==8); 277 s/,\*/,/ if ($SIZE_T==4); 278 s/\bbv\b/bve/ if ($SIZE_T==8); 279 280 print $_,"\n"; 281} 282close STDOUT or die "error closing STDOUT: $!"; 283