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