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