Update.
[glibc.git] / sysdeps / i386 / i586 / rshift.S
blob14ffbb84546b208d43d4ed5b966af023ce6c233f
1 /* Pentium optimized __mpn_rshift --
2    Copyright (C) 1992, 1994, 1995, 1996, 1997 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 Library General Public License as published by
7    the Free Software Foundation; either version 2 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 Library General Public
13    License for more details.
15    You should have received a copy of the GNU Library General Public License
16    along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
17    the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18    MA 02111-1307, USA. */
21   INPUT PARAMETERS
22   res_ptr       (sp + 4)
23   s_ptr         (sp + 8)
24   size          (sp + 12)
25   cnt           (sp + 16)
28 #include "sysdep.h"
29 #include "asm-syntax.h"
31 .text
32         ALIGN (3)
33         .globl C_SYMBOL_NAME(__mpn_rshift)
34 C_SYMBOL_NAME(__mpn_rshift:)
35         pushl   %edi
36         pushl   %esi
37         pushl   %ebx
38         pushl   %ebp
40         movl    20(%esp),%edi           /* res_ptr */
41         movl    24(%esp),%esi           /* s_ptr */
42         movl    28(%esp),%ebp           /* size */
43         movl    32(%esp),%ecx           /* cnt */
45 /* We can use faster code for shift-by-1 under certain conditions.  */
46         cmp     $1,%ecx
47         jne     L(normal)
48         leal    4(%edi),%eax
49         cmpl    %esi,%eax
50         jnc     L(special)              /* jump if res_ptr + 1 >= s_ptr */
51         leal    (%edi,%ebp,4),%eax
52         cmpl    %eax,%esi
53         jnc     L(special)              /* jump if s_ptr >= res_ptr + size */
55 L(normal):
56         movl    (%esi),%edx
57         addl    $4,%esi
58         xorl    %eax,%eax
59         shrdl   %cl,%edx,%eax           /* compute carry limb */
60         pushl   %eax                    /* push carry limb onto stack */
62         decl    %ebp
63         pushl   %ebp
64         shrl    $3,%ebp
65         jz      L(end)
67         movl    (%edi),%eax             /* fetch destination cache line */
69         ALIGN   (2)
70 L(oop): movl    28(%edi),%eax           /* fetch destination cache line */
71         movl    %edx,%ebx
73         movl    (%esi),%eax
74         movl    4(%esi),%edx
75         shrdl   %cl,%eax,%ebx
76         shrdl   %cl,%edx,%eax
77         movl    %ebx,(%edi)
78         movl    %eax,4(%edi)
80         movl    8(%esi),%ebx
81         movl    12(%esi),%eax
82         shrdl   %cl,%ebx,%edx
83         shrdl   %cl,%eax,%ebx
84         movl    %edx,8(%edi)
85         movl    %ebx,12(%edi)
87         movl    16(%esi),%edx
88         movl    20(%esi),%ebx
89         shrdl   %cl,%edx,%eax
90         shrdl   %cl,%ebx,%edx
91         movl    %eax,16(%edi)
92         movl    %edx,20(%edi)
94         movl    24(%esi),%eax
95         movl    28(%esi),%edx
96         shrdl   %cl,%eax,%ebx
97         shrdl   %cl,%edx,%eax
98         movl    %ebx,24(%edi)
99         movl    %eax,28(%edi)
101         addl    $32,%esi
102         addl    $32,%edi
103         decl    %ebp
104         jnz     L(oop)
106 L(end): popl    %ebp
107         andl    $7,%ebp
108         jz      L(end2)
109 L(oop2):
110         movl    (%esi),%eax
111         shrdl   %cl,%eax,%edx           /* compute result limb */
112         movl    %edx,(%edi)
113         movl    %eax,%edx
114         addl    $4,%esi
115         addl    $4,%edi
116         decl    %ebp
117         jnz     L(oop2)
119 L(end2):
120         shrl    %cl,%edx                /* compute most significant limb */
121         movl    %edx,(%edi)             /* store it */
123         popl    %eax                    /* pop carry limb */
125         popl    %ebp
126         popl    %ebx
127         popl    %esi
128         popl    %edi
129         ret
131 /* We loop from least significant end of the arrays, which is only
132    permissible if the source and destination don't overlap, since the
133    function is documented to work for overlapping source and destination.
136 L(special):
137         leal    -4(%edi,%ebp,4),%edi
138         leal    -4(%esi,%ebp,4),%esi
140         movl    (%esi),%edx
141         subl    $4,%esi
143         decl    %ebp
144         pushl   %ebp
145         shrl    $3,%ebp
147         shrl    $1,%edx
148         incl    %ebp
149         decl    %ebp
150         jz      L(Lend)
152         movl    (%edi),%eax             /* fetch destination cache line */
154         ALIGN   (2)
155 L(Loop):
156         movl    -28(%edi),%eax          /* fetch destination cache line */
157         movl    %edx,%ebx
159         movl    (%esi),%eax
160         movl    -4(%esi),%edx
161         rcrl    $1,%eax
162         movl    %ebx,(%edi)
163         rcrl    $1,%edx
164         movl    %eax,-4(%edi)
166         movl    -8(%esi),%ebx
167         movl    -12(%esi),%eax
168         rcrl    $1,%ebx
169         movl    %edx,-8(%edi)
170         rcrl    $1,%eax
171         movl    %ebx,-12(%edi)
173         movl    -16(%esi),%edx
174         movl    -20(%esi),%ebx
175         rcrl    $1,%edx
176         movl    %eax,-16(%edi)
177         rcrl    $1,%ebx
178         movl    %edx,-20(%edi)
180         movl    -24(%esi),%eax
181         movl    -28(%esi),%edx
182         rcrl    $1,%eax
183         movl    %ebx,-24(%edi)
184         rcrl    $1,%edx
185         movl    %eax,-28(%edi)
187         leal    -32(%esi),%esi          /* use leal not to clobber carry */
188         leal    -32(%edi),%edi
189         decl    %ebp
190         jnz     L(Loop)
192 L(Lend):
193         popl    %ebp
194         sbbl    %eax,%eax               /* save carry in %eax */
195         andl    $7,%ebp
196         jz      L(Lend2)
197         addl    %eax,%eax               /* restore carry from eax */
198 L(Loop2):
199         movl    %edx,%ebx
200         movl    (%esi),%edx
201         rcrl    $1,%edx
202         movl    %ebx,(%edi)
204         leal    -4(%esi),%esi           /* use leal not to clobber carry */
205         leal    -4(%edi),%edi
206         decl    %ebp
207         jnz     L(Loop2)
209         jmp     L(L1)
210 L(Lend2):
211         addl    %eax,%eax               /* restore carry from eax */
212 L(L1):  movl    %edx,(%edi)             /* store last limb */
214         movl    $0,%eax
215         rcrl    $1,%eax
217         popl    %ebp
218         popl    %ebx
219         popl    %esi
220         popl    %edi
221         ret