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