1 dnl x86 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
3 dnl Copyright 1992, 1994, 1995, 1996, 1999, 2000, 2001, 2002 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 3 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 License
19 dnl along with the GNU MP Library. If not, see http://www.gnu.org/licenses/.
21 include(`../config.m4')
32 ifdef(`OPERATION_add_n',`
34 define(M4_function_n, mpn_add_n)
35 define(M4_function_nc, mpn_add_nc)
37 ',`ifdef(`OPERATION_sub_n',`
39 define(M4_function_n, mpn_sub_n)
40 define(M4_function_nc, mpn_sub_nc)
42 ',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
45 MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
48 C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
50 C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
51 C mp_size_t size, mp_limb_t carry);
53 defframe(PARAM_CARRY,20)
54 defframe(PARAM_SIZE, 16)
55 defframe(PARAM_SRC2, 12)
56 defframe(PARAM_SRC1, 8)
57 defframe(PARAM_DST, 4)
62 PROLOGUE(M4_function_nc)
65 pushl %edi FRAME_pushl()
66 pushl %esi FRAME_pushl()
74 shrl $3,%ecx C compute count for unrolled loop
76 andl $7,%eax C get index where to start loop
77 jz L(oopgo) C necessary special case for 0
78 incl %ecx C adjust loop count
79 shll $2,%eax C adjustment for pointers...
80 subl %eax,%edi C ... since they are offset ...
81 subl %eax,%esi C ... by a constant when we ...
82 subl %eax,%edx C ... enter the loop
83 shrl $2,%eax C restore previous value
86 C Calculate start address in loop for PIC. Due to limitations in
87 C old gas, LF(M4_function_n,oop)-L(0a)-3 cannot be put into the leal
89 L(0a): leal (%eax,%eax,8),%eax
91 addl $L(oop)-L(0a)-3,%eax
94 C Calculate start address in loop for non-PIC.
95 leal L(oop)-3(%eax,%eax,8),%eax
98 C These lines initialize carry from the 5th parameter. Should be
99 C possible to simplify.
100 pushl %ebp FRAME_pushl()
101 movl PARAM_CARRY,%ebp
102 shrl $1,%ebp C shift bit 0 into carry
103 popl %ebp FRAME_popl()
105 jmp *%eax C jump into loop
111 PROLOGUE(M4_function_n)
114 pushl %edi FRAME_pushl()
115 pushl %esi FRAME_pushl()
123 shrl $3,%ecx C compute count for unrolled loop
125 andl $7,%eax C get index where to start loop
126 jz L(oop) C necessary special case for 0
127 incl %ecx C adjust loop count
128 shll $2,%eax C adjustment for pointers...
129 subl %eax,%edi C ... since they are offset ...
130 subl %eax,%esi C ... by a constant when we ...
131 subl %eax,%edx C ... enter the loop
132 shrl $2,%eax C restore previous value
135 C Calculate start address in loop for PIC. Due to limitations in
136 C some assemblers, L(oop)-L(0b)-3 cannot be put into the leal
138 L(0b): leal (%eax,%eax,8),%eax
140 addl $L(oop)-L(0b)-3,%eax
143 C Calculate start address in loop for non-PIC.
144 leal L(oop)-3(%eax,%eax,8),%eax
146 jmp *%eax C jump into loop
149 pushl %ebp FRAME_pushl()
150 movl PARAM_CARRY,%ebp
151 shrl $1,%ebp C shift bit 0 into carry
152 popl %ebp FRAME_popl()
155 L(oop): movl (%esi),%eax
165 M4_inst 12(%edx),%eax
168 M4_inst 16(%edx),%eax
171 M4_inst 20(%edx),%eax
174 M4_inst 24(%edx),%eax
177 M4_inst 28(%edx),%eax