1#!/usr/local/bin/perl
2# x86 assember
3
4sub bn_sub_words
5	{
6	local($name)=@_;
7
8	&function_begin($name,"");
9
10	&comment("");
11	$a="esi";
12	$b="edi";
13	$c="eax";
14	$r="ebx";
15	$tmp1="ecx";
16	$tmp2="edx";
17	$num="ebp";
18
19	&mov($r,&wparam(0));	# get r
20	 &mov($a,&wparam(1));	# get a
21	&mov($b,&wparam(2));	# get b
22	 &mov($num,&wparam(3));	# get num
23	&xor($c,$c);		# clear carry
24	 &and($num,0xfffffff8);	# num / 8
25
26	&jz(&label("aw_finish"));
27
28	&set_label("aw_loop",0);
29	for ($i=0; $i<8; $i++)
30		{
31		&comment("Round $i");
32
33		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
34		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
35		&sub($tmp1,$c);
36		 &mov($c,0);
37		&adc($c,$c);
38		 &sub($tmp1,$tmp2);
39		&adc($c,0);
40		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
41		}
42
43	&comment("");
44	&add($a,32);
45	 &add($b,32);
46	&add($r,32);
47	 &sub($num,8);
48	&jnz(&label("aw_loop"));
49
50	&set_label("aw_finish",0);
51	&mov($num,&wparam(3));	# get num
52	&and($num,7);
53	 &jz(&label("aw_end"));
54
55	for ($i=0; $i<7; $i++)
56		{
57		&comment("Tail Round $i");
58		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
59		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
60		&sub($tmp1,$c);
61		 &mov($c,0);
62		&adc($c,$c);
63		 &sub($tmp1,$tmp2);
64		&adc($c,0);
65		 &dec($num) if ($i != 6);
66		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *a
67		 &jz(&label("aw_end")) if ($i != 6);
68		}
69	&set_label("aw_end",0);
70
71#	&mov("eax",$c);		# $c is "eax"
72
73	&function_end($name);
74	}
75
761;
77