Drop main() prototype. Syncs with NetBSD-8
[minix.git] / common / lib / libc / arch / arm / quad / __aeabi_ldivmod.S
blob5be9333494303a0a735df736d30d5ea2bb32a80a
1 /*-
2  * Copyright (c) 2012 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Matt Thomas of 3am Software Foundry.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
16  *
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.
28  */
30 #include <machine/asm.h>
32 RCSID("$NetBSD: __aeabi_ldivmod.S,v 1.13 2014/05/06 16:02:11 joerg Exp $")
34 #ifdef __ARMEB__
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 */
39 #else
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 */
44 #endif
46 ENTRY(__aeabi_ldivmod)
47 #ifdef __ARM_EABI__
48 # if !defined(__ARM_DWARF_EH__)
49         .fnstart
50 # endif
51         .cfi_startproc
52 #endif
53 #if !defined(_KERNEL) && !defined(_STANDALONE)
54 #if !defined(__thumb__)
55         orrs    ip, BLO, BHI
56         beq     .Ldivbyzero
57 #elif defined(_ARM_ARCH_T2)
58         cbnz    BLO, 1f
59         cbz     BHI, .Ldivbyzero
60 #else
61         cmp     BLO, #0
62         bne     1f
63         cmp     BHI, #0
64         beq     .Ldivbyzero
65 #endif
67 #endif
69         push    {r4-r6, lr}
70 #ifdef __ARM_EABI__
71         .cfi_def_cfa_offset 16
72         .cfi_offset 14, -4
73         .cfi_offset 6, -8
74         .cfi_offset 5, -12
75         .cfi_offset 4, -16
76 #endif
77 #define NEG     r5
78         movs    NEG, #0
80         cmp     BHI, #0
81         bge     2f
82         movs    NEG, #1         /* flip quotient sign */
83         bl      .Lnegate_b
84         bcs     .Lmaxdenom
87         cmp     AHI, #0
88 #ifdef __thumb__
89         bge     3f
90         movs    r4, #3
91         eors    NEG, NEG, r4    /* flip quotient sign, flip remainder sign */
92         bl      .Lnegate_a
94 #else
95         eorlt   NEG, NEG, #3    /* flip quotient sign, flip remainder sign */
96         bllt    .Lnegate_a
97 #endif
99         /*
100          * Arguments are setup, allocate some stack for the remainder
101          * and call __qdivrem for the heavy lifting.
102          */
103 #ifdef __ARM_EABI__
104         .cfi_def_cfa_offset 32
105 #endif
106         sub     sp, sp, #16
107 #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
108         adds    r4, sp, #8
109 #else
110         mov     r4, sp
111         adds    r4, r4, #8
112 #endif
113         str     r4, [sp]
114         bl      PLT_SYM(__qdivrem)
115         add     sp, sp, #8
116 #ifdef __ARM_EABI__
117         .cfi_def_cfa_offset 24
118         .cfi_offset 3, -20
119         .cfi_offset 2, -24
120 #endif
122         /*
123          * The quotient is already in the right place and neither value
124          * needs its sign flipped.
125          */
126 #if defined(__thumb__) && defined(_ARM_ARCH_T2)
127         cbz     NEG, .Lnegate_neither
128 #else
129         cmp     NEG, #0         /* any signs to flip? */
130         beq     .Lnegate_neither
131 #endif
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 */
136 .Lnegate_a_only:
137         bl      .Lnegate_a      /* 1 means a only */
138 .Lnegate_neither:
139         pop     {r2-r6, pc}     /* grab b from stack */
140 .Lnegate_both:
141         bl      .Lnegate_a
142 .Lnegate_b_only:
143         pop     {r2-r3}         /* get remainder */
144 #ifdef __ARM_EABI__
145         .cfi_def_cfa_offset 16
146 #endif
147         bl      .Lnegate_b      /* negate it */
148         pop     {r4-r6, pc}
150         .align  0
151 .Lnegate_a:
152 #ifdef __thumb__
153         movs    r4, AHI
154         movs    AHI, #0
155         negs    ALO, ALO
156         sbcs    AHI, AHI, r4
157 #else
158         negs    ALO, ALO
159         rsc     AHI, AHI, #0
160 #endif
161         RET
163         .align  0
164 .Lnegate_b:
165 #ifdef __thumb__
166         movs    r4, BHI
167         movs    BHI, #0
168         negs    BLO, BLO
169         sbcs    BHI, BHI, r4
170 #else
171         negs    BLO, BLO
172         rsc     BHI, BHI, #0
173 #endif
174         RET
176         .align  0
177 .Lmaxdenom:
178         /*
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.
183          */
184         cmp     BHI, AHI
185 #ifdef __thumb__
186         bne     1f
187         cmp     BLO, ALO
188 #else
189         cmpeq   BLO, ALO
190 #endif
191         bne     1f
193         /*
194          * They were equal, so we return a quotient of 1 and remainder of 0.
195          */
196         movs    ALO, #1
197         movs    AHI, #0
198         movs    BLO, #0
199         movs    BHI, #0
200         pop     {r4-r6, pc}
202         /*
203          * Our remainder must be the numerator and our quotient is 0.
204          */
205         .align  0
206 1:      movs    BLO, ALO
207         movs    BHI, AHI
208         movs    ALO, #0
209         movs    AHI, #0
210         pop     {r4-r6, pc}
212 #if !defined(_KERNEL) && !defined(_STANDALONE)
213         .align  0
214 .Ldivbyzero:
215         push    {r0-r1,r4,lr}   
216 #ifdef __ARM_EABI__
217 # if !defined(__ARM_DWARF_EH__)
218         .save   {r0-r1,r4,lr}   
219 # endif
220         .cfi_def_cfa_offset 16
221         .cfi_offset 14, -4
222         .cfi_offset  4, -8
223 #endif
224         cmp     AHI, #0
225 #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
226 #ifdef __thumb__
227         ittee   ge
228 #endif
229         mvnge   ALO, #0
230         mvnge   AHI, #0x80000000
231         movlt   ALO, #0
232         movlt   AHI, #0x80000000
233 #else
234         blt     1f
235         movs    ALO, #0
236         mvns    ALO, ALO
237         mov     AHI, ALO
238         lsrs    AHI, AHI, #1
239         b       2f
241         movs    ALO, #0
242         movs    AHI, #1
243         lsls    AHI, AHI, #31
245 #endif /* __thumb__ && !_ARM_ARCH_T2 */
246         bl      PLT_SYM(__aeabi_ldiv0)
247         pop     {r2-r4, pc}
248 #endif  /* !_KERNEL && !_STANDALONE */
249 #ifdef __ARM_EABI__
250         .cfi_endproc
251 # if !defined(__ARM_DWARF_EH__)
252         .fnend
253 # endif
254 #endif
255 END(__aeabi_ldivmod)