1 ; mc88110 __gmpn_sub_n -- Subtract two limb vectors of the same length > 0 and
2 ; store difference in a third limb vector.
4 ; Copyright 1995, 1996, 2000 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 either:
11 ; * the GNU Lesser General Public License as published by the Free
12 ; Software Foundation; either version 3 of the License, or (at your
13 ; option) any later version.
17 ; * the GNU General Public License as published by the Free Software
18 ; Foundation; either version 2 of the License, or (at your option) any
21 ; or both in parallel, as here.
23 ; The GNU MP Library is distributed in the hope that it will be useful, but
24 ; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 ; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 ; You should have received copies of the GNU General Public License and the
29 ; GNU Lesser General Public License along with the GNU MP Library. If not,
30 ; see https://www.gnu.org/licenses/.
43 global C_SYMBOL_NAME(__gmpn_sub_n)
44 C_SYMBOL_NAME(__gmpn_sub_n):
45 subu.co r0,r0,r0 ; set cy flag
46 xor r12,s2_ptr,res_ptr
49 L0: bb0 2,res_ptr,L_v1 ; branch if res_ptr is aligned
50 /* Add least significant limb separately to align res_ptr and s2_ptr */
58 addu res_ptr,res_ptr,4
67 /* Add blocks of 8 limbs until less than 8 limbs remain */
69 Loop1: subu size,size,8
96 addu res_ptr,res_ptr,32
99 Lfin1: addu size,size,8-2
101 /* Add blocks of 2 limbs until less than 2 limbs remain */
102 Loope1: subu.cio r6,r10,r8
111 addu res_ptr,res_ptr,8
113 Lend1: subu.cio r6,r10,r8
124 Lret1: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
128 L1: xor r12,s1_ptr,res_ptr
131 bb0 2,res_ptr,L_v1b ; branch if res_ptr is aligned
132 /* Add least significant limb separately to align res_ptr and s1_ptr */
140 addu res_ptr,res_ptr,4
141 L_v1b: cmp r12,size,2
149 /* Add blocks of 8 limbs until less than 8 limbs remain */
151 Loop1b: subu size,size,8
174 addu s2_ptr,s2_ptr,32
176 addu s1_ptr,s1_ptr,32
178 addu res_ptr,res_ptr,32
181 Lfin1b: addu size,size,8-2
183 /* Add blocks of 2 limbs until less than 2 limbs remain */
184 Loope1b:subu.cio r6,r8,r10
193 addu res_ptr,res_ptr,8
194 bcnd ge0,size,Loope1b
195 Lend1b: subu.cio r6,r8,r10
206 Lret1b: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
211 /* If we come here, the alignment of s1_ptr and res_ptr as well as the
212 alignment of s2_ptr and res_ptr differ. Since there are only two ways
213 things can be aligned (that we care about) we now know that the alignment
214 of s1_ptr and s2_ptr are the same. */
218 bb0 2,s1_ptr,L_v2 ; branch if s1_ptr is aligned
219 /* Add least significant limb separately to align res_ptr and s2_ptr */
227 addu res_ptr,res_ptr,4
229 L_v2: subu size,size,8
231 /* Add blocks of 8 limbs until less than 8 limbs remain */
233 Loop2: subu size,size,8
258 addu s1_ptr,s1_ptr,32
259 addu s2_ptr,s2_ptr,32
260 addu res_ptr,res_ptr,32
263 Lfin2: addu size,size,8-2
265 Loope2: ld.d r8,s1_ptr,0
274 addu res_ptr,res_ptr,8
276 Lend2: bb0 0,size,Lret2
278 Ljone: ld r10,s1_ptr,0
283 Lret2: addu.ci r2,r0,r0 ; return carry-out from most sign. limb