]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/cortex-strings/src/thumb/aeabi_idiv.S
MFV r351500: Fix CLEAR_HASH macro to be usable as a single statement.
[FreeBSD/FreeBSD.git] / contrib / cortex-strings / src / thumb / aeabi_idiv.S
1 /*
2  * Copyright (c) 2014 ARM Ltd
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the company may not be used to endorse or promote
14  *    products derived from this software without specific prior written
15  *    permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /* An executable stack is *not* required for these functions.  */
30
31 .section .note.GNU-stack,"",%progbits
32 .previous
33 .eabi_attribute 25, 1
34
35 /* ANSI concatenation macros.  */
36
37 #define CONCAT1(a, b) CONCAT2(a, b)
38 #define CONCAT2(a, b) a ## b
39
40 /* Use the right prefix for global labels.  */
41
42 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
43
44 #define TYPE(x) .type SYM(x),function
45 #define SIZE(x) .size SYM(x), . - SYM(x)
46 #define LSYM(x) .x
47
48 .macro cfi_start        start_label, end_label
49         .pushsection    .debug_frame
50 LSYM(Lstart_frame):
51         .4byte  LSYM(Lend_cie) - LSYM(Lstart_cie)
52 LSYM(Lstart_cie):
53         .4byte  0xffffffff
54         .byte   0x1
55         .ascii  "\0"
56         .uleb128 0x1
57         .sleb128 -4
58         .byte   0xe
59         .byte   0xc
60         .uleb128 0xd
61         .uleb128 0x0
62
63         .align 2
64 LSYM(Lend_cie):
65         .4byte  LSYM(Lend_fde)-LSYM(Lstart_fde)
66 LSYM(Lstart_fde):
67         .4byte  LSYM(Lstart_frame)
68         .4byte  \start_label
69         .4byte  \end_label-\start_label
70         .popsection
71 .endm
72
73 .macro cfi_end  end_label
74         .pushsection    .debug_frame
75         .align  2
76 LSYM(Lend_fde):
77         .popsection
78 \end_label:
79 .endm
80
81 .macro THUMB_LDIV0 name signed
82         push    {r0, lr}
83         movs    r0, #0
84         bl      SYM(__aeabi_idiv0)
85         pop     {r1, pc}
86 .endm
87
88 .macro FUNC_END name
89         SIZE (__\name)
90 .endm
91
92 .macro DIV_FUNC_END name signed
93         cfi_start       __\name, LSYM(Lend_div0)
94 LSYM(Ldiv0):
95         THUMB_LDIV0 \name \signed
96         cfi_end LSYM(Lend_div0)
97         FUNC_END \name
98 .endm
99
100 .macro THUMB_FUNC_START name
101         .globl  SYM (\name)
102         TYPE    (\name)
103         .thumb_func
104 SYM (\name):
105 .endm
106
107 .macro FUNC_START name
108         .text
109         .globl SYM (__\name)
110         TYPE (__\name)
111         .align 0
112         .force_thumb
113         .thumb_func
114         .syntax unified
115 SYM (__\name):
116 .endm
117
118 .macro  FUNC_ALIAS new old
119         .globl  SYM (__\new)
120         .thumb_set      SYM (__\new), SYM (__\old)
121 .endm
122
123 /* Register aliases.  */
124 work            .req    r4
125 dividend        .req    r0
126 divisor         .req    r1
127 overdone        .req    r2
128 result          .req    r2
129 curbit          .req    r3
130
131 /* ------------------------------------------------------------------------ */
132 /*              Bodies of the division and modulo routines.                 */
133 /* ------------------------------------------------------------------------ */
134 .macro BranchToDiv n, label
135         lsrs    curbit, dividend, \n
136         cmp     curbit, divisor
137         bcc     \label
138 .endm
139
140 .macro DoDiv n
141         lsrs    curbit, dividend, \n
142         cmp     curbit, divisor
143         bcc     1f
144         lsls    curbit, divisor, \n
145         subs    dividend, dividend, curbit
146
147 1:      adcs    result, result
148 .endm
149
150 .macro THUMB1_Div_Positive
151         movs    result, #0
152         BranchToDiv #1, LSYM(Lthumb1_div1)
153         BranchToDiv #4, LSYM(Lthumb1_div4)
154         BranchToDiv #8, LSYM(Lthumb1_div8)
155         BranchToDiv #12, LSYM(Lthumb1_div12)
156         BranchToDiv #16, LSYM(Lthumb1_div16)
157 LSYM(Lthumb1_div_large_positive):
158         movs    result, #0xff
159         lsls    divisor, divisor, #8
160         rev     result, result
161         lsrs    curbit, dividend, #16
162         cmp     curbit, divisor
163         bcc     1f
164         asrs    result, #8
165         lsls    divisor, divisor, #8
166         beq     LSYM(Ldivbyzero_waypoint)
167
168 1:      lsrs    curbit, dividend, #12
169         cmp     curbit, divisor
170         bcc     LSYM(Lthumb1_div12)
171         b       LSYM(Lthumb1_div16)
172 LSYM(Lthumb1_div_loop):
173         lsrs    divisor, divisor, #8
174 LSYM(Lthumb1_div16):
175         Dodiv   #15
176         Dodiv   #14
177         Dodiv   #13
178         Dodiv   #12
179 LSYM(Lthumb1_div12):
180         Dodiv   #11
181         Dodiv   #10
182         Dodiv   #9
183         Dodiv   #8
184         bcs     LSYM(Lthumb1_div_loop)
185 LSYM(Lthumb1_div8):
186         Dodiv   #7
187         Dodiv   #6
188         Dodiv   #5
189 LSYM(Lthumb1_div5):
190         Dodiv   #4
191 LSYM(Lthumb1_div4):
192         Dodiv   #3
193 LSYM(Lthumb1_div3):
194         Dodiv   #2
195 LSYM(Lthumb1_div2):
196         Dodiv   #1
197 LSYM(Lthumb1_div1):
198         subs    divisor, dividend, divisor
199         bcs     1f
200         mov     divisor, dividend
201
202 1:      adcs    result, result
203         mov     dividend, result
204         bx      lr
205
206 LSYM(Ldivbyzero_waypoint):
207         b       LSYM(Ldiv0)
208 .endm
209
210 .macro THUMB1_Div_Negative
211         lsrs    result, divisor, #31
212         beq     1f
213         rsbs    divisor, divisor, #0
214
215 1:      asrs    curbit, dividend, #32
216         bcc     2f
217         rsbs    dividend, dividend, #0
218
219 2:      eors    curbit, result
220         movs    result, #0
221         mov     ip, curbit
222         BranchToDiv #4, LSYM(Lthumb1_div_negative4)
223         BranchToDiv #8, LSYM(Lthumb1_div_negative8)
224 LSYM(Lthumb1_div_large):
225         movs    result, #0xfc
226         lsls    divisor, divisor, #6
227         rev     result, result
228         lsrs    curbit, dividend, #8
229         cmp     curbit, divisor
230         bcc     LSYM(Lthumb1_div_negative8)
231
232         lsls    divisor, divisor, #6
233         asrs    result, result, #6
234         cmp     curbit, divisor
235         bcc     LSYM(Lthumb1_div_negative8)
236
237         lsls    divisor, divisor, #6
238         asrs    result, result, #6
239         cmp     curbit, divisor
240         bcc     LSYM(Lthumb1_div_negative8)
241
242         lsls    divisor, divisor, #6
243         beq     LSYM(Ldivbyzero_negative)
244         asrs    result, result, #6
245         b       LSYM(Lthumb1_div_negative8)
246 LSYM(Lthumb1_div_negative_loop):
247         lsrs    divisor, divisor, #6
248 LSYM(Lthumb1_div_negative8):
249         DoDiv   #7
250         DoDiv   #6
251         DoDiv   #5
252         DoDiv   #4
253 LSYM(Lthumb1_div_negative4):
254         DoDiv   #3
255         DoDiv   #2
256         bcs     LSYM(Lthumb1_div_negative_loop)
257         DoDiv   #1
258         subs    divisor, dividend, divisor
259         bcs     1f
260         mov     divisor, dividend
261
262 1:      mov     curbit, ip
263         adcs    result, result
264         asrs    curbit, curbit, #1
265         mov     dividend, result
266         bcc     2f
267         rsbs    dividend, dividend, #0
268         cmp     curbit, #0
269
270 2:      bpl     3f
271         rsbs    divisor, divisor, #0
272
273 3:      bx      lr
274
275 LSYM(Ldivbyzero_negative):
276         mov     curbit, ip
277         asrs    curbit, curbit, #1
278         bcc     LSYM(Ldiv0)
279         rsbs    dividend, dividend, #0
280 .endm
281
282 /* ------------------------------------------------------------------------ */
283 /*              Start of the Real Functions                                 */
284 /* ------------------------------------------------------------------------ */
285
286         FUNC_START aeabi_idiv0
287         bx      lr
288         FUNC_END aeabi_idiv0
289
290         FUNC_START divsi3
291         FUNC_ALIAS aeabi_idiv divsi3
292
293 LSYM(divsi3_skip_div0_test):
294         mov     curbit, dividend
295         orrs    curbit, divisor
296         bmi     LSYM(Lthumb1_div_negative)
297
298 LSYM(Lthumb1_div_positive):
299         THUMB1_Div_Positive
300
301 LSYM(Lthumb1_div_negative):
302         THUMB1_Div_Negative
303
304         DIV_FUNC_END divsi3 signed
305
306         FUNC_START aeabi_idivmod
307
308         cmp     r1, #0
309         beq     LSYM(Ldiv0)
310         push    {r0, r1, lr}
311         bl      LSYM(divsi3_skip_div0_test)
312         POP     {r1, r2, r3}
313         mul     r2, r0
314         sub     r1, r1, r2
315         bx      r3
316
317         FUNC_END aeabi_idivmod
318 /* ------------------------------------------------------------------------ */