1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#!/usr/local/bin/perl
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# x86 assember
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectsub bn_mul_add_words
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	local($name)=@_;
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&function_begin($name,"");
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&comment("");
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	$Low="eax";
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	$High="edx";
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	$a="ebx";
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	$w="ebp";
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	$r="edi";
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	$c="esi";
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&xor($c,$c);		# clear carry
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov($r,&wparam(0));	#
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov("ecx",&wparam(2));	#
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov($a,&wparam(1));	#
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&and("ecx",0xfffffff8);	# num / 8
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov($w,&wparam(3));	#
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&push("ecx");		# Up the stack for a tmp variable
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&jz(&label("maw_finish"));
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&set_label("maw_loop",0);
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov(&swtmp(0),"ecx");	#
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for ($i=0; $i<32; $i+=4)
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&comment("Round $i");
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&mul($w);			# *a * w
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&add("eax",$c);		# L(t)+= *r
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &mov($c,&DWP($i,$r,"",0));	# L(t)+= *r
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&adc("edx",0);			# H(t)+=carry
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &add("eax",$c);		# L(t)+=c
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&adc("edx",0);			# H(t)+=carry
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&mov($c,"edx");			# c=  H(t);
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&comment("");
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov("ecx",&swtmp(0));	#
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&add($a,32);
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&add($r,32);
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&sub("ecx",8);
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&jnz(&label("maw_loop"));
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&set_label("maw_finish",0);
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov("ecx",&wparam(2));	# get num
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&and("ecx",7);
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&jnz(&label("maw_finish2"));	# helps branch prediction
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&jmp(&label("maw_end"));
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&set_label("maw_finish2",1);
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for ($i=0; $i<7; $i++)
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&comment("Tail Round $i");
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &mov("eax",&DWP($i*4,$a,"",0));# *a
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&mul($w);			# *a * w
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&add("eax",$c);			# L(t)+=c
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &mov($c,&DWP($i*4,$r,"",0));	# L(t)+= *r
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&adc("edx",0);			# H(t)+=carry
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &add("eax",$c);
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&adc("edx",0);			# H(t)+=carry
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &dec("ecx") if ($i != 7-1);
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&mov(&DWP($i*4,$r,"",0),"eax");	# *r= L(t);
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 &mov($c,"edx");			# c=  H(t);
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&jz(&label("maw_end")) if ($i != 7-1);
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&set_label("maw_end",0);
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&mov("eax",$c);
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&pop("ecx");	# clear variable from
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	&function_end($name);
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project1;
88