Updated from GMP 1.906.7
[kopensolaris-gnu/glibc.git] / sysdeps / i386 / i586 / lshift.S
1 /* Pentium optimized __mpn_lshift -- 
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_lshift)
35 C_SYMBOL_NAME(__mpn_lshift:)
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         leal    -4(%edi,%ebp,4),%edi
55         leal    -4(%esi,%ebp,4),%esi
56
57         movl    (%esi),%edx
58         subl    $4,%esi
59         xorl    %eax,%eax
60         shldl   %cl,%edx,%eax           /* compute carry limb */
61         pushl   %eax                    /* push carry limb onto stack */
62
63         decl    %ebp
64         pushl   %ebp
65         shrl    $3,%ebp
66         jz      Lend
67
68         movl    (%edi),%eax             /* fetch destination cache line */
69
70         ALIGN   (2)
71 Loop:   movl    -28(%edi),%eax          /* fetch destination cache line */
72         movl    %edx,%ebx
73
74         movl    (%esi),%eax
75         movl    -4(%esi),%edx
76         shldl   %cl,%eax,%ebx
77         shldl   %cl,%edx,%eax
78         movl    %ebx,(%edi)
79         movl    %eax,-4(%edi)
80
81         movl    -8(%esi),%ebx
82         movl    -12(%esi),%eax
83         shldl   %cl,%ebx,%edx
84         shldl   %cl,%eax,%ebx
85         movl    %edx,-8(%edi)
86         movl    %ebx,-12(%edi)
87
88         movl    -16(%esi),%edx
89         movl    -20(%esi),%ebx
90         shldl   %cl,%edx,%eax
91         shldl   %cl,%ebx,%edx
92         movl    %eax,-16(%edi)
93         movl    %edx,-20(%edi)
94
95         movl    -24(%esi),%eax
96         movl    -28(%esi),%edx
97         shldl   %cl,%eax,%ebx
98         shldl   %cl,%edx,%eax
99         movl    %ebx,-24(%edi)
100         movl    %eax,-28(%edi)
101
102         subl    $32,%esi
103         subl    $32,%edi
104         decl    %ebp
105         jnz     Loop
106
107 Lend:   popl    %ebp
108         andl    $7,%ebp
109         jz      Lend2
110 Loop2:  movl    (%esi),%eax
111         shldl   %cl,%eax,%edx
112         movl    %edx,(%edi)
113         movl    %eax,%edx
114         subl    $4,%esi
115         subl    $4,%edi
116         decl    %ebp
117         jnz     Loop2
118
119 Lend2:  shll    %cl,%edx                /* compute least significant limb */
120         movl    %edx,(%edi)             /* store it */
121
122         popl    %eax                    /* pop carry limb */
123
124         popl    %ebp
125         popl    %ebx
126         popl    %esi
127         popl    %edi
128         ret
129
130 /* We loop from least significant end of the arrays, which is only
131    permissable if the source and destination don't overlap, since the
132    function is documented to work for overlapping source and destination.
133 */
134
135 Lspecial:
136         movl    (%esi),%edx
137         addl    $4,%esi
138
139         decl    %ebp
140         pushl   %ebp
141         shrl    $3,%ebp
142
143         addl    %edx,%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         adcl    %eax,%eax
157         movl    %ebx,(%edi)
158         adcl    %edx,%edx
159         movl    %eax,4(%edi)
160
161         movl    8(%esi),%ebx
162         movl    12(%esi),%eax
163         adcl    %ebx,%ebx
164         movl    %edx,8(%edi)
165         adcl    %eax,%eax
166         movl    %ebx,12(%edi)
167
168         movl    16(%esi),%edx
169         movl    20(%esi),%ebx
170         adcl    %edx,%edx
171         movl    %eax,16(%edi)
172         adcl    %ebx,%ebx
173         movl    %edx,20(%edi)
174
175         movl    24(%esi),%eax
176         movl    28(%esi),%edx
177         adcl    %eax,%eax
178         movl    %ebx,24(%edi)
179         adcl    %edx,%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         adcl    %edx,%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         sbbl    %eax,%eax
207         negl    %eax
208
209         popl    %ebp
210         popl    %ebx
211         popl    %esi
212         popl    %edi
213         ret