417caf15a37e041851e320762bcd711798dca7a8
[libgcrypt.git] / mpi / i386 / mpih-lshift.S
1 /* i80386   lshift
2  *      Copyright (C) 1992, 1994, 1998,
3  *                    2001, 2002 Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt 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 Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  *
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  */
27
28
29 #include "sysdep.h"
30 #include "asm-syntax.h"
31
32
33 /*******************
34  * mpi_limb_t
35  * _gcry_mpih_lshift( mpi_ptr_t wp,     (sp + 4)
36  *                 mpi_ptr_t up,        (sp + 8)
37  *                 mpi_size_t usize,    (sp + 12)
38  *                 unsigned cnt)        (sp + 16)
39  */
40
41 .text
42         ALIGN (3)
43         .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
44 C_SYMBOL_NAME(_gcry_mpih_lshift:)
45         pushl   %edi
46         pushl   %esi
47         pushl   %ebx
48
49         movl    16(%esp),%edi           /* res_ptr */
50         movl    20(%esp),%esi           /* s_ptr */
51         movl    24(%esp),%edx           /* size */
52         movl    28(%esp),%ecx           /* cnt */
53
54         subl    $4,%esi                 /* adjust s_ptr */
55
56         movl    (%esi,%edx,4),%ebx      /* read most significant limb */
57         xorl    %eax,%eax
58         shldl   %cl,%ebx,%eax           /* compute carry limb */
59         decl    %edx
60         jz      Lend
61         pushl   %eax                    /* push carry limb onto stack */
62         testb   $1,%edx
63         jnz     L1                      /* enter loop in the middle */
64         movl    %ebx,%eax
65
66         ALIGN (3)
67 Loop:   movl    (%esi,%edx,4),%ebx      /* load next lower limb */
68         shldl   %cl,%ebx,%eax           /* compute result limb */
69         movl    %eax,(%edi,%edx,4)      /* store it */
70         decl    %edx
71 L1:     movl    (%esi,%edx,4),%eax
72         shldl   %cl,%eax,%ebx
73         movl    %ebx,(%edi,%edx,4)
74         decl    %edx
75         jnz     Loop
76
77         shll    %cl,%eax                /* compute least significant limb */
78         movl    %eax,(%edi)             /* store it */
79
80         popl    %eax                    /* pop carry limb */
81
82         popl    %ebx
83         popl    %esi
84         popl    %edi
85         ret
86
87 Lend:   shll    %cl,%ebx                /* compute least significant limb */
88         movl    %ebx,(%edi)             /* store it */
89
90         popl    %ebx
91         popl    %esi
92         popl    %edi
93         ret
94