1 dnl x86 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
3 dnl Copyright (C) 1992, 1994, 1995, 1996, 1999, 2000 Free Software
6 dnl This file is part of the GNU MP Library.
8 dnl The GNU MP Library is free software; you can redistribute it and/or
9 dnl modify it under the terms of the GNU Lesser General Public License as
10 dnl published by the Free Software Foundation; either version 2.1 of the
11 dnl License, or (at your option) any later version.
13 dnl The GNU MP Library is distributed in the hope that it will be useful,
14 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
15 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 dnl Lesser General Public License for more details.
18 dnl You should have received a copy of the GNU Lesser General Public
19 dnl License along with the GNU MP Library; see the file COPYING.LIB. If
20 dnl not, write to the Free Software Foundation, Inc., 59 Temple Place -
21 dnl Suite 330, Boston, MA 02111-1307, USA.
24 include(`../config.m4')
27 ifdef(`OPERATION_add_n',`
29 define(M4_function_n, mpn_add_n)
30 define(M4_function_nc, mpn_add_nc)
32 ',`ifdef(`OPERATION_sub_n',`
34 define(M4_function_n, mpn_sub_n)
35 define(M4_function_nc, mpn_sub_nc)
37 ',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
40 MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
43 C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
45 C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
46 C mp_size_t size, mp_limb_t carry);
48 defframe(PARAM_CARRY,20)
49 defframe(PARAM_SIZE, 16)
50 defframe(PARAM_SRC2, 12)
51 defframe(PARAM_SRC1, 8)
52 defframe(PARAM_DST, 4)
57 PROLOGUE(M4_function_nc)
60 pushl %edi FRAME_pushl()
61 pushl %esi FRAME_pushl()
69 shrl $3,%ecx C compute count for unrolled loop
71 andl $7,%eax C get index where to start loop
72 jz LF(M4_function_n,oopgo) C necessary special case for 0
73 incl %ecx C adjust loop count
74 shll $2,%eax C adjustment for pointers...
75 subl %eax,%edi C ... since they are offset ...
76 subl %eax,%esi C ... by a constant when we ...
77 subl %eax,%edx C ... enter the loop
78 shrl $2,%eax C restore previous value
81 C Calculate start address in loop for PIC. Due to limitations in
82 C old gas, LF(M4_function_n,oop)-L(0a)-3 cannot be put into the leal
84 L(0a): leal (%eax,%eax,8),%eax
86 addl $LF(M4_function_n,oop)-L(0a)-3,%eax
89 C Calculate start address in loop for non-PIC.
90 leal LF(M4_function_n,oop)-3(%eax,%eax,8),%eax
93 C These lines initialize carry from the 5th parameter. Should be
94 C possible to simplify.
95 pushl %ebp FRAME_pushl()
97 shrl $1,%ebp C shift bit 0 into carry
98 popl %ebp FRAME_popl()
100 jmp *%eax C jump into loop
106 PROLOGUE(M4_function_n)
109 pushl %edi FRAME_pushl()
110 pushl %esi FRAME_pushl()
118 shrl $3,%ecx C compute count for unrolled loop
120 andl $7,%eax C get index where to start loop
121 jz L(oop) C necessary special case for 0
122 incl %ecx C adjust loop count
123 shll $2,%eax C adjustment for pointers...
124 subl %eax,%edi C ... since they are offset ...
125 subl %eax,%esi C ... by a constant when we ...
126 subl %eax,%edx C ... enter the loop
127 shrl $2,%eax C restore previous value
130 C Calculate start address in loop for PIC. Due to limitations in
131 C some assemblers, L(oop)-L(0b)-3 cannot be put into the leal
133 L(0b): leal (%eax,%eax,8),%eax
135 addl $L(oop)-L(0b)-3,%eax
138 C Calculate start address in loop for non-PIC.
139 leal L(oop)-3(%eax,%eax,8),%eax
141 jmp *%eax C jump into loop
144 pushl %ebp FRAME_pushl()
145 movl PARAM_CARRY,%ebp
146 shrl $1,%ebp C shift bit 0 into carry
147 popl %ebp FRAME_popl()
150 L(oop): movl (%esi),%eax
160 M4_inst 12(%edx),%eax
163 M4_inst 16(%edx),%eax
166 M4_inst 20(%edx),%eax
169 M4_inst 24(%edx),%eax
172 M4_inst 28(%edx),%eax