1/* i80586 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, 1996, 1998,
5 *                    2001, 2002 Free Software Foundation, Inc.
6 *
7 * This file is part of Libgcrypt.
8 *
9 * Libgcrypt is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * Libgcrypt is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 */
23
24
25#include "sysdep.h"
26#include "asm-syntax.h"
27
28
29/*******************
30 *  mpi_limb_t
31 *  _gcry_mpih_add_n( mpi_ptr_t res_ptr,	(sp + 4)
32 *		   mpi_ptr_t s1_ptr,	(sp + 8)
33 *		   mpi_ptr_t s2_ptr,	(sp + 12)
34 *		   mpi_size_t size)	(sp + 16)
35 */
36
37.text
38	ALIGN (3)
39	.globl C_SYMBOL_NAME(_gcry_mpih_add_n)
40C_SYMBOL_NAME(_gcry_mpih_add_n:)
41	pushl	%edi
42	pushl	%esi
43	pushl	%ebx
44	pushl	%ebp
45
46	movl	20(%esp),%edi		/* res_ptr */
47	movl	24(%esp),%esi		/* s1_ptr */
48	movl	28(%esp),%ebp		/* s2_ptr */
49	movl	32(%esp),%ecx		/* size */
50
51	movl	(%ebp),%ebx
52
53	decl	%ecx
54	movl	%ecx,%edx
55	shrl	$3,%ecx
56	andl	$7,%edx
57	testl	%ecx,%ecx		/* zero carry flag */
58	jz	Lend
59	pushl	%edx
60
61	ALIGN (3)
62Loop:	movl	28(%edi),%eax		/* fetch destination cache line */
63	leal	32(%edi),%edi
64
65L1:	movl	(%esi),%eax
66	movl	4(%esi),%edx
67	adcl	%ebx,%eax
68	movl	4(%ebp),%ebx
69	adcl	%ebx,%edx
70	movl	8(%ebp),%ebx
71	movl	%eax,-32(%edi)
72	movl	%edx,-28(%edi)
73
74L2:	movl	8(%esi),%eax
75	movl	12(%esi),%edx
76	adcl	%ebx,%eax
77	movl	12(%ebp),%ebx
78	adcl	%ebx,%edx
79	movl	16(%ebp),%ebx
80	movl	%eax,-24(%edi)
81	movl	%edx,-20(%edi)
82
83L3:	movl	16(%esi),%eax
84	movl	20(%esi),%edx
85	adcl	%ebx,%eax
86	movl	20(%ebp),%ebx
87	adcl	%ebx,%edx
88	movl	24(%ebp),%ebx
89	movl	%eax,-16(%edi)
90	movl	%edx,-12(%edi)
91
92L4:	movl	24(%esi),%eax
93	movl	28(%esi),%edx
94	adcl	%ebx,%eax
95	movl	28(%ebp),%ebx
96	adcl	%ebx,%edx
97	movl	32(%ebp),%ebx
98	movl	%eax,-8(%edi)
99	movl	%edx,-4(%edi)
100
101	leal	32(%esi),%esi
102	leal	32(%ebp),%ebp
103	decl	%ecx
104	jnz	Loop
105
106	popl	%edx
107Lend:
108	decl	%edx			/* test %edx w/o clobbering carry */
109	js	Lend2
110	incl	%edx
111Loop2:
112	leal	4(%edi),%edi
113	movl	(%esi),%eax
114	adcl	%ebx,%eax
115	movl	4(%ebp),%ebx
116	movl	%eax,-4(%edi)
117	leal	4(%esi),%esi
118	leal	4(%ebp),%ebp
119	decl	%edx
120	jnz	Loop2
121Lend2:
122	movl	(%esi),%eax
123	adcl	%ebx,%eax
124	movl	%eax,(%edi)
125
126	sbbl	%eax,%eax
127	negl	%eax
128
129	popl	%ebp
130	popl	%ebx
131	popl	%esi
132	popl	%edi
133	ret
134
135
136