Add test case for bug 18287
[glibc.git] / sysdeps / arm / submul_1.S
blob8f83f06f350da85c7f6d70d331e3c8bbcf979589
1 /* mpn_submul_1 -- multiply and subtract bignums.
2    Copyright (C) 2013-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library.  If not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
21         .syntax unified
22         .text
24 @               cycles/limb
25 @ StrongArm        ?
26 @ Cortex-A8        ?
27 @ Cortex-A9        ?
28 @ Cortex-A15       4
30 /* mp_limb_t mpn_submul_1(res_ptr, src1_ptr, size, s2_limb) */
32 ENTRY (__mpn_submul_1)
33         push    { r4, r5, r6, r7 }
34         cfi_adjust_cfa_offset (16)
35         cfi_rel_offset (r4, 0)
36         cfi_rel_offset (r5, 4)
37         cfi_rel_offset (r6, 8)
38         cfi_rel_offset (r7, 12)
40         sfi_breg r1, \
41         ldr     r6, [\B], #4
42         sfi_breg r0, \
43         ldr     r7, [\B]
44         mov     r4, #0                  /* init carry in */
45         b       1f
47         sfi_breg r1, \
48         ldr     r6, [\B], #4            /* load next ul */
49         adds    r5, r5, r4              /* (lpl, c) = lpl + cl */
50         adc     r4, ip, #0              /* cl = hpl + c */
51         subs    r5, r7, r5              /* (lpl, !c) = rl - lpl */
52         sfi_breg r0, \
53         ldr     r7, [\B, #4]            /* load next rl */
54         it      cc
55         addcc   r4, r4, #1              /* cl += !c */
56         sfi_breg r0, \
57         str     r5, [\B], #4
59         umull   r5, ip, r6, r3          /* (hpl, lpl) = ul * vl */
60         subs    r2, r2, #1
61         bne     0b
63         adds    r5, r5, r4              /* (lpl, c) = lpl + cl */
64         adc     r4, ip, #0              /* cl = hpl + c */
65         subs    r5, r7, r5              /* (lpl, !c) = rl - lpl */
66         sfi_breg r0, \
67         str     r5, [\B], #4
68         it      cc
69         addcc   r4, r4, #1              /* cl += !c */
70         mov     r0, r4                  /* return carry */
72         pop     { r4, r5, r6, r7 }
73         DO_RET  (lr)
74 END (__mpn_submul_1)