crypto/bn/asm/rsaz-x86_64.pl: make it work on Win64.
[openssl.git] / crypto / bn / asm / rsaz-x86_64.pl
1 #!/usr/bin/env perl
2
3 ##############################################################################
4 #                                                                            #
5 #  Copyright (c) 2012, Intel Corporation                                     #
6 #                                                                            #
7 #  All rights reserved.                                                      #
8 #                                                                            #
9 #  Redistribution and use in source and binary forms, with or without        #
10 #  modification, are permitted provided that the following conditions are    #
11 #  met:                                                                      #
12 #                                                                            #
13 #  *  Redistributions of source code must retain the above copyright         #
14 #     notice, this list of conditions and the following disclaimer.          #
15 #                                                                            #
16 #  *  Redistributions in binary form must reproduce the above copyright      #
17 #     notice, this list of conditions and the following disclaimer in the    #
18 #     documentation and/or other materials provided with the                 #
19 #     distribution.                                                          #
20 #                                                                            #
21 #  *  Neither the name of the Intel Corporation nor the names of its         #
22 #     contributors may be used to endorse or promote products derived from   #
23 #     this software without specific prior written permission.               #
24 #                                                                            #
25 #                                                                            #
26 #  THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY          #
27 #  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE         #
28 #  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        #
29 #  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR            #
30 #  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
31 #  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       #
32 #  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        #
33 #  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    #
34 #  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      #
35 #  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        #
36 #  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              #
37 #                                                                            #
38 ##############################################################################
39 # Developers and authors:                                                    #
40 # Shay Gueron (1, 2), and Vlad Krasnov (1)                                   #
41 # (1) Intel Architecture Group, Microprocessor and Chipset Development,      #
42 #     Israel Development Center, Haifa, Israel                               #
43 # (2) University of Haifa                                                    #
44 ##############################################################################
45 # Reference:                                                                 #
46 # [1] S. Gueron, "Efficient Software Implementations of Modular              #
47 #     Exponentiation", http://eprint.iacr.org/2011/239                       #
48 # [2] S. Gueron, V. Krasnov. "Speeding up Big-Numbers Squaring".             #
49 #     IEEE Proceedings of 9th International Conference on Information        #
50 #     Technology: New Generations (ITNG 2012), 821-823 (2012).               #
51 # [3] S. Gueron, Efficient Software Implementations of Modular Exponentiation#
52 #     Journal of Cryptographic Engineering 2:31-43 (2012).                   #
53 # [4] S. Gueron, V. Krasnov: "[PATCH] Efficient and side channel analysis    #
54 #     resistant 512-bit and 1024-bit modular exponentiation for optimizing   #
55 #     RSA1024 and RSA2048 on x86_64 platforms",                              #
56 #     http://rt.openssl.org/Ticket/Display.html?id=2582&user=guest&pass=guest#
57 ##############################################################################
58
59 # While original submission covers 512- and 1024-bit exponentiation,
60 # this module is limited to 512-bit version only (and as such
61 # accelerates RSA1024 sign). This is because improvement for longer
62 # keys is not high enough to justify the effort, highest measured
63 # was ~5% on Westmere. [This is relative to OpenSSL 1.0.2, upcoming
64 # for the moment of this writing!] Nor does this module implement
65 # "monolithic" complete exponentiation jumbo-subroutine, but adheres
66 # to more modular mixture of C and assembly. And it's optimized even
67 # for processors other than Intel Core family (see table below for
68 # improvement coefficients).
69 #                                               <appro@openssl.org>
70 #
71 # RSA1024 sign/sec      this/original   |this/rsax(*)   this/fips(*)
72 #                       ----------------+---------------------------
73 # Opteron               +13%            |+5%            +20%
74 # Bulldozer             -0%             |-1%            +10%
75 # P4                    +11%            |+7%            +8%
76 # Westmere              +5%             |+14%           +17%
77 # Sandy Bridge          +2%             |+12%           +29%
78 # Ivy Bridge            +1%             |+11%           +35%
79 # Haswell(**)           -0%             |+12%           +39%
80 # Atom                  +13%            |+11%           +4%
81 # VIA Nano              +70%            |+9%            +25%
82 #
83 # (*)   rsax engine and fips numbers are presented for reference
84 #       purposes;
85 # (**)  MULX was attempted, but found to give only marginal improvement;
86
87 $flavour = shift;
88 $output  = shift;
89 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
90
91 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
92
93 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
94 ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
95 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
96 die "can't locate x86_64-xlate.pl";
97
98 open OUT,"| $^X $xlate $flavour $output";
99 *STDOUT=*OUT;
100
101 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
102                 =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
103         $addx = ($1>=2.23);
104 }
105
106 if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
107             `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
108         $addx = ($1>=2.10);
109 }
110
111 if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
112             `ml64 2>&1` =~ /Version ([0-9]+)\./) {
113         $addx = ($1>=11);
114 }
115
116 ($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp");  # common internal API
117 {
118 my ($out,$inp,$mod,$n0,$times) = ("%rdi","%rsi","%rdx","%rcx","%r8d");
119
120 $code.=<<___;
121 .text
122
123 .extern OPENSSL_ia32cap_P
124
125 .globl  rsaz_512_sqr
126 .type   rsaz_512_sqr,\@function,5
127 .align  32
128 rsaz_512_sqr:                           # 25-29% faster than rsaz_512_mul
129         push    %rbx
130         push    %rbp
131         push    %r12
132         push    %r13
133         push    %r14
134         push    %r15
135
136         subq    \$128+24, %rsp
137 .Lsqr_body:
138         movq    $mod, %rbp              # common argument
139         movq    ($inp), %rdx
140         movq    8($inp), %rax
141         movq    $n0, 128(%rsp)
142 ___
143 $code.=<<___ if ($addx);
144         movl    \$0x80100,%r11d
145         andl    OPENSSL_ia32cap_P+8(%rip),%r11d
146         cmpl    \$0x80100,%r11d         # check for MULX and ADO/CX
147         je      .Loop_sqrx
148 ___
149 $code.=<<___;
150         jmp     .Loop_sqr
151
152 .align  32
153 .Loop_sqr:
154         movl    $times,128+8(%rsp)
155 #first iteration
156         movq    %rdx, %rbx
157         mulq    %rdx
158         movq    %rax, %r8
159         movq    16($inp), %rax
160         movq    %rdx, %r9
161
162         mulq    %rbx
163         addq    %rax, %r9
164         movq    24($inp), %rax
165         movq    %rdx, %r10
166         adcq    \$0, %r10
167
168         mulq    %rbx
169         addq    %rax, %r10
170         movq    32($inp), %rax
171         movq    %rdx, %r11
172         adcq    \$0, %r11
173
174         mulq    %rbx
175         addq    %rax, %r11
176         movq    40($inp), %rax
177         movq    %rdx, %r12
178         adcq    \$0, %r12
179
180         mulq    %rbx
181         addq    %rax, %r12
182         movq    48($inp), %rax
183         movq    %rdx, %r13
184         adcq    \$0, %r13
185
186         mulq    %rbx
187         addq    %rax, %r13
188         movq    56($inp), %rax
189         movq    %rdx, %r14
190         adcq    \$0, %r14
191
192         mulq    %rbx
193         addq    %rax, %r14
194         movq    %rbx, %rax
195         movq    %rdx, %r15
196         adcq    \$0, %r15
197
198         addq    %r8, %r8                #shlq   \$1, %r8
199         movq    %r9, %rcx
200         adcq    %r9, %r9                #shld   \$1, %r8, %r9
201
202         mulq    %rax
203         movq    %rax, (%rsp)
204         addq    %rdx, %r8
205         adcq    \$0, %r9
206
207         movq    %r8, 8(%rsp)
208         shrq    \$63, %rcx
209
210 #second iteration
211         movq    8($inp), %r8
212         movq    16($inp), %rax
213         mulq    %r8
214         addq    %rax, %r10
215         movq    24($inp), %rax
216         movq    %rdx, %rbx
217         adcq    \$0, %rbx
218
219         mulq    %r8
220         addq    %rax, %r11
221         movq    32($inp), %rax
222         adcq    \$0, %rdx
223         addq    %rbx, %r11
224         movq    %rdx, %rbx
225         adcq    \$0, %rbx
226
227         mulq    %r8
228         addq    %rax, %r12
229         movq    40($inp), %rax
230         adcq    \$0, %rdx
231         addq    %rbx, %r12
232         movq    %rdx, %rbx
233         adcq    \$0, %rbx
234