155714Skris#!/usr/local/bin/perl 255714Skris# x86 assember 355714Skris 455714Skrissub bn_mul_add_words 555714Skris { 655714Skris local($name)=@_; 755714Skris 855714Skris &function_begin($name,""); 955714Skris 1055714Skris &comment(""); 1155714Skris $Low="eax"; 1255714Skris $High="edx"; 1355714Skris $a="ebx"; 1455714Skris $w="ebp"; 1555714Skris $r="edi"; 1655714Skris $c="esi"; 1755714Skris 1855714Skris &xor($c,$c); # clear carry 1955714Skris &mov($r,&wparam(0)); # 2055714Skris 2155714Skris &mov("ecx",&wparam(2)); # 2255714Skris &mov($a,&wparam(1)); # 2355714Skris 2455714Skris &and("ecx",0xfffffff8); # num / 8 2555714Skris &mov($w,&wparam(3)); # 2655714Skris 2755714Skris &push("ecx"); # Up the stack for a tmp variable 2855714Skris 2955714Skris &jz(&label("maw_finish")); 3055714Skris 3155714Skris &set_label("maw_loop",0); 3255714Skris 3355714Skris &mov(&swtmp(0),"ecx"); # 3455714Skris 3555714Skris for ($i=0; $i<32; $i+=4) 3655714Skris { 3755714Skris &comment("Round $i"); 3855714Skris 3955714Skris &mov("eax",&DWP($i,$a,"",0)); # *a 4055714Skris &mul($w); # *a * w 4155714Skris &add("eax",$c); # L(t)+= *r 4255714Skris &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r 4355714Skris &adc("edx",0); # H(t)+=carry 4455714Skris &add("eax",$c); # L(t)+=c 4555714Skris &adc("edx",0); # H(t)+=carry 4655714Skris &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); 4755714Skris &mov($c,"edx"); # c= H(t); 4855714Skris } 4955714Skris 5055714Skris &comment(""); 5155714Skris &mov("ecx",&swtmp(0)); # 5255714Skris &add($a,32); 5355714Skris &add($r,32); 5455714Skris &sub("ecx",8); 5555714Skris &jnz(&label("maw_loop")); 5655714Skris 5755714Skris &set_label("maw_finish",0); 5855714Skris &mov("ecx",&wparam(2)); # get num 5955714Skris &and("ecx",7); 6055714Skris &jnz(&label("maw_finish2")); # helps branch prediction 6155714Skris &jmp(&label("maw_end")); 6255714Skris 6355714Skris &set_label("maw_finish2",1); 6455714Skris for ($i=0; $i<7; $i++) 6555714Skris { 6655714Skris &comment("Tail Round $i"); 6755714Skris &mov("eax",&DWP($i*4,$a,"",0));# *a 6855714Skris &mul($w); # *a * w 6955714Skris &add("eax",$c); # L(t)+=c 7055714Skris &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r 7155714Skris &adc("edx",0); # H(t)+=carry 7255714Skris &add("eax",$c); 7355714Skris &adc("edx",0); # H(t)+=carry 7455714Skris &dec("ecx") if ($i != 7-1); 7555714Skris &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t); 7655714Skris &mov($c,"edx"); # c= H(t); 7755714Skris &jz(&label("maw_end")) if ($i != 7-1); 7855714Skris } 7955714Skris &set_label("maw_end",0); 8055714Skris &mov("eax",$c); 8155714Skris 8255714Skris &pop("ecx"); # clear variable from 8355714Skris 8455714Skris &function_end($name); 8555714Skris } 8655714Skris 8755714Skris1; 88