1 ! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
2 ! sum in a third limb vector.
4 ! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
6 ! This file is part of the GNU MP Library.
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.
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.
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., 59 Temple Place - Suite 330, Boston,
34 .global C_SYMBOL_NAME(__mpn_add_n)
35 C_SYMBOL_NAME(__mpn_add_n):
36 xor s2_ptr,res_ptr,%g1
38 bne L1 ! branch if alignment differs
41 L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
42 be L_v1 ! if no, branch
44 /* Add least significant limb separately to align res_ptr and s2_ptr */
53 L_v1: addx %g0,%g0,%o4 ! save cy in register
54 cmp size,2 ! if size < 2 ...
55 bl Lend2 ! ... branch to tail code
56 subcc %g0,%o4,%g0 ! restore cy
63 subcc %g0,%o4,%g0 ! restore cy
64 /* Add blocks of 8 limbs until less than 8 limbs remain */
65 Loop1: addxcc %g4,%g2,%o4
89 addx %g0,%g0,%o4 ! save cy in register
93 add res_ptr,32,res_ptr
95 subcc %g0,%o4,%g0 ! restore cy
97 Lfin1: addcc size,8-2,size
99 subcc %g0,%o4,%g0 ! restore cy
100 /* Add blocks of 2 limbs until less than 2 limbs remain */
101 Loope1: addxcc %g4,%g2,%o4
107 addx %g0,%g0,%o4 ! save cy in register
111 add res_ptr,8,res_ptr
113 subcc %g0,%o4,%g0 ! restore cy
114 Lend1: addxcc %g4,%g2,%o4
117 addx %g0,%g0,%o4 ! save cy in register
121 subcc %g0,%o4,%g0 ! restore cy
129 addx %g0,%g0,%o0 ! return carry-out from most sign. limb
131 L1: xor s1_ptr,res_ptr,%g1
142 /* If we come here, the alignment of s1_ptr and res_ptr as well as the
143 alignment of s2_ptr and res_ptr differ. Since there are only two ways
144 things can be aligned (that we care about) we now know that the alignment
145 of s1_ptr and s2_ptr are the same. */
150 andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
151 be L_v2 ! if no, branch
153 /* Add least significant limb separately to align s1_ptr and s2_ptr */
161 add res_ptr,4,res_ptr
163 L_v2: addx %g0,%g0,%o4 ! save cy in register
166 subcc %g0,%o4,%g0 ! restore cy
167 /* Add blocks of 8 limbs until less than 8 limbs remain */
168 Loop2: ldd [s1_ptr+0],%g2
192 addx %g0,%g0,%o4 ! save cy in register
196 add res_ptr,32,res_ptr
198 subcc %g0,%o4,%g0 ! restore cy
200 Lfin2: addcc size,8-2,size
202 subcc %g0,%o4,%g0 ! restore cy
203 Loope2: ldd [s1_ptr+0],%g2
209 addx %g0,%g0,%o4 ! save cy in register
213 add res_ptr,8,res_ptr
215 subcc %g0,%o4,%g0 ! restore cy
216 Lend2: andcc size,1,%g0
218 subcc %g0,%o4,%g0 ! restore cy
220 Ljone: ld [s1_ptr],%g4
226 addx %g0,%g0,%o0 ! return carry-out from most sign. limb