Update from main archive 961219
[glibc.git] / sysdeps / i386 / i586 / lshift.S
blobbf9b223a0b67e97311e55e600ef4261d8a553623
1 /* Pentium optimized __mpn_lshift --
2    Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C 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 C 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_lshift)
34 C_SYMBOL_NAME(__mpn_lshift:)
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     Lnormal
48         leal    4(%esi),%eax
49         cmpl    %edi,%eax
50         jnc     Lspecial                /* jump if s_ptr + 1 >= res_ptr */
51         leal    (%esi,%ebp,4),%eax
52         cmpl    %eax,%edi
53         jnc     Lspecial                /* jump if res_ptr >= s_ptr + size */
55 Lnormal:
56         leal    -4(%edi,%ebp,4),%edi
57         leal    -4(%esi,%ebp,4),%esi
59         movl    (%esi),%edx
60         subl    $4,%esi
61         xorl    %eax,%eax
62         shldl   %cl,%edx,%eax           /* compute carry limb */
63         pushl   %eax                    /* push carry limb onto stack */
65         decl    %ebp
66         pushl   %ebp
67         shrl    $3,%ebp
68         jz      Lend
70         movl    (%edi),%eax             /* fetch destination cache line */
72         ALIGN   (2)
73 Loop:   movl    -28(%edi),%eax          /* fetch destination cache line */
74         movl    %edx,%ebx
76         movl    (%esi),%eax
77         movl    -4(%esi),%edx
78         shldl   %cl,%eax,%ebx
79         shldl   %cl,%edx,%eax
80         movl    %ebx,(%edi)
81         movl    %eax,-4(%edi)
83         movl    -8(%esi),%ebx
84         movl    -12(%esi),%eax
85         shldl   %cl,%ebx,%edx
86         shldl   %cl,%eax,%ebx
87         movl    %edx,-8(%edi)
88         movl    %ebx,-12(%edi)
90         movl    -16(%esi),%edx
91         movl    -20(%esi),%ebx
92         shldl   %cl,%edx,%eax
93         shldl   %cl,%ebx,%edx
94         movl    %eax,-16(%edi)
95         movl    %edx,-20(%edi)
97         movl    -24(%esi),%eax
98         movl    -28(%esi),%edx
99         shldl   %cl,%eax,%ebx
100         shldl   %cl,%edx,%eax
101         movl    %ebx,-24(%edi)
102         movl    %eax,-28(%edi)
104         subl    $32,%esi
105         subl    $32,%edi
106         decl    %ebp
107         jnz     Loop
109 Lend:   popl    %ebp
110         andl    $7,%ebp
111         jz      Lend2
112 Loop2:  movl    (%esi),%eax
113         shldl   %cl,%eax,%edx
114         movl    %edx,(%edi)
115         movl    %eax,%edx
116         subl    $4,%esi
117         subl    $4,%edi
118         decl    %ebp
119         jnz     Loop2
121 Lend2:  shll    %cl,%edx                /* compute least significant limb */
122         movl    %edx,(%edi)             /* store it */
124         popl    %eax                    /* pop carry limb */
126         popl    %ebp
127         popl    %ebx
128         popl    %esi
129         popl    %edi
130         ret
132 /* We loop from least significant end of the arrays, which is only
133    permissible if the source and destination don't overlap, since the
134    function is documented to work for overlapping source and destination.
137 Lspecial:
138         movl    (%esi),%edx
139         addl    $4,%esi
141         decl    %ebp
142         pushl   %ebp
143         shrl    $3,%ebp
145         addl    %edx,%edx
146         incl    %ebp
147         decl    %ebp
148         jz      LLend
150         movl    (%edi),%eax             /* fetch destination cache line */
152         ALIGN   (2)
153 LLoop:  movl    28(%edi),%eax           /* fetch destination cache line */
154         movl    %edx,%ebx
156         movl    (%esi),%eax
157         movl    4(%esi),%edx
158         adcl    %eax,%eax
159         movl    %ebx,(%edi)
160         adcl    %edx,%edx
161         movl    %eax,4(%edi)
163         movl    8(%esi),%ebx
164         movl    12(%esi),%eax
165         adcl    %ebx,%ebx
166         movl    %edx,8(%edi)
167         adcl    %eax,%eax
168         movl    %ebx,12(%edi)
170         movl    16(%esi),%edx
171         movl    20(%esi),%ebx
172         adcl    %edx,%edx
173         movl    %eax,16(%edi)
174         adcl    %ebx,%ebx
175         movl    %edx,20(%edi)
177         movl    24(%esi),%eax
178         movl    28(%esi),%edx
179         adcl    %eax,%eax
180         movl    %ebx,24(%edi)
181         adcl    %edx,%edx
182         movl    %eax,28(%edi)
184         leal    32(%esi),%esi           /* use leal not to clobber carry */
185         leal    32(%edi),%edi
186         decl    %ebp
187         jnz     LLoop
189 LLend:  popl    %ebp
190         sbbl    %eax,%eax               /* save carry in %eax */
191         andl    $7,%ebp
192         jz      LLend2
193         addl    %eax,%eax               /* restore carry from eax */
194 LLoop2: movl    %edx,%ebx
195         movl    (%esi),%edx
196         adcl    %edx,%edx
197         movl    %ebx,(%edi)
199         leal    4(%esi),%esi            /* use leal not to clobber carry */
200         leal    4(%edi),%edi
201         decl    %ebp
202         jnz     LLoop2
204         jmp     LL1
205 LLend2: addl    %eax,%eax               /* restore carry from eax */
206 LL1:    movl    %edx,(%edi)             /* store last limb */
208         sbbl    %eax,%eax
209         negl    %eax
211         popl    %ebp
212         popl    %ebx
213         popl    %esi
214         popl    %edi
215         ret