lib1funcs.S revision 1.8 1 1.1 mrg @ libgcc routines for ARM cpu.
2 1.1 mrg @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
3 1.1 mrg
4 1.8 mrg /* Copyright (C) 1995-2019 Free Software Foundation, Inc.
5 1.1 mrg
6 1.1 mrg This file is free software; you can redistribute it and/or modify it
7 1.1 mrg under the terms of the GNU General Public License as published by the
8 1.1 mrg Free Software Foundation; either version 3, or (at your option) any
9 1.1 mrg later version.
10 1.1 mrg
11 1.1 mrg This file is distributed in the hope that it will be useful, but
12 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 1.1 mrg General Public License for more details.
15 1.1 mrg
16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
17 1.1 mrg permissions described in the GCC Runtime Library Exception, version
18 1.1 mrg 3.1, as published by the Free Software Foundation.
19 1.1 mrg
20 1.1 mrg You should have received a copy of the GNU General Public License and
21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.1 mrg <http://www.gnu.org/licenses/>. */
24 1.1 mrg
25 1.1 mrg /* An executable stack is *not* required for these functions. */
26 1.1 mrg #if defined(__ELF__) && defined(__linux__)
27 1.1 mrg .section .note.GNU-stack,"",%progbits
28 1.1 mrg .previous
29 1.1 mrg #endif /* __ELF__ and __linux__ */
30 1.1 mrg
31 1.1 mrg #ifdef __ARM_EABI__
32 1.1 mrg /* Some attributes that are common to all routines in this file. */
33 1.1 mrg /* Tag_ABI_align_needed: This code does not require 8-byte
34 1.1 mrg alignment from the caller. */
35 1.1 mrg /* .eabi_attribute 24, 0 -- default setting. */
36 1.1 mrg /* Tag_ABI_align_preserved: This code preserves 8-byte
37 1.1 mrg alignment in any callee. */
38 1.1 mrg .eabi_attribute 25, 1
39 1.1 mrg #endif /* __ARM_EABI__ */
40 1.1 mrg /* ------------------------------------------------------------------------ */
41 1.1 mrg
42 1.1 mrg /* We need to know what prefix to add to function names. */
43 1.1 mrg
44 1.1 mrg #ifndef __USER_LABEL_PREFIX__
45 1.1 mrg #error __USER_LABEL_PREFIX__ not defined
46 1.1 mrg #endif
47 1.1 mrg
48 1.1 mrg /* ANSI concatenation macros. */
49 1.1 mrg
50 1.1 mrg #define CONCAT1(a, b) CONCAT2(a, b)
51 1.1 mrg #define CONCAT2(a, b) a ## b
52 1.1 mrg
53 1.1 mrg /* Use the right prefix for global labels. */
54 1.1 mrg
55 1.1 mrg #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
56 1.1 mrg
57 1.1 mrg #ifdef __ELF__
58 1.1 mrg #ifdef __thumb__
59 1.1 mrg #define __PLT__ /* Not supported in Thumb assembler (for now). */
60 1.1 mrg #elif defined __vxworks && !defined __PIC__
61 1.1 mrg #define __PLT__ /* Not supported by the kernel loader. */
62 1.1 mrg #else
63 1.1 mrg #define __PLT__ (PLT)
64 1.1 mrg #endif
65 1.1 mrg #define TYPE(x) .type SYM(x),function
66 1.1 mrg #define SIZE(x) .size SYM(x), . - SYM(x)
67 1.1 mrg #define LSYM(x) .x
68 1.1 mrg #else
69 1.1 mrg #define __PLT__
70 1.1 mrg #define TYPE(x)
71 1.1 mrg #define SIZE(x)
72 1.1 mrg #define LSYM(x) x
73 1.1 mrg #endif
74 1.1 mrg
75 1.1 mrg /* Function end macros. Variants for interworking. */
76 1.1 mrg
77 1.1 mrg /* There are times when we might prefer Thumb1 code even if ARM code is
78 1.1 mrg permitted, for example, the code might be smaller, or there might be
79 1.1 mrg interworking problems with switching to ARM state if interworking is
80 1.1 mrg disabled. */
81 1.1 mrg #if (defined(__thumb__) \
82 1.1 mrg && !defined(__thumb2__) \
83 1.1 mrg && (!defined(__THUMB_INTERWORK__) \
84 1.1 mrg || defined (__OPTIMIZE_SIZE__) \
85 1.6 mrg || !__ARM_ARCH_ISA_ARM))
86 1.1 mrg # define __prefer_thumb__
87 1.1 mrg #endif
88 1.1 mrg
89 1.6 mrg #if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1
90 1.6 mrg #define NOT_ISA_TARGET_32BIT 1
91 1.6 mrg #endif
92 1.6 mrg
93 1.1 mrg /* How to return from a function call depends on the architecture variant. */
94 1.1 mrg
95 1.8 mrg #if (__ARM_ARCH > 4) || defined(__ARM_ARCH_4T__)
96 1.1 mrg
97 1.1 mrg # define RET bx lr
98 1.1 mrg # define RETc(x) bx##x lr
99 1.1 mrg
100 1.1 mrg /* Special precautions for interworking on armv4t. */
101 1.8 mrg # if (__ARM_ARCH == 4)
102 1.1 mrg
103 1.1 mrg /* Always use bx, not ldr pc. */
104 1.1 mrg # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
105 1.1 mrg # define __INTERWORKING__
106 1.1 mrg # endif /* __THUMB__ || __THUMB_INTERWORK__ */
107 1.1 mrg
108 1.1 mrg /* Include thumb stub before arm mode code. */
109 1.1 mrg # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
110 1.1 mrg # define __INTERWORKING_STUBS__
111 1.1 mrg # endif /* __thumb__ && !__THUMB_INTERWORK__ */
112 1.1 mrg
113 1.1 mrg #endif /* __ARM_ARCH == 4 */
114 1.1 mrg
115 1.1 mrg #else
116 1.1 mrg
117 1.1 mrg # define RET mov pc, lr
118 1.1 mrg # define RETc(x) mov##x pc, lr
119 1.1 mrg
120 1.1 mrg #endif
121 1.1 mrg
122 1.1 mrg .macro cfi_pop advance, reg, cfa_offset
123 1.1 mrg #ifdef __ELF__
124 1.1 mrg .pushsection .debug_frame
125 1.1 mrg .byte 0x4 /* DW_CFA_advance_loc4 */
126 1.1 mrg .4byte \advance
127 1.1 mrg .byte (0xc0 | \reg) /* DW_CFA_restore */
128 1.1 mrg .byte 0xe /* DW_CFA_def_cfa_offset */
129 1.1 mrg .uleb128 \cfa_offset
130 1.1 mrg .popsection
131 1.1 mrg #endif
132 1.1 mrg .endm
133 1.1 mrg .macro cfi_push advance, reg, offset, cfa_offset
134 1.1 mrg #ifdef __ELF__
135 1.1 mrg .pushsection .debug_frame
136 1.1 mrg .byte 0x4 /* DW_CFA_advance_loc4 */
137 1.1 mrg .4byte \advance
138 1.1 mrg .byte (0x80 | \reg) /* DW_CFA_offset */
139 1.1 mrg .uleb128 (\offset / -4)
140 1.1 mrg .byte 0xe /* DW_CFA_def_cfa_offset */
141 1.1 mrg .uleb128 \cfa_offset
142 1.1 mrg .popsection
143 1.1 mrg #endif
144 1.1 mrg .endm
145 1.1 mrg .macro cfi_start start_label, end_label
146 1.1 mrg #ifdef __ELF__
147 1.1 mrg .pushsection .debug_frame
148 1.1 mrg LSYM(Lstart_frame):
149 1.1 mrg .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
150 1.1 mrg LSYM(Lstart_cie):
151 1.1 mrg .4byte 0xffffffff @ CIE Identifier Tag
152 1.1 mrg .byte 0x1 @ CIE Version
153 1.1 mrg .ascii "\0" @ CIE Augmentation
154 1.1 mrg .uleb128 0x1 @ CIE Code Alignment Factor
155 1.1 mrg .sleb128 -4 @ CIE Data Alignment Factor
156 1.1 mrg .byte 0xe @ CIE RA Column
157 1.1 mrg .byte 0xc @ DW_CFA_def_cfa
158 1.1 mrg .uleb128 0xd
159 1.1 mrg .uleb128 0x0
160 1.1 mrg
161 1.1 mrg .align 2
162 1.1 mrg LSYM(Lend_cie):
163 1.1 mrg .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
164 1.1 mrg LSYM(Lstart_fde):
165 1.1 mrg .4byte LSYM(Lstart_frame) @ FDE CIE offset
166 1.1 mrg .4byte \start_label @ FDE initial location
167 1.1 mrg .4byte \end_label-\start_label @ FDE address range
168 1.1 mrg .popsection
169 1.1 mrg #endif
170 1.1 mrg .endm
171 1.1 mrg .macro cfi_end end_label
172 1.1 mrg #ifdef __ELF__
173 1.1 mrg .pushsection .debug_frame
174 1.1 mrg .align 2
175 1.1 mrg LSYM(Lend_fde):
176 1.1 mrg .popsection
177 1.1 mrg \end_label:
178 1.1 mrg #endif
179 1.1 mrg .endm
180 1.1 mrg
181 1.1 mrg /* Don't pass dirn, it's there just to get token pasting right. */
182 1.1 mrg
183 1.1 mrg .macro RETLDM regs=, cond=, unwind=, dirn=ia
184 1.1 mrg #if defined (__INTERWORKING__)
185 1.1 mrg .ifc "\regs",""
186 1.1 mrg ldr\cond lr, [sp], #8
187 1.1 mrg .else
188 1.1 mrg # if defined(__thumb2__)
189 1.1 mrg pop\cond {\regs, lr}
190 1.1 mrg # else
191 1.1 mrg ldm\cond\dirn sp!, {\regs, lr}
192 1.1 mrg # endif
193 1.1 mrg .endif
194 1.1 mrg .ifnc "\unwind", ""
195 1.1 mrg /* Mark LR as restored. */
196 1.1 mrg 97: cfi_pop 97b - \unwind, 0xe, 0x0
197 1.1 mrg .endif
198 1.1 mrg bx\cond lr
199 1.1 mrg #else
200 1.1 mrg /* Caller is responsible for providing IT instruction. */
201 1.1 mrg .ifc "\regs",""
202 1.1 mrg ldr\cond pc, [sp], #8
203 1.1 mrg .else
204 1.1 mrg # if defined(__thumb2__)
205 1.1 mrg pop\cond {\regs, pc}
206 1.1 mrg # else
207 1.1 mrg ldm\cond\dirn sp!, {\regs, pc}
208 1.1 mrg # endif
209 1.1 mrg .endif
210 1.1 mrg #endif
211 1.1 mrg .endm
212 1.1 mrg
213 1.1 mrg /* The Unified assembly syntax allows the same code to be assembled for both
214 1.1 mrg ARM and Thumb-2. However this is only supported by recent gas, so define
215 1.1 mrg a set of macros to allow ARM code on older assemblers. */
216 1.1 mrg #if defined(__thumb2__)
217 1.1 mrg .macro do_it cond, suffix=""
218 1.1 mrg it\suffix \cond
219 1.1 mrg .endm
220 1.1 mrg .macro shift1 op, arg0, arg1, arg2
221 1.1 mrg \op \arg0, \arg1, \arg2
222 1.1 mrg .endm
223 1.1 mrg #define do_push push
224 1.1 mrg #define do_pop pop
225 1.1 mrg #define COND(op1, op2, cond) op1 ## op2 ## cond
226 1.1 mrg /* Perform an arithmetic operation with a variable shift operand. This
227 1.1 mrg requires two instructions and a scratch register on Thumb-2. */
228 1.1 mrg .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
229 1.1 mrg \shiftop \tmp, \src2, \shiftreg
230 1.1 mrg \name \dest, \src1, \tmp
231 1.1 mrg .endm
232 1.1 mrg #else
233 1.1 mrg .macro do_it cond, suffix=""
234 1.1 mrg .endm
235 1.1 mrg .macro shift1 op, arg0, arg1, arg2
236 1.1 mrg mov \arg0, \arg1, \op \arg2
237 1.1 mrg .endm
238 1.1 mrg #define do_push stmfd sp!,
239 1.1 mrg #define do_pop ldmfd sp!,
240 1.1 mrg #define COND(op1, op2, cond) op1 ## cond ## op2
241 1.1 mrg .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
242 1.1 mrg \name \dest, \src1, \src2, \shiftop \shiftreg
243 1.1 mrg .endm
244 1.1 mrg #endif
245 1.1 mrg
246 1.1 mrg #ifdef __ARM_EABI__
247 1.1 mrg .macro ARM_LDIV0 name signed
248 1.1 mrg cmp r0, #0
249 1.1 mrg .ifc \signed, unsigned
250 1.1 mrg movne r0, #0xffffffff
251 1.1 mrg .else
252 1.1 mrg movgt r0, #0x7fffffff
253 1.1 mrg movlt r0, #0x80000000
254 1.1 mrg .endif
255 1.1 mrg b SYM (__aeabi_idiv0) __PLT__
256 1.1 mrg .endm
257 1.1 mrg #else
258 1.1 mrg .macro ARM_LDIV0 name signed
259 1.1 mrg str lr, [sp, #-8]!
260 1.1 mrg 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
261 1.1 mrg bl SYM (__div0) __PLT__
262 1.1 mrg mov r0, #0 @ About as wrong as it could be.
263 1.1 mrg RETLDM unwind=98b
264 1.1 mrg .endm
265 1.1 mrg #endif
266 1.1 mrg
267 1.1 mrg
268 1.1 mrg #ifdef __ARM_EABI__
269 1.1 mrg .macro THUMB_LDIV0 name signed
270 1.6 mrg #ifdef NOT_ISA_TARGET_32BIT
271 1.6 mrg
272 1.6 mrg push {r0, lr}
273 1.1 mrg mov r0, #0
274 1.6 mrg bl SYM(__aeabi_idiv0)
275 1.1 mrg @ We know we are not on armv4t, so pop pc is safe.
276 1.6 mrg pop {r1, pc}
277 1.6 mrg
278 1.1 mrg #elif defined(__thumb2__)
279 1.1 mrg .syntax unified
280 1.1 mrg .ifc \signed, unsigned
281 1.1 mrg cbz r0, 1f
282 1.1 mrg mov r0, #0xffffffff
283 1.1 mrg 1:
284 1.1 mrg .else
285 1.1 mrg cmp r0, #0
286 1.1 mrg do_it gt
287 1.1 mrg movgt r0, #0x7fffffff
288 1.1 mrg do_it lt
289 1.1 mrg movlt r0, #0x80000000
290 1.1 mrg .endif
291 1.1 mrg b.w SYM(__aeabi_idiv0) __PLT__
292 1.1 mrg #else
293 1.1 mrg .align 2
294 1.1 mrg bx pc
295 1.1 mrg nop
296 1.1 mrg .arm
297 1.1 mrg cmp r0, #0
298 1.1 mrg .ifc \signed, unsigned
299 1.1 mrg movne r0, #0xffffffff
300 1.1 mrg .else
301 1.1 mrg movgt r0, #0x7fffffff
302 1.1 mrg movlt r0, #0x80000000
303 1.1 mrg .endif
304 1.1 mrg b SYM(__aeabi_idiv0) __PLT__
305 1.1 mrg .thumb
306 1.1 mrg #endif
307 1.1 mrg .endm
308 1.1 mrg #else
309 1.1 mrg .macro THUMB_LDIV0 name signed
310 1.1 mrg push { r1, lr }
311 1.1 mrg 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
312 1.1 mrg bl SYM (__div0)
313 1.1 mrg mov r0, #0 @ About as wrong as it could be.
314 1.1 mrg #if defined (__INTERWORKING__)
315 1.1 mrg pop { r1, r2 }
316 1.1 mrg bx r2
317 1.1 mrg #else
318 1.1 mrg pop { r1, pc }
319 1.1 mrg #endif
320 1.1 mrg .endm
321 1.1 mrg #endif
322 1.1 mrg
323 1.1 mrg .macro FUNC_END name
324 1.1 mrg SIZE (__\name)
325 1.1 mrg .endm
326 1.1 mrg
327 1.1 mrg .macro DIV_FUNC_END name signed
328 1.1 mrg cfi_start __\name, LSYM(Lend_div0)
329 1.1 mrg LSYM(Ldiv0):
330 1.1 mrg #ifdef __thumb__
331 1.1 mrg THUMB_LDIV0 \name \signed
332 1.1 mrg #else
333 1.1 mrg ARM_LDIV0 \name \signed
334 1.1 mrg #endif
335 1.1 mrg cfi_end LSYM(Lend_div0)
336 1.1 mrg FUNC_END \name
337 1.1 mrg .endm
338 1.1 mrg
339 1.1 mrg .macro THUMB_FUNC_START name
340 1.1 mrg .globl SYM (\name)
341 1.1 mrg TYPE (\name)
342 1.1 mrg .thumb_func
343 1.1 mrg SYM (\name):
344 1.1 mrg .endm
345 1.1 mrg
346 1.1 mrg /* Function start macros. Variants for ARM and Thumb. */
347 1.1 mrg
348 1.1 mrg #ifdef __thumb__
349 1.1 mrg #define THUMB_FUNC .thumb_func
350 1.1 mrg #define THUMB_CODE .force_thumb
351 1.1 mrg # if defined(__thumb2__)
352 1.1 mrg #define THUMB_SYNTAX .syntax divided
353 1.1 mrg # else
354 1.1 mrg #define THUMB_SYNTAX
355 1.1 mrg # endif
356 1.1 mrg #else
357 1.1 mrg #define THUMB_FUNC
358 1.1 mrg #define THUMB_CODE
359 1.1 mrg #define THUMB_SYNTAX
360 1.1 mrg #endif
361 1.1 mrg
362 1.8 mrg .macro FUNC_START name
363 1.1 mrg .text
364 1.1 mrg .globl SYM (__\name)
365 1.1 mrg TYPE (__\name)
366 1.1 mrg .align 0
367 1.1 mrg THUMB_CODE
368 1.1 mrg THUMB_FUNC
369 1.1 mrg THUMB_SYNTAX
370 1.1 mrg SYM (__\name):
371 1.1 mrg .endm
372 1.1 mrg
373 1.3 mrg .macro ARM_SYM_START name
374 1.3 mrg TYPE (\name)
375 1.3 mrg .align 0
376 1.3 mrg SYM (\name):
377 1.3 mrg .endm
378 1.3 mrg
379 1.3 mrg .macro SYM_END name
380 1.3 mrg SIZE (\name)
381 1.3 mrg .endm
382 1.3 mrg
383 1.1 mrg /* Special function that will always be coded in ARM assembly, even if
384 1.1 mrg in Thumb-only compilation. */
385 1.1 mrg
386 1.1 mrg #if defined(__thumb2__)
387 1.1 mrg
388 1.1 mrg /* For Thumb-2 we build everything in thumb mode. */
389 1.8 mrg .macro ARM_FUNC_START name
390 1.8 mrg FUNC_START \name
391 1.1 mrg .syntax unified
392 1.1 mrg .endm
393 1.1 mrg #define EQUIV .thumb_set
394 1.1 mrg .macro ARM_CALL name
395 1.1 mrg bl __\name
396 1.1 mrg .endm
397 1.1 mrg
398 1.1 mrg #elif defined(__INTERWORKING_STUBS__)
399 1.1 mrg
400 1.1 mrg .macro ARM_FUNC_START name
401 1.1 mrg FUNC_START \name
402 1.1 mrg bx pc
403 1.1 mrg nop
404 1.1 mrg .arm
405 1.1 mrg /* A hook to tell gdb that we've switched to ARM mode. Also used to call
406 1.1 mrg directly from other local arm routines. */
407 1.1 mrg _L__\name:
408 1.1 mrg .endm
409 1.1 mrg #define EQUIV .thumb_set
410 1.1 mrg /* Branch directly to a function declared with ARM_FUNC_START.
411 1.1 mrg Must be called in arm mode. */
412 1.1 mrg .macro ARM_CALL name
413 1.1 mrg bl _L__\name
414 1.1 mrg .endm
415 1.1 mrg
416 1.1 mrg #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
417 1.1 mrg
418 1.6 mrg #ifdef NOT_ISA_TARGET_32BIT
419 1.1 mrg #define EQUIV .thumb_set
420 1.1 mrg #else
421 1.8 mrg .macro ARM_FUNC_START name
422 1.1 mrg .text
423 1.1 mrg .globl SYM (__\name)
424 1.1 mrg TYPE (__\name)
425 1.1 mrg .align 0
426 1.1 mrg .arm
427 1.1 mrg SYM (__\name):
428 1.1 mrg .endm
429 1.1 mrg #define EQUIV .set
430 1.1 mrg .macro ARM_CALL name
431 1.1 mrg bl __\name
432 1.1 mrg .endm
433 1.1 mrg #endif
434 1.1 mrg
435 1.1 mrg #endif
436 1.1 mrg
437 1.1 mrg .macro FUNC_ALIAS new old
438 1.1 mrg .globl SYM (__\new)
439 1.1 mrg #if defined (__thumb__)
440 1.1 mrg .thumb_set SYM (__\new), SYM (__\old)
441 1.1 mrg #else
442 1.1 mrg .set SYM (__\new), SYM (__\old)
443 1.1 mrg #endif
444 1.1 mrg .endm
445 1.1 mrg
446 1.6 mrg #ifndef NOT_ISA_TARGET_32BIT
447 1.1 mrg .macro ARM_FUNC_ALIAS new old
448 1.1 mrg .globl SYM (__\new)
449 1.1 mrg EQUIV SYM (__\new), SYM (__\old)
450 1.1 mrg #if defined(__INTERWORKING_STUBS__)
451 1.1 mrg .set SYM (_L__\new), SYM (_L__\old)
452 1.1 mrg #endif
453 1.1 mrg .endm
454 1.1 mrg #endif
455 1.1 mrg
456 1.1 mrg #ifdef __ARMEB__
457 1.1 mrg #define xxh r0
458 1.1 mrg #define xxl r1
459 1.1 mrg #define yyh r2
460 1.1 mrg #define yyl r3
461 1.1 mrg #else
462 1.1 mrg #define xxh r1
463 1.1 mrg #define xxl r0
464 1.1 mrg #define yyh r3
465 1.1 mrg #define yyl r2
466 1.1 mrg #endif
467 1.1 mrg
468 1.1 mrg #ifdef __ARM_EABI__
469 1.1 mrg .macro WEAK name
470 1.1 mrg .weak SYM (__\name)
471 1.1 mrg .endm
472 1.1 mrg #endif
473 1.1 mrg
474 1.1 mrg #ifdef __thumb__
475 1.1 mrg /* Register aliases. */
476 1.1 mrg
477 1.1 mrg work .req r4 @ XXXX is this safe ?
478 1.1 mrg dividend .req r0
479 1.1 mrg divisor .req r1
480 1.1 mrg overdone .req r2
481 1.1 mrg result .req r2
482 1.1 mrg curbit .req r3
483 1.1 mrg #endif
484 1.1 mrg #if 0
485 1.1 mrg ip .req r12
486 1.1 mrg sp .req r13
487 1.1 mrg lr .req r14
488 1.1 mrg pc .req r15
489 1.1 mrg #endif
490 1.1 mrg
491 1.1 mrg /* ------------------------------------------------------------------------ */
492 1.1 mrg /* Bodies of the division and modulo routines. */
493 1.1 mrg /* ------------------------------------------------------------------------ */
494 1.1 mrg .macro ARM_DIV_BODY dividend, divisor, result, curbit
495 1.1 mrg
496 1.8 mrg #if defined (__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__)
497 1.1 mrg
498 1.1 mrg #if defined (__thumb2__)
499 1.1 mrg clz \curbit, \dividend
500 1.1 mrg clz \result, \divisor
501 1.1 mrg sub \curbit, \result, \curbit
502 1.1 mrg rsb \curbit, \curbit, #31
503 1.1 mrg adr \result, 1f
504 1.1 mrg add \curbit, \result, \curbit, lsl #4
505 1.1 mrg mov \result, #0
506 1.1 mrg mov pc, \curbit
507 1.1 mrg .p2align 3
508 1.1 mrg 1:
509 1.1 mrg .set shift, 32
510 1.1 mrg .rept 32
511 1.1 mrg .set shift, shift - 1
512 1.1 mrg cmp.w \dividend, \divisor, lsl #shift
513 1.1 mrg nop.n
514 1.1 mrg adc.w \result, \result, \result
515 1.1 mrg it cs
516 1.1 mrg subcs.w \dividend, \dividend, \divisor, lsl #shift
517 1.1 mrg .endr
518 1.1 mrg #else
519 1.1 mrg clz \curbit, \dividend
520 1.1 mrg clz \result, \divisor
521 1.1 mrg sub \curbit, \result, \curbit
522 1.1 mrg rsbs \curbit, \curbit, #31
523 1.1 mrg addne \curbit, \curbit, \curbit, lsl #1
524 1.1 mrg mov \result, #0
525 1.1 mrg addne pc, pc, \curbit, lsl #2
526 1.1 mrg nop
527 1.1 mrg .set shift, 32
528 1.1 mrg .rept 32
529 1.1 mrg .set shift, shift - 1
530 1.1 mrg cmp \dividend, \divisor, lsl #shift
531 1.1 mrg adc \result, \result, \result
532 1.1 mrg subcs \dividend, \dividend, \divisor, lsl #shift
533 1.1 mrg .endr
534 1.1 mrg #endif
535 1.1 mrg
536 1.8 mrg #else /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
537 1.8 mrg #if defined (__ARM_FEATURE_CLZ)
538 1.1 mrg
539 1.1 mrg clz \curbit, \divisor
540 1.1 mrg clz \result, \dividend
541 1.1 mrg sub \result, \curbit, \result
542 1.1 mrg mov \curbit, #1
543 1.1 mrg mov \divisor, \divisor, lsl \result
544 1.1 mrg mov \curbit, \curbit, lsl \result
545 1.1 mrg mov \result, #0
546 1.1 mrg
547 1.8 mrg #else /* !defined (__ARM_FEATURE_CLZ) */
548 1.1 mrg
549 1.1 mrg @ Initially shift the divisor left 3 bits if possible,
550 1.1 mrg @ set curbit accordingly. This allows for curbit to be located
551 1.1 mrg @ at the left end of each 4-bit nibbles in the division loop
552 1.1 mrg @ to save one loop in most cases.
553 1.1 mrg tst \divisor, #0xe0000000
554 1.1 mrg moveq \divisor, \divisor, lsl #3
555 1.1 mrg moveq \curbit, #8
556 1.1 mrg movne \curbit, #1
557 1.1 mrg
558 1.1 mrg @ Unless the divisor is very big, shift it up in multiples of
559 1.1 mrg @ four bits, since this is the amount of unwinding in the main
560 1.1 mrg @ division loop. Continue shifting until the divisor is
561 1.1 mrg @ larger than the dividend.
562 1.1 mrg 1: cmp \divisor, #0x10000000
563 1.1 mrg cmplo \divisor, \dividend
564 1.1 mrg movlo \divisor, \divisor, lsl #4
565 1.1 mrg movlo \curbit, \curbit, lsl #4
566 1.1 mrg blo 1b
567 1.1 mrg
568 1.1 mrg @ For very big divisors, we must shift it a bit at a time, or
569 1.1 mrg @ we will be in danger of overflowing.
570 1.1 mrg 1: cmp \divisor, #0x80000000
571 1.1 mrg cmplo \divisor, \dividend
572 1.1 mrg movlo \divisor, \divisor, lsl #1
573 1.1 mrg movlo \curbit, \curbit, lsl #1
574 1.1 mrg blo 1b
575 1.1 mrg
576 1.1 mrg mov \result, #0
577 1.1 mrg
578 1.8 mrg #endif /* !defined (__ARM_FEATURE_CLZ) */
579 1.1 mrg
580 1.1 mrg @ Division loop
581 1.1 mrg 1: cmp \dividend, \divisor
582 1.1 mrg do_it hs, t
583 1.1 mrg subhs \dividend, \dividend, \divisor
584 1.1 mrg orrhs \result, \result, \curbit
585 1.1 mrg cmp \dividend, \divisor, lsr #1
586 1.1 mrg do_it hs, t
587 1.1 mrg subhs \dividend, \dividend, \divisor, lsr #1
588 1.1 mrg orrhs \result, \result, \curbit, lsr #1
589 1.1 mrg cmp \dividend, \divisor, lsr #2
590 1.1 mrg do_it hs, t
591 1.1 mrg subhs \dividend, \dividend, \divisor, lsr #2
592 1.1 mrg orrhs \result, \result, \curbit, lsr #2
593 1.1 mrg cmp \dividend, \divisor, lsr #3
594 1.1 mrg do_it hs, t
595 1.1 mrg subhs \dividend, \dividend, \divisor, lsr #3
596 1.1 mrg orrhs \result, \result, \curbit, lsr #3
597 1.1 mrg cmp \dividend, #0 @ Early termination?
598 1.1 mrg do_it ne, t
599 1.1 mrg movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
600 1.1 mrg movne \divisor, \divisor, lsr #4
601 1.1 mrg bne 1b
602 1.1 mrg
603 1.8 mrg #endif /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
604 1.1 mrg
605 1.1 mrg .endm
606 1.1 mrg /* ------------------------------------------------------------------------ */
607 1.1 mrg .macro ARM_DIV2_ORDER divisor, order
608 1.1 mrg
609 1.8 mrg #if defined (__ARM_FEATURE_CLZ)
610 1.1 mrg
611 1.1 mrg clz \order, \divisor
612 1.1 mrg rsb \order, \order, #31
613 1.1 mrg
614 1.1 mrg #else
615 1.1 mrg
616 1.1 mrg cmp \divisor, #(1 << 16)
617 1.1 mrg movhs \divisor, \divisor, lsr #16
618 1.1 mrg movhs \order, #16
619 1.1 mrg movlo \order, #0
620 1.1 mrg
621 1.1 mrg cmp \divisor, #(1 << 8)
622 1.1 mrg movhs \divisor, \divisor, lsr #8
623 1.1 mrg addhs \order, \order, #8
624 1.1 mrg
625 1.1 mrg cmp \divisor, #(1 << 4)
626 1.1 mrg movhs \divisor, \divisor, lsr #4
627 1.1 mrg addhs \order, \order, #4
628 1.1 mrg
629 1.1 mrg cmp \divisor, #(1 << 2)
630 1.1 mrg addhi \order, \order, #3
631 1.1 mrg addls \order, \order, \divisor, lsr #1
632 1.1 mrg
633 1.1 mrg #endif
634 1.1 mrg
635 1.1 mrg .endm
636 1.1 mrg /* ------------------------------------------------------------------------ */
637 1.1 mrg .macro ARM_MOD_BODY dividend, divisor, order, spare
638 1.1 mrg
639 1.8 mrg #if defined(__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__)
640 1.1 mrg
641 1.1 mrg clz \order, \divisor
642 1.1 mrg clz \spare, \dividend
643 1.1 mrg sub \order, \order, \spare
644 1.1 mrg rsbs \order, \order, #31
645 1.1 mrg addne pc, pc, \order, lsl #3
646 1.1 mrg nop
647 1.1 mrg .set shift, 32
648 1.1 mrg .rept 32
649 1.1 mrg .set shift, shift - 1
650 1.1 mrg cmp \dividend, \divisor, lsl #shift
651 1.1 mrg subcs \dividend, \dividend, \divisor, lsl #shift
652 1.1 mrg .endr
653 1.1 mrg
654 1.8 mrg #else /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
655 1.8 mrg #if defined (__ARM_FEATURE_CLZ)
656 1.1 mrg
657 1.1 mrg clz \order, \divisor
658 1.1 mrg clz \spare, \dividend
659 1.1 mrg sub \order, \order, \spare
660 1.1 mrg mov \divisor, \divisor, lsl \order
661 1.1 mrg
662 1.8 mrg #else /* !defined (__ARM_FEATURE_CLZ) */
663 1.1 mrg
664 1.1 mrg mov \order, #0
665 1.1 mrg
666 1.1 mrg @ Unless the divisor is very big, shift it up in multiples of
667 1.1 mrg @ four bits, since this is the amount of unwinding in the main
668 1.1 mrg @ division loop. Continue shifting until the divisor is
669 1.1 mrg @ larger than the dividend.
670 1.1 mrg 1: cmp \divisor, #0x10000000
671 1.1 mrg cmplo \divisor, \dividend
672 1.1 mrg movlo \divisor, \divisor, lsl #4
673 1.1 mrg addlo \order, \order, #4
674 1.1 mrg blo 1b
675 1.1 mrg
676 1.1 mrg @ For very big divisors, we must shift it a bit at a time, or
677 1.1 mrg @ we will be in danger of overflowing.
678 1.1 mrg 1: cmp \divisor, #0x80000000
679 1.1 mrg cmplo \divisor, \dividend
680 1.1 mrg movlo \divisor, \divisor, lsl #1
681 1.1 mrg addlo \order, \order, #1
682 1.1 mrg blo 1b
683 1.1 mrg
684 1.8 mrg #endif /* !defined (__ARM_FEATURE_CLZ) */
685 1.1 mrg
686 1.1 mrg @ Perform all needed substractions to keep only the reminder.
687 1.1 mrg @ Do comparisons in batch of 4 first.
688 1.1 mrg subs \order, \order, #3 @ yes, 3 is intended here
689 1.1 mrg blt 2f
690 1.1 mrg
691 1.1 mrg 1: cmp \dividend, \divisor
692 1.1 mrg subhs \dividend, \dividend, \divisor
693 1.1 mrg cmp \dividend, \divisor, lsr #1
694 1.1 mrg subhs \dividend, \dividend, \divisor, lsr #1
695 1.1 mrg cmp \dividend, \divisor, lsr #2
696 1.1 mrg subhs \dividend, \dividend, \divisor, lsr #2
697 1.1 mrg cmp \dividend, \divisor, lsr #3
698 1.1 mrg subhs \dividend, \dividend, \divisor, lsr #3
699 1.1 mrg cmp \dividend, #1
700 1.1 mrg mov \divisor, \divisor, lsr #4
701 1.1 mrg subges \order, \order, #4
702 1.1 mrg bge 1b
703 1.1 mrg
704 1.1 mrg tst \order, #3
705 1.1 mrg teqne \dividend, #0
706 1.1 mrg beq 5f
707 1.1 mrg
708 1.1 mrg @ Either 1, 2 or 3 comparison/substractions are left.
709 1.1 mrg 2: cmn \order, #2
710 1.1 mrg blt 4f
711 1.1 mrg beq 3f
712 1.1 mrg cmp \dividend, \divisor
713 1.1 mrg subhs \dividend, \dividend, \divisor
714 1.1 mrg mov \divisor, \divisor, lsr #1
715 1.1 mrg 3: cmp \dividend, \divisor
716 1.1 mrg subhs \dividend, \dividend, \divisor
717 1.1 mrg mov \divisor, \divisor, lsr #1
718 1.1 mrg 4: cmp \dividend, \divisor
719 1.1 mrg subhs \dividend, \dividend, \divisor
720 1.1 mrg 5:
721 1.1 mrg
722 1.8 mrg #endif /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
723 1.1 mrg
724 1.1 mrg .endm
725 1.1 mrg /* ------------------------------------------------------------------------ */
726 1.1 mrg .macro THUMB_DIV_MOD_BODY modulo
727 1.1 mrg @ Load the constant 0x10000000 into our work register.
728 1.1 mrg mov work, #1
729 1.1 mrg lsl work, #28
730 1.1 mrg LSYM(Loop1):
731 1.1 mrg @ Unless the divisor is very big, shift it up in multiples of
732 1.1 mrg @ four bits, since this is the amount of unwinding in the main
733 1.1 mrg @ division loop. Continue shifting until the divisor is
734 1.1 mrg @ larger than the dividend.
735 1.1 mrg cmp divisor, work
736 1.1 mrg bhs LSYM(Lbignum)
737 1.1 mrg cmp divisor, dividend
738 1.1 mrg bhs LSYM(Lbignum)
739 1.1 mrg lsl divisor, #4
740 1.1 mrg lsl curbit, #4
741 1.1 mrg b LSYM(Loop1)
742 1.1 mrg LSYM(Lbignum):
743 1.1 mrg @ Set work to 0x80000000
744 1.1 mrg lsl work, #3
745 1.1 mrg LSYM(Loop2):
746 1.1 mrg @ For very big divisors, we must shift it a bit at a time, or
747 1.1 mrg @ we will be in danger of overflowing.
748 1.1 mrg cmp divisor, work
749 1.1 mrg bhs LSYM(Loop3)
750 1.1 mrg cmp divisor, dividend
751 1.1 mrg bhs LSYM(Loop3)
752 1.1 mrg lsl divisor, #1
753 1.1 mrg lsl curbit, #1
754 1.1 mrg b LSYM(Loop2)
755 1.1 mrg LSYM(Loop3):
756 1.1 mrg @ Test for possible subtractions ...
757 1.1 mrg .if \modulo
758 1.1 mrg @ ... On the final pass, this may subtract too much from the dividend,
759 1.1 mrg @ so keep track of which subtractions are done, we can fix them up
760 1.1 mrg @ afterwards.
761 1.1 mrg mov overdone, #0
762 1.1 mrg cmp dividend, divisor
763 1.1 mrg blo LSYM(Lover1)
764 1.1 mrg sub dividend, dividend, divisor
765 1.1 mrg LSYM(Lover1):
766 1.1 mrg lsr work, divisor, #1
767 1.1 mrg cmp dividend, work
768 1.1 mrg blo LSYM(Lover2)
769 1.1 mrg sub dividend, dividend, work
770 1.1 mrg mov ip, curbit
771 1.1 mrg mov work, #1
772 1.1 mrg ror curbit, work
773 1.1 mrg orr overdone, curbit
774 1.1 mrg mov curbit, ip
775 1.1 mrg LSYM(Lover2):
776 1.1 mrg lsr work, divisor, #2
777 1.1 mrg cmp dividend, work
778 1.1 mrg blo LSYM(Lover3)
779 1.1 mrg sub dividend, dividend, work
780 1.1 mrg mov ip, curbit
781 1.1 mrg mov work, #2
782 1.1 mrg ror curbit, work
783 1.1 mrg orr overdone, curbit
784 1.1 mrg mov curbit, ip
785 1.1 mrg LSYM(Lover3):
786 1.1 mrg lsr work, divisor, #3
787 1.1 mrg cmp dividend, work
788 1.1 mrg blo LSYM(Lover4)
789 1.1 mrg sub dividend, dividend, work
790 1.1 mrg mov ip, curbit
791 1.1 mrg mov work, #3
792 1.1 mrg ror curbit, work
793 1.1 mrg orr overdone, curbit
794 1.1 mrg mov curbit, ip
795 1.1 mrg LSYM(Lover4):
796 1.1 mrg mov ip, curbit
797 1.1 mrg .else
798 1.1 mrg @ ... and note which bits are done in the result. On the final pass,
799 1.1 mrg @ this may subtract too much from the dividend, but the result will be ok,
800 1.1 mrg @ since the "bit" will have been shifted out at the bottom.
801 1.1 mrg cmp dividend, divisor
802 1.1 mrg blo LSYM(Lover1)
803 1.1 mrg sub dividend, dividend, divisor
804 1.1 mrg orr result, result, curbit
805 1.1 mrg LSYM(Lover1):
806 1.1 mrg lsr work, divisor, #1
807 1.1 mrg cmp dividend, work
808 1.1 mrg blo LSYM(Lover2)
809 1.1 mrg sub dividend, dividend, work
810 1.1 mrg lsr work, curbit, #1
811 1.1 mrg orr result, work
812 1.1 mrg LSYM(Lover2):
813 1.1 mrg lsr work, divisor, #2
814 1.1 mrg cmp dividend, work
815 1.1 mrg blo LSYM(Lover3)
816 1.1 mrg sub dividend, dividend, work
817 1.1 mrg lsr work, curbit, #2
818 1.1 mrg orr result, work
819 1.1 mrg LSYM(Lover3):
820 1.1 mrg lsr work, divisor, #3
821 1.1 mrg cmp dividend, work
822 1.1 mrg blo LSYM(Lover4)
823 1.1 mrg sub dividend, dividend, work
824 1.1 mrg lsr work, curbit, #3
825 1.1 mrg orr result, work
826 1.1 mrg LSYM(Lover4):
827 1.1 mrg .endif
828 1.1 mrg
829 1.1 mrg cmp dividend, #0 @ Early termination?
830 1.1 mrg beq LSYM(Lover5)
831 1.1 mrg lsr curbit, #4 @ No, any more bits to do?
832 1.1 mrg beq LSYM(Lover5)
833 1.1 mrg lsr divisor, #4
834 1.1 mrg b LSYM(Loop3)
835 1.1 mrg LSYM(Lover5):
836 1.1 mrg .if \modulo
837 1.1 mrg @ Any subtractions that we should not have done will be recorded in
838 1.1 mrg @ the top three bits of "overdone". Exactly which were not needed
839 1.1 mrg @ are governed by the position of the bit, stored in ip.
840 1.1 mrg mov work, #0xe
841 1.1 mrg lsl work, #28
842 1.1 mrg and overdone, work
843 1.1 mrg beq LSYM(Lgot_result)
844 1.1 mrg
845 1.1 mrg @ If we terminated early, because dividend became zero, then the
846 1.1 mrg @ bit in ip will not be in the bottom nibble, and we should not
847 1.1 mrg @ perform the additions below. We must test for this though
848 1.1 mrg @ (rather relying upon the TSTs to prevent the additions) since
849 1.1 mrg @ the bit in ip could be in the top two bits which might then match
850 1.1 mrg @ with one of the smaller RORs.
851 1.1 mrg mov curbit, ip
852 1.1 mrg mov work, #0x7
853 1.1 mrg tst curbit, work
854 1.1 mrg beq LSYM(Lgot_result)
855 1.1 mrg
856 1.1 mrg mov curbit, ip
857 1.1 mrg mov work, #3
858 1.1 mrg ror curbit, work
859 1.1 mrg tst overdone, curbit
860 1.1 mrg beq LSYM(Lover6)
861 1.1 mrg lsr work, divisor, #3
862 1.1 mrg add dividend, work
863 1.1 mrg LSYM(Lover6):
864 1.1 mrg mov curbit, ip
865 1.1 mrg mov work, #2
866 1.1 mrg ror curbit, work
867 1.1 mrg tst overdone, curbit
868 1.1 mrg beq LSYM(Lover7)
869 1.1 mrg lsr work, divisor, #2
870 1.1 mrg add dividend, work
871 1.1 mrg LSYM(Lover7):
872 1.1 mrg mov curbit, ip
873 1.1 mrg mov work, #1
874 1.1 mrg ror curbit, work
875 1.1 mrg tst overdone, curbit
876 1.1 mrg beq LSYM(Lgot_result)
877 1.1 mrg lsr work, divisor, #1
878 1.1 mrg add dividend, work
879 1.1 mrg .endif
880 1.1 mrg LSYM(Lgot_result):
881 1.6 mrg .endm
882 1.6 mrg
883 1.6 mrg /* If performance is preferred, the following functions are provided. */
884 1.6 mrg #if defined(__prefer_thumb__) && !defined(__OPTIMIZE_SIZE__)
885 1.6 mrg
886 1.6 mrg /* Branch to div(n), and jump to label if curbit is lo than divisior. */
887 1.6 mrg .macro BranchToDiv n, label
888 1.6 mrg lsr curbit, dividend, \n
889 1.6 mrg cmp curbit, divisor
890 1.6 mrg blo \label
891 1.6 mrg .endm
892 1.6 mrg
893 1.6 mrg /* Body of div(n). Shift the divisor in n bits and compare the divisor
894 1.6 mrg and dividend. Update the dividend as the substruction result. */
895 1.6 mrg .macro DoDiv n
896 1.6 mrg lsr curbit, dividend, \n
897 1.6 mrg cmp curbit, divisor
898 1.6 mrg bcc 1f
899 1.6 mrg lsl curbit, divisor, \n
900 1.6 mrg sub dividend, dividend, curbit
901 1.6 mrg
902 1.6 mrg 1: adc result, result
903 1.6 mrg .endm
904 1.6 mrg
905 1.6 mrg /* The body of division with positive divisor. Unless the divisor is very
906 1.6 mrg big, shift it up in multiples of four bits, since this is the amount of
907 1.6 mrg unwinding in the main division loop. Continue shifting until the divisor
908 1.6 mrg is larger than the dividend. */
909 1.6 mrg .macro THUMB1_Div_Positive
910 1.6 mrg mov result, #0
911 1.6 mrg BranchToDiv #1, LSYM(Lthumb1_div1)
912 1.6 mrg BranchToDiv #4, LSYM(Lthumb1_div4)
913 1.6 mrg BranchToDiv #8, LSYM(Lthumb1_div8)
914 1.6 mrg BranchToDiv #12, LSYM(Lthumb1_div12)
915 1.6 mrg BranchToDiv #16, LSYM(Lthumb1_div16)
916 1.6 mrg LSYM(Lthumb1_div_large_positive):
917 1.6 mrg mov result, #0xff
918 1.6 mrg lsl divisor, divisor, #8
919 1.6 mrg rev result, result
920 1.6 mrg lsr curbit, dividend, #16
921 1.6 mrg cmp curbit, divisor
922 1.6 mrg blo 1f
923 1.6 mrg asr result, #8
924 1.6 mrg lsl divisor, divisor, #8
925 1.6 mrg beq LSYM(Ldivbyzero_waypoint)
926 1.6 mrg
927 1.6 mrg 1: lsr curbit, dividend, #12
928 1.6 mrg cmp curbit, divisor
929 1.6 mrg blo LSYM(Lthumb1_div12)
930 1.6 mrg b LSYM(Lthumb1_div16)
931 1.6 mrg LSYM(Lthumb1_div_loop):
932 1.6 mrg lsr divisor, divisor, #8
933 1.6 mrg LSYM(Lthumb1_div16):
934 1.6 mrg Dodiv #15
935 1.6 mrg Dodiv #14
936 1.6 mrg Dodiv #13
937 1.6 mrg Dodiv #12
938 1.6 mrg LSYM(Lthumb1_div12):
939 1.6 mrg Dodiv #11
940 1.6 mrg Dodiv #10
941 1.6 mrg Dodiv #9
942 1.6 mrg Dodiv #8
943 1.6 mrg bcs LSYM(Lthumb1_div_loop)
944 1.6 mrg LSYM(Lthumb1_div8):
945 1.6 mrg Dodiv #7
946 1.6 mrg Dodiv #6
947 1.6 mrg Dodiv #5
948 1.6 mrg LSYM(Lthumb1_div5):
949 1.6 mrg Dodiv #4
950 1.6 mrg LSYM(Lthumb1_div4):
951 1.6 mrg Dodiv #3
952 1.6 mrg LSYM(Lthumb1_div3):
953 1.6 mrg Dodiv #2
954 1.6 mrg LSYM(Lthumb1_div2):
955 1.6 mrg Dodiv #1
956 1.6 mrg LSYM(Lthumb1_div1):
957 1.6 mrg sub divisor, dividend, divisor
958 1.6 mrg bcs 1f
959 1.6 mrg cpy divisor, dividend
960 1.6 mrg
961 1.6 mrg 1: adc result, result
962 1.6 mrg cpy dividend, result
963 1.6 mrg RET
964 1.6 mrg
965 1.6 mrg LSYM(Ldivbyzero_waypoint):
966 1.6 mrg b LSYM(Ldiv0)
967 1.6 mrg .endm
968 1.6 mrg
969 1.6 mrg /* The body of division with negative divisor. Similar with
970 1.6 mrg THUMB1_Div_Positive except that the shift steps are in multiples
971 1.6 mrg of six bits. */
972 1.6 mrg .macro THUMB1_Div_Negative
973 1.6 mrg lsr result, divisor, #31
974 1.6 mrg beq 1f
975 1.6 mrg neg divisor, divisor
976 1.6 mrg
977 1.6 mrg 1: asr curbit, dividend, #32
978 1.6 mrg bcc 2f
979 1.6 mrg neg dividend, dividend
980 1.6 mrg
981 1.6 mrg 2: eor curbit, result
982 1.6 mrg mov result, #0
983 1.6 mrg cpy ip, curbit
984 1.6 mrg BranchToDiv #4, LSYM(Lthumb1_div_negative4)
985 1.6 mrg BranchToDiv #8, LSYM(Lthumb1_div_negative8)
986 1.6 mrg LSYM(Lthumb1_div_large):
987 1.6 mrg mov result, #0xfc
988 1.6 mrg lsl divisor, divisor, #6
989 1.6 mrg rev result, result
990 1.6 mrg lsr curbit, dividend, #8
991 1.6 mrg cmp curbit, divisor
992 1.6 mrg blo LSYM(Lthumb1_div_negative8)
993 1.6 mrg
994 1.6 mrg lsl divisor, divisor, #6
995 1.6 mrg asr result, result, #6
996 1.6 mrg cmp curbit, divisor
997 1.6 mrg blo LSYM(Lthumb1_div_negative8)
998 1.6 mrg
999 1.6 mrg lsl divisor, divisor, #6
1000 1.6 mrg asr result, result, #6
1001 1.6 mrg cmp curbit, divisor
1002 1.6 mrg blo LSYM(Lthumb1_div_negative8)
1003 1.6 mrg
1004 1.6 mrg lsl divisor, divisor, #6
1005 1.6 mrg beq LSYM(Ldivbyzero_negative)
1006 1.6 mrg asr result, result, #6
1007 1.6 mrg b LSYM(Lthumb1_div_negative8)
1008 1.6 mrg LSYM(Lthumb1_div_negative_loop):
1009 1.6 mrg lsr divisor, divisor, #6
1010 1.6 mrg LSYM(Lthumb1_div_negative8):
1011 1.6 mrg DoDiv #7
1012 1.6 mrg DoDiv #6
1013 1.6 mrg DoDiv #5
1014 1.6 mrg DoDiv #4
1015 1.6 mrg LSYM(Lthumb1_div_negative4):
1016 1.6 mrg DoDiv #3
1017 1.6 mrg DoDiv #2
1018 1.6 mrg bcs LSYM(Lthumb1_div_negative_loop)
1019 1.6 mrg DoDiv #1
1020 1.6 mrg sub divisor, dividend, divisor
1021 1.6 mrg bcs 1f
1022 1.6 mrg cpy divisor, dividend
1023 1.6 mrg
1024 1.6 mrg 1: cpy curbit, ip
1025 1.6 mrg adc result, result
1026 1.6 mrg asr curbit, curbit, #1
1027 1.6 mrg cpy dividend, result
1028 1.6 mrg bcc 2f
1029 1.6 mrg neg dividend, dividend
1030 1.6 mrg cmp curbit, #0
1031 1.6 mrg
1032 1.6 mrg 2: bpl 3f
1033 1.6 mrg neg divisor, divisor
1034 1.6 mrg
1035 1.6 mrg 3: RET
1036 1.6 mrg
1037 1.6 mrg LSYM(Ldivbyzero_negative):
1038 1.6 mrg cpy curbit, ip
1039 1.6 mrg asr curbit, curbit, #1
1040 1.6 mrg bcc LSYM(Ldiv0)
1041 1.6 mrg neg dividend, dividend
1042 1.6 mrg .endm
1043 1.6 mrg #endif /* ARM Thumb version. */
1044 1.6 mrg
1045 1.1 mrg /* ------------------------------------------------------------------------ */
1046 1.1 mrg /* Start of the Real Functions */
1047 1.1 mrg /* ------------------------------------------------------------------------ */
1048 1.1 mrg #ifdef L_udivsi3
1049 1.1 mrg
1050 1.1 mrg #if defined(__prefer_thumb__)
1051 1.1 mrg
1052 1.1 mrg FUNC_START udivsi3
1053 1.1 mrg FUNC_ALIAS aeabi_uidiv udivsi3
1054 1.6 mrg #if defined(__OPTIMIZE_SIZE__)
1055 1.1 mrg
1056 1.1 mrg cmp divisor, #0
1057 1.1 mrg beq LSYM(Ldiv0)
1058 1.1 mrg LSYM(udivsi3_skip_div0_test):
1059 1.1 mrg mov curbit, #1
1060 1.1 mrg mov result, #0
1061 1.1 mrg
1062 1.1 mrg push { work }
1063 1.1 mrg cmp dividend, divisor
1064 1.1 mrg blo LSYM(Lgot_result)
1065 1.1 mrg
1066 1.1 mrg THUMB_DIV_MOD_BODY 0
1067 1.1 mrg
1068 1.1 mrg mov r0, result
1069 1.1 mrg pop { work }
1070 1.1 mrg RET
1071 1.1 mrg
1072 1.6 mrg /* Implementation of aeabi_uidiv for ARMv6m. This version is only
1073 1.6 mrg used in ARMv6-M when we need an efficient implementation. */
1074 1.6 mrg #else
1075 1.6 mrg LSYM(udivsi3_skip_div0_test):
1076 1.6 mrg THUMB1_Div_Positive
1077 1.6 mrg
1078 1.6 mrg #endif /* __OPTIMIZE_SIZE__ */
1079 1.6 mrg
1080 1.1 mrg #elif defined(__ARM_ARCH_EXT_IDIV__)
1081 1.1 mrg
1082 1.1 mrg ARM_FUNC_START udivsi3
1083 1.1 mrg ARM_FUNC_ALIAS aeabi_uidiv udivsi3
1084 1.1 mrg
1085 1.1 mrg cmp r1, #0
1086 1.1 mrg beq LSYM(Ldiv0)
1087 1.1 mrg
1088 1.1 mrg udiv r0, r0, r1
1089 1.1 mrg RET
1090 1.1 mrg
1091 1.1 mrg #else /* ARM version/Thumb-2. */
1092 1.1 mrg
1093 1.1 mrg ARM_FUNC_START udivsi3
1094 1.1 mrg ARM_FUNC_ALIAS aeabi_uidiv udivsi3
1095 1.1 mrg
1096 1.1 mrg /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
1097 1.1 mrg check for division-by-zero a second time. */
1098 1.1 mrg LSYM(udivsi3_skip_div0_test):
1099 1.1 mrg subs r2, r1, #1
1100 1.1 mrg do_it eq
1101 1.1 mrg RETc(eq)
1102 1.1 mrg bcc LSYM(Ldiv0)
1103 1.1 mrg cmp r0, r1
1104 1.1 mrg bls 11f
1105 1.1 mrg tst r1, r2
1106 1.1 mrg beq 12f
1107 1.1 mrg
1108 1.1 mrg ARM_DIV_BODY r0, r1, r2, r3
1109 1.1 mrg
1110 1.1 mrg mov r0, r2
1111 1.1 mrg RET
1112 1.1 mrg
1113 1.1 mrg 11: do_it eq, e
1114 1.1 mrg moveq r0, #1
1115 1.1 mrg movne r0, #0
1116 1.1 mrg RET
1117 1.1 mrg
1118 1.1 mrg 12: ARM_DIV2_ORDER r1, r2
1119 1.1 mrg
1120 1.1 mrg mov r0, r0, lsr r2
1121 1.1 mrg RET
1122 1.1 mrg
1123 1.1 mrg #endif /* ARM version */
1124 1.1 mrg
1125 1.1 mrg DIV_FUNC_END udivsi3 unsigned
1126 1.1 mrg
1127 1.1 mrg #if defined(__prefer_thumb__)
1128 1.1 mrg FUNC_START aeabi_uidivmod
1129 1.1 mrg cmp r1, #0
1130 1.1 mrg beq LSYM(Ldiv0)
1131 1.6 mrg # if defined(__OPTIMIZE_SIZE__)
1132 1.1 mrg push {r0, r1, lr}
1133 1.1 mrg bl LSYM(udivsi3_skip_div0_test)
1134 1.1 mrg POP {r1, r2, r3}
1135 1.1 mrg mul r2, r0
1136 1.1 mrg sub r1, r1, r2
1137 1.1 mrg bx r3
1138 1.6 mrg # else
1139 1.6 mrg /* Both the quotient and remainder are calculated simultaneously
1140 1.6 mrg in THUMB1_Div_Positive. There is no need to calculate the
1141 1.6 mrg remainder again here. */
1142 1.6 mrg b LSYM(udivsi3_skip_div0_test)
1143 1.6 mrg RET
1144 1.6 mrg # endif /* __OPTIMIZE_SIZE__ */
1145 1.6 mrg
1146 1.1 mrg #elif defined(__ARM_ARCH_EXT_IDIV__)
1147 1.1 mrg ARM_FUNC_START aeabi_uidivmod
1148 1.1 mrg cmp r1, #0
1149 1.1 mrg beq LSYM(Ldiv0)
1150 1.1 mrg mov r2, r0
1151 1.1 mrg udiv r0, r0, r1
1152 1.1 mrg mls r1, r0, r1, r2
1153 1.1 mrg RET
1154 1.1 mrg #else
1155 1.1 mrg ARM_FUNC_START aeabi_uidivmod
1156 1.1 mrg cmp r1, #0
1157 1.1 mrg beq LSYM(Ldiv0)
1158 1.1 mrg stmfd sp!, { r0, r1, lr }
1159 1.1 mrg bl LSYM(udivsi3_skip_div0_test)
1160 1.1 mrg ldmfd sp!, { r1, r2, lr }
1161 1.1 mrg mul r3, r2, r0
1162 1.1 mrg sub r1, r1, r3
1163 1.1 mrg RET
1164 1.1 mrg #endif
1165 1.1 mrg FUNC_END aeabi_uidivmod
1166 1.1 mrg
1167 1.1 mrg #endif /* L_udivsi3 */
1168 1.1 mrg /* ------------------------------------------------------------------------ */
1169 1.1 mrg #ifdef L_umodsi3
1170 1.1 mrg
1171 1.6 mrg #if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1
1172 1.1 mrg
1173 1.1 mrg ARM_FUNC_START umodsi3
1174 1.1 mrg
1175 1.1 mrg cmp r1, #0
1176 1.1 mrg beq LSYM(Ldiv0)
1177 1.1 mrg udiv r2, r0, r1
1178 1.1 mrg mls r0, r1, r2, r0
1179 1.1 mrg RET
1180 1.1 mrg
1181 1.1 mrg #elif defined(__thumb__)
1182 1.1 mrg
1183 1.1 mrg FUNC_START umodsi3
1184 1.1 mrg
1185 1.1 mrg cmp divisor, #0
1186 1.1 mrg beq LSYM(Ldiv0)
1187 1.1 mrg mov curbit, #1
1188 1.1 mrg cmp dividend, divisor
1189 1.1 mrg bhs LSYM(Lover10)
1190 1.1 mrg RET
1191 1.1 mrg
1192 1.1 mrg LSYM(Lover10):
1193 1.1 mrg push { work }
1194 1.1 mrg
1195 1.1 mrg THUMB_DIV_MOD_BODY 1
1196 1.1 mrg
1197 1.1 mrg pop { work }
1198 1.1 mrg RET
1199 1.1 mrg
1200 1.1 mrg #else /* ARM version. */
1201 1.6 mrg
1202 1.1 mrg FUNC_START umodsi3
1203 1.1 mrg
1204 1.1 mrg subs r2, r1, #1 @ compare divisor with 1
1205 1.1 mrg bcc LSYM(Ldiv0)
1206 1.1 mrg cmpne r0, r1 @ compare dividend with divisor
1207 1.1 mrg moveq r0, #0
1208 1.1 mrg tsthi r1, r2 @ see if divisor is power of 2
1209 1.1 mrg andeq r0, r0, r2
1210 1.1 mrg RETc(ls)
1211 1.1 mrg
1212 1.1 mrg ARM_MOD_BODY r0, r1, r2, r3
1213 1.1 mrg
1214 1.1 mrg RET
1215 1.1 mrg
1216 1.1 mrg #endif /* ARM version. */
1217 1.1 mrg
1218 1.1 mrg DIV_FUNC_END umodsi3 unsigned
1219 1.1 mrg
1220 1.1 mrg #endif /* L_umodsi3 */
1221 1.1 mrg /* ------------------------------------------------------------------------ */
1222 1.1 mrg #ifdef L_divsi3
1223 1.1 mrg
1224 1.1 mrg #if defined(__prefer_thumb__)
1225 1.1 mrg
1226 1.6 mrg FUNC_START divsi3
1227 1.1 mrg FUNC_ALIAS aeabi_idiv divsi3
1228 1.6 mrg #if defined(__OPTIMIZE_SIZE__)
1229 1.1 mrg
1230 1.1 mrg cmp divisor, #0
1231 1.1 mrg beq LSYM(Ldiv0)
1232 1.1 mrg LSYM(divsi3_skip_div0_test):
1233 1.1 mrg push { work }
1234 1.1 mrg mov work, dividend
1235 1.1 mrg eor work, divisor @ Save the sign of the result.
1236 1.1 mrg mov ip, work
1237 1.1 mrg mov curbit, #1
1238 1.1 mrg mov result, #0
1239 1.1 mrg cmp divisor, #0
1240 1.1 mrg bpl LSYM(Lover10)
1241 1.1 mrg neg divisor, divisor @ Loops below use unsigned.
1242 1.1 mrg LSYM(Lover10):
1243 1.1 mrg cmp dividend, #0
1244 1.1 mrg bpl LSYM(Lover11)
1245 1.1 mrg neg dividend, dividend
1246 1.1 mrg LSYM(Lover11):
1247 1.1 mrg cmp dividend, divisor
1248 1.1 mrg blo LSYM(Lgot_result)
1249 1.1 mrg
1250 1.1 mrg THUMB_DIV_MOD_BODY 0
1251 1.6 mrg
1252 1.1 mrg mov r0, result
1253 1.1 mrg mov work, ip
1254 1.1 mrg cmp work, #0
1255 1.1 mrg bpl LSYM(Lover12)
1256 1.1 mrg neg r0, r0
1257 1.1 mrg LSYM(Lover12):
1258 1.1 mrg pop { work }
1259 1.1 mrg RET
1260 1.1 mrg
1261 1.6 mrg /* Implementation of aeabi_idiv for ARMv6m. This version is only
1262 1.6 mrg used in ARMv6-M when we need an efficient implementation. */
1263 1.6 mrg #else
1264 1.6 mrg LSYM(divsi3_skip_div0_test):
1265 1.6 mrg cpy curbit, dividend
1266 1.6 mrg orr curbit, divisor
1267 1.6 mrg bmi LSYM(Lthumb1_div_negative)
1268 1.6 mrg
1269 1.6 mrg LSYM(Lthumb1_div_positive):
1270 1.6 mrg THUMB1_Div_Positive
1271 1.6 mrg
1272 1.6 mrg LSYM(Lthumb1_div_negative):
1273 1.6 mrg THUMB1_Div_Negative
1274 1.6 mrg
1275 1.6 mrg #endif /* __OPTIMIZE_SIZE__ */
1276 1.6 mrg
1277 1.1 mrg #elif defined(__ARM_ARCH_EXT_IDIV__)
1278 1.1 mrg
1279 1.1 mrg ARM_FUNC_START divsi3
1280 1.1 mrg ARM_FUNC_ALIAS aeabi_idiv divsi3
1281 1.1 mrg
1282 1.1 mrg cmp r1, #0
1283 1.1 mrg beq LSYM(Ldiv0)
1284 1.1 mrg sdiv r0, r0, r1
1285 1.1 mrg RET
1286 1.1 mrg
1287 1.1 mrg #else /* ARM/Thumb-2 version. */
1288 1.6 mrg
1289 1.6 mrg ARM_FUNC_START divsi3
1290 1.1 mrg ARM_FUNC_ALIAS aeabi_idiv divsi3
1291 1.1 mrg
1292 1.1 mrg cmp r1, #0
1293 1.1 mrg beq LSYM(Ldiv0)
1294 1.1 mrg LSYM(divsi3_skip_div0_test):
1295 1.1 mrg eor ip, r0, r1 @ save the sign of the result.
1296 1.1 mrg do_it mi
1297 1.1 mrg rsbmi r1, r1, #0 @ loops below use unsigned.
1298 1.1 mrg subs r2, r1, #1 @ division by 1 or -1 ?
1299 1.1 mrg beq 10f
1300 1.1 mrg movs r3, r0
1301 1.1 mrg do_it mi
1302 1.1 mrg rsbmi r3, r0, #0 @ positive dividend value
1303 1.1 mrg cmp r3, r1
1304 1.1 mrg bls 11f
1305 1.1 mrg tst r1, r2 @ divisor is power of 2 ?
1306 1.1 mrg beq 12f
1307 1.1 mrg
1308 1.1 mrg ARM_DIV_BODY r3, r1, r0, r2
1309 1.1 mrg
1310 1.1 mrg cmp ip, #0
1311 1.1 mrg do_it mi
1312 1.1 mrg rsbmi r0, r0, #0
1313 1.1 mrg RET
1314 1.1 mrg
1315 1.1 mrg 10: teq ip, r0 @ same sign ?
1316 1.1 mrg do_it mi
1317 1.1 mrg rsbmi r0, r0, #0
1318 1.1 mrg RET
1319 1.1 mrg
1320 1.1 mrg 11: do_it lo
1321 1.1 mrg movlo r0, #0
1322 1.1 mrg do_it eq,t
1323 1.1 mrg moveq r0, ip, asr #31
1324 1.1 mrg orreq r0, r0, #1
1325 1.1 mrg RET
1326 1.1 mrg
1327 1.1 mrg 12: ARM_DIV2_ORDER r1, r2
1328 1.1 mrg
1329 1.1 mrg cmp ip, #0
1330 1.1 mrg mov r0, r3, lsr r2
1331 1.1 mrg do_it mi
1332 1.1 mrg rsbmi r0, r0, #0
1333 1.1 mrg RET
1334 1.1 mrg
1335 1.1 mrg #endif /* ARM version */
1336 1.1 mrg
1337 1.1 mrg DIV_FUNC_END divsi3 signed
1338 1.1 mrg
1339 1.1 mrg #if defined(__prefer_thumb__)
1340 1.1 mrg FUNC_START aeabi_idivmod
1341 1.1 mrg cmp r1, #0
1342 1.1 mrg beq LSYM(Ldiv0)
1343 1.6 mrg # if defined(__OPTIMIZE_SIZE__)
1344 1.1 mrg push {r0, r1, lr}
1345 1.1 mrg bl LSYM(divsi3_skip_div0_test)
1346 1.1 mrg POP {r1, r2, r3}
1347 1.1 mrg mul r2, r0
1348 1.1 mrg sub r1, r1, r2
1349 1.1 mrg bx r3
1350 1.6 mrg # else
1351 1.6 mrg /* Both the quotient and remainder are calculated simultaneously
1352 1.6 mrg in THUMB1_Div_Positive and THUMB1_Div_Negative. There is no
1353 1.6 mrg need to calculate the remainder again here. */
1354 1.6 mrg b LSYM(divsi3_skip_div0_test)
1355 1.6 mrg RET
1356 1.6 mrg # endif /* __OPTIMIZE_SIZE__ */
1357 1.6 mrg
1358 1.1 mrg #elif defined(__ARM_ARCH_EXT_IDIV__)
1359 1.1 mrg ARM_FUNC_START aeabi_idivmod
1360 1.1 mrg cmp r1, #0
1361 1.1 mrg beq LSYM(Ldiv0)
1362 1.1 mrg mov r2, r0
1363 1.1 mrg sdiv r0, r0, r1
1364 1.1 mrg mls r1, r0, r1, r2
1365 1.1 mrg RET
1366 1.1 mrg #else
1367 1.1 mrg ARM_FUNC_START aeabi_idivmod
1368 1.1 mrg cmp r1, #0
1369 1.1 mrg beq LSYM(Ldiv0)
1370 1.1 mrg stmfd sp!, { r0, r1, lr }
1371 1.1 mrg bl LSYM(divsi3_skip_div0_test)
1372 1.1 mrg ldmfd sp!, { r1, r2, lr }
1373 1.1 mrg mul r3, r2, r0
1374 1.1 mrg sub r1, r1, r3
1375 1.1 mrg RET
1376 1.1 mrg #endif
1377 1.1 mrg FUNC_END aeabi_idivmod
1378 1.1 mrg
1379 1.1 mrg #endif /* L_divsi3 */
1380 1.1 mrg /* ------------------------------------------------------------------------ */
1381 1.1 mrg #ifdef L_modsi3
1382 1.1 mrg
1383 1.6 mrg #if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1
1384 1.1 mrg
1385 1.1 mrg ARM_FUNC_START modsi3
1386 1.1 mrg
1387 1.1 mrg cmp r1, #0
1388 1.1 mrg beq LSYM(Ldiv0)
1389 1.1 mrg
1390 1.1 mrg sdiv r2, r0, r1
1391 1.1 mrg mls r0, r1, r2, r0
1392 1.1 mrg RET
1393 1.1 mrg
1394 1.1 mrg #elif defined(__thumb__)
1395 1.1 mrg
1396 1.1 mrg FUNC_START modsi3
1397 1.1 mrg
1398 1.1 mrg mov curbit, #1
1399 1.1 mrg cmp divisor, #0
1400 1.1 mrg beq LSYM(Ldiv0)
1401 1.1 mrg bpl LSYM(Lover10)
1402 1.1 mrg neg divisor, divisor @ Loops below use unsigned.
1403 1.1 mrg LSYM(Lover10):
1404 1.1 mrg push { work }
1405 1.1 mrg @ Need to save the sign of the dividend, unfortunately, we need
1406 1.1 mrg @ work later on. Must do this after saving the original value of
1407 1.1 mrg @ the work register, because we will pop this value off first.
1408 1.1 mrg push { dividend }
1409 1.1 mrg cmp dividend, #0
1410 1.1 mrg bpl LSYM(Lover11)
1411 1.1 mrg neg dividend, dividend
1412 1.1 mrg LSYM(Lover11):
1413 1.1 mrg cmp dividend, divisor
1414 1.1 mrg blo LSYM(Lgot_result)
1415 1.1 mrg
1416 1.1 mrg THUMB_DIV_MOD_BODY 1
1417 1.1 mrg
1418 1.1 mrg pop { work }
1419 1.1 mrg cmp work, #0
1420 1.1 mrg bpl LSYM(Lover12)
1421 1.1 mrg neg dividend, dividend
1422 1.1 mrg LSYM(Lover12):
1423 1.1 mrg pop { work }
1424 1.1 mrg RET
1425 1.1 mrg
1426 1.1 mrg #else /* ARM version. */
1427 1.1 mrg
1428 1.1 mrg FUNC_START modsi3
1429 1.1 mrg
1430 1.1 mrg cmp r1, #0
1431 1.1 mrg beq LSYM(Ldiv0)
1432 1.1 mrg rsbmi r1, r1, #0 @ loops below use unsigned.
1433 1.1 mrg movs ip, r0 @ preserve sign of dividend
1434 1.1 mrg rsbmi r0, r0, #0 @ if negative make positive
1435 1.1 mrg subs r2, r1, #1 @ compare divisor with 1
1436 1.1 mrg cmpne r0, r1 @ compare dividend with divisor
1437 1.1 mrg moveq r0, #0
1438 1.1 mrg tsthi r1, r2 @ see if divisor is power of 2
1439 1.1 mrg andeq r0, r0, r2
1440 1.1 mrg bls 10f
1441 1.1 mrg
1442 1.1 mrg ARM_MOD_BODY r0, r1, r2, r3
1443 1.1 mrg
1444 1.1 mrg 10: cmp ip, #0
1445 1.1 mrg rsbmi r0, r0, #0
1446 1.1 mrg RET
1447 1.1 mrg
1448 1.1 mrg #endif /* ARM version */
1449 1.1 mrg
1450 1.1 mrg DIV_FUNC_END modsi3 signed
1451 1.1 mrg
1452 1.1 mrg #endif /* L_modsi3 */
1453 1.1 mrg /* ------------------------------------------------------------------------ */
1454 1.1 mrg #ifdef L_dvmd_tls
1455 1.1 mrg
1456 1.1 mrg #ifdef __ARM_EABI__
1457 1.1 mrg WEAK aeabi_idiv0
1458 1.1 mrg WEAK aeabi_ldiv0
1459 1.1 mrg FUNC_START aeabi_idiv0
1460 1.1 mrg FUNC_START aeabi_ldiv0
1461 1.1 mrg RET
1462 1.1 mrg FUNC_END aeabi_ldiv0
1463 1.1 mrg FUNC_END aeabi_idiv0
1464 1.1 mrg #else
1465 1.1 mrg FUNC_START div0
1466 1.1 mrg RET
1467 1.1 mrg FUNC_END div0
1468 1.1 mrg #endif
1469 1.1 mrg
1470 1.1 mrg #endif /* L_divmodsi_tools */
1471 1.1 mrg /* ------------------------------------------------------------------------ */
1472 1.1 mrg #ifdef L_dvmd_lnx
1473 1.1 mrg @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1474 1.1 mrg
1475 1.1 mrg /* Constant taken from <asm/signal.h>. */
1476 1.1 mrg #define SIGFPE 8
1477 1.1 mrg
1478 1.1 mrg #ifdef __ARM_EABI__
1479 1.4 mrg cfi_start __aeabi_ldiv0, LSYM(Lend_aeabi_ldiv0)
1480 1.1 mrg WEAK aeabi_idiv0
1481 1.1 mrg WEAK aeabi_ldiv0
1482 1.1 mrg ARM_FUNC_START aeabi_idiv0
1483 1.1 mrg ARM_FUNC_START aeabi_ldiv0
1484 1.4 mrg do_push {r1, lr}
1485 1.4 mrg 98: cfi_push 98b - __aeabi_ldiv0, 0xe, -0x4, 0x8
1486 1.1 mrg #else
1487 1.4 mrg cfi_start __div0, LSYM(Lend_div0)
1488 1.1 mrg ARM_FUNC_START div0
1489 1.4 mrg do_push {r1, lr}
1490 1.4 mrg 98: cfi_push 98b - __div0, 0xe, -0x4, 0x8
1491 1.1 mrg #endif
1492 1.1 mrg
1493 1.1 mrg mov r0, #SIGFPE
1494 1.1 mrg bl SYM(raise) __PLT__
1495 1.4 mrg RETLDM r1 unwind=98b
1496 1.1 mrg
1497 1.1 mrg #ifdef __ARM_EABI__
1498 1.4 mrg cfi_end LSYM(Lend_aeabi_ldiv0)
1499 1.1 mrg FUNC_END aeabi_ldiv0
1500 1.1 mrg FUNC_END aeabi_idiv0
1501 1.1 mrg #else
1502 1.4 mrg cfi_end LSYM(Lend_div0)
1503 1.1 mrg FUNC_END div0
1504 1.1 mrg #endif
1505 1.1 mrg
1506 1.1 mrg #endif /* L_dvmd_lnx */
1507 1.1 mrg #ifdef L_clear_cache
1508 1.1 mrg #if defined __ARM_EABI__ && defined __linux__
1509 1.1 mrg @ EABI GNU/Linux call to cacheflush syscall.
1510 1.1 mrg ARM_FUNC_START clear_cache
1511 1.1 mrg do_push {r7}
1512 1.8 mrg #if __ARM_ARCH >= 7 || defined(__ARM_ARCH_6T2__)
1513 1.1 mrg movw r7, #2
1514 1.1 mrg movt r7, #0xf
1515 1.1 mrg #else
1516 1.1 mrg mov r7, #0xf0000
1517 1.1 mrg add r7, r7, #2
1518 1.1 mrg #endif
1519 1.1 mrg mov r2, #0
1520 1.1 mrg swi 0
1521 1.1 mrg do_pop {r7}
1522 1.1 mrg RET
1523 1.1 mrg FUNC_END clear_cache
1524 1.1 mrg #else
1525 1.1 mrg #error "This is only for ARM EABI GNU/Linux"
1526 1.1 mrg #endif
1527 1.1 mrg #endif /* L_clear_cache */
1528 1.8 mrg
1529 1.8 mrg #ifdef L_speculation_barrier
1530 1.8 mrg FUNC_START speculation_barrier
1531 1.8 mrg #if __ARM_ARCH >= 7
1532 1.8 mrg isb
1533 1.8 mrg dsb sy
1534 1.8 mrg #elif defined __ARM_EABI__ && defined __linux__
1535 1.8 mrg /* We don't have a speculation barrier directly for this
1536 1.8 mrg platform/architecture variant. But we can use a kernel
1537 1.8 mrg clear_cache service routine which will emit such instructions
1538 1.8 mrg if run on a later version of the architecture. We don't
1539 1.8 mrg really want to flush the cache, but we must give it a valid
1540 1.8 mrg address, so just clear pc..pc+1. */
1541 1.8 mrg #if defined __thumb__ && !defined __thumb2__
1542 1.8 mrg push {r7}
1543 1.8 mrg mov r7, #0xf
1544 1.8 mrg lsl r7, #16
1545 1.8 mrg add r7, #2
1546 1.8 mrg adr r0, . + 4
1547 1.8 mrg add r1, r0, #1
1548 1.8 mrg mov r2, #0
1549 1.8 mrg svc 0
1550 1.8 mrg pop {r7}
1551 1.8 mrg #else
1552 1.8 mrg do_push {r7}
1553 1.8 mrg #ifdef __ARM_ARCH_6T2__
1554 1.8 mrg movw r7, #2
1555 1.8 mrg movt r7, #0xf
1556 1.8 mrg #else
1557 1.8 mrg mov r7, #0xf0000
1558 1.8 mrg add r7, r7, #2
1559 1.8 mrg #endif
1560 1.8 mrg add r0, pc, #0 /* ADR. */
1561 1.8 mrg add r1, r0, #1
1562 1.8 mrg mov r2, #0
1563 1.8 mrg svc 0
1564 1.8 mrg do_pop {r7}
1565 1.8 mrg #endif /* Thumb1 only */
1566 1.8 mrg #else
1567 1.8 mrg #warning "No speculation barrier defined for this platform"
1568 1.8 mrg #endif
1569 1.8 mrg RET
1570 1.8 mrg FUNC_END speculation_barrier
1571 1.8 mrg #endif
1572 1.1 mrg /* ------------------------------------------------------------------------ */
1573 1.1 mrg /* Dword shift operations. */
1574 1.1 mrg /* All the following Dword shift variants rely on the fact that
1575 1.1 mrg shft xxx, Reg
1576 1.1 mrg is in fact done as
1577 1.1 mrg shft xxx, (Reg & 255)
1578 1.1 mrg so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1579 1.1 mrg case of logical shifts) or the sign (for asr). */
1580 1.1 mrg
1581 1.1 mrg #ifdef __ARMEB__
1582 1.1 mrg #define al r1
1583 1.1 mrg #define ah r0
1584 1.1 mrg #else
1585 1.1 mrg #define al r0
1586 1.1 mrg #define ah r1
1587 1.1 mrg #endif
1588 1.1 mrg
1589 1.1 mrg /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1590 1.1 mrg #ifndef __symbian__
1591 1.1 mrg
1592 1.1 mrg #ifdef L_lshrdi3
1593 1.1 mrg
1594 1.1 mrg FUNC_START lshrdi3
1595 1.1 mrg FUNC_ALIAS aeabi_llsr lshrdi3
1596 1.1 mrg
1597 1.1 mrg #ifdef __thumb__
1598 1.1 mrg lsr al, r2
1599 1.1 mrg mov r3, ah
1600 1.1 mrg lsr ah, r2
1601 1.1 mrg mov ip, r3
1602 1.1 mrg sub r2, #32
1603 1.1 mrg lsr r3, r2
1604 1.1 mrg orr al, r3
1605 1.1 mrg neg r2, r2
1606 1.1 mrg mov r3, ip
1607 1.1 mrg lsl r3, r2
1608 1.1 mrg orr al, r3
1609 1.1 mrg RET
1610 1.1 mrg #else
1611 1.1 mrg subs r3, r2, #32
1612 1.1 mrg rsb ip, r2, #32
1613 1.1 mrg movmi al, al, lsr r2
1614 1.1 mrg movpl al, ah, lsr r3
1615 1.1 mrg orrmi al, al, ah, lsl ip
1616 1.1 mrg mov ah, ah, lsr r2
1617 1.1 mrg RET
1618 1.1 mrg #endif
1619 1.1 mrg FUNC_END aeabi_llsr
1620 1.1 mrg FUNC_END lshrdi3
1621 1.1 mrg
1622 1.1 mrg #endif
1623 1.1 mrg
1624 1.1 mrg #ifdef L_ashrdi3
1625 1.1 mrg
1626 1.1 mrg FUNC_START ashrdi3
1627 1.1 mrg FUNC_ALIAS aeabi_lasr ashrdi3
1628 1.1 mrg
1629 1.1 mrg #ifdef __thumb__
1630 1.1 mrg lsr al, r2
1631 1.1 mrg mov r3, ah
1632 1.1 mrg asr ah, r2
1633 1.1 mrg sub r2, #32
1634 1.1 mrg @ If r2 is negative at this point the following step would OR
1635 1.1 mrg @ the sign bit into all of AL. That's not what we want...
1636 1.1 mrg bmi 1f
1637 1.1 mrg mov ip, r3
1638 1.1 mrg asr r3, r2
1639 1.1 mrg orr al, r3
1640 1.1 mrg mov r3, ip
1641 1.1 mrg 1:
1642 1.1 mrg neg r2, r2
1643 1.1 mrg lsl r3, r2
1644 1.1 mrg orr al, r3
1645 1.1 mrg RET
1646 1.1 mrg #else
1647 1.1 mrg subs r3, r2, #32
1648 1.1 mrg rsb ip, r2, #32
1649 1.1 mrg movmi al, al, lsr r2
1650 1.1 mrg movpl al, ah, asr r3
1651 1.1 mrg orrmi al, al, ah, lsl ip
1652 1.1 mrg mov ah, ah, asr r2
1653 1.1 mrg RET
1654 1.1 mrg #endif
1655 1.1 mrg
1656 1.1 mrg FUNC_END aeabi_lasr
1657 1.1 mrg FUNC_END ashrdi3
1658 1.1 mrg
1659 1.1 mrg #endif
1660 1.1 mrg
1661 1.1 mrg #ifdef L_ashldi3
1662 1.1 mrg
1663 1.1 mrg FUNC_START ashldi3
1664 1.1 mrg FUNC_ALIAS aeabi_llsl ashldi3
1665 1.1 mrg
1666 1.1 mrg #ifdef __thumb__
1667 1.1 mrg lsl ah, r2
1668 1.1 mrg mov r3, al
1669 1.1 mrg lsl al, r2
1670 1.1 mrg mov ip, r3
1671 1.1 mrg sub r2, #32
1672 1.1 mrg lsl r3, r2
1673 1.1 mrg orr ah, r3
1674 1.1 mrg neg r2, r2
1675 1.1 mrg mov r3, ip
1676 1.1 mrg lsr r3, r2
1677 1.1 mrg orr ah, r3
1678 1.1 mrg RET
1679 1.1 mrg #else
1680 1.1 mrg subs r3, r2, #32
1681 1.1 mrg rsb ip, r2, #32
1682 1.1 mrg movmi ah, ah, lsl r2
1683 1.1 mrg movpl ah, al, lsl r3
1684 1.1 mrg orrmi ah, ah, al, lsr ip
1685 1.1 mrg mov al, al, lsl r2
1686 1.1 mrg RET
1687 1.1 mrg #endif
1688 1.1 mrg FUNC_END aeabi_llsl
1689 1.1 mrg FUNC_END ashldi3
1690 1.1 mrg
1691 1.1 mrg #endif
1692 1.1 mrg
1693 1.1 mrg #endif /* __symbian__ */
1694 1.1 mrg
1695 1.1 mrg #ifdef L_clzsi2
1696 1.6 mrg #ifdef NOT_ISA_TARGET_32BIT
1697 1.1 mrg FUNC_START clzsi2
1698 1.1 mrg mov r1, #28
1699 1.1 mrg mov r3, #1
1700 1.1 mrg lsl r3, r3, #16
1701 1.1 mrg cmp r0, r3 /* 0x10000 */
1702 1.1 mrg bcc 2f
1703 1.1 mrg lsr r0, r0, #16
1704 1.1 mrg sub r1, r1, #16
1705 1.1 mrg 2: lsr r3, r3, #8
1706 1.1 mrg cmp r0, r3 /* #0x100 */
1707 1.1 mrg bcc 2f
1708 1.1 mrg lsr r0, r0, #8
1709 1.1 mrg sub r1, r1, #8
1710 1.1 mrg 2: lsr r3, r3, #4
1711 1.1 mrg cmp r0, r3 /* #0x10 */
1712 1.1 mrg bcc 2f
1713 1.1 mrg lsr r0, r0, #4
1714 1.1 mrg sub r1, r1, #4
1715 1.1 mrg 2: adr r2, 1f
1716 1.1 mrg ldrb r0, [r2, r0]
1717 1.1 mrg add r0, r0, r1
1718 1.1 mrg bx lr
1719 1.1 mrg .align 2
1720 1.1 mrg 1:
1721 1.1 mrg .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1722 1.1 mrg FUNC_END clzsi2
1723 1.1 mrg #else
1724 1.1 mrg ARM_FUNC_START clzsi2
1725 1.8 mrg # if defined (__ARM_FEATURE_CLZ)
1726 1.1 mrg clz r0, r0
1727 1.1 mrg RET
1728 1.1 mrg # else
1729 1.1 mrg mov r1, #28
1730 1.1 mrg cmp r0, #0x10000
1731 1.1 mrg do_it cs, t
1732 1.1 mrg movcs r0, r0, lsr #16
1733 1.1 mrg subcs r1, r1, #16
1734 1.1 mrg cmp r0, #0x100
1735 1.1 mrg do_it cs, t
1736 1.1 mrg movcs r0, r0, lsr #8
1737 1.1 mrg subcs r1, r1, #8
1738 1.1 mrg cmp r0, #0x10
1739 1.1 mrg do_it cs, t
1740 1.1 mrg movcs r0, r0, lsr #4
1741 1.1 mrg subcs r1, r1, #4
1742 1.1 mrg adr r2, 1f
1743 1.1 mrg ldrb r0, [r2, r0]
1744 1.1 mrg add r0, r0, r1
1745 1.1 mrg RET
1746 1.1 mrg .align 2
1747 1.1 mrg 1:
1748 1.1 mrg .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1749 1.8 mrg # endif /* !defined (__ARM_FEATURE_CLZ) */
1750 1.1 mrg FUNC_END clzsi2
1751 1.1 mrg #endif
1752 1.1 mrg #endif /* L_clzsi2 */
1753 1.1 mrg
1754 1.1 mrg #ifdef L_clzdi2
1755 1.8 mrg #if !defined (__ARM_FEATURE_CLZ)
1756 1.1 mrg
1757 1.6 mrg # ifdef NOT_ISA_TARGET_32BIT
1758 1.1 mrg FUNC_START clzdi2
1759 1.1 mrg push {r4, lr}
1760 1.1 mrg # else
1761 1.1 mrg ARM_FUNC_START clzdi2
1762 1.1 mrg do_push {r4, lr}
1763 1.1 mrg # endif
1764 1.1 mrg cmp xxh, #0
1765 1.1 mrg bne 1f
1766 1.1 mrg # ifdef __ARMEB__
1767 1.1 mrg mov r0, xxl
1768 1.1 mrg bl __clzsi2
1769 1.1 mrg add r0, r0, #32
1770 1.1 mrg b 2f
1771 1.1 mrg 1:
1772 1.1 mrg bl __clzsi2
1773 1.1 mrg # else
1774 1.1 mrg bl __clzsi2
1775 1.1 mrg add r0, r0, #32
1776 1.1 mrg b 2f
1777 1.1 mrg 1:
1778 1.1 mrg mov r0, xxh
1779 1.1 mrg bl __clzsi2
1780 1.1 mrg # endif
1781 1.1 mrg 2:
1782 1.6 mrg # ifdef NOT_ISA_TARGET_32BIT
1783 1.1 mrg pop {r4, pc}
1784 1.1 mrg # else
1785 1.1 mrg RETLDM r4
1786 1.1 mrg # endif
1787 1.1 mrg FUNC_END clzdi2
1788 1.1 mrg
1789 1.8 mrg #else /* defined (__ARM_FEATURE_CLZ) */
1790 1.1 mrg
1791 1.1 mrg ARM_FUNC_START clzdi2
1792 1.1 mrg cmp xxh, #0
1793 1.1 mrg do_it eq, et
1794 1.1 mrg clzeq r0, xxl
1795 1.1 mrg clzne r0, xxh
1796 1.1 mrg addeq r0, r0, #32
1797 1.1 mrg RET
1798 1.1 mrg FUNC_END clzdi2
1799 1.1 mrg
1800 1.1 mrg #endif
1801 1.1 mrg #endif /* L_clzdi2 */
1802 1.1 mrg
1803 1.1 mrg #ifdef L_ctzsi2
1804 1.6 mrg #ifdef NOT_ISA_TARGET_32BIT
1805 1.1 mrg FUNC_START ctzsi2
1806 1.1 mrg neg r1, r0
1807 1.1 mrg and r0, r0, r1
1808 1.1 mrg mov r1, #28
1809 1.1 mrg mov r3, #1
1810 1.1 mrg lsl r3, r3, #16
1811 1.1 mrg cmp r0, r3 /* 0x10000 */
1812 1.1 mrg bcc 2f
1813 1.1 mrg lsr r0, r0, #16
1814 1.1 mrg sub r1, r1, #16
1815 1.1 mrg 2: lsr r3, r3, #8
1816 1.1 mrg cmp r0, r3 /* #0x100 */
1817 1.1 mrg bcc 2f
1818 1.1 mrg lsr r0, r0, #8
1819 1.1 mrg sub r1, r1, #8
1820 1.1 mrg 2: lsr r3, r3, #4
1821 1.1 mrg cmp r0, r3 /* #0x10 */
1822 1.1 mrg bcc 2f
1823 1.1 mrg lsr r0, r0, #4
1824 1.1 mrg sub r1, r1, #4
1825 1.1 mrg 2: adr r2, 1f
1826 1.1 mrg ldrb r0, [r2, r0]
1827 1.1 mrg sub r0, r0, r1
1828 1.1 mrg bx lr
1829 1.1 mrg .align 2
1830 1.1 mrg 1:
1831 1.1 mrg .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1832 1.1 mrg FUNC_END ctzsi2
1833 1.1 mrg #else
1834 1.1 mrg ARM_FUNC_START ctzsi2
1835 1.1 mrg rsb r1, r0, #0
1836 1.1 mrg and r0, r0, r1
1837 1.8 mrg # if defined (__ARM_FEATURE_CLZ)
1838 1.1 mrg clz r0, r0
1839 1.1 mrg rsb r0, r0, #31
1840 1.1 mrg RET
1841 1.1 mrg # else
1842 1.1 mrg mov r1, #28
1843 1.1 mrg cmp r0, #0x10000
1844 1.1 mrg do_it cs, t
1845 1.1 mrg movcs r0, r0, lsr #16
1846 1.1 mrg subcs r1, r1, #16
1847 1.1 mrg cmp r0, #0x100
1848 1.1 mrg do_it cs, t
1849 1.1 mrg movcs r0, r0, lsr #8
1850 1.1 mrg subcs r1, r1, #8
1851 1.1 mrg cmp r0, #0x10
1852 1.1 mrg do_it cs, t
1853 1.1 mrg movcs r0, r0, lsr #4
1854 1.1 mrg subcs r1, r1, #4
1855 1.1 mrg adr r2, 1f
1856 1.1 mrg ldrb r0, [r2, r0]
1857 1.1 mrg sub r0, r0, r1
1858 1.1 mrg RET
1859 1.1 mrg .align 2
1860 1.1 mrg 1:
1861 1.1 mrg .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1862 1.8 mrg # endif /* !defined (__ARM_FEATURE_CLZ) */
1863 1.1 mrg FUNC_END ctzsi2
1864 1.1 mrg #endif
1865 1.1 mrg #endif /* L_clzsi2 */
1866 1.1 mrg
1867 1.1 mrg /* ------------------------------------------------------------------------ */
1868 1.1 mrg /* These next two sections are here despite the fact that they contain Thumb
1869 1.1 mrg assembler because their presence allows interworked code to be linked even
1870 1.1 mrg when the GCC library is this one. */
1871 1.1 mrg
1872 1.1 mrg /* Do not build the interworking functions when the target architecture does
1873 1.1 mrg not support Thumb instructions. (This can be a multilib option). */
1874 1.1 mrg #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1875 1.1 mrg || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1876 1.8 mrg || __ARM_ARCH >= 6
1877 1.1 mrg
1878 1.1 mrg #if defined L_call_via_rX
1879 1.1 mrg
1880 1.1 mrg /* These labels & instructions are used by the Arm/Thumb interworking code.
1881 1.1 mrg The address of function to be called is loaded into a register and then
1882 1.1 mrg one of these labels is called via a BL instruction. This puts the
1883 1.1 mrg return address into the link register with the bottom bit set, and the
1884 1.1 mrg code here switches to the correct mode before executing the function. */
1885 1.1 mrg
1886 1.1 mrg .text
1887 1.1 mrg .align 0
1888 1.1 mrg .force_thumb
1889 1.1 mrg
1890 1.1 mrg .macro call_via register
1891 1.1 mrg THUMB_FUNC_START _call_via_\register
1892 1.1 mrg
1893 1.1 mrg bx \register
1894 1.1 mrg nop
1895 1.1 mrg
1896 1.1 mrg SIZE (_call_via_\register)
1897 1.1 mrg .endm
1898 1.1 mrg
1899 1.1 mrg call_via r0
1900 1.1 mrg call_via r1
1901 1.1 mrg call_via r2
1902 1.1 mrg call_via r3
1903 1.1 mrg call_via r4
1904 1.1 mrg call_via r5
1905 1.1 mrg call_via r6
1906 1.1 mrg call_via r7
1907 1.1 mrg call_via r8
1908 1.1 mrg call_via r9
1909 1.1 mrg call_via sl
1910 1.1 mrg call_via fp
1911 1.1 mrg call_via ip
1912 1.1 mrg call_via sp
1913 1.1 mrg call_via lr
1914 1.1 mrg
1915 1.1 mrg #endif /* L_call_via_rX */
1916 1.1 mrg
1917 1.1 mrg /* Don't bother with the old interworking routines for Thumb-2. */
1918 1.1 mrg /* ??? Maybe only omit these on "m" variants. */
1919 1.6 mrg #if !defined(__thumb2__) && __ARM_ARCH_ISA_ARM
1920 1.1 mrg
1921 1.1 mrg #if defined L_interwork_call_via_rX
1922 1.1 mrg
1923 1.1 mrg /* These labels & instructions are used by the Arm/Thumb interworking code,
1924 1.1 mrg when the target address is in an unknown instruction set. The address
1925 1.1 mrg of function to be called is loaded into a register and then one of these
1926 1.1 mrg labels is called via a BL instruction. This puts the return address
1927 1.1 mrg into the link register with the bottom bit set, and the code here
1928 1.1 mrg switches to the correct mode before executing the function. Unfortunately
1929 1.1 mrg the target code cannot be relied upon to return via a BX instruction, so
1930 1.1 mrg instead we have to store the resturn address on the stack and allow the
1931 1.1 mrg called function to return here instead. Upon return we recover the real
1932 1.1 mrg return address and use a BX to get back to Thumb mode.
1933 1.1 mrg
1934 1.1 mrg There are three variations of this code. The first,
1935 1.1 mrg _interwork_call_via_rN(), will push the return address onto the
1936 1.1 mrg stack and pop it in _arm_return(). It should only be used if all
1937 1.1 mrg arguments are passed in registers.
1938 1.1 mrg
1939 1.1 mrg The second, _interwork_r7_call_via_rN(), instead stores the return
1940 1.1 mrg address at [r7, #-4]. It is the caller's responsibility to ensure
1941 1.1 mrg that this address is valid and contains no useful data.
1942 1.1 mrg
1943 1.1 mrg The third, _interwork_r11_call_via_rN(), works in the same way but
1944 1.1 mrg uses r11 instead of r7. It is useful if the caller does not really
1945 1.1 mrg need a frame pointer. */
1946 1.1 mrg
1947 1.1 mrg .text
1948 1.1 mrg .align 0
1949 1.1 mrg
1950 1.1 mrg .code 32
1951 1.1 mrg .globl _arm_return
1952 1.1 mrg LSYM(Lstart_arm_return):
1953 1.1 mrg cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1954 1.1 mrg cfi_push 0, 0xe, -0x8, 0x8
1955 1.1 mrg nop @ This nop is for the benefit of debuggers, so that
1956 1.1 mrg @ backtraces will use the correct unwind information.
1957 1.1 mrg _arm_return:
1958 1.1 mrg RETLDM unwind=LSYM(Lstart_arm_return)
1959 1.1 mrg cfi_end LSYM(Lend_arm_return)
1960 1.1 mrg
1961 1.1 mrg .globl _arm_return_r7
1962 1.1 mrg _arm_return_r7:
1963 1.1 mrg ldr lr, [r7, #-4]
1964 1.1 mrg bx lr
1965 1.1 mrg
1966 1.1 mrg .globl _arm_return_r11
1967 1.1 mrg _arm_return_r11:
1968 1.1 mrg ldr lr, [r11, #-4]
1969 1.1 mrg bx lr
1970 1.1 mrg
1971 1.1 mrg .macro interwork_with_frame frame, register, name, return
1972 1.1 mrg .code 16
1973 1.1 mrg
1974 1.1 mrg THUMB_FUNC_START \name
1975 1.1 mrg
1976 1.1 mrg bx pc
1977 1.1 mrg nop
1978 1.1 mrg
1979 1.1 mrg .code 32
1980 1.1 mrg tst \register, #1
1981 1.1 mrg streq lr, [\frame, #-4]
1982 1.1 mrg adreq lr, _arm_return_\frame
1983 1.1 mrg bx \register
1984 1.1 mrg
1985 1.1 mrg SIZE (\name)
1986 1.1 mrg .endm
1987 1.1 mrg
1988 1.1 mrg .macro interwork register
1989 1.1 mrg .code 16
1990 1.1 mrg
1991 1.1 mrg THUMB_FUNC_START _interwork_call_via_\register
1992 1.1 mrg
1993 1.1 mrg bx pc
1994 1.1 mrg nop
1995 1.1 mrg
1996 1.1 mrg .code 32
1997 1.1 mrg .globl LSYM(Lchange_\register)
1998 1.1 mrg LSYM(Lchange_\register):
1999 1.1 mrg tst \register, #1
2000 1.1 mrg streq lr, [sp, #-8]!
2001 1.1 mrg adreq lr, _arm_return
2002 1.1 mrg bx \register
2003 1.1 mrg
2004 1.1 mrg SIZE (_interwork_call_via_\register)
2005 1.1 mrg
2006 1.1 mrg interwork_with_frame r7,\register,_interwork_r7_call_via_\register
2007 1.1 mrg interwork_with_frame r11,\register,_interwork_r11_call_via_\register
2008 1.1 mrg .endm
2009 1.1 mrg
2010 1.1 mrg interwork r0
2011 1.1 mrg interwork r1
2012 1.1 mrg interwork r2
2013 1.1 mrg interwork r3
2014 1.1 mrg interwork r4
2015 1.1 mrg interwork r5
2016 1.1 mrg interwork r6
2017 1.1 mrg interwork r7
2018 1.1 mrg interwork r8
2019 1.1 mrg interwork r9
2020 1.1 mrg interwork sl
2021 1.1 mrg interwork fp
2022 1.1 mrg interwork ip
2023 1.1 mrg interwork sp
2024 1.1 mrg
2025 1.1 mrg /* The LR case has to be handled a little differently... */
2026 1.1 mrg .code 16
2027 1.1 mrg
2028 1.1 mrg THUMB_FUNC_START _interwork_call_via_lr
2029 1.1 mrg
2030 1.1 mrg bx pc
2031 1.1 mrg nop
2032 1.1 mrg
2033 1.1 mrg .code 32
2034 1.1 mrg .globl .Lchange_lr
2035 1.1 mrg .Lchange_lr:
2036 1.1 mrg tst lr, #1
2037 1.1 mrg stmeqdb r13!, {lr, pc}
2038 1.1 mrg mov ip, lr
2039 1.1 mrg adreq lr, _arm_return
2040 1.1 mrg bx ip
2041 1.1 mrg
2042 1.1 mrg SIZE (_interwork_call_via_lr)
2043 1.1 mrg
2044 1.1 mrg #endif /* L_interwork_call_via_rX */
2045 1.1 mrg #endif /* !__thumb2__ */
2046 1.1 mrg
2047 1.1 mrg /* Functions to support compact pic switch tables in thumb1 state.
2048 1.1 mrg All these routines take an index into the table in r0. The
2049 1.1 mrg table is at LR & ~1 (but this must be rounded up in the case
2050 1.1 mrg of 32-bit entires). They are only permitted to clobber r12
2051 1.1 mrg and r14 and r0 must be preserved on exit. */
2052 1.1 mrg #ifdef L_thumb1_case_sqi
2053 1.1 mrg
2054 1.1 mrg .text
2055 1.1 mrg .align 0
2056 1.1 mrg .force_thumb
2057 1.1 mrg .syntax unified
2058 1.1 mrg THUMB_FUNC_START __gnu_thumb1_case_sqi
2059 1.1 mrg push {r1}
2060 1.1 mrg mov r1, lr
2061 1.1 mrg lsrs r1, r1, #1
2062 1.1 mrg lsls r1, r1, #1
2063 1.1 mrg ldrsb r1, [r1, r0]
2064 1.1 mrg lsls r1, r1, #1
2065 1.1 mrg add lr, lr, r1
2066 1.1 mrg pop {r1}
2067 1.1 mrg bx lr
2068 1.1 mrg SIZE (__gnu_thumb1_case_sqi)
2069 1.1 mrg #endif
2070 1.1 mrg
2071 1.1 mrg #ifdef L_thumb1_case_uqi
2072 1.1 mrg
2073 1.1 mrg .text
2074 1.1 mrg .align 0
2075 1.1 mrg .force_thumb
2076 1.1 mrg .syntax unified
2077 1.1 mrg THUMB_FUNC_START __gnu_thumb1_case_uqi
2078 1.1 mrg push {r1}
2079 1.1 mrg mov r1, lr
2080 1.1 mrg lsrs r1, r1, #1
2081 1.1 mrg lsls r1, r1, #1
2082 1.1 mrg ldrb r1, [r1, r0]
2083 1.1 mrg lsls r1, r1, #1
2084 1.1 mrg add lr, lr, r1
2085 1.1 mrg pop {r1}
2086 1.1 mrg bx lr
2087 1.1 mrg SIZE (__gnu_thumb1_case_uqi)
2088 1.1 mrg #endif
2089 1.1 mrg
2090 1.1 mrg #ifdef L_thumb1_case_shi
2091 1.1 mrg
2092 1.1 mrg .text
2093 1.1 mrg .align 0
2094 1.1 mrg .force_thumb
2095 1.1 mrg .syntax unified
2096 1.1 mrg THUMB_FUNC_START __gnu_thumb1_case_shi
2097 1.1 mrg push {r0, r1}
2098 1.1 mrg mov r1, lr
2099 1.1 mrg lsrs r1, r1, #1
2100 1.1 mrg lsls r0, r0, #1
2101 1.1 mrg lsls r1, r1, #1
2102 1.1 mrg ldrsh r1, [r1, r0]
2103 1.1 mrg lsls r1, r1, #1
2104 1.1 mrg add lr, lr, r1
2105 1.1 mrg pop {r0, r1}
2106 1.1 mrg bx lr
2107 1.1 mrg SIZE (__gnu_thumb1_case_shi)
2108 1.1 mrg #endif
2109 1.1 mrg
2110 1.1 mrg #ifdef L_thumb1_case_uhi
2111 1.1 mrg
2112 1.1 mrg .text
2113 1.1 mrg .align 0
2114 1.1 mrg .force_thumb
2115 1.1 mrg .syntax unified
2116 1.1 mrg THUMB_FUNC_START __gnu_thumb1_case_uhi
2117 1.1 mrg push {r0, r1}
2118 1.1 mrg mov r1, lr
2119 1.1 mrg lsrs r1, r1, #1
2120 1.1 mrg lsls r0, r0, #1
2121 1.1 mrg lsls r1, r1, #1
2122 1.1 mrg ldrh r1, [r1, r0]
2123 1.1 mrg lsls r1, r1, #1
2124 1.1 mrg add lr, lr, r1
2125 1.1 mrg pop {r0, r1}
2126 1.1 mrg bx lr
2127 1.1 mrg SIZE (__gnu_thumb1_case_uhi)
2128 1.1 mrg #endif
2129 1.1 mrg
2130 1.1 mrg #ifdef L_thumb1_case_si
2131 1.1 mrg
2132 1.1 mrg .text
2133 1.1 mrg .align 0
2134 1.1 mrg .force_thumb
2135 1.1 mrg .syntax unified
2136 1.1 mrg THUMB_FUNC_START __gnu_thumb1_case_si
2137 1.1 mrg push {r0, r1}
2138 1.1 mrg mov r1, lr
2139 1.1 mrg adds.n r1, r1, #2 /* Align to word. */
2140 1.1 mrg lsrs r1, r1, #2
2141 1.1 mrg lsls r0, r0, #2
2142 1.1 mrg lsls r1, r1, #2
2143 1.1 mrg ldr r0, [r1, r0]
2144 1.1 mrg adds r0, r0, r1
2145 1.1 mrg mov lr, r0
2146 1.1 mrg pop {r0, r1}
2147 1.1 mrg mov pc, lr /* We know we were called from thumb code. */
2148 1.1 mrg SIZE (__gnu_thumb1_case_si)
2149 1.1 mrg #endif
2150 1.1 mrg
2151 1.1 mrg #endif /* Arch supports thumb. */
2152 1.1 mrg
2153 1.4 mrg .macro CFI_START_FUNCTION
2154 1.4 mrg .cfi_startproc
2155 1.4 mrg .cfi_remember_state
2156 1.4 mrg .endm
2157 1.4 mrg
2158 1.4 mrg .macro CFI_END_FUNCTION
2159 1.4 mrg .cfi_restore_state
2160 1.4 mrg .cfi_endproc
2161 1.4 mrg .endm
2162 1.4 mrg
2163 1.1 mrg #ifndef __symbian__
2164 1.8 mrg /* The condition here must match the one in gcc/config/arm/elf.h and
2165 1.8 mrg libgcc/config/arm/t-elf. */
2166 1.6 mrg #ifndef NOT_ISA_TARGET_32BIT
2167 1.1 mrg #include "ieee754-df.S"
2168 1.1 mrg #include "ieee754-sf.S"
2169 1.1 mrg #include "bpabi.S"
2170 1.6 mrg #else /* NOT_ISA_TARGET_32BIT */
2171 1.1 mrg #include "bpabi-v6m.S"
2172 1.6 mrg #endif /* NOT_ISA_TARGET_32BIT */
2173 1.1 mrg #endif /* !__symbian__ */
2174