1
/* i80586 rshift, lshift
2
* Copyright (C) 1998 Free Software Foundation, Inc.
3
* Copyright (C) 1992, 1994 Free Software Foundation, Inc.
5
* This file is part of GNUPG.
7
* GNUPG is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* GNUPG is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
* Note: This code is heavily based on the GNU MP Library.
22
* Actually it's the same code with only minor changes in the
23
* way the data is stored; this is to support the abstraction
24
* of an optional secure memory allocation which may be used
25
* to avoid revealing of sensitive data due to paging etc.
26
* The GNU MP Library itself is published under the LGPL;
27
* however I decided to publish this code under the plain GPL.
32
#include "asm-syntax.h"
37
* mpihelp_lshift( mpi_ptr_t wp, (sp + 4)
38
* mpi_ptr_t up, (sp + 8)
39
* mpi_size_t usize, (sp + 12)
40
* unsigned cnt) (sp + 16)
45
.globl C_SYMBOL_NAME(mpihelp_lshift)
46
C_SYMBOL_NAME(mpihelp_lshift:)
53
movl 20(%esp),%edi /* res_ptr */
54
movl 24(%esp),%esi /* s_ptr */
55
movl 28(%esp),%ebp /* size */
56
movl 32(%esp),%ecx /* cnt */
58
/* We can use faster code for shift-by-1 under certain conditions. */
63
jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
64
leal (%esi,%ebp,4),%eax
66
jnc Lspecial /* jump if res_ptr >= s_ptr + size */
69
leal -4(%edi,%ebp,4),%edi
70
leal -4(%esi,%ebp,4),%esi
75
shldl %cl,%edx,%eax /* compute carry limb */
76
pushl %eax /* push carry limb onto stack */
83
movl (%edi),%eax /* fetch destination cache line */
86
Loop: movl -28(%edi),%eax /* fetch destination cache line */
125
Loop2: movl (%esi),%eax
134
Lend2: shll %cl,%edx /* compute least significant limb */
135
movl %edx,(%edi) /* store it */
137
popl %eax /* pop carry limb */
145
/* We loop from least significant end of the arrays, which is only
146
permissable if the source and destination don't overlap, since the
147
function is documented to work for overlapping source and destination.
163
movl (%edi),%eax /* fetch destination cache line */
166
LLoop: movl 28(%edi),%eax /* fetch destination cache line */
197
leal 32(%esi),%esi /* use leal not to clobber carry */
203
sbbl %eax,%eax /* save carry in %eax */
206
addl %eax,%eax /* restore carry from eax */
207
LLoop2: movl %edx,%ebx
212
leal 4(%esi),%esi /* use leal not to clobber carry */
218
LLend2: addl %eax,%eax /* restore carry from eax */
219
LL1: movl %edx,(%edi) /* store last limb */
235
* mpihelp_rshift( mpi_ptr_t wp, (sp + 4)
236
* mpi_ptr_t up, (sp + 8)
237
* mpi_size_t usize, (sp + 12)
238
* unsigned cnt) (sp + 16)
243
.globl C_SYMBOL_NAME(mpihelp_rshift)
244
C_SYMBOL_NAME(mpihelp_rshift:)
250
movl 20(%esp),%edi /* res_ptr */
251
movl 24(%esp),%esi /* s_ptr */
252
movl 28(%esp),%ebp /* size */
253
movl 32(%esp),%ecx /* cnt */
255
/* We can use faster code for shift-by-1 under certain conditions. */
260
jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */
261
leal (%edi,%ebp,4),%eax
263
jnc Rspecial /* jump if s_ptr >= res_ptr + size */
269
shrdl %cl,%edx,%eax /* compute carry limb */
270
pushl %eax /* push carry limb onto stack */
277
movl (%edi),%eax /* fetch destination cache line */
280
Roop: movl 28(%edi),%eax /* fetch destination cache line */
319
Roop2: movl (%esi),%eax
320
shrdl %cl,%eax,%edx /* compute result limb */
328
Rend2: shrl %cl,%edx /* compute most significant limb */
329
movl %edx,(%edi) /* store it */
331
popl %eax /* pop carry limb */
339
/* We loop from least significant end of the arrays, which is only
340
permissable if the source and destination don't overlap, since the
341
function is documented to work for overlapping source and destination.
345
leal -4(%edi,%ebp,4),%edi
346
leal -4(%esi,%ebp,4),%esi
360
movl (%edi),%eax /* fetch destination cache line */
363
RLoop: movl -28(%edi),%eax /* fetch destination cache line */
394
leal -32(%esi),%esi /* use leal not to clobber carry */
400
sbbl %eax,%eax /* save carry in %eax */
403
addl %eax,%eax /* restore carry from eax */
404
RLoop2: movl %edx,%ebx
409
leal -4(%esi),%esi /* use leal not to clobber carry */
415
RLend2: addl %eax,%eax /* restore carry from eax */
416
RL1: movl %edx,(%edi) /* store last limb */