Updated from GMP 1.906.7
[kopensolaris-gnu/glibc.git] / sysdeps / i386 / i586 / add_n.S
1 /* Pentium __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., 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 #define r1      %eax
31 #define r2      %edx
32 #define src1    %esi
33 #define src2    %ebp
34 #define dst     %edi
35 #define x       %ebx
36
37 #include "sysdep.h"
38 #include "asm-syntax.h"
39
40 .text
41         ALIGN (3)
42         .globl C_SYMBOL_NAME(__mpn_add_n)
43 C_SYMBOL_NAME(__mpn_add_n:)
44         pushl   %edi
45         pushl   %esi
46         pushl   %ebx
47         pushl   %ebp
48
49         movl    20(%esp),dst            /* res_ptr */
50         movl    24(%esp),src1           /* s1_ptr */
51         movl    28(%esp),src2           /* s2_ptr */
52         movl    32(%esp),%ecx           /* size */
53
54         movl    (src2),x
55
56         decl    %ecx
57         movl    %ecx,r2
58         shrl    $3,%ecx
59         andl    $7,r2
60         testl   %ecx,%ecx               /* zero carry flag */
61         jz      Lend
62         pushl   r2
63
64         ALIGN (3)
65 Loop:   movl    28(dst),%eax            /* fetch destination cache line */
66         leal    32(dst),dst
67
68 L1:     movl    (src1),r1
69         movl    4(src1),r2
70         adcl    x,r1
71         movl    4(src2),x
72         adcl    x,r2
73         movl    8(src2),x
74         movl    r1,-32(dst)
75         movl    r2,-28(dst)
76
77 L2:     movl    8(src1),r1
78         movl    12(src1),r2
79         adcl    x,r1
80         movl    12(src2),x
81         adcl    x,r2
82         movl    16(src2),x
83         movl    r1,-24(dst)
84         movl    r2,-20(dst)
85
86 L3:     movl    16(src1),r1
87         movl    20(src1),r2
88         adcl    x,r1
89         movl    20(src2),x
90         adcl    x,r2
91         movl    24(src2),x
92         movl    r1,-16(dst)
93         movl    r2,-12(dst)
94
95 L4:     movl    24(src1),r1
96         movl    28(src1),r2
97         adcl    x,r1
98         movl    28(src2),x
99         adcl    x,r2
100         movl    32(src2),x
101         movl    r1,-8(dst)
102         movl    r2,-4(dst)
103
104         leal    32(src1),src1
105         leal    32(src2),src2
106         decl    %ecx
107         jnz     Loop
108
109         popl    r2
110 Lend:
111         decl    r2                      /* test r2 w/o clobbering carry */
112         js      Lend2
113         incl    r2
114 Loop2:
115         leal    4(dst),dst
116         movl    (src1),r1
117         adcl    x,r1
118         movl    4(src2),x
119         movl    r1,-4(dst)
120         leal    4(src1),src1
121         leal    4(src2),src2
122         decl    r2
123         jnz     Loop2
124 Lend2:
125         movl    (src1),r1
126         adcl    x,r1
127         movl    r1,(dst)
128
129         sbbl    %eax,%eax
130         negl    %eax
131
132         popl    %ebp
133         popl    %ebx
134         popl    %esi
135         popl    %edi
136         ret