2 * Copyright (c) 2014 ARM Ltd
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
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.
29 /* An executable stack is *not* required for these functions. */
31 .section .note.GNU-stack,"",%progbits
35 /* ANSI concatenation macros. */
37 #define CONCAT1(a, b) CONCAT2(a, b)
38 #define CONCAT2(a, b) a ## b
40 /* Use the right prefix for global labels. */
42 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
44 #define TYPE(x) .type SYM(x),function
45 #define SIZE(x) .size SYM(x), . - SYM(x)
48 .macro cfi_start start_label, end_label
49 .pushsection .debug_frame
51 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie)
65 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde)
67 .4byte LSYM(Lstart_frame)
69 .4byte \end_label-\start_label
73 .macro cfi_end end_label
74 .pushsection .debug_frame
81 .macro THUMB_LDIV0 name signed
92 .macro DIV_FUNC_END name signed
93 cfi_start __\name, LSYM(Lend_div0)
95 THUMB_LDIV0 \name \signed
96 cfi_end LSYM(Lend_div0)
100 .macro THUMB_FUNC_START name
107 .macro FUNC_START name
118 .macro FUNC_ALIAS new old
120 .thumb_set SYM (__\new), SYM (__\old)
123 /* Register aliases. */
131 /* ------------------------------------------------------------------------ */
132 /* Bodies of the division and modulo routines. */
133 /* ------------------------------------------------------------------------ */
134 .macro BranchToDiv n, label
135 lsrs curbit, dividend, \n
141 lsrs curbit, dividend, \n
144 lsls curbit, divisor, \n
145 subs dividend, dividend, curbit
147 1: adcs result, result
150 .macro THUMB1_Div_Positive
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):
159 lsls divisor, divisor, #8
161 lsrs curbit, dividend, #16
165 lsls divisor, divisor, #8
166 beq LSYM(Ldivbyzero_waypoint)
168 1: lsrs curbit, dividend, #12
170 bcc LSYM(Lthumb1_div12)
171 b LSYM(Lthumb1_div16)
172 LSYM(Lthumb1_div_loop):
173 lsrs divisor, divisor, #8
184 bcs LSYM(Lthumb1_div_loop)
198 subs divisor, dividend, divisor
200 mov divisor, dividend
202 1: adcs result, result
206 LSYM(Ldivbyzero_waypoint):
210 .macro THUMB1_Div_Negative
211 lsrs result, divisor, #31
213 rsbs divisor, divisor, #0
215 1: asrs curbit, dividend, #32
217 rsbs dividend, dividend, #0
219 2: eors curbit, result
222 BranchToDiv #4, LSYM(Lthumb1_div_negative4)
223 BranchToDiv #8, LSYM(Lthumb1_div_negative8)
224 LSYM(Lthumb1_div_large):
226 lsls divisor, divisor, #6
228 lsrs curbit, dividend, #8
230 bcc LSYM(Lthumb1_div_negative8)
232 lsls divisor, divisor, #6
233 asrs result, result, #6
235 bcc LSYM(Lthumb1_div_negative8)
237 lsls divisor, divisor, #6
238 asrs result, result, #6
240 bcc LSYM(Lthumb1_div_negative8)
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):
253 LSYM(Lthumb1_div_negative4):
256 bcs LSYM(Lthumb1_div_negative_loop)
258 subs divisor, dividend, divisor
260 mov divisor, dividend
264 asrs curbit, curbit, #1
267 rsbs dividend, dividend, #0
271 rsbs divisor, divisor, #0
275 LSYM(Ldivbyzero_negative):
277 asrs curbit, curbit, #1
279 rsbs dividend, dividend, #0
282 /* ------------------------------------------------------------------------ */
283 /* Start of the Real Functions */
284 /* ------------------------------------------------------------------------ */
286 FUNC_START aeabi_idiv0
291 FUNC_ALIAS aeabi_idiv divsi3
293 LSYM(divsi3_skip_div0_test):
296 bmi LSYM(Lthumb1_div_negative)
298 LSYM(Lthumb1_div_positive):
301 LSYM(Lthumb1_div_negative):
304 DIV_FUNC_END divsi3 signed
306 FUNC_START aeabi_idivmod
311 bl LSYM(divsi3_skip_div0_test)
317 FUNC_END aeabi_idivmod
318 /* ------------------------------------------------------------------------ */