155714Skris#!/usr/local/bin/perl 255714Skris# x86 assember 355714Skris 455714Skrissub mul_add_c 555714Skris { 655714Skris local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; 755714Skris 855714Skris # pos == -1 if eax and edx are pre-loaded, 0 to load from next 955714Skris # words, and 1 if load return value 1055714Skris 1155714Skris &comment("mul a[$ai]*b[$bi]"); 1255714Skris 1355714Skris # "eax" and "edx" will always be pre-loaded. 1455714Skris # &mov("eax",&DWP($ai*4,$a,"",0)) ; 1555714Skris # &mov("edx",&DWP($bi*4,$b,"",0)); 1655714Skris 1755714Skris &mul("edx"); 1855714Skris &add($c0,"eax"); 1955714Skris &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a 2055714Skris &mov("eax",&wparam(0)) if $pos > 0; # load r[] 2155714Skris ### 2255714Skris &adc($c1,"edx"); 2355714Skris &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b 2455714Skris &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b 2555714Skris ### 2655714Skris &adc($c2,0); 2755714Skris # is pos > 1, it means it is the last loop 2855714Skris &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[]; 2955714Skris &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a 3055714Skris } 3155714Skris 3255714Skrissub sqr_add_c 3355714Skris { 3455714Skris local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; 3555714Skris 3655714Skris # pos == -1 if eax and edx are pre-loaded, 0 to load from next 3755714Skris # words, and 1 if load return value 3855714Skris 3955714Skris &comment("sqr a[$ai]*a[$bi]"); 4055714Skris 4155714Skris # "eax" and "edx" will always be pre-loaded. 4255714Skris # &mov("eax",&DWP($ai*4,$a,"",0)) ; 4355714Skris # &mov("edx",&DWP($bi*4,$b,"",0)); 4455714Skris 4555714Skris if ($ai == $bi) 4655714Skris { &mul("eax");} 4755714Skris else 4855714Skris { &mul("edx");} 4955714Skris &add($c0,"eax"); 5055714Skris &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a 5155714Skris ### 5255714Skris &adc($c1,"edx"); 5355714Skris &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb); 5455714Skris ### 5555714Skris &adc($c2,0); 5655714Skris # is pos > 1, it means it is the last loop 5755714Skris &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; 5855714Skris &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b 5955714Skris } 6055714Skris 6155714Skrissub sqr_add_c2 6255714Skris { 6355714Skris local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; 6455714Skris 6555714Skris # pos == -1 if eax and edx are pre-loaded, 0 to load from next 6655714Skris # words, and 1 if load return value 6755714Skris 6855714Skris &comment("sqr a[$ai]*a[$bi]"); 6955714Skris 7055714Skris # "eax" and "edx" will always be pre-loaded. 7155714Skris # &mov("eax",&DWP($ai*4,$a,"",0)) ; 7255714Skris # &mov("edx",&DWP($bi*4,$a,"",0)); 7355714Skris 7455714Skris if ($ai == $bi) 7555714Skris { &mul("eax");} 7655714Skris else 7755714Skris { &mul("edx");} 7855714Skris &add("eax","eax"); 7955714Skris ### 8055714Skris &adc("edx","edx"); 8155714Skris ### 8255714Skris &adc($c2,0); 8355714Skris &add($c0,"eax"); 8455714Skris &adc($c1,"edx"); 8555714Skris &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a 8655714Skris &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b 8755714Skris &adc($c2,0); 8855714Skris &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; 8955714Skris &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb); 9055714Skris ### 9155714Skris } 9255714Skris 9355714Skrissub bn_mul_comba 9455714Skris { 9555714Skris local($name,$num)=@_; 9655714Skris local($a,$b,$c0,$c1,$c2); 9755714Skris local($i,$as,$ae,$bs,$be,$ai,$bi); 9855714Skris local($tot,$end); 9955714Skris 10055714Skris &function_begin_B($name,""); 10155714Skris 10255714Skris $c0="ebx"; 10355714Skris $c1="ecx"; 10455714Skris $c2="ebp"; 10555714Skris $a="esi"; 10655714Skris $b="edi"; 10755714Skris 10855714Skris $as=0; 10955714Skris $ae=0; 11055714Skris $bs=0; 11155714Skris $be=0; 11255714Skris $tot=$num+$num-1; 11355714Skris 11455714Skris &push("esi"); 11555714Skris &mov($a,&wparam(1)); 11655714Skris &push("edi"); 11755714Skris &mov($b,&wparam(2)); 11855714Skris &push("ebp"); 11955714Skris &push("ebx"); 12055714Skris 12155714Skris &xor($c0,$c0); 12255714Skris &mov("eax",&DWP(0,$a,"",0)); # load the first word 12355714Skris &xor($c1,$c1); 12455714Skris &mov("edx",&DWP(0,$b,"",0)); # load the first second 12555714Skris 12655714Skris for ($i=0; $i<$tot; $i++) 12755714Skris { 12855714Skris $ai=$as; 12955714Skris $bi=$bs; 13055714Skris $end=$be+1; 13155714Skris 13255714Skris &comment("################## Calculate word $i"); 13355714Skris 13455714Skris for ($j=$bs; $j<$end; $j++) 13555714Skris { 13655714Skris &xor($c2,$c2) if ($j == $bs); 13755714Skris if (($j+1) == $end) 13855714Skris { 13955714Skris $v=1; 14055714Skris $v=2 if (($i+1) == $tot); 14155714Skris } 14255714Skris else 14355714Skris { $v=0; } 14455714Skris if (($j+1) != $end) 14555714Skris { 14655714Skris $na=($ai-1); 14755714Skris $nb=($bi+1); 14855714Skris } 14955714Skris else 15055714Skris { 15155714Skris $na=$as+($i < ($num-1)); 15255714Skris $nb=$bs+($i >= ($num-1)); 15355714Skris } 15455714Skris#printf STDERR "[$ai,$bi] -> [$na,$nb]\n"; 15555714Skris &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb); 15655714Skris if ($v) 15755714Skris { 15855714Skris &comment("saved r[$i]"); 15955714Skris # &mov("eax",&wparam(0)); 16055714Skris # &mov(&DWP($i*4,"eax","",0),$c0); 16155714Skris ($c0,$c1,$c2)=($c1,$c2,$c0); 16255714Skris } 16355714Skris $ai--; 16455714Skris $bi++; 16555714Skris } 16655714Skris $as++ if ($i < ($num-1)); 16755714Skris $ae++ if ($i >= ($num-1)); 16855714Skris 16955714Skris $bs++ if ($i >= ($num-1)); 17055714Skris $be++ if ($i < ($num-1)); 17155714Skris } 17255714Skris &comment("save r[$i]"); 17355714Skris # &mov("eax",&wparam(0)); 17455714Skris &mov(&DWP($i*4,"eax","",0),$c0); 17555714Skris 17655714Skris &pop("ebx"); 17755714Skris &pop("ebp"); 17855714Skris &pop("edi"); 17955714Skris &pop("esi"); 18055714Skris &ret(); 18155714Skris &function_end_B($name); 18255714Skris } 18355714Skris 18455714Skrissub bn_sqr_comba 18555714Skris { 18655714Skris local($name,$num)=@_; 18755714Skris local($r,$a,$c0,$c1,$c2)=@_; 18855714Skris local($i,$as,$ae,$bs,$be,$ai,$bi); 18955714Skris local($b,$tot,$end,$half); 19055714Skris 19155714Skris &function_begin_B($name,""); 19255714Skris 19355714Skris $c0="ebx"; 19455714Skris $c1="ecx"; 19555714Skris $c2="ebp"; 19655714Skris $a="esi"; 19755714Skris $r="edi"; 19855714Skris 19955714Skris &push("esi"); 20055714Skris &push("edi"); 20155714Skris &push("ebp"); 20255714Skris &push("ebx"); 20355714Skris &mov($r,&wparam(0)); 20455714Skris &mov($a,&wparam(1)); 20555714Skris &xor($c0,$c0); 20655714Skris &xor($c1,$c1); 20755714Skris &mov("eax",&DWP(0,$a,"",0)); # load the first word 20855714Skris 20955714Skris $as=0; 21055714Skris $ae=0; 21155714Skris $bs=0; 21255714Skris $be=0; 21355714Skris $tot=$num+$num-1; 21455714Skris 21555714Skris for ($i=0; $i<$tot; $i++) 21655714Skris { 21755714Skris $ai=$as; 21855714Skris $bi=$bs; 21955714Skris $end=$be+1; 22055714Skris 22155714Skris &comment("############### Calculate word $i"); 22255714Skris for ($j=$bs; $j<$end; $j++) 22355714Skris { 22455714Skris &xor($c2,$c2) if ($j == $bs); 22555714Skris if (($ai-1) < ($bi+1)) 22655714Skris { 22755714Skris $v=1; 22855714Skris $v=2 if ($i+1) == $tot; 22955714Skris } 23055714Skris else 23155714Skris { $v=0; } 23255714Skris if (!$v) 23355714Skris { 23455714Skris $na=$ai-1; 23555714Skris $nb=$bi+1; 23655714Skris } 23755714Skris else 23855714Skris { 23955714Skris $na=$as+($i < ($num-1)); 24055714Skris $nb=$bs+($i >= ($num-1)); 24155714Skris } 24255714Skris if ($ai == $bi) 24355714Skris { 24455714Skris &sqr_add_c($r,$a,$ai,$bi, 24555714Skris $c0,$c1,$c2,$v,$i,$na,$nb); 24655714Skris } 24755714Skris else 24855714Skris { 24955714Skris &sqr_add_c2($r,$a,$ai,$bi, 25055714Skris $c0,$c1,$c2,$v,$i,$na,$nb); 25155714Skris } 25255714Skris if ($v) 25355714Skris { 25455714Skris &comment("saved r[$i]"); 25555714Skris #&mov(&DWP($i*4,$r,"",0),$c0); 25655714Skris ($c0,$c1,$c2)=($c1,$c2,$c0); 25755714Skris last; 25855714Skris } 25955714Skris $ai--; 26055714Skris $bi++; 26155714Skris } 26255714Skris $as++ if ($i < ($num-1)); 26355714Skris $ae++ if ($i >= ($num-1)); 26455714Skris 26555714Skris $bs++ if ($i >= ($num-1)); 26655714Skris $be++ if ($i < ($num-1)); 26755714Skris } 26855714Skris &mov(&DWP($i*4,$r,"",0),$c0); 26955714Skris &pop("ebx"); 27055714Skris &pop("ebp"); 27155714Skris &pop("edi"); 27255714Skris &pop("esi"); 27355714Skris &ret(); 27455714Skris &function_end_B($name); 27555714Skris } 27655714Skris 27755714Skris1; 278