2 * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Matt Thomas of 3am Software Foundry.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
30 #include <machine/asm.h>
32 RCSID("$NetBSD: __aeabi_ldivmod.S,v 1.13 2014/05/06 16:02:11 joerg Exp $")
35 #define ALO r1 /* incoming numerator, outgoing quotient */
36 #define AHI r0 /* incoming numerator, outgoing quotient */
37 #define BLO r3 /* incoming denominator, outgoing remainder */
38 #define BHI r2 /* incoming denominator, outgoing remainder */
40 #define ALO r0 /* incoming numerator, outgoing quotient */
41 #define AHI r1 /* incoming numerator, outgoing quotient */
42 #define BLO r2 /* incoming denominator, outgoing remainder */
43 #define BHI r3 /* incoming denominator, outgoing remainder */
46 ENTRY(__aeabi_ldivmod)
48 # if !defined(__ARM_DWARF_EH__)
53 #if !defined(_KERNEL) && !defined(_STANDALONE)
54 #if !defined(__thumb__)
57 #elif defined(_ARM_ARCH_T2)
71 .cfi_def_cfa_offset 16
82 movs NEG, #1 /* flip quotient sign */
91 eors NEG, NEG, r4 /* flip quotient sign, flip remainder sign */
95 eorlt NEG, NEG, #3 /* flip quotient sign, flip remainder sign */
100 * Arguments are setup, allocate some stack for the remainder
101 * and call __qdivrem for the heavy lifting.
104 .cfi_def_cfa_offset 32
107 #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
114 bl PLT_SYM(__qdivrem)
117 .cfi_def_cfa_offset 24
123 * The quotient is already in the right place and neither value
124 * needs its sign flipped.
126 #if defined(__thumb__) && defined(_ARM_ARCH_T2)
127 cbz NEG, .Lnegate_neither
129 cmp NEG, #0 /* any signs to flip? */
133 cmp NEG, #2 /* does remainder need to be negative? */
134 beq .Lnegate_b_only /* 2 means b only */
135 bgt .Lnegate_both /* 3 means both */
137 bl .Lnegate_a /* 1 means a only */
139 pop {r2-r6, pc} /* grab b from stack */
143 pop {r2-r3} /* get remainder */
145 .cfi_def_cfa_offset 16
147 bl .Lnegate_b /* negate it */
179 * We had a carry so the denominator must have INT64_MIN
180 * Also BLO and BHI never changed values so we can use
181 * them to see if the numerator has the same value. We
182 * don't have to worry about sign.
194 * They were equal, so we return a quotient of 1 and remainder of 0.
203 * Our remainder must be the numerator and our quotient is 0.
212 #if !defined(_KERNEL) && !defined(_STANDALONE)
217 # if !defined(__ARM_DWARF_EH__)
220 .cfi_def_cfa_offset 16
225 #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
230 mvnge AHI, #0x80000000
232 movlt AHI, #0x80000000
245 #endif /* __thumb__ && !_ARM_ARCH_T2 */
246 bl PLT_SYM(__aeabi_ldiv0)
248 #endif /* !_KERNEL && !_STANDALONE */
251 # if !defined(__ARM_DWARF_EH__)