newly generated ones
[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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 /*
23   INPUT PARAMETERS
24   res_ptr       (sp + 4)
25   s1_ptr        (sp + 8)
26   s2_ptr        (sp + 12)
27   size          (sp + 16)
28 */
29
30 #include "sysdep.h"
31 #include "asm-syntax.h"
32
33 .text
34         ALIGN (3)
35         .globl C_SYMBOL_NAME(__mpn_add_n)
36 C_SYMBOL_NAME(__mpn_add_n:)
37         pushl %edi
38         pushl %esi
39
40         movl 12(%esp),%edi              /* res_ptr */
41         movl 16(%esp),%esi              /* s1_ptr */
42         movl 20(%esp),%edx              /* s2_ptr */
43         movl 24(%esp),%ecx              /* size */
44
45         movl    %ecx,%eax
46         shrl    $3,%ecx                 /* compute count for unrolled loop */
47         negl    %eax
48         andl    $7,%eax                 /* get index where to start loop */
49         jz      Loop                    /* necessary special case for 0 */
50         incl    %ecx                    /* adjust loop count */
51         shll    $2,%eax                 /* adjustment for pointers... */
52         subl    %eax,%edi               /* ... since they are offset ... */
53         subl    %eax,%esi               /* ... by a constant when we ... */
54         subl    %eax,%edx               /* ... enter the loop */
55         shrl    $2,%eax                 /* restore previous value */
56         leal    (Loop - 3)(%eax,%eax,8),%eax    /* calc start addr in loop */
57         jmp     *%eax                   /* jump into loop */
58         ALIGN (3)
59 Loop:   movl    (%esi),%eax
60         adcl    (%edx),%eax
61         movl    %eax,(%edi)
62         movl    4(%esi),%eax
63         adcl    4(%edx),%eax
64         movl    %eax,4(%edi)
65         movl    8(%esi),%eax
66         adcl    8(%edx),%eax
67         movl    %eax,8(%edi)
68         movl    12(%esi),%eax
69         adcl    12(%edx),%eax
70         movl    %eax,12(%edi)
71         movl    16(%esi),%eax
72         adcl    16(%edx),%eax
73         movl    %eax,16(%edi)
74         movl    20(%esi),%eax
75         adcl    20(%edx),%eax
76         movl    %eax,20(%edi)
77         movl    24(%esi),%eax
78         adcl    24(%edx),%eax
79         movl    %eax,24(%edi)
80         movl    28(%esi),%eax
81         adcl    28(%edx),%eax
82         movl    %eax,28(%edi)
83         leal    32(%edi),%edi
84         leal    32(%esi),%esi
85         leal    32(%edx),%edx
86         decl    %ecx
87         jnz     Loop
88
89         sbbl    %eax,%eax
90         negl    %eax
91
92         popl %esi
93         popl %edi
94         ret