Updated from GMP 1.906.7
[kopensolaris-gnu/glibc.git] / sysdeps / i386 / i586 / rshift.S
1 /* Pentium optimized __mpn_rshift -- 
2
3 Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Library General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
15 License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /*
22   INPUT PARAMETERS
23   res_ptr       (sp + 4)
24   s_ptr         (sp + 8)
25   size          (sp + 12)
26   cnt           (sp + 16)
27 */
28
29 #include "sysdep.h"
30 #include "asm-syntax.h"
31
32 .text
33         ALIGN (3)
34         .globl C_SYMBOL_NAME(__mpn_rshift)
35 C_SYMBOL_NAME(__mpn_rshift:)
36         pushl   %edi
37         pushl   %esi
38         pushl   %ebx
39         pushl   %ebp
40
41         movl    20(%esp),%edi           /* res_ptr */
42         movl    24(%esp),%esi           /* s_ptr */
43         movl    28(%esp),%ebp           /* size */
44         movl    32(%esp),%ecx           /* cnt */
45
46         cmp     $1,%ecx
47         jne     Lnormal
48         movl    %edi,%eax
49         subl    %esi,%eax
50         cmpl    %ebp,%eax
51         jnc     Lspecial
52
53 Lnormal:
54         movl    (%esi),%edx
55         addl    $4,%esi
56         xorl    %eax,%eax
57         shrdl   %cl,%edx,%eax           /* compute carry limb */
58         pushl   %eax                    /* push carry limb onto stack */
59
60         decl    %ebp
61         pushl   %ebp
62         shrl    $3,%ebp
63         jz      Lend
64
65         movl    (%edi),%eax             /* fetch destination cache line */
66
67         ALIGN   (2)
68 Loop:   movl    28(%edi),%eax           /* fetch destination cache line */
69         movl    %edx,%ebx
70
71         movl    (%esi),%eax
72         movl    4(%esi),%edx
73         shrdl   %cl,%eax,%ebx
74         shrdl   %cl,%edx,%eax
75         movl    %ebx,(%edi)
76         movl    %eax,4(%edi)
77
78         movl    8(%esi),%ebx
79         movl    12(%esi),%eax
80         shrdl   %cl,%ebx,%edx
81         shrdl   %cl,%eax,%ebx
82         movl    %edx,8(%edi)
83         movl    %ebx,12(%edi)
84
85         movl    16(%esi),%edx
86         movl    20(%esi),%ebx
87         shrdl   %cl,%edx,%eax
88         shrdl   %cl,%ebx,%edx
89         movl    %eax,16(%edi)
90         movl    %edx,20(%edi)
91
92         movl    24(%esi),%eax
93         movl    28(%esi),%edx
94         shrdl   %cl,%eax,%ebx
95         shrdl   %cl,%edx,%eax
96         movl    %ebx,24(%edi)
97         movl    %eax,28(%edi)
98
99         addl    $32,%esi
100         addl    $32,%edi
101         decl    %ebp
102         jnz     Loop
103
104 Lend:   popl    %ebp
105         andl    $7,%ebp
106         jz      Lend2
107 Loop2:  movl    (%esi),%eax
108         shrdl   %cl,%eax,%edx           /* compute result limb */
109         movl    %edx,(%edi)
110         movl    %eax,%edx
111         addl    $4,%esi
112         addl    $4,%edi
113         decl    %ebp
114         jnz     Loop2
115
116 Lend2:  shrl    %cl,%edx                /* compute most significant limb */
117         movl    %edx,(%edi)             /* store it */
118
119         popl    %eax                    /* pop carry limb */
120
121         popl    %ebp
122         popl    %ebx
123         popl    %esi
124         popl    %edi
125         ret
126
127 /* We loop from least significant end of the arrays, which is only
128    permissable if the source and destination don't overlap, since the
129    function is documented to work for overlapping source and destination.
130 */
131
132 Lspecial:
133         leal    -4(%edi,%ebp,4),%edi
134         leal    -4(%esi,%ebp,4),%esi
135
136         movl    (%esi),%edx
137         subl    $4,%esi
138
139         decl    %ebp
140         pushl   %ebp
141         shrl    $3,%ebp
142
143         shrl    $1,%edx
144         incl    %ebp
145         decl    %ebp
146         jz      LLend
147
148         movl    (%edi),%eax             /* fetch destination cache line */
149
150         ALIGN   (2)
151 LLoop:  movl    -28(%edi),%eax          /* fetch destination cache line */
152         movl    %edx,%ebx
153
154         movl    (%esi),%eax
155         movl    -4(%esi),%edx
156         rcrl    $1,%eax
157         movl    %ebx,(%edi)
158         rcrl    $1,%edx
159         movl    %eax,-4(%edi)
160
161         movl    -8(%esi),%ebx
162         movl    -12(%esi),%eax
163         rcrl    $1,%ebx
164         movl    %edx,-8(%edi)
165         rcrl    $1,%eax
166         movl    %ebx,-12(%edi)
167
168         movl    -16(%esi),%edx
169         movl    -20(%esi),%ebx
170         rcrl    $1,%edx
171         movl    %eax,-16(%edi)
172         rcrl    $1,%ebx
173         movl    %edx,-20(%edi)
174
175         movl    -24(%esi),%eax
176         movl    -28(%esi),%edx
177         rcrl    $1,%eax
178         movl    %ebx,-24(%edi)
179         rcrl    $1,%edx
180         movl    %eax,-28(%edi)
181
182         leal    -32(%esi),%esi          /* use leal not to clobber carry */
183         leal    -32(%edi),%edi
184         decl    %ebp
185         jnz     LLoop
186
187 LLend:  popl    %ebp
188         sbbl    %eax,%eax               /* save carry in %eax */
189         andl    $7,%ebp
190         jz      LLend2
191         addl    %eax,%eax               /* restore carry from eax */
192 LLoop2: movl    %edx,%ebx
193         movl    (%esi),%edx
194         rcrl    $1,%edx
195         movl    %ebx,(%edi)
196
197         leal    -4(%esi),%esi           /* use leal not to clobber carry */
198         leal    -4(%edi),%edi
199         decl    %ebp
200         jnz     LLoop2
201
202         jmp     LL1
203 LLend2: addl    %eax,%eax               /* restore carry from eax */
204 LL1:    movl    %edx,(%edi)             /* store last limb */
205
206         movl    $0,%eax
207         rcrl    $1,%eax
208
209         popl    %ebp
210         popl    %ebx
211         popl    %esi
212         popl    %edi
213         ret