1 ! sparc __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
2 ! store difference in a third limb vector.
4 ! Copyright (C) 1995 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., 675 Mass Ave, Cambridge, MA 02139, USA.
33 .global C_SYMBOL_NAME(__mpn_sub_n)
34 C_SYMBOL_NAME(__mpn_sub_n):
35 xor s2_ptr,res_ptr,%g1
37 bne L1 ! branch if alignment differs
40 andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
41 beq L_v1 ! if no, branch
43 /* Add least significant limb separately to align res_ptr and s2_ptr */
52 L_v1: addx %g0,%g0,%o4 ! save cy in register
53 cmp size,2 ! if size < 2 ...
54 bl Lend2 ! ... branch to tail code
55 subcc %g0,%o4,%g0 ! restore cy
62 subcc %g0,%o4,%g0 ! restore cy
63 /* Add blocks of 8 limbs until less than 8 limbs remain */
64 Loop1: subxcc %g4,%g2,%o4
88 addx %g0,%g0,%o4 ! save cy in register
92 add res_ptr,32,res_ptr
94 subcc %g0,%o4,%g0 ! restore cy
96 Lfin1: addcc size,8-2,size
98 subcc %g0,%o4,%g0 ! restore cy
99 /* Add blocks of 2 limbs until less than 2 limbs remain */
100 Loope1: subxcc %g4,%g2,%o4
106 addx %g0,%g0,%o4 ! save cy in register
110 add res_ptr,8,res_ptr
112 subcc %g0,%o4,%g0 ! restore cy
113 Lend1: subxcc %g4,%g2,%o4
116 addx %g0,%g0,%o4 ! save cy in register
120 subcc %g0,%o4,%g0 ! restore cy
128 addx %g0,%g0,%o0 ! return carry-out from most sign. limb
130 L1: xor s1_ptr,res_ptr,%g1
135 andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
136 beq L_v1b ! if no, branch
138 /* Add least significant limb separately to align res_ptr and s2_ptr */
146 add res_ptr,4,res_ptr
147 L_v1b: addx %g0,%g0,%o4 ! save cy in register
148 cmp size,2 ! if size < 2 ...
149 bl Lend2 ! ... branch to tail code
150 subcc %g0,%o4,%g0 ! restore cy
157 subcc %g0,%o4,%g0 ! restore cy
158 /* Add blocks of 8 limbs until less than 8 limbs remain */
159 Loop1b: subxcc %g2,%g4,%o4
183 addx %g0,%g0,%o4 ! save cy in register
187 add res_ptr,32,res_ptr
189 subcc %g0,%o4,%g0 ! restore cy
191 Lfin1b: addcc size,8-2,size
193 subcc %g0,%o4,%g0 ! restore cy
194 /* Add blocks of 2 limbs until less than 2 limbs remain */
195 Loope1b:subxcc %g2,%g4,%o4
201 addx %g0,%g0,%o4 ! save cy in register
205 add res_ptr,8,res_ptr
207 subcc %g0,%o4,%g0 ! restore cy
208 Lend1b: subxcc %g2,%g4,%o4
211 addx %g0,%g0,%o4 ! save cy in register
215 subcc %g0,%o4,%g0 ! restore cy
223 addx %g0,%g0,%o0 ! return carry-out from most sign. limb
226 /* If we come here, the alignment of s1_ptr and res_ptr as well as the
227 alignment of s2_ptr and res_ptr differ. Since there are only two ways
228 things can be aligned (that we care about) we now know that the alignment
229 of s1_ptr and s2_ptr are the same. */
234 andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
235 beq L_v2 ! if no, branch
237 /* Add least significant limb separately to align s1_ptr and s2_ptr */
245 add res_ptr,4,res_ptr
247 L_v2: addx %g0,%g0,%o4 ! save cy in register
250 subcc %g0,%o4,%g0 ! restore cy
251 /* Add blocks of 8 limbs until less than 8 limbs remain */
252 Loop2: ldd [s1_ptr+0],%g2
276 addx %g0,%g0,%o4 ! save cy in register
280 add res_ptr,32,res_ptr
282 subcc %g0,%o4,%g0 ! restore cy
284 Lfin2: addcc size,8-2,size
286 subcc %g0,%o4,%g0 ! restore cy
287 Loope2: ldd [s1_ptr+0],%g2
293 addx %g0,%g0,%o4 ! save cy in register
297 add res_ptr,8,res_ptr
299 subcc %g0,%o4,%g0 ! restore cy
300 Lend2: andcc size,1,%g0
302 subcc %g0,%o4,%g0 ! restore cy
304 Ljone: ld [s1_ptr],%g4
310 addx %g0,%g0,%o0 ! return carry-out from most sign. limb