Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 

293 rindas
5.6 KiB

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