add-key works
[gnupg.git] / mpi / i586 / mpih-rshift.S
1 /* i80586   rshift
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *      Copyright (C) 1992, 1994 Free Software Foundation, Inc.
4  *
5  * This file is part of GNUPG.
6  *
7  * GNUPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GNUPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  *
21  * Note: This code is heavily based on the GNU MP Library.
22  *       Actually it's the same code with only minor changes in the
23  *       way the data is stored; this is to support the abstraction
24  *       of an optional secure memory allocation which may be used
25  *       to avoid revealing of sensitive data due to paging etc.
26  *       The GNU MP Library itself is published under the LGPL;
27  *       however I decided to publish this code under the plain GPL.
28  */
29
30
31 #include "sysdep.h"
32 #include "asm-syntax.h"
33
34
35
36 /*******************
37  * mpi_limb_t
38  * mpihelp_rshift( mpi_ptr_t wp,        (sp + 4)
39  *                 mpi_ptr_t up,        (sp + 8)
40  *                 mpi_size_t usize,    (sp + 12)
41  *                 unsigned cnt)        (sp + 16)
42  */
43
44 .text
45         ALIGN (3)
46         .globl C_SYMBOL_NAME(mpihelp_rshift)
47 C_SYMBOL_NAME(mpihelp_rshift:)
48         pushl   %edi
49         pushl   %esi
50         pushl   %ebx
51         pushl   %ebp
52
53         movl    20(%esp),%edi           /* res_ptr */
54         movl    24(%esp),%esi           /* s_ptr */
55         movl    28(%esp),%ebp           /* size */
56         movl    32(%esp),%ecx           /* cnt */
57
58 /* We can use faster code for shift-by-1 under certain conditions.  */
59         cmp     $1,%ecx
60         jne     Rnormal
61         leal    4(%edi),%eax
62         cmpl    %esi,%eax
63         jnc     Rspecial                /* jump if res_ptr + 1 >= s_ptr */
64         leal    (%edi,%ebp,4),%eax
65         cmpl    %eax,%esi
66         jnc     Rspecial                /* jump if s_ptr >= res_ptr + size */
67
68 Rnormal:
69         movl    (%esi),%edx
70         addl    $4,%esi
71         xorl    %eax,%eax
72         shrdl   %cl,%edx,%eax           /* compute carry limb */
73         pushl   %eax                    /* push carry limb onto stack */
74
75         decl    %ebp
76         pushl   %ebp
77         shrl    $3,%ebp
78         jz      Rend
79
80         movl    (%edi),%eax             /* fetch destination cache line */
81
82         ALIGN   (2)
83 Roop:   movl    28(%edi),%eax           /* fetch destination cache line */
84         movl    %edx,%ebx
85
86         movl    (%esi),%eax
87         movl    4(%esi),%edx
88         shrdl   %cl,%eax,%ebx
89         shrdl   %cl,%edx,%eax
90         movl    %ebx,(%edi)
91         movl    %eax,4(%edi)
92
93         movl    8(%esi),%ebx
94         movl    12(%esi),%eax
95         shrdl   %cl,%ebx,%edx
96         shrdl   %cl,%eax,%ebx
97         movl    %edx,8(%edi)
98         movl    %ebx,12(%edi)
99
100         movl    16(%esi),%edx
101         movl    20(%esi),%ebx
102         shrdl   %cl,%edx,%eax
103         shrdl   %cl,%ebx,%edx
104         movl    %eax,16(%edi)
105         movl    %edx,20(%edi)
106
107         movl    24(%esi),%eax
108         movl    28(%esi),%edx
109         shrdl   %cl,%eax,%ebx
110         shrdl   %cl,%edx,%eax
111         movl    %ebx,24(%edi)
112         movl    %eax,28(%edi)
113
114         addl    $32,%esi
115         addl    $32,%edi
116         decl    %ebp
117         jnz     Roop
118
119 Rend:   popl    %ebp
120         andl    $7,%ebp
121         jz      Rend2
122 Roop2:  movl    (%esi),%eax
123         shrdl   %cl,%eax,%edx           /* compute result limb */
124         movl    %edx,(%edi)
125         movl    %eax,%edx
126         addl    $4,%esi
127         addl    $4,%edi
128         decl    %ebp
129         jnz     Roop2
130
131 Rend2:  shrl    %cl,%edx                /* compute most significant limb */
132         movl    %edx,(%edi)             /* store it */
133
134         popl    %eax                    /* pop carry limb */
135
136         popl    %ebp
137         popl    %ebx
138         popl    %esi
139         popl    %edi
140         ret
141
142 /* We loop from least significant end of the arrays, which is only
143    permissable if the source and destination don't overlap, since the
144    function is documented to work for overlapping source and destination.
145 */
146
147 Rspecial:
148         leal    -4(%edi,%ebp,4),%edi
149         leal    -4(%esi,%ebp,4),%esi
150
151         movl    (%esi),%edx
152         subl    $4,%esi
153
154         decl    %ebp
155         pushl   %ebp
156         shrl    $3,%ebp
157
158         shrl    $1,%edx
159         incl    %ebp
160         decl    %ebp
161         jz      RLend
162
163         movl    (%edi),%eax             /* fetch destination cache line */
164
165         ALIGN   (2)
166 RLoop:  movl    -28(%edi),%eax          /* fetch destination cache line */
167         movl    %edx,%ebx
168
169         movl    (%esi),%eax
170         movl    -4(%esi),%edx
171         rcrl    $1,%eax
172         movl    %ebx,(%edi)
173         rcrl    $1,%edx
174         movl    %eax,-4(%edi)
175
176         movl    -8(%esi),%ebx
177         movl    -12(%esi),%eax
178         rcrl    $1,%ebx
179         movl    %edx,-8(%edi)
180         rcrl    $1,%eax
181         movl    %ebx,-12(%edi)
182
183         movl    -16(%esi),%edx
184         movl    -20(%esi),%ebx
185         rcrl    $1,%edx
186         movl    %eax,-16(%edi)
187         rcrl    $1,%ebx
188         movl    %edx,-20(%edi)
189
190         movl    -24(%esi),%eax
191         movl    -28(%esi),%edx
192         rcrl    $1,%eax
193         movl    %ebx,-24(%edi)
194         rcrl    $1,%edx
195         movl    %eax,-28(%edi)
196
197         leal    -32(%esi),%esi          /* use leal not to clobber carry */
198         leal    -32(%edi),%edi
199         decl    %ebp
200         jnz     RLoop
201
202 RLend:  popl    %ebp
203         sbbl    %eax,%eax               /* save carry in %eax */
204         andl    $7,%ebp
205         jz      RLend2
206         addl    %eax,%eax               /* restore carry from eax */
207 RLoop2: movl    %edx,%ebx
208         movl    (%esi),%edx
209         rcrl    $1,%edx
210         movl    %ebx,(%edi)
211
212         leal    -4(%esi),%esi           /* use leal not to clobber carry */
213         leal    -4(%edi),%edi
214         decl    %ebp
215         jnz     RLoop2
216
217         jmp     RL1
218 RLend2: addl    %eax,%eax               /* restore carry from eax */
219 RL1:    movl    %edx,(%edi)             /* store last limb */
220
221         movl    $0,%eax
222         rcrl    $1,%eax
223
224         popl    %ebp
225         popl    %ebx
226         popl    %esi
227         popl    %edi
228         ret
229