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