mpi: make stack unwinding work at i386 mpi functions
[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         CFI_STARTPROC()
46         pushl   %edi
47         CFI_PUSH(%edi)
48         pushl   %esi
49         CFI_PUSH(%esi)
50         pushl   %ebx
51         CFI_PUSH(%ebx)
52
53         movl    16(%esp),%edi           /* res_ptr */
54         movl    20(%esp),%esi           /* s_ptr */
55         movl    24(%esp),%edx           /* size */
56         movl    28(%esp),%ecx           /* cnt */
57
58         subl    $4,%esi                 /* adjust s_ptr */
59
60         movl    (%esi,%edx,4),%ebx      /* read most significant limb */
61         xorl    %eax,%eax
62         shldl   %cl,%ebx,%eax           /* compute carry limb */
63         decl    %edx
64         jz      Lend
65         pushl   %eax                    /* push carry limb onto stack */
66         testb   $1,%dl
67         jnz     L1                      /* enter loop in the middle */
68         movl    %ebx,%eax
69
70         ALIGN (3)
71 Loop:   movl    (%esi,%edx,4),%ebx      /* load next lower limb */
72         shldl   %cl,%ebx,%eax           /* compute result limb */
73         movl    %eax,(%edi,%edx,4)      /* store it */
74         decl    %edx
75 L1:     movl    (%esi,%edx,4),%eax
76         shldl   %cl,%eax,%ebx
77         movl    %ebx,(%edi,%edx,4)
78         decl    %edx
79         jnz     Loop
80
81         shll    %cl,%eax                /* compute least significant limb */
82         movl    %eax,(%edi)             /* store it */
83
84         popl    %eax                    /* pop carry limb */
85
86         popl    %ebx
87         popl    %esi
88         popl    %edi
89         ret
90
91 Lend:   shll    %cl,%ebx                /* compute least significant limb */
92         movl    %ebx,(%edi)             /* store it */
93
94         popl    %ebx
95         CFI_POP(%ebx)
96         popl    %esi
97         CFI_POP(%esi)
98         popl    %edi
99         CFI_POP(%edi)
100         ret
101         CFI_ENDPROC()
102