Switched to GPLv3.
[gnupg.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 GnuPG.
8  *
9  * GnuPG is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * GnuPG 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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, see <http://www.gnu.org/licenses/>.
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  *       The GNU MP Library itself is published under the LGPL;
28  *       however I decided to publish this code under the plain GPL.
29  */
30
31
32 #include "sysdep.h"
33 #include "asm-syntax.h"
34
35
36 /*******************
37  *  mpi_limb_t
38  *  mpihelp_add_n( mpi_ptr_t res_ptr,   (sp + 4)
39  *                 mpi_ptr_t s1_ptr,    (sp + 8)
40  *                 mpi_ptr_t s2_ptr,    (sp + 12)
41  *                 mpi_size_t size)     (sp + 16)
42  */
43
44 .text
45         ALIGN (3)
46         .globl C_SYMBOL_NAME(mpihelp_add_n)
47 C_SYMBOL_NAME(mpihelp_add_n:)
48         pushl %edi
49         pushl %esi
50
51         movl 12(%esp),%edi              /* res_ptr */
52         movl 16(%esp),%esi              /* s1_ptr */
53         movl 20(%esp),%edx              /* s2_ptr */
54         movl 24(%esp),%ecx              /* size */
55
56         movl    %ecx,%eax
57         shrl    $3,%ecx                 /* compute count for unrolled loop */
58         negl    %eax
59         andl    $7,%eax                 /* get index where to start loop */
60         jz      Loop                    /* necessary special case for 0 */
61         incl    %ecx                    /* adjust loop count */
62         shll    $2,%eax                 /* adjustment for pointers... */
63         subl    %eax,%edi               /* ... since they are offset ... */
64         subl    %eax,%esi               /* ... by a constant when we ... */
65         subl    %eax,%edx               /* ... enter the loop */
66         shrl    $2,%eax                 /* restore previous value */
67 #ifdef PIC
68 /* Calculate start address in loop for PIC.  Due to limitations in some
69    assemblers, Loop-L0-3 cannot be put into the leal */
70         call    L0
71 L0:     leal    (%eax,%eax,8),%eax
72         addl    (%esp),%eax
73         addl    $(Loop-L0-3),%eax
74         addl    $4,%esp
75 #else
76 /* Calculate start address in loop for non-PIC.  */
77         leal    Loop-3(%eax,%eax,8),%eax
78 #endif
79         jmp     *%eax                   /* jump into loop */
80         ALIGN (3)
81 Loop:   movl    (%esi),%eax
82         adcl    (%edx),%eax
83         movl    %eax,(%edi)
84         movl    4(%esi),%eax
85         adcl    4(%edx),%eax
86         movl    %eax,4(%edi)
87         movl    8(%esi),%eax
88         adcl    8(%edx),%eax
89         movl    %eax,8(%edi)
90         movl    12(%esi),%eax
91         adcl    12(%edx),%eax
92         movl    %eax,12(%edi)
93         movl    16(%esi),%eax
94         adcl    16(%edx),%eax
95         movl    %eax,16(%edi)
96         movl    20(%esi),%eax
97         adcl    20(%edx),%eax
98         movl    %eax,20(%edi)
99         movl    24(%esi),%eax
100         adcl    24(%edx),%eax
101         movl    %eax,24(%edi)
102         movl    28(%esi),%eax
103         adcl    28(%edx),%eax
104         movl    %eax,28(%edi)
105         leal    32(%edi),%edi
106         leal    32(%esi),%esi
107         leal    32(%edx),%edx
108         decl    %ecx
109         jnz     Loop
110
111         sbbl    %eax,%eax
112         negl    %eax
113
114         popl %esi
115         popl %edi
116         ret
117