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, 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_sub_n)
35 C_SYMBOL_NAME(__mpn_sub_n):
36 xor s2_ptr,res_ptr,%g1
38 bne L1 ! branch if alignment differs
41 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: subxcc %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: subxcc %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: subxcc %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
136 andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
137 be L_v1b ! if no, branch
139 /* Add least significant limb separately to align res_ptr and s1_ptr */
147 add res_ptr,4,res_ptr
148 L_v1b: addx %g0,%g0,%o4 ! save cy in register
149 cmp size,2 ! if size < 2 ...
150 bl Lend2 ! ... branch to tail code
151 subcc %g0,%o4,%g0 ! restore cy
158 subcc %g0,%o4,%g0 ! restore cy
159 /* Add blocks of 8 limbs until less than 8 limbs remain */
160 Loop1b: subxcc %g2,%g4,%o4
184 addx %g0,%g0,%o4 ! save cy in register
188 add res_ptr,32,res_ptr
190 subcc %g0,%o4,%g0 ! restore cy
192 Lfin1b: addcc size,8-2,size
194 subcc %g0,%o4,%g0 ! restore cy
195 /* Add blocks of 2 limbs until less than 2 limbs remain */
196 Loope1b:subxcc %g2,%g4,%o4
202 addx %g0,%g0,%o4 ! save cy in register
206 add res_ptr,8,res_ptr
208 subcc %g0,%o4,%g0 ! restore cy
209 Lend1b: subxcc %g2,%g4,%o4
212 addx %g0,%g0,%o4 ! save cy in register
216 subcc %g0,%o4,%g0 ! restore cy
224 addx %g0,%g0,%o0 ! return carry-out from most sign. limb
227 /* If we come here, the alignment of s1_ptr and res_ptr as well as the
228 alignment of s2_ptr and res_ptr differ. Since there are only two ways
229 things can be aligned (that we care about) we now know that the alignment
230 of s1_ptr and s2_ptr are the same. */
235 andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
236 be L_v2 ! if no, branch
238 /* Add least significant limb separately to align s1_ptr and s2_ptr */
246 add res_ptr,4,res_ptr
248 L_v2: addx %g0,%g0,%o4 ! save cy in register
251 subcc %g0,%o4,%g0 ! restore cy
252 /* Add blocks of 8 limbs until less than 8 limbs remain */
253 Loop2: ldd [s1_ptr+0],%g2
277 addx %g0,%g0,%o4 ! save cy in register
281 add res_ptr,32,res_ptr
283 subcc %g0,%o4,%g0 ! restore cy
285 Lfin2: addcc size,8-2,size
287 subcc %g0,%o4,%g0 ! restore cy
288 Loope2: ldd [s1_ptr+0],%g2
294 addx %g0,%g0,%o4 ! save cy in register
298 add res_ptr,8,res_ptr
300 subcc %g0,%o4,%g0 ! restore cy
301 Lend2: andcc size,1,%g0
303 subcc %g0,%o4,%g0 ! restore cy
305 Ljone: ld [s1_ptr],%g4
311 addx %g0,%g0,%o0 ! return carry-out from most sign. limb