Replace FSF snail mail address with URLs.
[glibc.git] / sysdeps / i386 / i586 / rshift.S
blobcaf0986d2f473c741853565e9bebca3b55a361aa
1 /* Pentium optimized __mpn_rshift --
2    Copyright (C) 1992,94,95,96,97,98,2000,2005 Free Software Foundation, Inc.
3    This file is part of the GNU MP Library.
5    The GNU MP Library is free software; you can redistribute it and/or modify
6    it under the terms of the GNU Lesser General Public License as published by
7    the Free Software Foundation; either version 2.1 of the License, or (at your
8    option) any later version.
10    The GNU MP Library is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
13    License for more details.
15    You should have received a copy of the GNU Lesser General Public License
16    along with the GNU MP Library; see the file COPYING.LIB.  If not,
17    see <http://www.gnu.org/licenses/>.  */
19 #include "sysdep.h"
20 #include "asm-syntax.h"
21 #include "bp-sym.h"
22 #include "bp-asm.h"
24 #define PARMS   LINKAGE+16              /* space for 4 saved regs */
25 #define RES     PARMS
26 #define S       RES+PTR_SIZE
27 #define SIZE    S+PTR_SIZE
28 #define CNT     SIZE+4
30         .text
31 ENTRY (BP_SYM (__mpn_rshift))
32         ENTER
34         pushl   %edi
35         cfi_adjust_cfa_offset (4)
36         pushl   %esi
37         cfi_adjust_cfa_offset (4)
38         pushl   %ebp
39         cfi_adjust_cfa_offset (4)
40         cfi_rel_offset (ebp, 0)
41         pushl   %ebx
42         cfi_adjust_cfa_offset (4)
44         movl    RES(%esp),%edi
45         cfi_rel_offset (edi, 12)
46         movl    S(%esp),%esi
47         cfi_rel_offset (esi, 8)
48         movl    SIZE(%esp),%ebx
49         cfi_rel_offset (ebx, 0)
50         movl    CNT(%esp),%ecx
51 #if __BOUNDED_POINTERS__
52         shll    $2, %ebx                /* convert limbs to bytes */
53         CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ebx)
54         CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %ebx)
55         shrl    $2, %ebx
56 #endif
58 /* We can use faster code for shift-by-1 under certain conditions.  */
59         cmp     $1,%ecx
60         jne     L(normal)
61         leal    4(%edi),%eax
62         cmpl    %esi,%eax
63         jnc     L(special)              /* jump if res_ptr + 1 >= s_ptr */
64         leal    (%edi,%ebx,4),%eax
65         cmpl    %eax,%esi
66         jnc     L(special)              /* jump if s_ptr >= res_ptr + size */
68 L(normal):
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         cfi_adjust_cfa_offset (4)
76         decl    %ebx
77         pushl   %ebx
78         cfi_adjust_cfa_offset (4)
79         shrl    $3,%ebx
80         jz      L(end)
82         movl    (%edi),%eax             /* fetch destination cache line */
84         ALIGN   (2)
85 L(oop): movl    28(%edi),%eax           /* fetch destination cache line */
86         movl    %edx,%ebp
88         movl    (%esi),%eax
89         movl    4(%esi),%edx
90         shrdl   %cl,%eax,%ebp
91         shrdl   %cl,%edx,%eax
92         movl    %ebp,(%edi)
93         movl    %eax,4(%edi)
95         movl    8(%esi),%ebp
96         movl    12(%esi),%eax
97         shrdl   %cl,%ebp,%edx
98         shrdl   %cl,%eax,%ebp
99         movl    %edx,8(%edi)
100         movl    %ebp,12(%edi)
102         movl    16(%esi),%edx
103         movl    20(%esi),%ebp
104         shrdl   %cl,%edx,%eax
105         shrdl   %cl,%ebp,%edx
106         movl    %eax,16(%edi)
107         movl    %edx,20(%edi)
109         movl    24(%esi),%eax
110         movl    28(%esi),%edx
111         shrdl   %cl,%eax,%ebp
112         shrdl   %cl,%edx,%eax
113         movl    %ebp,24(%edi)
114         movl    %eax,28(%edi)
116         addl    $32,%esi
117         addl    $32,%edi
118         decl    %ebx
119         jnz     L(oop)
121 L(end): popl    %ebx
122         cfi_adjust_cfa_offset (-4)
123         andl    $7,%ebx
124         jz      L(end2)
125 L(oop2):
126         movl    (%esi),%eax
127         shrdl   %cl,%eax,%edx           /* compute result limb */
128         movl    %edx,(%edi)
129         movl    %eax,%edx
130         addl    $4,%esi
131         addl    $4,%edi
132         decl    %ebx
133         jnz     L(oop2)
135 L(end2):
136         shrl    %cl,%edx                /* compute most significant limb */
137         movl    %edx,(%edi)             /* store it */
139         popl    %eax                    /* pop carry limb */
140         cfi_adjust_cfa_offset (-4)
142         popl    %ebx
143         cfi_adjust_cfa_offset (-4)
144         cfi_restore (ebx)
145         popl    %ebp
146         cfi_adjust_cfa_offset (-4)
147         cfi_restore (ebp)
148         popl    %esi
149         cfi_adjust_cfa_offset (-4)
150         cfi_restore (esi)
151         popl    %edi
152         cfi_adjust_cfa_offset (-4)
153         cfi_restore (edi)
155         LEAVE
156         ret
158 /* We loop from least significant end of the arrays, which is only
159    permissible if the source and destination don't overlap, since the
160    function is documented to work for overlapping source and destination.
163         cfi_adjust_cfa_offset (16)
164         cfi_rel_offset (edi, 12)
165         cfi_rel_offset (esi, 8)
166         cfi_rel_offset (ebp, 4)
167         cfi_rel_offset (ebx, 0)
168 L(special):
169         leal    -4(%edi,%ebx,4),%edi
170         leal    -4(%esi,%ebx,4),%esi
172         movl    (%esi),%edx
173         subl    $4,%esi
175         decl    %ebx
176         pushl   %ebx
177         cfi_adjust_cfa_offset (4)
178         shrl    $3,%ebx
180         shrl    $1,%edx
181         incl    %ebx
182         decl    %ebx
183         jz      L(Lend)
185         movl    (%edi),%eax             /* fetch destination cache line */
187         ALIGN   (2)
188 L(Loop):
189         movl    -28(%edi),%eax          /* fetch destination cache line */
190         movl    %edx,%ebp
192         movl    (%esi),%eax
193         movl    -4(%esi),%edx
194         rcrl    $1,%eax
195         movl    %ebp,(%edi)
196         rcrl    $1,%edx
197         movl    %eax,-4(%edi)
199         movl    -8(%esi),%ebp
200         movl    -12(%esi),%eax
201         rcrl    $1,%ebp
202         movl    %edx,-8(%edi)
203         rcrl    $1,%eax
204         movl    %ebp,-12(%edi)
206         movl    -16(%esi),%edx
207         movl    -20(%esi),%ebp
208         rcrl    $1,%edx
209         movl    %eax,-16(%edi)
210         rcrl    $1,%ebp
211         movl    %edx,-20(%edi)
213         movl    -24(%esi),%eax
214         movl    -28(%esi),%edx
215         rcrl    $1,%eax
216         movl    %ebp,-24(%edi)
217         rcrl    $1,%edx
218         movl    %eax,-28(%edi)
220         leal    -32(%esi),%esi          /* use leal not to clobber carry */
221         leal    -32(%edi),%edi
222         decl    %ebx
223         jnz     L(Loop)
225 L(Lend):
226         popl    %ebx
227         cfi_adjust_cfa_offset (-4)
228         sbbl    %eax,%eax               /* save carry in %eax */
229         andl    $7,%ebx
230         jz      L(Lend2)
231         addl    %eax,%eax               /* restore carry from eax */
232 L(Loop2):
233         movl    %edx,%ebp
234         movl    (%esi),%edx
235         rcrl    $1,%edx
236         movl    %ebp,(%edi)
238         leal    -4(%esi),%esi           /* use leal not to clobber carry */
239         leal    -4(%edi),%edi
240         decl    %ebx
241         jnz     L(Loop2)
243         jmp     L(L1)
244 L(Lend2):
245         addl    %eax,%eax               /* restore carry from eax */
246 L(L1):  movl    %edx,(%edi)             /* store last limb */
248         movl    $0,%eax
249         rcrl    $1,%eax
251         popl    %ebx
252         cfi_adjust_cfa_offset (-4)
253         cfi_restore (ebx)
254         popl    %ebp
255         cfi_adjust_cfa_offset (-4)
256         cfi_restore (ebp)
257         popl    %esi
258         cfi_adjust_cfa_offset (-4)
259         cfi_restore (esi)
260         popl    %edi
261         cfi_adjust_cfa_offset (-4)
262         cfi_restore (edi)
264         LEAVE
265         ret
266 END (BP_SYM (__mpn_rshift))