Fix intermittent sslapitest early data related failures
[openssl.git] / crypto / sha / asm / sha1-ia64.pl
1 #! /usr/bin/env perl
2 # Copyright 2004-2016 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 # Eternal question is what's wrong with compiler generated code? The
18 # trick is that it's possible to reduce the number of shifts required
19 # to perform rotations by maintaining copy of 32-bit value in upper
20 # bits of 64-bit register. Just follow mux2 and shrp instructions...
21 # Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which
22 # is >50% better than HP C and >2x better than gcc.
23
24 # $output is the last argument if it looks like a file (it has an extension)
25 $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
26
27 $code=<<___;
28 .ident  \"sha1-ia64.s, version 1.3\"
29 .ident  \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\"
30 .explicit
31
32 ___
33
34
35 if ($^O eq "hpux") {
36     $ADDP="addp4";
37     for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
38 } else { $ADDP="add"; }
39
40 #$human=1;
41 if ($human) {   # useful for visual code auditing...
42         ($A,$B,$C,$D,$E)   = ("A","B","C","D","E");
43         ($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4");
44         ($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
45             (   "K_00_19","K_20_39","K_40_59","K_60_79" );
46         @X= (   "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7",
47                 "X8", "X9","X10","X11","X12","X13","X14","X15"  );
48 }
49 else {
50         ($A,$B,$C,$D,$E)   =    ("loc0","loc1","loc2","loc3","loc4");
51         ($h0,$h1,$h2,$h3,$h4) = ("loc5","loc6","loc7","loc8","loc9");
52         ($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
53             (   "r14", "r15", "loc10", "loc11"  );
54         @X= (   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
55                 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"  );
56 }
57
58 sub BODY_00_15 {
59 local   *code=shift;
60 my      ($i,$a,$b,$c,$d,$e)=@_;
61 my      $j=$i+1;
62 my      $Xn=@X[$j%16];
63
64 $code.=<<___ if ($i==0);
65 { .mmi; ld1     $X[$i]=[inp],2              // MSB
66         ld1     tmp2=[tmp3],2           };;
67 { .mmi; ld1     tmp0=[inp],2
68         ld1     tmp4=[tmp3],2               // LSB
69         dep     $X[$i]=$X[$i],tmp2,8,8  };;
70 ___
71 if ($i<15) {
72         $code.=<<___;
73 { .mmi; ld1     $Xn=[inp],2                 // forward Xload
74         nop.m   0x0
75         dep     tmp1=tmp0,tmp4,8,8      };;
76 { .mmi; ld1     tmp2=[tmp3],2               // forward Xload
77         and     tmp4=$c,$b
78         dep     $X[$i]=$X[$i],tmp1,16,16} //;;
79 { .mmi; add     $e=$e,$K_00_19              // e+=K_00_19
80         andcm   tmp1=$d,$b
81         dep.z   tmp5=$a,5,27            };; // a<<5
82 { .mmi; add     $e=$e,$X[$i]                // e+=Xload
83         or      tmp4=tmp4,tmp1              // F_00_19(b,c,d)=(b&c)|(~b&d)
84         extr.u  tmp1=$a,27,5            };; // a>>27
85 { .mmi; ld1     tmp0=[inp],2                // forward Xload
86         add     $e=$e,tmp4                  // e+=F_00_19(b,c,d)
87         shrp    $b=tmp6,tmp6,2          }   // b=ROTATE(b,30)
88 { .mmi; ld1     tmp4=[tmp3],2               // forward Xload
89         or      tmp5=tmp1,tmp5              // ROTATE(a,5)
90         mux2    tmp6=$a,0x44            };; // see b in next iteration
91 { .mii; add     $e=$e,tmp5                  // e+=ROTATE(a,5)
92         dep     $Xn=$Xn,tmp2,8,8            // forward Xload
93         mux2    $X[$i]=$X[$i],0x44      } //;;
94
95 ___
96         }
97 else    {
98         $code.=<<___;
99 { .mii; and     tmp3=$c,$b
100         dep     tmp1=tmp0,tmp4,8,8;;
101         dep     $X[$i]=$X[$i],tmp1,16,16} //;;
102 { .mmi; add     $e=$e,$K_00_19              // e+=K_00_19
103         andcm   tmp1=$d,$b
104         dep.z   tmp5=$a,5,27            };; // a<<5
105 { .mmi; add     $e=$e,$X[$i]                // e+=Xupdate
106         or      tmp4=tmp3,tmp1              // F_00_19(b,c,d)=(b&c)|(~b&d)
107         extr.u  tmp1=$a,27,5            }   // a>>27
108 { .mmi; xor     $Xn=$Xn,$X[($j+2)%16]       // forward Xupdate
109         xor     tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate
110         nop.i   0                       };;
111 { .mmi; add     $e=$e,tmp4                  // e+=F_00_19(b,c,d)
112         xor     $Xn=$Xn,tmp3                // forward Xupdate
113         shrp    $b=tmp6,tmp6,2          }   // b=ROTATE(b,30)
114 { .mmi; or      tmp1=tmp1,tmp5              // ROTATE(a,5)
115         mux2    tmp6=$a,0x44            };; // see b in next iteration
116 { .mii; add     $e=$e,tmp1                  // e+=ROTATE(a,5)
117         shrp    $Xn=$Xn,$Xn,31              // ROTATE(x[0]^x[2]^x[8]^x[13],1)
118         mux2    $X[$i]=$X[$i],0x44      };;
119
120 ___
121         }
122 }
123
124 sub BODY_16_19 {
125 local   *code=shift;
126 my      ($i,$a,$b,$c,$d,$e)=@_;
127 my      $j=$i+1;
128 my      $Xn=@X[$j%16];
129
130 $code.=<<___;
131 { .mib; add     $e=$e,$K_00_19              // e+=K_00_19
132         dep.z   tmp5=$a,5,27            }   // a<<5
133 { .mib; andcm   tmp1=$d,$b
134         and     tmp0=$c,$b              };;
135 { .mmi; add     $e=$e,$X[$i%16]             // e+=Xupdate
136         or      tmp0=tmp0,tmp1              // F_00_19(b,c,d)=(b&c)|(~b&d)
137         extr.u  tmp1=$a,27,5            }   // a>>27
138 { .mmi; xor     $Xn=$Xn,$X[($j+2)%16]       // forward Xupdate
139         xor     tmp3=$X[($j+8)%16],$X[($j+13)%16]       // forward Xupdate
140         nop.i   0                       };;
141 { .mmi; add     $e=$e,tmp0                  // f+=F_00_19(b,c,d)
142         xor     $Xn=$Xn,tmp3                // forward Xupdate
143         shrp    $b=tmp6,tmp6,2          }   // b=ROTATE(b,30)
144 { .mmi; or      tmp1=tmp1,tmp5              // ROTATE(a,5)
145         mux2    tmp6=$a,0x44            };; // see b in next iteration
146 { .mii; add     $e=$e,tmp1                  // e+=ROTATE(a,5)
147         shrp    $Xn=$Xn,$Xn,31              // ROTATE(x[0]^x[2]^x[8]^x[13],1)
148         nop.i   0                       };;
149
150 ___
151 }
152
153 sub BODY_20_39 {
154 local   *code=shift;
155 my      ($i,$a,$b,$c,$d,$e,$Konst)=@_;
156         $Konst = $K_20_39 if (!defined($Konst));
157 my      $j=$i+1;
158 my      $Xn=@X[$j%16];
159
160 if ($i<79) {
161 $code.=<<___;
162 { .mib; add     $e=$e,$Konst                // e+=K_XX_XX
163         dep.z   tmp5=$a,5,27            }   // a<<5
164 { .mib; xor     tmp0=$c,$b
165         xor     $Xn=$Xn,$X[($j+2)%16]   };; // forward Xupdate
166 { .mib; add     $e=$e,$X[$i%16]             // e+=Xupdate
167         extr.u  tmp1=$a,27,5            }   // a>>27
168 { .mib; xor     tmp0=tmp0,$d                // F_20_39(b,c,d)=b^c^d
169         xor     $Xn=$Xn,$X[($j+8)%16]   };; // forward Xupdate
170 { .mmi; add     $e=$e,tmp0                  // e+=F_20_39(b,c,d)
171         xor     $Xn=$Xn,$X[($j+13)%16]      // forward Xupdate
172         shrp    $b=tmp6,tmp6,2          }   // b=ROTATE(b,30)
173 { .mmi; or      tmp1=tmp1,tmp5              // ROTATE(a,5)
174         mux2    tmp6=$a,0x44            };; // see b in next iteration
175 { .mii; add     $e=$e,tmp1                  // e+=ROTATE(a,5)
176         shrp    $Xn=$Xn,$Xn,31              // ROTATE(x[0]^x[2]^x[8]^x[13],1)
177         nop.i   0                       };;
178
179 ___
180 }
181 else {
182 $code.=<<___;
183 { .mib; add     $e=$e,$Konst                // e+=K_60_79
184         dep.z   tmp5=$a,5,27            }   // a<<5
185 { .mib; xor     tmp0=$c,$b
186         add     $h1=$h1,$a              };; // wrap up
187 { .mib; add     $e=$e,$X[$i%16]             // e+=Xupdate
188         extr.u  tmp1=$a,27,5            }   // a>>27
189 { .mib; xor     tmp0=tmp0,$d                // F_20_39(b,c,d)=b^c^d
190         add     $h3=$h3,$c              };; // wrap up
191 { .mmi; add     $e=$e,tmp0                  // e+=F_20_39(b,c,d)
192         or      tmp1=tmp1,tmp5              // ROTATE(a,5)
193         shrp    $b=tmp6,tmp6,2          };; // b=ROTATE(b,30) ;;?
194 { .mmi; add     $e=$e,tmp1                  // e+=ROTATE(a,5)
195         add     tmp3=1,inp                  // used in unaligned codepath
196         add     $h4=$h4,$d              };; // wrap up
197
198 ___
199 }
200 }
201
202 sub BODY_40_59 {
203 local   *code=shift;
204 my      ($i,$a,$b,$c,$d,$e)=@_;
205 my      $j=$i+1;
206 my      $Xn=@X[$j%16];
207
208 $code.=<<___;
209 { .mib; add     $e=$e,$K_40_59              // e+=K_40_59
210         dep.z   tmp5=$a,5,27            }   // a<<5
211 { .mib; and     tmp1=$c,$d
212         xor     tmp0=$c,$d              };;
213 { .mmi; add     $e=$e,$X[$i%16]             // e+=Xupdate
214         add     tmp5=tmp5,tmp1              // a<<5+(c&d)
215         extr.u  tmp1=$a,27,5            }   // a>>27
216 { .mmi; and     tmp0=tmp0,$b
217         xor     $Xn=$Xn,$X[($j+2)%16]       // forward Xupdate
218         xor     tmp3=$X[($j+8)%16],$X[($j+13)%16] };;   // forward Xupdate
219 { .mmi; add     $e=$e,tmp0                  // e+=b&(c^d)
220         add     tmp5=tmp5,tmp1              // ROTATE(a,5)+(c&d)
221         shrp    $b=tmp6,tmp6,2          }   // b=ROTATE(b,30)
222 { .mmi; xor     $Xn=$Xn,tmp3
223         mux2    tmp6=$a,0x44            };; // see b in next iteration
224 { .mii; add     $e=$e,tmp5                  // e+=ROTATE(a,5)+(c&d)
225         shrp    $Xn=$Xn,$Xn,31              // ROTATE(x[0]^x[2]^x[8]^x[13],1)
226         nop.i   0x0                     };;
227
228 ___
229 }
230 sub BODY_60_79  { &BODY_20_39(@_,$K_60_79); }
231
232 $code.=<<___;
233 .text
234
235 tmp0=r8;
236 tmp1=r9;
237 tmp2=r10;
238 tmp3=r11;
239 ctx=r32;        // in0
240 inp=r33;        // in1
241
242 // void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num);
243 .global sha1_block_data_order#
244 .proc   sha1_block_data_order#
245 .align  32
246 sha1_block_data_order:
247         .prologue
248 { .mmi; alloc   tmp1=ar.pfs,3,14,0,0
249         $ADDP   tmp0=4,ctx
250         .save   ar.lc,r3
251         mov     r3=ar.lc                }
252 { .mmi; $ADDP   ctx=0,ctx
253         $ADDP   inp=0,inp
254         mov     r2=pr                   };;
255 tmp4=in2;
256 tmp5=loc12;
257 tmp6=loc13;
258         .body
259 { .mlx; ld4     $h0=[ctx],8
260         movl    $K_00_19=0x5a827999     }
261 { .mlx; ld4     $h1=[tmp0],8
262         movl    $K_20_39=0x6ed9eba1     };;
263 { .mlx; ld4     $h2=[ctx],8
264         movl    $K_40_59=0x8f1bbcdc     }
265 { .mlx; ld4     $h3=[tmp0]
266         movl    $K_60_79=0xca62c1d6     };;
267 { .mmi; ld4     $h4=[ctx],-16
268         add     in2=-1,in2                  // adjust num for ar.lc
269         mov     ar.ec=1                 };;
270 { .mmi; nop.m   0
271         add     tmp3=1,inp
272         mov     ar.lc=in2               };; // brp.loop.imp: too far
273
274 .Ldtop:
275 { .mmi; mov     $A=$h0
276         mov     $B=$h1
277         mux2    tmp6=$h1,0x44           }
278 { .mmi; mov     $C=$h2
279         mov     $D=$h3
280         mov     $E=$h4                  };;
281
282 ___
283
284 { my $i;
285   my @V=($A,$B,$C,$D,$E);
286
287         for($i=0;$i<16;$i++)    { &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); }
288         for(;$i<20;$i++)        { &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); }
289         for(;$i<40;$i++)        { &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); }
290         for(;$i<60;$i++)        { &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); }
291         for(;$i<80;$i++)        { &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); }
292
293         (($V[0] eq $A) and ($V[4] eq $E)) or die;       # double-check
294 }
295
296 $code.=<<___;
297 { .mmb; add     $h0=$h0,$A
298         add     $h2=$h2,$C
299         br.ctop.dptk.many       .Ldtop  };;
300 .Ldend:
301 { .mmi; add     tmp0=4,ctx
302         mov     ar.lc=r3                };;
303 { .mmi; st4     [ctx]=$h0,8
304         st4     [tmp0]=$h1,8            };;
305 { .mmi; st4     [ctx]=$h2,8
306         st4     [tmp0]=$h3              };;
307 { .mib; st4     [ctx]=$h4,-16
308         mov     pr=r2,0x1ffff
309         br.ret.sptk.many        b0      };;
310 .endp   sha1_block_data_order#
311 stringz "SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
312 ___
313
314 open STDOUT,">$output" if $output;
315 print $code;