]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/i386/add_n.S
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[thirdparty/glibc.git] / sysdeps / i386 / add_n.S
CommitLineData
5929563f
UD
1/* Add two limb vectors of the same length > 0 and store sum in a third
2 limb vector.
a334319f 3 Copyright (C) 1992, 94, 95, 97, 98, 2000 Free Software Foundation, Inc.
5929563f 4 This file is part of the GNU MP Library.
28f540f4 5
5929563f 6 The GNU MP Library is free software; you can redistribute it and/or modify
6d84f89a
AJ
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or (at your
5929563f 9 option) any later version.
28f540f4 10
5929563f
UD
11 The GNU MP Library is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6d84f89a 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
5929563f 14 License for more details.
28f540f4 15
6d84f89a 16 You should have received a copy of the GNU Lesser General Public License
5929563f
UD
17 along with the GNU MP Library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA. */
28f540f4 20
28f540f4
RM
21#include "sysdep.h"
22#include "asm-syntax.h"
2fc08826 23#include "bp-sym.h"
3f02f778
GM
24#include "bp-asm.h"
25
26#define PARMS LINKAGE+8 /* space for 2 saved regs */
27#define RES PARMS
28#define S1 RES+PTR_SIZE
29#define S2 S1+PTR_SIZE
30#define SIZE S2+PTR_SIZE
28f540f4 31
ae828bc6 32 .text
2fc08826 33ENTRY (BP_SYM (__mpn_add_n))
3f02f778
GM
34 ENTER
35
28f540f4
RM
36 pushl %edi
37 pushl %esi
38
3f02f778
GM
39 movl RES(%esp),%edi
40 movl S1(%esp),%esi
41 movl S2(%esp),%edx
42 movl SIZE(%esp),%ecx
2fc08826
GM
43#if __BOUNDED_POINTERS__
44 shll $2, %ecx /* convert limbs to bytes */
45 CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
46 CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
47 CHECK_BOUNDS_BOTH_WIDE (%edx, S2(%esp), %ecx)
48 shrl $2, %ecx
49#endif
28f540f4
RM
50 movl %ecx,%eax
51 shrl $3,%ecx /* compute count for unrolled loop */
52 negl %eax
53 andl $7,%eax /* get index where to start loop */
5929563f 54 jz L(oop) /* necessary special case for 0 */
28f540f4
RM
55 incl %ecx /* adjust loop count */
56 shll $2,%eax /* adjustment for pointers... */
57 subl %eax,%edi /* ... since they are offset ... */
58 subl %eax,%esi /* ... by a constant when we ... */
59 subl %eax,%edx /* ... enter the loop */
60 shrl $2,%eax /* restore previous value */
53afa8d9 61#ifdef PIC
8f5ca04b
RM
62/* Calculate start address in loop for PIC. Due to limitations in some
63 assemblers, Loop-L0-3 cannot be put into the leal */
5929563f
UD
64 call L(0)
65L(0): leal (%eax,%eax,8),%eax
8f5ca04b 66 addl (%esp),%eax
5929563f 67 addl $(L(oop)-L(0)-3),%eax
8f5ca04b 68 addl $4,%esp
53afa8d9 69#else
8f5ca04b 70/* Calculate start address in loop for non-PIC. */
5929563f 71 leal (L(oop) - 3)(%eax,%eax,8),%eax
e215c478 72#endif
8f5ca04b 73 jmp *%eax /* jump into loop */
28f540f4 74 ALIGN (3)
5929563f 75L(oop): movl (%esi),%eax
28f540f4
RM
76 adcl (%edx),%eax
77 movl %eax,(%edi)
78 movl 4(%esi),%eax
79 adcl 4(%edx),%eax
80 movl %eax,4(%edi)
81 movl 8(%esi),%eax
82 adcl 8(%edx),%eax
83 movl %eax,8(%edi)
84 movl 12(%esi),%eax
85 adcl 12(%edx),%eax
86 movl %eax,12(%edi)
87 movl 16(%esi),%eax
88 adcl 16(%edx),%eax
89 movl %eax,16(%edi)
90 movl 20(%esi),%eax
91 adcl 20(%edx),%eax
92 movl %eax,20(%edi)
93 movl 24(%esi),%eax
94 adcl 24(%edx),%eax
95 movl %eax,24(%edi)
96 movl 28(%esi),%eax
97 adcl 28(%edx),%eax
98 movl %eax,28(%edi)
99 leal 32(%edi),%edi
100 leal 32(%esi),%esi
101 leal 32(%edx),%edx
102 decl %ecx
5929563f 103 jnz L(oop)
28f540f4
RM
104
105 sbbl %eax,%eax
106 negl %eax
107
108 popl %esi
109 popl %edi
3f02f778
GM
110
111 LEAVE
28f540f4 112 ret
2fc08826 113END (BP_SYM (__mpn_add_n))