mpi: make stack unwinding work at i386 mpi functions
[libgcrypt.git] / mpi / i386 / mpih-mul1.S
1 /* i80386 mul_1 -- Multiply a limb vector with a limb and store
2  *                       the result in a second limb vector.
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_mul_1( mpi_ptr_t res_ptr, (sp + 4)
37  *                mpi_ptr_t s1_ptr,     (sp + 8)
38  *                mpi_size_t s1_size,   (sp + 12)
39  *                mpi_limb_t s2_limb)   (sp + 16)
40  */
41
42 #define res_ptr edi
43 #define s1_ptr  esi
44 #define size    ecx
45 #define s2_limb ebp
46
47         TEXT
48         ALIGN (3)
49         GLOBL   C_SYMBOL_NAME(_gcry_mpih_mul_1)
50 C_SYMBOL_NAME(_gcry_mpih_mul_1:)
51
52         CFI_STARTPROC()
53         INSN1(push,l    ,R(edi))
54         CFI_PUSH(%edi)
55         INSN1(push,l    ,R(esi))
56         CFI_PUSH(%esi)
57         INSN1(push,l    ,R(ebx))
58         CFI_PUSH(%ebx)
59         INSN1(push,l    ,R(ebp))
60         CFI_PUSH(%ebp)
61
62         INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
63         INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
64         INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
65         INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
66
67         INSN2(lea,l     ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
68         INSN2(lea,l     ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
69         INSN1(neg,l     ,R(size))
70         INSN2(xor,l     ,R(ebx),R(ebx))
71         ALIGN (3)
72 Loop:
73         INSN2(mov,l     ,R(eax),MEM_INDEX(s1_ptr,size,4))
74         INSN1(mul,l     ,R(s2_limb))
75         INSN2(add,l     ,R(eax),R(ebx))
76         INSN2(mov,l     ,MEM_INDEX(res_ptr,size,4),R(eax))
77         INSN2(adc,l     ,R(edx),$0)
78         INSN2(mov,l     ,R(ebx),R(edx))
79
80         INSN1(inc,l     ,R(size))
81         INSN1(jnz,      ,Loop)
82         INSN2(mov,l     ,R(eax),R(ebx))
83
84         INSN1(pop,l     ,R(ebp))
85         CFI_POP(%ebp)
86         INSN1(pop,l     ,R(ebx))
87         CFI_POP(%ebx)
88         INSN1(pop,l     ,R(esi))
89         CFI_POP(%esi)
90         INSN1(pop,l     ,R(edi))
91         CFI_POP(%edi)
92         ret
93         CFI_ENDPROC()
94