1/* mpn_add_n -- add (or subtract) bignums. 2 Copyright (C) 2013-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 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. 9 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. 14 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 <https://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20#include <arm-features.h> 21 22 .syntax unified 23 .text 24 25#ifdef USE_AS_SUB_N 26# define INITC cmp r0, r0 27# define OPC sbcs 28# define RETC sbc r0, r0, r0; neg r0, r0 29# define FUNC __mpn_sub_n 30#else 31# define INITC cmn r0, #0 32# define OPC adcs 33# define RETC mov r0, #0; adc r0, r0, r0 34# define FUNC __mpn_add_n 35#endif 36 37/* mp_limb_t mpn_add_n(res_ptr, src1_ptr, src2_ptr, size) */ 38 39ENTRY (FUNC) 40 push { r4, r5, r6, r7, r8, r10, lr } 41 cfi_adjust_cfa_offset (28) 42 cfi_rel_offset (r4, 0) 43 cfi_rel_offset (r5, 4) 44 cfi_rel_offset (r6, 8) 45 cfi_rel_offset (r7, 12) 46 cfi_rel_offset (r8, 16) 47 cfi_rel_offset (r10, 20) 48 cfi_rel_offset (lr, 24) 49 50 INITC /* initialize carry flag */ 51 tst r3, #1 /* count & 1 == 1? */ 52 add lr, r1, r3, lsl #2 /* compute end src1 */ 53 beq 1f 54 55 ldr r4, [r1], #4 /* do one to make count even */ 56 ldr r5, [r2], #4 57 OPC r4, r4, r5 58 teq r1, lr /* end of count? (preserve carry) */ 59 str r4, [r0], #4 60 beq 9f 611: 62 tst r3, #2 /* count & 2 == 2? */ 63 beq 2f 64 ldm r1!, { r4, r5 } /* do two to make count 0 mod 4 */ 65 ldm r2!, { r6, r7 } 66 OPC r4, r4, r6 67 OPC r5, r5, r7 68 teq r1, lr /* end of count? */ 69 stm r0!, { r4, r5 } 70 beq 9f 712: 72 ldm r1!, { r3, r5, r7, r10 } /* do four each loop */ 73 ldm r2!, { r4, r6, r8, ip } 74 OPC r3, r3, r4 75 OPC r5, r5, r6 76 OPC r7, r7, r8 77 OPC r10, r10, ip 78 teq r1, lr 79 stm r0!, { r3, r5, r7, r10 } 80 bne 2b 81 829: 83 RETC /* copy carry out */ 84#ifndef ARM_ALWAYS_BX 85 pop { r4, r5, r6, r7, r8, r10, pc } 86#else 87 pop { r4, r5, r6, r7, r8, r10, lr } 88 bx lr 89#endif 90END (FUNC) 91