cipher/Makefile.am: add '-fcoverage-*' to instrumentation munging
[libgcrypt.git] / mpi / i386 / mpih-add1.S
1 /* i80386 add_n -- Add two limb vectors of the same length > 0 and store
2  *                 sum in a third limb vector.
3  *
4  *      Copyright (C) 1992, 1994, 1995, 1998, 
5  *                    2001, 2002 Free Software Foundation, Inc.
6  *
7  * This file is part of Libgcrypt.
8  *
9  * Libgcrypt is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as
11  * published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * Libgcrypt is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22  *
23  * Note: This code is heavily based on the GNU MP Library.
24  *       Actually it's the same code with only minor changes in the
25  *       way the data is stored; this is to support the abstraction
26  *       of an optional secure memory allocation which may be used
27  *       to avoid revealing of sensitive data due to paging etc.
28  */
29
30
31 #include "sysdep.h"
32 #include "asm-syntax.h"
33
34
35 /*******************
36  *  mpi_limb_t
37  *  _gcry_mpih_add_n( mpi_ptr_t res_ptr,        (sp + 4)
38  *                 mpi_ptr_t s1_ptr,    (sp + 8)
39  *                 mpi_ptr_t s2_ptr,    (sp + 12)
40  *                 mpi_size_t size)     (sp + 16)
41  */
42
43 .text
44         ALIGN (3)
45         .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
46 C_SYMBOL_NAME(_gcry_mpih_add_n:)
47         CFI_STARTPROC()
48         pushl %edi
49         CFI_PUSH(%edi)
50         pushl %esi
51         CFI_PUSH(%esi)
52
53         movl 12(%esp),%edi              /* res_ptr */
54         movl 16(%esp),%esi              /* s1_ptr */
55         movl 20(%esp),%edx              /* s2_ptr */
56         movl 24(%esp),%ecx              /* size */
57
58         movl    %ecx,%eax
59         shrl    $3,%ecx                 /* compute count for unrolled loop */
60         negl    %eax
61         andl    $7,%eax                 /* get index where to start loop */
62         jz      Loop                    /* necessary special case for 0 */
63         incl    %ecx                    /* adjust loop count */
64         shll    $2,%eax                 /* adjustment for pointers... */
65         subl    %eax,%edi               /* ... since they are offset ... */
66         subl    %eax,%esi               /* ... by a constant when we ... */
67         subl    %eax,%edx               /* ... enter the loop */
68         shrl    $2,%eax                 /* restore previous value */
69 #ifdef PIC
70 /* Calculate start address in loop for PIC.  Due to limitations in some
71    assemblers, Loop-L0-3 cannot be put into the leal */
72         call    L0
73 L0:     leal    (%eax,%eax,8),%eax
74         addl    (%esp),%eax
75         addl    $(Loop-L0-3),%eax
76         addl    $4,%esp
77 #else
78 /* Calculate start address in loop for non-PIC.  */
79         leal    (Loop - 3)(%eax,%eax,8),%eax
80 #endif
81         jmp     *%eax                   /* jump into loop */
82         ALIGN (3)
83 Loop:   movl    (%esi),%eax
84         adcl    (%edx),%eax
85         movl    %eax,(%edi)
86         movl    4(%esi),%eax
87         adcl    4(%edx),%eax
88         movl    %eax,4(%edi)
89         movl    8(%esi),%eax
90         adcl    8(%edx),%eax
91         movl    %eax,8(%edi)
92         movl    12(%esi),%eax
93         adcl    12(%edx),%eax
94         movl    %eax,12(%edi)
95         movl    16(%esi),%eax
96         adcl    16(%edx),%eax
97         movl    %eax,16(%edi)
98         movl    20(%esi),%eax
99         adcl    20(%edx),%eax
100         movl    %eax,20(%edi)
101         movl    24(%esi),%eax
102         adcl    24(%edx),%eax
103         movl    %eax,24(%edi)
104         movl    28(%esi),%eax
105         adcl    28(%edx),%eax
106         movl    %eax,28(%edi)
107         leal    32(%edi),%edi
108         leal    32(%esi),%esi
109         leal    32(%edx),%edx
110         decl    %ecx
111         jnz     Loop
112
113         sbbl    %eax,%eax
114         negl    %eax
115
116         popl %esi
117         CFI_POP(%esi)
118         popl %edi
119         CFI_POP(%edi)
120         ret
121         CFI_ENDPROC()
122