mul_add.pl 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #!/usr/local/bin/perl
  2. # x86 assember
  3. sub bn_mul_add_words
  4. {
  5. local($name)=@_;
  6. &function_begin($name,"");
  7. &comment("");
  8. $Low="eax";
  9. $High="edx";
  10. $a="ebx";
  11. $w="ebp";
  12. $r="edi";
  13. $c="esi";
  14. &xor($c,$c); # clear carry
  15. &mov($r,&wparam(0)); #
  16. &mov("ecx",&wparam(2)); #
  17. &mov($a,&wparam(1)); #
  18. &and("ecx",0xfffffff8); # num / 8
  19. &mov($w,&wparam(3)); #
  20. &push("ecx"); # Up the stack for a tmp variable
  21. &jz(&label("maw_finish"));
  22. &set_label("maw_loop",0);
  23. &mov(&swtmp(0),"ecx"); #
  24. for ($i=0; $i<32; $i+=4)
  25. {
  26. &comment("Round $i");
  27. &mov("eax",&DWP($i,$a,"",0)); # *a
  28. &mul($w); # *a * w
  29. &add("eax",$c); # L(t)+= *r
  30. &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r
  31. &adc("edx",0); # H(t)+=carry
  32. &add("eax",$c); # L(t)+=c
  33. &adc("edx",0); # H(t)+=carry
  34. &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t);
  35. &mov($c,"edx"); # c= H(t);
  36. }
  37. &comment("");
  38. &mov("ecx",&swtmp(0)); #
  39. &add($a,32);
  40. &add($r,32);
  41. &sub("ecx",8);
  42. &jnz(&label("maw_loop"));
  43. &set_label("maw_finish",0);
  44. &mov("ecx",&wparam(2)); # get num
  45. &and("ecx",7);
  46. &jnz(&label("maw_finish2")); # helps branch prediction
  47. &jmp(&label("maw_end"));
  48. &set_label("maw_finish2",1);
  49. for ($i=0; $i<7; $i++)
  50. {
  51. &comment("Tail Round $i");
  52. &mov("eax",&DWP($i*4,$a,"",0));# *a
  53. &mul($w); # *a * w
  54. &add("eax",$c); # L(t)+=c
  55. &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r
  56. &adc("edx",0); # H(t)+=carry
  57. &add("eax",$c);
  58. &adc("edx",0); # H(t)+=carry
  59. &dec("ecx") if ($i != 7-1);
  60. &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t);
  61. &mov($c,"edx"); # c= H(t);
  62. &jz(&label("maw_end")) if ($i != 7-1);
  63. }
  64. &set_label("maw_end",0);
  65. &mov("eax",$c);
  66. &pop("ecx"); # clear variable from
  67. &function_end($name);
  68. }
  69. 1;