1#! /usr/bin/env perl 2# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the OpenSSL license (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$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 10push(@INC,"${dir}","${dir}../../perlasm"); 11require "x86asm.pl"; 12 13$output = pop; 14open STDOUT,">$output"; 15 16&asm_init($ARGV[0]); 17 18&bn_mul_comba("bn_mul_comba8",8); 19&bn_mul_comba("bn_mul_comba4",4); 20&bn_sqr_comba("bn_sqr_comba8",8); 21&bn_sqr_comba("bn_sqr_comba4",4); 22 23&asm_finish(); 24 25close STDOUT or die "error closing STDOUT: $!"; 26 27sub mul_add_c 28 { 29 local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; 30 31 # pos == -1 if eax and edx are pre-loaded, 0 to load from next 32 # words, and 1 if load return value 33 34 &comment("mul a[$ai]*b[$bi]"); 35 36 # "eax" and "edx" will always be pre-loaded. 37 # &mov("eax",&DWP($ai*4,$a,"",0)) ; 38 # &mov("edx",&DWP($bi*4,$b,"",0)); 39 40 &mul("edx"); 41 &add($c0,"eax"); 42 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a 43 &mov("eax",&wparam(0)) if $pos > 0; # load r[] 44 ### 45 &adc($c1,"edx"); 46 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # load next b 47 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # load next b 48 ### 49 &adc($c2,0); 50 # is pos > 1, it means it is the last loop 51 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[]; 52 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next a 53 } 54 55sub sqr_add_c 56 { 57 local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; 58 59 # pos == -1 if eax and edx are pre-loaded, 0 to load from next 60 # words, and 1 if load return value 61 62 &comment("sqr a[$ai]*a[$bi]"); 63 64 # "eax" and "edx" will always be pre-loaded. 65 # &mov("eax",&DWP($ai*4,$a,"",0)) ; 66 # &mov("edx",&DWP($bi*4,$b,"",0)); 67 68 if ($ai == $bi) 69 { &mul("eax");} 70 else 71 { &mul("edx");} 72 &add($c0,"eax"); 73 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a 74 ### 75 &adc($c1,"edx"); 76 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb); 77 ### 78 &adc($c2,0); 79 # is pos > 1, it means it is the last loop 80 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; 81 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b 82 } 83 84sub sqr_add_c2 85 { 86 local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; 87 88 # pos == -1 if eax and edx are pre-loaded, 0 to load from next 89 # words, and 1 if load return value 90 91 &comment("sqr a[$ai]*a[$bi]"); 92 93 # "eax" and "edx" will always be pre-loaded. 94 # &mov("eax",&DWP($ai*4,$a,"",0)) ; 95 # &mov("edx",&DWP($bi*4,$a,"",0)); 96 97 if ($ai == $bi) 98 { &mul("eax");} 99 else 100 { &mul("edx");} 101 &add("eax","eax"); 102 ### 103 &adc("edx","edx"); 104 ### 105 &adc($c2,0); 106 &add($c0,"eax"); 107 &adc($c1,"edx"); 108 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a 109 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b 110 &adc($c2,0); 111 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; 112 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb); 113 ### 114 } 115 116sub bn_mul_comba 117 { 118 local($name,$num)=@_; 119 local($a,$b,$c0,$c1,$c2); 120 local($i,$as,$ae,$bs,$be,$ai,$bi); 121 local($tot,$end); 122 123 &function_begin_B($name,""); 124 125 $c0="ebx"; 126 $c1="ecx"; 127 $c2="ebp"; 128 $a="esi"; 129 $b="edi"; 130 131 $as=0; 132 $ae=0; 133 $bs=0; 134 $be=0; 135 $tot=$num+$num-1; 136 137 &push("esi"); 138 &mov($a,&wparam(1)); 139 &push("edi"); 140 &mov($b,&wparam(2)); 141 &push("ebp"); 142 &push("ebx"); 143 144 &xor($c0,$c0); 145 &mov("eax",&DWP(0,$a,"",0)); # load the first word 146 &xor($c1,$c1); 147 &mov("edx",&DWP(0,$b,"",0)); # load the first second 148 149 for ($i=0; $i<$tot; $i++) 150 { 151 $ai=$as; 152 $bi=$bs; 153 $end=$be+1; 154 155 &comment("################## Calculate word $i"); 156 157 for ($j=$bs; $j<$end; $j++) 158 { 159 &xor($c2,$c2) if ($j == $bs); 160 if (($j+1) == $end) 161 { 162 $v=1; 163 $v=2 if (($i+1) == $tot); 164 } 165 else 166 { $v=0; } 167 if (($j+1) != $end) 168 { 169 $na=($ai-1); 170 $nb=($bi+1); 171 } 172 else 173 { 174 $na=$as+($i < ($num-1)); 175 $nb=$bs+($i >= ($num-1)); 176 } 177#printf STDERR "[$ai,$bi] -> [$na,$nb]\n"; 178 &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb); 179 if ($v) 180 { 181 &comment("saved r[$i]"); 182 # &mov("eax",&wparam(0)); 183 # &mov(&DWP($i*4,"eax","",0),$c0); 184 ($c0,$c1,$c2)=($c1,$c2,$c0); 185 } 186 $ai--; 187 $bi++; 188 } 189 $as++ if ($i < ($num-1)); 190 $ae++ if ($i >= ($num-1)); 191 192 $bs++ if ($i >= ($num-1)); 193 $be++ if ($i < ($num-1)); 194 } 195 &comment("save r[$i]"); 196 # &mov("eax",&wparam(0)); 197 &mov(&DWP($i*4,"eax","",0),$c0); 198 199 &pop("ebx"); 200 &pop("ebp"); 201 &pop("edi"); 202 &pop("esi"); 203 &ret(); 204 &function_end_B($name); 205 } 206 207sub bn_sqr_comba 208 { 209 local($name,$num)=@_; 210 local($r,$a,$c0,$c1,$c2)=@_; 211 local($i,$as,$ae,$bs,$be,$ai,$bi); 212 local($b,$tot,$end,$half); 213 214 &function_begin_B($name,""); 215 216 $c0="ebx"; 217 $c1="ecx"; 218 $c2="ebp"; 219 $a="esi"; 220 $r="edi"; 221 222 &push("esi"); 223 &push("edi"); 224 &push("ebp"); 225 &push("ebx"); 226 &mov($r,&wparam(0)); 227 &mov($a,&wparam(1)); 228 &xor($c0,$c0); 229 &xor($c1,$c1); 230 &mov("eax",&DWP(0,$a,"",0)); # load the first word 231 232 $as=0; 233 $ae=0; 234 $bs=0; 235 $be=0; 236 $tot=$num+$num-1; 237 238 for ($i=0; $i<$tot; $i++) 239 { 240 $ai=$as; 241 $bi=$bs; 242 $end=$be+1; 243 244 &comment("############### Calculate word $i"); 245 for ($j=$bs; $j<$end; $j++) 246 { 247 &xor($c2,$c2) if ($j == $bs); 248 if (($ai-1) < ($bi+1)) 249 { 250 $v=1; 251 $v=2 if ($i+1) == $tot; 252 } 253 else 254 { $v=0; } 255 if (!$v) 256 { 257 $na=$ai-1; 258 $nb=$bi+1; 259 } 260 else 261 { 262 $na=$as+($i < ($num-1)); 263 $nb=$bs+($i >= ($num-1)); 264 } 265 if ($ai == $bi) 266 { 267 &sqr_add_c($r,$a,$ai,$bi, 268 $c0,$c1,$c2,$v,$i,$na,$nb); 269 } 270 else 271 { 272 &sqr_add_c2($r,$a,$ai,$bi, 273 $c0,$c1,$c2,$v,$i,$na,$nb); 274 } 275 if ($v) 276 { 277 &comment("saved r[$i]"); 278 #&mov(&DWP($i*4,$r,"",0),$c0); 279 ($c0,$c1,$c2)=($c1,$c2,$c0); 280 last; 281 } 282 $ai--; 283 $bi++; 284 } 285 $as++ if ($i < ($num-1)); 286 $ae++ if ($i >= ($num-1)); 287 288 $bs++ if ($i >= ($num-1)); 289 $be++ if ($i < ($num-1)); 290 } 291 &mov(&DWP($i*4,$r,"",0),$c0); 292 &pop("ebx"); 293 &pop("ebp"); 294 &pop("edi"); 295 &pop("esi"); 296 &ret(); 297 &function_end_B($name); 298 } 299