Mon Jun 24 19:57:01 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
[kopensolaris-gnu/glibc.git] / sysdeps / i386 / add_n.S
1 /* i80386 __mpn_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 Free Software Foundation, Inc.
5
6 This file is part of the GNU MP Library.
7
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Library General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or (at your
11 option) any later version.
12
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
16 License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 MA 02111-1307, USA. */
22
23 /*
24   INPUT PARAMETERS
25   res_ptr       (sp + 4)
26   s1_ptr        (sp + 8)
27   s2_ptr        (sp + 12)
28   size          (sp + 16)
29 */
30
31 #include "sysdep.h"
32 #include "asm-syntax.h"
33
34 .text
35         ALIGN (3)
36         .globl C_SYMBOL_NAME(__mpn_add_n)
37 C_SYMBOL_NAME(__mpn_add_n:)
38         pushl %edi
39         pushl %esi
40
41         movl 12(%esp),%edi              /* res_ptr */
42         movl 16(%esp),%esi              /* s1_ptr */
43         movl 20(%esp),%edx              /* s2_ptr */
44         movl 24(%esp),%ecx              /* size */
45
46         movl    %ecx,%eax
47         shrl    $3,%ecx                 /* compute count for unrolled loop */
48         negl    %eax
49         andl    $7,%eax                 /* get index where to start loop */
50         jz      Loop                    /* necessary special case for 0 */
51         incl    %ecx                    /* adjust loop count */
52         shll    $2,%eax                 /* adjustment for pointers... */
53         subl    %eax,%edi               /* ... since they are offset ... */
54         subl    %eax,%esi               /* ... by a constant when we ... */
55         subl    %eax,%edx               /* ... enter the loop */
56         shrl    $2,%eax                 /* restore previous value */
57 #ifdef PIC
58 /* Calculate start address in loop for PIC.  Due to limitations in some
59    assemblers, Loop-L0-3 cannot be put into the leal */
60         call    L0
61 L0:     leal    (%eax,%eax,8),%eax
62         addl    (%esp),%eax
63         addl    $(Loop-L0-3),%eax 
64         addl    $4,%esp
65 #else
66 /* Calculate start address in loop for non-PIC.  */
67         leal    (Loop - 3)(%eax,%eax,8),%eax
68 #endif
69         jmp     *%eax                   /* jump into loop */
70         ALIGN (3)
71 Loop:   movl    (%esi),%eax
72         adcl    (%edx),%eax
73         movl    %eax,(%edi)
74         movl    4(%esi),%eax
75         adcl    4(%edx),%eax
76         movl    %eax,4(%edi)
77         movl    8(%esi),%eax
78         adcl    8(%edx),%eax
79         movl    %eax,8(%edi)
80         movl    12(%esi),%eax
81         adcl    12(%edx),%eax
82         movl    %eax,12(%edi)
83         movl    16(%esi),%eax
84         adcl    16(%edx),%eax
85         movl    %eax,16(%edi)
86         movl    20(%esi),%eax
87         adcl    20(%edx),%eax
88         movl    %eax,20(%edi)
89         movl    24(%esi),%eax
90         adcl    24(%edx),%eax
91         movl    %eax,24(%edi)
92         movl    28(%esi),%eax
93         adcl    28(%edx),%eax
94         movl    %eax,28(%edi)
95         leal    32(%edi),%edi
96         leal    32(%esi),%esi
97         leal    32(%edx),%edx
98         decl    %ecx
99         jnz     Loop
100
101         sbbl    %eax,%eax
102         negl    %eax
103
104         popl %esi
105         popl %edi
106         ret