co-586.pl 5.5 KB

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