]> git.proxmox.com Git - grub2.git/blob - grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S
Import grub2_2.02+dfsg1.orig.tar.xz
[grub2.git] / grub-core / lib / libgcrypt / mpi / i586 / mpih-lshift.S
1 /* i80586 lshift
2 *
3 * Copyright (C) 1992, 1994, 1998,
4 * 2001, 2002 Free Software Foundation, Inc.
5 *
6 * This file is part of Libgcrypt.
7 *
8 * Libgcrypt is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * Libgcrypt is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 *
22 * Note: This code is heavily based on the GNU MP Library.
23 * Actually it's the same code with only minor changes in the
24 * way the data is stored; this is to support the abstraction
25 * of an optional secure memory allocation which may be used
26 * to avoid revealing of sensitive data due to paging etc.
27 */
28
29
30 #include "sysdep.h"
31 #include "asm-syntax.h"
32
33
34 /*******************
35 * mpi_limb_t
36 * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
37 * mpi_ptr_t up, (sp + 8)
38 * mpi_size_t usize, (sp + 12)
39 * unsigned cnt) (sp + 16)
40 */
41
42 .text
43 ALIGN (3)
44 .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
45 C_SYMBOL_NAME(_gcry_mpih_lshift:)
46
47 pushl %edi
48 pushl %esi
49 pushl %ebx
50 pushl %ebp
51
52 movl 20(%esp),%edi /* res_ptr */
53 movl 24(%esp),%esi /* s_ptr */
54 movl 28(%esp),%ebp /* size */
55 movl 32(%esp),%ecx /* cnt */
56
57 /* We can use faster code for shift-by-1 under certain conditions. */
58 cmp $1,%ecx
59 jne Lnormal
60 leal 4(%esi),%eax
61 cmpl %edi,%eax
62 jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
63 leal (%esi,%ebp,4),%eax
64 cmpl %eax,%edi
65 jnc Lspecial /* jump if res_ptr >= s_ptr + size */
66
67 Lnormal:
68 leal -4(%edi,%ebp,4),%edi
69 leal -4(%esi,%ebp,4),%esi
70
71 movl (%esi),%edx
72 subl $4,%esi
73 xorl %eax,%eax
74 shldl %cl,%edx,%eax /* compute carry limb */
75 pushl %eax /* push carry limb onto stack */
76
77 decl %ebp
78 pushl %ebp
79 shrl $3,%ebp
80 jz Lend
81
82 movl (%edi),%eax /* fetch destination cache line */
83
84 ALIGN (2)
85 Loop: movl -28(%edi),%eax /* fetch destination cache line */
86 movl %edx,%ebx
87
88 movl (%esi),%eax
89 movl -4(%esi),%edx
90 shldl %cl,%eax,%ebx
91 shldl %cl,%edx,%eax
92 movl %ebx,(%edi)
93 movl %eax,-4(%edi)
94
95 movl -8(%esi),%ebx
96 movl -12(%esi),%eax
97 shldl %cl,%ebx,%edx
98 shldl %cl,%eax,%ebx
99 movl %edx,-8(%edi)
100 movl %ebx,-12(%edi)
101
102 movl -16(%esi),%edx
103 movl -20(%esi),%ebx
104 shldl %cl,%edx,%eax
105 shldl %cl,%ebx,%edx
106 movl %eax,-16(%edi)
107 movl %edx,-20(%edi)
108
109 movl -24(%esi),%eax
110 movl -28(%esi),%edx
111 shldl %cl,%eax,%ebx
112 shldl %cl,%edx,%eax
113 movl %ebx,-24(%edi)
114 movl %eax,-28(%edi)
115
116 subl $32,%esi
117 subl $32,%edi
118 decl %ebp
119 jnz Loop
120
121 Lend: popl %ebp
122 andl $7,%ebp
123 jz Lend2
124 Loop2: movl (%esi),%eax
125 shldl %cl,%eax,%edx
126 movl %edx,(%edi)
127 movl %eax,%edx
128 subl $4,%esi
129 subl $4,%edi
130 decl %ebp
131 jnz Loop2
132
133 Lend2: shll %cl,%edx /* compute least significant limb */
134 movl %edx,(%edi) /* store it */
135
136 popl %eax /* pop carry limb */
137
138 popl %ebp
139 popl %ebx
140 popl %esi
141 popl %edi
142 ret
143
144 /* We loop from least significant end of the arrays, which is only
145 permissable if the source and destination don't overlap, since the
146 function is documented to work for overlapping source and destination.
147 */
148
149 Lspecial:
150 movl (%esi),%edx
151 addl $4,%esi
152
153 decl %ebp
154 pushl %ebp
155 shrl $3,%ebp
156
157 addl %edx,%edx
158 incl %ebp
159 decl %ebp
160 jz LLend
161
162 movl (%edi),%eax /* fetch destination cache line */
163
164 ALIGN (2)
165 LLoop: movl 28(%edi),%eax /* fetch destination cache line */
166 movl %edx,%ebx
167
168 movl (%esi),%eax
169 movl 4(%esi),%edx
170 adcl %eax,%eax
171 movl %ebx,(%edi)
172 adcl %edx,%edx
173 movl %eax,4(%edi)
174
175 movl 8(%esi),%ebx
176 movl 12(%esi),%eax
177 adcl %ebx,%ebx
178 movl %edx,8(%edi)
179 adcl %eax,%eax
180 movl %ebx,12(%edi)
181
182 movl 16(%esi),%edx
183 movl 20(%esi),%ebx
184 adcl %edx,%edx
185 movl %eax,16(%edi)
186 adcl %ebx,%ebx
187 movl %edx,20(%edi)
188
189 movl 24(%esi),%eax
190 movl 28(%esi),%edx
191 adcl %eax,%eax
192 movl %ebx,24(%edi)
193 adcl %edx,%edx
194 movl %eax,28(%edi)
195
196 leal 32(%esi),%esi /* use leal not to clobber carry */
197 leal 32(%edi),%edi
198 decl %ebp
199 jnz LLoop
200
201 LLend: popl %ebp
202 sbbl %eax,%eax /* save carry in %eax */
203 andl $7,%ebp
204 jz LLend2
205 addl %eax,%eax /* restore carry from eax */
206 LLoop2: movl %edx,%ebx
207 movl (%esi),%edx
208 adcl %edx,%edx
209 movl %ebx,(%edi)
210
211 leal 4(%esi),%esi /* use leal not to clobber carry */
212 leal 4(%edi),%edi
213 decl %ebp
214 jnz LLoop2
215
216 jmp LL1
217 LLend2: addl %eax,%eax /* restore carry from eax */
218 LL1: movl %edx,(%edi) /* store last limb */
219
220 sbbl %eax,%eax
221 negl %eax
222
223 popl %ebp
224 popl %ebx
225 popl %esi
226 popl %edi
227 ret
228
229