1 ; mc88110 __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 Lesser General Public License as published by
10 ; the Free Software Foundation; either version 2.1 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 Lesser General Public
16 ; License for more details.
18 ; You should have received a copy of the GNU Lesser 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 subu.co r0,r0,r0 ; set cy flag
37 xor r12,s2_ptr,res_ptr
40 L0: bb0 2,res_ptr,L_v1 ; branch if res_ptr is aligned
41 /* Add least significant limb separately to align res_ptr and s2_ptr */
49 addu res_ptr,res_ptr,4
58 /* Add blocks of 8 limbs until less than 8 limbs remain */
60 Loop1: subu size,size,8
87 addu res_ptr,res_ptr,32
90 Lfin1: addu size,size,8-2
92 /* Add blocks of 2 limbs until less than 2 limbs remain */
93 Loope1: subu.cio r6,r10,r8
102 addu res_ptr,res_ptr,8
104 Lend1: subu.cio r6,r10,r8
115 Lret1: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
119 L1: xor r12,s1_ptr,res_ptr
122 bb0 2,res_ptr,L_v1b ; branch if res_ptr is aligned
123 /* Add least significant limb separately to align res_ptr and s1_ptr */
131 addu res_ptr,res_ptr,4
132 L_v1b: cmp r12,size,2
140 /* Add blocks of 8 limbs until less than 8 limbs remain */
142 Loop1b: subu size,size,8
165 addu s2_ptr,s2_ptr,32
167 addu s1_ptr,s1_ptr,32
169 addu res_ptr,res_ptr,32
172 Lfin1b: addu size,size,8-2
174 /* Add blocks of 2 limbs until less than 2 limbs remain */
175 Loope1b:subu.cio r6,r8,r10
184 addu res_ptr,res_ptr,8
185 bcnd ge0,size,Loope1b
186 Lend1b: subu.cio r6,r8,r10
197 Lret1b: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
202 /* If we come here, the alignment of s1_ptr and res_ptr as well as the
203 alignment of s2_ptr and res_ptr differ. Since there are only two ways
204 things can be aligned (that we care about) we now know that the alignment
205 of s1_ptr and s2_ptr are the same. */
209 bb0 2,s1_ptr,L_v2 ; branch if s1_ptr is aligned
210 /* Add least significant limb separately to align res_ptr and s2_ptr */
218 addu res_ptr,res_ptr,4
220 L_v2: subu size,size,8
222 /* Add blocks of 8 limbs until less than 8 limbs remain */
224 Loop2: subu size,size,8
249 addu s1_ptr,s1_ptr,32
250 addu s2_ptr,s2_ptr,32
251 addu res_ptr,res_ptr,32
254 Lfin2: addu size,size,8-2
256 Loope2: ld.d r8,s1_ptr,0
265 addu res_ptr,res_ptr,8
267 Lend2: bb0 0,size,Lret2
269 Ljone: ld r10,s1_ptr,0
274 Lret2: addu.ci r2,r0,r0 ; return carry-out from most sign. limb