alpha-mont.pl: gcc portability fix and make-rule.
[openssl.git] / crypto / bn / asm / x86 / mul_add.pl
1 #!/usr/local/bin/perl
2 # x86 assember
3
4 sub bn_mul_add_words
5         {
6         local($name)=@_;
7
8         &function_begin($name,"");
9
10         &comment("");
11         $Low="eax";
12         $High="edx";
13         $a="ebx";
14         $w="ebp";
15         $r="edi";
16         $c="esi";
17
18         &xor($c,$c);            # clear carry
19         &mov($r,&wparam(0));    #
20
21         &mov("ecx",&wparam(2)); #
22         &mov($a,&wparam(1));    #
23
24         &and("ecx",0xfffffff8); # num / 8
25         &mov($w,&wparam(3));    #
26
27         &push("ecx");           # Up the stack for a tmp variable
28
29         &jz(&label("maw_finish"));
30
31         &set_label("maw_loop",0);
32
33         &mov(&swtmp(0),"ecx");  #
34
35         for ($i=0; $i<32; $i+=4)
36                 {
37                 &comment("Round $i");
38
39                  &mov("eax",&DWP($i,$a,"",0));  # *a
40                 &mul($w);                       # *a * w
41                 &add("eax",$c);         # L(t)+= *r
42                  &mov($c,&DWP($i,$r,"",0));     # L(t)+= *r
43                 &adc("edx",0);                  # H(t)+=carry
44                  &add("eax",$c);                # L(t)+=c
45                 &adc("edx",0);                  # H(t)+=carry
46                  &mov(&DWP($i,$r,"",0),"eax");  # *r= L(t);
47                 &mov($c,"edx");                 # c=  H(t);
48                 }
49
50         &comment("");
51         &mov("ecx",&swtmp(0));  #
52         &add($a,32);
53         &add($r,32);
54         &sub("ecx",8);
55         &jnz(&label("maw_loop"));
56
57         &set_label("maw_finish",0);
58         &mov("ecx",&wparam(2)); # get num
59         &and("ecx",7);
60         &jnz(&label("maw_finish2"));    # helps branch prediction
61         &jmp(&label("maw_end"));
62
63         &set_label("maw_finish2",1);
64         for ($i=0; $i<7; $i++)
65                 {
66                 &comment("Tail Round $i");
67                  &mov("eax",&DWP($i*4,$a,"",0));# *a
68                 &mul($w);                       # *a * w
69                 &add("eax",$c);                 # L(t)+=c
70                  &mov($c,&DWP($i*4,$r,"",0));   # L(t)+= *r
71                 &adc("edx",0);                  # H(t)+=carry
72                  &add("eax",$c);
73                 &adc("edx",0);                  # H(t)+=carry
74                  &dec("ecx") if ($i != 7-1);
75                 &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t);
76                  &mov($c,"edx");                        # c=  H(t);
77                 &jz(&label("maw_end")) if ($i != 7-1);
78                 }
79         &set_label("maw_end",0);
80         &mov("eax",$c);
81
82         &pop("ecx");    # clear variable from
83
84         &function_end($name);
85         }
86
87 1;