Merged r158465 through r158660 into branch.
[official-gcc.git] / gcc / config / arm / lib1funcs.asm
blob34aa23e6979c6b11b0846cb932c746f136ee4399
1 @ libgcc routines for ARM cpu.
2 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
4 /* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008,
5 2009, 2010 Free Software Foundation, Inc.
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
10 later version.
12 This file is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 /* An executable stack is *not* required for these functions. */
27 #if defined(__ELF__) && defined(__linux__)
28 .section .note.GNU-stack,"",%progbits
29 .previous
30 #endif /* __ELF__ and __linux__ */
32 #ifdef __ARM_EABI__
33 /* Some attributes that are common to all routines in this file. */
34 /* Tag_ABI_align_needed: This code does not require 8-byte
35 alignment from the caller. */
36 /* .eabi_attribute 24, 0 -- default setting. */
37 /* Tag_ABI_align_preserved: This code preserves 8-byte
38 alignment in any callee. */
39 .eabi_attribute 25, 1
40 #endif /* __ARM_EABI__ */
41 /* ------------------------------------------------------------------------ */
43 /* We need to know what prefix to add to function names. */
45 #ifndef __USER_LABEL_PREFIX__
46 #error __USER_LABEL_PREFIX__ not defined
47 #endif
49 /* ANSI concatenation macros. */
51 #define CONCAT1(a, b) CONCAT2(a, b)
52 #define CONCAT2(a, b) a ## b
54 /* Use the right prefix for global labels. */
56 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
58 #ifdef __ELF__
59 #ifdef __thumb__
60 #define __PLT__ /* Not supported in Thumb assembler (for now). */
61 #elif defined __vxworks && !defined __PIC__
62 #define __PLT__ /* Not supported by the kernel loader. */
63 #else
64 #define __PLT__ (PLT)
65 #endif
66 #define TYPE(x) .type SYM(x),function
67 #define SIZE(x) .size SYM(x), . - SYM(x)
68 #define LSYM(x) .x
69 #else
70 #define __PLT__
71 #define TYPE(x)
72 #define SIZE(x)
73 #define LSYM(x) x
74 #endif
76 /* Function end macros. Variants for interworking. */
78 #if defined(__ARM_ARCH_2__)
79 # define __ARM_ARCH__ 2
80 #endif
82 #if defined(__ARM_ARCH_3__)
83 # define __ARM_ARCH__ 3
84 #endif
86 #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
87 || defined(__ARM_ARCH_4T__)
88 /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
89 long multiply instructions. That includes v3M. */
90 # define __ARM_ARCH__ 4
91 #endif
93 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
94 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
95 || defined(__ARM_ARCH_5TEJ__)
96 # define __ARM_ARCH__ 5
97 #endif
99 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
100 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
101 || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
102 || defined(__ARM_ARCH_6M__)
103 # define __ARM_ARCH__ 6
104 #endif
106 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
107 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
108 # define __ARM_ARCH__ 7
109 #endif
111 #ifndef __ARM_ARCH__
112 #error Unable to determine architecture.
113 #endif
115 /* There are times when we might prefer Thumb1 code even if ARM code is
116 permitted, for example, the code might be smaller, or there might be
117 interworking problems with switching to ARM state if interworking is
118 disabled. */
119 #if (defined(__thumb__) \
120 && !defined(__thumb2__) \
121 && (!defined(__THUMB_INTERWORK__) \
122 || defined (__OPTIMIZE_SIZE__) \
123 || defined(__ARM_ARCH_6M__)))
124 # define __prefer_thumb__
125 #endif
127 /* How to return from a function call depends on the architecture variant. */
129 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
131 # define RET bx lr
132 # define RETc(x) bx##x lr
134 /* Special precautions for interworking on armv4t. */
135 # if (__ARM_ARCH__ == 4)
137 /* Always use bx, not ldr pc. */
138 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
139 # define __INTERWORKING__
140 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
142 /* Include thumb stub before arm mode code. */
143 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
144 # define __INTERWORKING_STUBS__
145 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
147 #endif /* __ARM_ARCH == 4 */
149 #else
151 # define RET mov pc, lr
152 # define RETc(x) mov##x pc, lr
154 #endif
156 .macro cfi_pop advance, reg, cfa_offset
157 #ifdef __ELF__
158 .pushsection .debug_frame
159 .byte 0x4 /* DW_CFA_advance_loc4 */
160 .4byte \advance
161 .byte (0xc0 | \reg) /* DW_CFA_restore */
162 .byte 0xe /* DW_CFA_def_cfa_offset */
163 .uleb128 \cfa_offset
164 .popsection
165 #endif
166 .endm
167 .macro cfi_push advance, reg, offset, cfa_offset
168 #ifdef __ELF__
169 .pushsection .debug_frame
170 .byte 0x4 /* DW_CFA_advance_loc4 */
171 .4byte \advance
172 .byte (0x80 | \reg) /* DW_CFA_offset */
173 .uleb128 (\offset / -4)
174 .byte 0xe /* DW_CFA_def_cfa_offset */
175 .uleb128 \cfa_offset
176 .popsection
177 #endif
178 .endm
179 .macro cfi_start start_label, end_label
180 #ifdef __ELF__
181 .pushsection .debug_frame
182 LSYM(Lstart_frame):
183 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
184 LSYM(Lstart_cie):
185 .4byte 0xffffffff @ CIE Identifier Tag
186 .byte 0x1 @ CIE Version
187 .ascii "\0" @ CIE Augmentation
188 .uleb128 0x1 @ CIE Code Alignment Factor
189 .sleb128 -4 @ CIE Data Alignment Factor
190 .byte 0xe @ CIE RA Column
191 .byte 0xc @ DW_CFA_def_cfa
192 .uleb128 0xd
193 .uleb128 0x0
195 .align 2
196 LSYM(Lend_cie):
197 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
198 LSYM(Lstart_fde):
199 .4byte LSYM(Lstart_frame) @ FDE CIE offset
200 .4byte \start_label @ FDE initial location
201 .4byte \end_label-\start_label @ FDE address range
202 .popsection
203 #endif
204 .endm
205 .macro cfi_end end_label
206 #ifdef __ELF__
207 .pushsection .debug_frame
208 .align 2
209 LSYM(Lend_fde):
210 .popsection
211 \end_label:
212 #endif
213 .endm
215 /* Don't pass dirn, it's there just to get token pasting right. */
217 .macro RETLDM regs=, cond=, unwind=, dirn=ia
218 #if defined (__INTERWORKING__)
219 .ifc "\regs",""
220 ldr\cond lr, [sp], #8
221 .else
222 # if defined(__thumb2__)
223 pop\cond {\regs, lr}
224 # else
225 ldm\cond\dirn sp!, {\regs, lr}
226 # endif
227 .endif
228 .ifnc "\unwind", ""
229 /* Mark LR as restored. */
230 97: cfi_pop 97b - \unwind, 0xe, 0x0
231 .endif
232 bx\cond lr
233 #else
234 /* Caller is responsible for providing IT instruction. */
235 .ifc "\regs",""
236 ldr\cond pc, [sp], #8
237 .else
238 # if defined(__thumb2__)
239 pop\cond {\regs, pc}
240 # else
241 ldm\cond\dirn sp!, {\regs, pc}
242 # endif
243 .endif
244 #endif
245 .endm
247 /* The Unified assembly syntax allows the same code to be assembled for both
248 ARM and Thumb-2. However this is only supported by recent gas, so define
249 a set of macros to allow ARM code on older assemblers. */
250 #if defined(__thumb2__)
251 .macro do_it cond, suffix=""
252 it\suffix \cond
253 .endm
254 .macro shift1 op, arg0, arg1, arg2
255 \op \arg0, \arg1, \arg2
256 .endm
257 #define do_push push
258 #define do_pop pop
259 #define COND(op1, op2, cond) op1 ## op2 ## cond
260 /* Perform an arithmetic operation with a variable shift operand. This
261 requires two instructions and a scratch register on Thumb-2. */
262 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
263 \shiftop \tmp, \src2, \shiftreg
264 \name \dest, \src1, \tmp
265 .endm
266 #else
267 .macro do_it cond, suffix=""
268 .endm
269 .macro shift1 op, arg0, arg1, arg2
270 mov \arg0, \arg1, \op \arg2
271 .endm
272 #define do_push stmfd sp!,
273 #define do_pop ldmfd sp!,
274 #define COND(op1, op2, cond) op1 ## cond ## op2
275 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
276 \name \dest, \src1, \src2, \shiftop \shiftreg
277 .endm
278 #endif
280 #ifdef __ARM_EABI__
281 .macro ARM_LDIV0 name signed
282 cmp r0, #0
283 .ifc \signed, unsigned
284 movne r0, #0xffffffff
285 .else
286 movgt r0, #0x7fffffff
287 movlt r0, #0x80000000
288 .endif
289 b SYM (__aeabi_idiv0) __PLT__
290 .endm
291 #else
292 .macro ARM_LDIV0 name signed
293 str lr, [sp, #-8]!
294 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
295 bl SYM (__div0) __PLT__
296 mov r0, #0 @ About as wrong as it could be.
297 RETLDM unwind=98b
298 .endm
299 #endif
302 #ifdef __ARM_EABI__
303 .macro THUMB_LDIV0 name signed
304 #if defined(__ARM_ARCH_6M__)
305 .ifc \signed, unsigned
306 cmp r0, #0
307 beq 1f
308 mov r0, #0
309 mvn r0, r0 @ 0xffffffff
311 .else
312 cmp r0, #0
313 beq 2f
314 blt 3f
315 mov r0, #0
316 mvn r0, r0
317 lsr r0, r0, #1 @ 0x7fffffff
318 b 2f
319 3: mov r0, #0x80
320 lsl r0, r0, #24 @ 0x80000000
322 .endif
323 push {r0, r1, r2}
324 ldr r0, 4f
325 adr r1, 4f
326 add r0, r1
327 str r0, [sp, #8]
328 @ We know we are not on armv4t, so pop pc is safe.
329 pop {r0, r1, pc}
330 .align 2
332 .word __aeabi_idiv0 - 4b
333 #elif defined(__thumb2__)
334 .syntax unified
335 .ifc \signed, unsigned
336 cbz r0, 1f
337 mov r0, #0xffffffff
339 .else
340 cmp r0, #0
341 do_it gt
342 movgt r0, #0x7fffffff
343 do_it lt
344 movlt r0, #0x80000000
345 .endif
346 b.w SYM(__aeabi_idiv0) __PLT__
347 #else
348 .align 2
349 bx pc
351 .arm
352 cmp r0, #0
353 .ifc \signed, unsigned
354 movne r0, #0xffffffff
355 .else
356 movgt r0, #0x7fffffff
357 movlt r0, #0x80000000
358 .endif
359 b SYM(__aeabi_idiv0) __PLT__
360 .thumb
361 #endif
362 .endm
363 #else
364 .macro THUMB_LDIV0 name signed
365 push { r1, lr }
366 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
367 bl SYM (__div0)
368 mov r0, #0 @ About as wrong as it could be.
369 #if defined (__INTERWORKING__)
370 pop { r1, r2 }
371 bx r2
372 #else
373 pop { r1, pc }
374 #endif
375 .endm
376 #endif
378 .macro FUNC_END name
379 SIZE (__\name)
380 .endm
382 .macro DIV_FUNC_END name signed
383 cfi_start __\name, LSYM(Lend_div0)
384 LSYM(Ldiv0):
385 #ifdef __thumb__
386 THUMB_LDIV0 \name \signed
387 #else
388 ARM_LDIV0 \name \signed
389 #endif
390 cfi_end LSYM(Lend_div0)
391 FUNC_END \name
392 .endm
394 .macro THUMB_FUNC_START name
395 .globl SYM (\name)
396 TYPE (\name)
397 .thumb_func
398 SYM (\name):
399 .endm
401 /* Function start macros. Variants for ARM and Thumb. */
403 #ifdef __thumb__
404 #define THUMB_FUNC .thumb_func
405 #define THUMB_CODE .force_thumb
406 # if defined(__thumb2__)
407 #define THUMB_SYNTAX .syntax divided
408 # else
409 #define THUMB_SYNTAX
410 # endif
411 #else
412 #define THUMB_FUNC
413 #define THUMB_CODE
414 #define THUMB_SYNTAX
415 #endif
417 .macro FUNC_START name
418 .text
419 .globl SYM (__\name)
420 TYPE (__\name)
421 .align 0
422 THUMB_CODE
423 THUMB_FUNC
424 THUMB_SYNTAX
425 SYM (__\name):
426 .endm
428 /* Special function that will always be coded in ARM assembly, even if
429 in Thumb-only compilation. */
431 #if defined(__thumb2__)
433 /* For Thumb-2 we build everything in thumb mode. */
434 .macro ARM_FUNC_START name
435 FUNC_START \name
436 .syntax unified
437 .endm
438 #define EQUIV .thumb_set
439 .macro ARM_CALL name
440 bl __\name
441 .endm
443 #elif defined(__INTERWORKING_STUBS__)
445 .macro ARM_FUNC_START name
446 FUNC_START \name
447 bx pc
449 .arm
450 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
451 directly from other local arm routines. */
452 _L__\name:
453 .endm
454 #define EQUIV .thumb_set
455 /* Branch directly to a function declared with ARM_FUNC_START.
456 Must be called in arm mode. */
457 .macro ARM_CALL name
458 bl _L__\name
459 .endm
461 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
463 #ifdef __ARM_ARCH_6M__
464 #define EQUIV .thumb_set
465 #else
466 .macro ARM_FUNC_START name
467 .text
468 .globl SYM (__\name)
469 TYPE (__\name)
470 .align 0
471 .arm
472 SYM (__\name):
473 .endm
474 #define EQUIV .set
475 .macro ARM_CALL name
476 bl __\name
477 .endm
478 #endif
480 #endif
482 .macro FUNC_ALIAS new old
483 .globl SYM (__\new)
484 #if defined (__thumb__)
485 .thumb_set SYM (__\new), SYM (__\old)
486 #else
487 .set SYM (__\new), SYM (__\old)
488 #endif
489 .endm
491 #ifndef __ARM_ARCH_6M__
492 .macro ARM_FUNC_ALIAS new old
493 .globl SYM (__\new)
494 EQUIV SYM (__\new), SYM (__\old)
495 #if defined(__INTERWORKING_STUBS__)
496 .set SYM (_L__\new), SYM (_L__\old)
497 #endif
498 .endm
499 #endif
501 #ifdef __ARMEB__
502 #define xxh r0
503 #define xxl r1
504 #define yyh r2
505 #define yyl r3
506 #else
507 #define xxh r1
508 #define xxl r0
509 #define yyh r3
510 #define yyl r2
511 #endif
513 #ifdef __ARM_EABI__
514 .macro WEAK name
515 .weak SYM (__\name)
516 .endm
517 #endif
519 #ifdef __thumb__
520 /* Register aliases. */
522 work .req r4 @ XXXX is this safe ?
523 dividend .req r0
524 divisor .req r1
525 overdone .req r2
526 result .req r2
527 curbit .req r3
528 #endif
529 #if 0
530 ip .req r12
531 sp .req r13
532 lr .req r14
533 pc .req r15
534 #endif
536 /* ------------------------------------------------------------------------ */
537 /* Bodies of the division and modulo routines. */
538 /* ------------------------------------------------------------------------ */
539 .macro ARM_DIV_BODY dividend, divisor, result, curbit
541 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
543 #if defined (__thumb2__)
544 clz \curbit, \dividend
545 clz \result, \divisor
546 sub \curbit, \result, \curbit
547 rsb \curbit, \curbit, #31
548 adr \result, 1f
549 add \curbit, \result, \curbit, lsl #4
550 mov \result, #0
551 mov pc, \curbit
552 .p2align 3
554 .set shift, 32
555 .rept 32
556 .set shift, shift - 1
557 cmp.w \dividend, \divisor, lsl #shift
558 nop.n
559 adc.w \result, \result, \result
560 it cs
561 subcs.w \dividend, \dividend, \divisor, lsl #shift
562 .endr
563 #else
564 clz \curbit, \dividend
565 clz \result, \divisor
566 sub \curbit, \result, \curbit
567 rsbs \curbit, \curbit, #31
568 addne \curbit, \curbit, \curbit, lsl #1
569 mov \result, #0
570 addne pc, pc, \curbit, lsl #2
572 .set shift, 32
573 .rept 32
574 .set shift, shift - 1
575 cmp \dividend, \divisor, lsl #shift
576 adc \result, \result, \result
577 subcs \dividend, \dividend, \divisor, lsl #shift
578 .endr
579 #endif
581 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
582 #if __ARM_ARCH__ >= 5
584 clz \curbit, \divisor
585 clz \result, \dividend
586 sub \result, \curbit, \result
587 mov \curbit, #1
588 mov \divisor, \divisor, lsl \result
589 mov \curbit, \curbit, lsl \result
590 mov \result, #0
592 #else /* __ARM_ARCH__ < 5 */
594 @ Initially shift the divisor left 3 bits if possible,
595 @ set curbit accordingly. This allows for curbit to be located
596 @ at the left end of each 4-bit nibbles in the division loop
597 @ to save one loop in most cases.
598 tst \divisor, #0xe0000000
599 moveq \divisor, \divisor, lsl #3
600 moveq \curbit, #8
601 movne \curbit, #1
603 @ Unless the divisor is very big, shift it up in multiples of
604 @ four bits, since this is the amount of unwinding in the main
605 @ division loop. Continue shifting until the divisor is
606 @ larger than the dividend.
607 1: cmp \divisor, #0x10000000
608 cmplo \divisor, \dividend
609 movlo \divisor, \divisor, lsl #4
610 movlo \curbit, \curbit, lsl #4
611 blo 1b
613 @ For very big divisors, we must shift it a bit at a time, or
614 @ we will be in danger of overflowing.
615 1: cmp \divisor, #0x80000000
616 cmplo \divisor, \dividend
617 movlo \divisor, \divisor, lsl #1
618 movlo \curbit, \curbit, lsl #1
619 blo 1b
621 mov \result, #0
623 #endif /* __ARM_ARCH__ < 5 */
625 @ Division loop
626 1: cmp \dividend, \divisor
627 do_it hs, t
628 subhs \dividend, \dividend, \divisor
629 orrhs \result, \result, \curbit
630 cmp \dividend, \divisor, lsr #1
631 do_it hs, t
632 subhs \dividend, \dividend, \divisor, lsr #1
633 orrhs \result, \result, \curbit, lsr #1
634 cmp \dividend, \divisor, lsr #2
635 do_it hs, t
636 subhs \dividend, \dividend, \divisor, lsr #2
637 orrhs \result, \result, \curbit, lsr #2
638 cmp \dividend, \divisor, lsr #3
639 do_it hs, t
640 subhs \dividend, \dividend, \divisor, lsr #3
641 orrhs \result, \result, \curbit, lsr #3
642 cmp \dividend, #0 @ Early termination?
643 do_it hs, t
644 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
645 movne \divisor, \divisor, lsr #4
646 bne 1b
648 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
650 .endm
651 /* ------------------------------------------------------------------------ */
652 .macro ARM_DIV2_ORDER divisor, order
654 #if __ARM_ARCH__ >= 5
656 clz \order, \divisor
657 rsb \order, \order, #31
659 #else
661 cmp \divisor, #(1 << 16)
662 movhs \divisor, \divisor, lsr #16
663 movhs \order, #16
664 movlo \order, #0
666 cmp \divisor, #(1 << 8)
667 movhs \divisor, \divisor, lsr #8
668 addhs \order, \order, #8
670 cmp \divisor, #(1 << 4)
671 movhs \divisor, \divisor, lsr #4
672 addhs \order, \order, #4
674 cmp \divisor, #(1 << 2)
675 addhi \order, \order, #3
676 addls \order, \order, \divisor, lsr #1
678 #endif
680 .endm
681 /* ------------------------------------------------------------------------ */
682 .macro ARM_MOD_BODY dividend, divisor, order, spare
684 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
686 clz \order, \divisor
687 clz \spare, \dividend
688 sub \order, \order, \spare
689 rsbs \order, \order, #31
690 addne pc, pc, \order, lsl #3
692 .set shift, 32
693 .rept 32
694 .set shift, shift - 1
695 cmp \dividend, \divisor, lsl #shift
696 subcs \dividend, \dividend, \divisor, lsl #shift
697 .endr
699 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
700 #if __ARM_ARCH__ >= 5
702 clz \order, \divisor
703 clz \spare, \dividend
704 sub \order, \order, \spare
705 mov \divisor, \divisor, lsl \order
707 #else /* __ARM_ARCH__ < 5 */
709 mov \order, #0
711 @ Unless the divisor is very big, shift it up in multiples of
712 @ four bits, since this is the amount of unwinding in the main
713 @ division loop. Continue shifting until the divisor is
714 @ larger than the dividend.
715 1: cmp \divisor, #0x10000000
716 cmplo \divisor, \dividend
717 movlo \divisor, \divisor, lsl #4
718 addlo \order, \order, #4
719 blo 1b
721 @ For very big divisors, we must shift it a bit at a time, or
722 @ we will be in danger of overflowing.
723 1: cmp \divisor, #0x80000000
724 cmplo \divisor, \dividend
725 movlo \divisor, \divisor, lsl #1
726 addlo \order, \order, #1
727 blo 1b
729 #endif /* __ARM_ARCH__ < 5 */
731 @ Perform all needed substractions to keep only the reminder.
732 @ Do comparisons in batch of 4 first.
733 subs \order, \order, #3 @ yes, 3 is intended here
734 blt 2f
736 1: cmp \dividend, \divisor
737 subhs \dividend, \dividend, \divisor
738 cmp \dividend, \divisor, lsr #1
739 subhs \dividend, \dividend, \divisor, lsr #1
740 cmp \dividend, \divisor, lsr #2
741 subhs \dividend, \dividend, \divisor, lsr #2
742 cmp \dividend, \divisor, lsr #3
743 subhs \dividend, \dividend, \divisor, lsr #3
744 cmp \dividend, #1
745 mov \divisor, \divisor, lsr #4
746 subges \order, \order, #4
747 bge 1b
749 tst \order, #3
750 teqne \dividend, #0
751 beq 5f
753 @ Either 1, 2 or 3 comparison/substractions are left.
754 2: cmn \order, #2
755 blt 4f
756 beq 3f
757 cmp \dividend, \divisor
758 subhs \dividend, \dividend, \divisor
759 mov \divisor, \divisor, lsr #1
760 3: cmp \dividend, \divisor
761 subhs \dividend, \dividend, \divisor
762 mov \divisor, \divisor, lsr #1
763 4: cmp \dividend, \divisor
764 subhs \dividend, \dividend, \divisor
767 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
769 .endm
770 /* ------------------------------------------------------------------------ */
771 .macro THUMB_DIV_MOD_BODY modulo
772 @ Load the constant 0x10000000 into our work register.
773 mov work, #1
774 lsl work, #28
775 LSYM(Loop1):
776 @ Unless the divisor is very big, shift it up in multiples of
777 @ four bits, since this is the amount of unwinding in the main
778 @ division loop. Continue shifting until the divisor is
779 @ larger than the dividend.
780 cmp divisor, work
781 bhs LSYM(Lbignum)
782 cmp divisor, dividend
783 bhs LSYM(Lbignum)
784 lsl divisor, #4
785 lsl curbit, #4
786 b LSYM(Loop1)
787 LSYM(Lbignum):
788 @ Set work to 0x80000000
789 lsl work, #3
790 LSYM(Loop2):
791 @ For very big divisors, we must shift it a bit at a time, or
792 @ we will be in danger of overflowing.
793 cmp divisor, work
794 bhs LSYM(Loop3)
795 cmp divisor, dividend
796 bhs LSYM(Loop3)
797 lsl divisor, #1
798 lsl curbit, #1
799 b LSYM(Loop2)
800 LSYM(Loop3):
801 @ Test for possible subtractions ...
802 .if \modulo
803 @ ... On the final pass, this may subtract too much from the dividend,
804 @ so keep track of which subtractions are done, we can fix them up
805 @ afterwards.
806 mov overdone, #0
807 cmp dividend, divisor
808 blo LSYM(Lover1)
809 sub dividend, dividend, divisor
810 LSYM(Lover1):
811 lsr work, divisor, #1
812 cmp dividend, work
813 blo LSYM(Lover2)
814 sub dividend, dividend, work
815 mov ip, curbit
816 mov work, #1
817 ror curbit, work
818 orr overdone, curbit
819 mov curbit, ip
820 LSYM(Lover2):
821 lsr work, divisor, #2
822 cmp dividend, work
823 blo LSYM(Lover3)
824 sub dividend, dividend, work
825 mov ip, curbit
826 mov work, #2
827 ror curbit, work
828 orr overdone, curbit
829 mov curbit, ip
830 LSYM(Lover3):
831 lsr work, divisor, #3
832 cmp dividend, work
833 blo LSYM(Lover4)
834 sub dividend, dividend, work
835 mov ip, curbit
836 mov work, #3
837 ror curbit, work
838 orr overdone, curbit
839 mov curbit, ip
840 LSYM(Lover4):
841 mov ip, curbit
842 .else
843 @ ... and note which bits are done in the result. On the final pass,
844 @ this may subtract too much from the dividend, but the result will be ok,
845 @ since the "bit" will have been shifted out at the bottom.
846 cmp dividend, divisor
847 blo LSYM(Lover1)
848 sub dividend, dividend, divisor
849 orr result, result, curbit
850 LSYM(Lover1):
851 lsr work, divisor, #1
852 cmp dividend, work
853 blo LSYM(Lover2)
854 sub dividend, dividend, work
855 lsr work, curbit, #1
856 orr result, work
857 LSYM(Lover2):
858 lsr work, divisor, #2
859 cmp dividend, work
860 blo LSYM(Lover3)
861 sub dividend, dividend, work
862 lsr work, curbit, #2
863 orr result, work
864 LSYM(Lover3):
865 lsr work, divisor, #3
866 cmp dividend, work
867 blo LSYM(Lover4)
868 sub dividend, dividend, work
869 lsr work, curbit, #3
870 orr result, work
871 LSYM(Lover4):
872 .endif
874 cmp dividend, #0 @ Early termination?
875 beq LSYM(Lover5)
876 lsr curbit, #4 @ No, any more bits to do?
877 beq LSYM(Lover5)
878 lsr divisor, #4
879 b LSYM(Loop3)
880 LSYM(Lover5):
881 .if \modulo
882 @ Any subtractions that we should not have done will be recorded in
883 @ the top three bits of "overdone". Exactly which were not needed
884 @ are governed by the position of the bit, stored in ip.
885 mov work, #0xe
886 lsl work, #28
887 and overdone, work
888 beq LSYM(Lgot_result)
890 @ If we terminated early, because dividend became zero, then the
891 @ bit in ip will not be in the bottom nibble, and we should not
892 @ perform the additions below. We must test for this though
893 @ (rather relying upon the TSTs to prevent the additions) since
894 @ the bit in ip could be in the top two bits which might then match
895 @ with one of the smaller RORs.
896 mov curbit, ip
897 mov work, #0x7
898 tst curbit, work
899 beq LSYM(Lgot_result)
901 mov curbit, ip
902 mov work, #3
903 ror curbit, work
904 tst overdone, curbit
905 beq LSYM(Lover6)
906 lsr work, divisor, #3
907 add dividend, work
908 LSYM(Lover6):
909 mov curbit, ip
910 mov work, #2
911 ror curbit, work
912 tst overdone, curbit
913 beq LSYM(Lover7)
914 lsr work, divisor, #2
915 add dividend, work
916 LSYM(Lover7):
917 mov curbit, ip
918 mov work, #1
919 ror curbit, work
920 tst overdone, curbit
921 beq LSYM(Lgot_result)
922 lsr work, divisor, #1
923 add dividend, work
924 .endif
925 LSYM(Lgot_result):
926 .endm
927 /* ------------------------------------------------------------------------ */
928 /* Start of the Real Functions */
929 /* ------------------------------------------------------------------------ */
930 #ifdef L_udivsi3
932 #if defined(__prefer_thumb__)
934 FUNC_START udivsi3
935 FUNC_ALIAS aeabi_uidiv udivsi3
937 cmp divisor, #0
938 beq LSYM(Ldiv0)
939 LSYM(udivsi3_skip_div0_test):
940 mov curbit, #1
941 mov result, #0
943 push { work }
944 cmp dividend, divisor
945 blo LSYM(Lgot_result)
947 THUMB_DIV_MOD_BODY 0
949 mov r0, result
950 pop { work }
953 #else /* ARM version/Thumb-2. */
955 ARM_FUNC_START udivsi3
956 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
958 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
959 check for division-by-zero a second time. */
960 LSYM(udivsi3_skip_div0_test):
961 subs r2, r1, #1
962 do_it eq
963 RETc(eq)
964 bcc LSYM(Ldiv0)
965 cmp r0, r1
966 bls 11f
967 tst r1, r2
968 beq 12f
970 ARM_DIV_BODY r0, r1, r2, r3
972 mov r0, r2
973 RET
975 11: do_it eq, e
976 moveq r0, #1
977 movne r0, #0
980 12: ARM_DIV2_ORDER r1, r2
982 mov r0, r0, lsr r2
985 #endif /* ARM version */
987 DIV_FUNC_END udivsi3 unsigned
989 #if defined(__prefer_thumb__)
990 FUNC_START aeabi_uidivmod
991 cmp r1, #0
992 beq LSYM(Ldiv0)
993 push {r0, r1, lr}
994 bl LSYM(udivsi3_skip_div0_test)
995 POP {r1, r2, r3}
996 mul r2, r0
997 sub r1, r1, r2
998 bx r3
999 #else
1000 ARM_FUNC_START aeabi_uidivmod
1001 cmp r1, #0
1002 beq LSYM(Ldiv0)
1003 stmfd sp!, { r0, r1, lr }
1004 bl LSYM(udivsi3_skip_div0_test)
1005 ldmfd sp!, { r1, r2, lr }
1006 mul r3, r2, r0
1007 sub r1, r1, r3
1009 #endif
1010 FUNC_END aeabi_uidivmod
1012 #endif /* L_udivsi3 */
1013 /* ------------------------------------------------------------------------ */
1014 #ifdef L_umodsi3
1016 FUNC_START umodsi3
1018 #ifdef __thumb__
1020 cmp divisor, #0
1021 beq LSYM(Ldiv0)
1022 mov curbit, #1
1023 cmp dividend, divisor
1024 bhs LSYM(Lover10)
1025 RET
1027 LSYM(Lover10):
1028 push { work }
1030 THUMB_DIV_MOD_BODY 1
1032 pop { work }
1035 #else /* ARM version. */
1037 subs r2, r1, #1 @ compare divisor with 1
1038 bcc LSYM(Ldiv0)
1039 cmpne r0, r1 @ compare dividend with divisor
1040 moveq r0, #0
1041 tsthi r1, r2 @ see if divisor is power of 2
1042 andeq r0, r0, r2
1043 RETc(ls)
1045 ARM_MOD_BODY r0, r1, r2, r3
1047 RET
1049 #endif /* ARM version. */
1051 DIV_FUNC_END umodsi3 unsigned
1053 #endif /* L_umodsi3 */
1054 /* ------------------------------------------------------------------------ */
1055 #ifdef L_divsi3
1057 #if defined(__prefer_thumb__)
1059 FUNC_START divsi3
1060 FUNC_ALIAS aeabi_idiv divsi3
1062 cmp divisor, #0
1063 beq LSYM(Ldiv0)
1064 LSYM(divsi3_skip_div0_test):
1065 push { work }
1066 mov work, dividend
1067 eor work, divisor @ Save the sign of the result.
1068 mov ip, work
1069 mov curbit, #1
1070 mov result, #0
1071 cmp divisor, #0
1072 bpl LSYM(Lover10)
1073 neg divisor, divisor @ Loops below use unsigned.
1074 LSYM(Lover10):
1075 cmp dividend, #0
1076 bpl LSYM(Lover11)
1077 neg dividend, dividend
1078 LSYM(Lover11):
1079 cmp dividend, divisor
1080 blo LSYM(Lgot_result)
1082 THUMB_DIV_MOD_BODY 0
1084 mov r0, result
1085 mov work, ip
1086 cmp work, #0
1087 bpl LSYM(Lover12)
1088 neg r0, r0
1089 LSYM(Lover12):
1090 pop { work }
1093 #else /* ARM/Thumb-2 version. */
1095 ARM_FUNC_START divsi3
1096 ARM_FUNC_ALIAS aeabi_idiv divsi3
1098 cmp r1, #0
1099 beq LSYM(Ldiv0)
1100 LSYM(divsi3_skip_div0_test):
1101 eor ip, r0, r1 @ save the sign of the result.
1102 do_it mi
1103 rsbmi r1, r1, #0 @ loops below use unsigned.
1104 subs r2, r1, #1 @ division by 1 or -1 ?
1105 beq 10f
1106 movs r3, r0
1107 do_it mi
1108 rsbmi r3, r0, #0 @ positive dividend value
1109 cmp r3, r1
1110 bls 11f
1111 tst r1, r2 @ divisor is power of 2 ?
1112 beq 12f
1114 ARM_DIV_BODY r3, r1, r0, r2
1116 cmp ip, #0
1117 do_it mi
1118 rsbmi r0, r0, #0
1119 RET
1121 10: teq ip, r0 @ same sign ?
1122 do_it mi
1123 rsbmi r0, r0, #0
1124 RET
1126 11: do_it lo
1127 movlo r0, #0
1128 do_it eq,t
1129 moveq r0, ip, asr #31
1130 orreq r0, r0, #1
1133 12: ARM_DIV2_ORDER r1, r2
1135 cmp ip, #0
1136 mov r0, r3, lsr r2
1137 do_it mi
1138 rsbmi r0, r0, #0
1141 #endif /* ARM version */
1143 DIV_FUNC_END divsi3 signed
1145 #if defined(__prefer_thumb__)
1146 FUNC_START aeabi_idivmod
1147 cmp r1, #0
1148 beq LSYM(Ldiv0)
1149 push {r0, r1, lr}
1150 bl LSYM(divsi3_skip_div0_test)
1151 POP {r1, r2, r3}
1152 mul r2, r0
1153 sub r1, r1, r2
1154 bx r3
1155 #else
1156 ARM_FUNC_START aeabi_idivmod
1157 cmp r1, #0
1158 beq LSYM(Ldiv0)
1159 stmfd sp!, { r0, r1, lr }
1160 bl LSYM(divsi3_skip_div0_test)
1161 ldmfd sp!, { r1, r2, lr }
1162 mul r3, r2, r0
1163 sub r1, r1, r3
1165 #endif
1166 FUNC_END aeabi_idivmod
1168 #endif /* L_divsi3 */
1169 /* ------------------------------------------------------------------------ */
1170 #ifdef L_modsi3
1172 FUNC_START modsi3
1174 #ifdef __thumb__
1176 mov curbit, #1
1177 cmp divisor, #0
1178 beq LSYM(Ldiv0)
1179 bpl LSYM(Lover10)
1180 neg divisor, divisor @ Loops below use unsigned.
1181 LSYM(Lover10):
1182 push { work }
1183 @ Need to save the sign of the dividend, unfortunately, we need
1184 @ work later on. Must do this after saving the original value of
1185 @ the work register, because we will pop this value off first.
1186 push { dividend }
1187 cmp dividend, #0
1188 bpl LSYM(Lover11)
1189 neg dividend, dividend
1190 LSYM(Lover11):
1191 cmp dividend, divisor
1192 blo LSYM(Lgot_result)
1194 THUMB_DIV_MOD_BODY 1
1196 pop { work }
1197 cmp work, #0
1198 bpl LSYM(Lover12)
1199 neg dividend, dividend
1200 LSYM(Lover12):
1201 pop { work }
1202 RET
1204 #else /* ARM version. */
1206 cmp r1, #0
1207 beq LSYM(Ldiv0)
1208 rsbmi r1, r1, #0 @ loops below use unsigned.
1209 movs ip, r0 @ preserve sign of dividend
1210 rsbmi r0, r0, #0 @ if negative make positive
1211 subs r2, r1, #1 @ compare divisor with 1
1212 cmpne r0, r1 @ compare dividend with divisor
1213 moveq r0, #0
1214 tsthi r1, r2 @ see if divisor is power of 2
1215 andeq r0, r0, r2
1216 bls 10f
1218 ARM_MOD_BODY r0, r1, r2, r3
1220 10: cmp ip, #0
1221 rsbmi r0, r0, #0
1222 RET
1224 #endif /* ARM version */
1226 DIV_FUNC_END modsi3 signed
1228 #endif /* L_modsi3 */
1229 /* ------------------------------------------------------------------------ */
1230 #ifdef L_dvmd_tls
1232 #ifdef __ARM_EABI__
1233 WEAK aeabi_idiv0
1234 WEAK aeabi_ldiv0
1235 FUNC_START aeabi_idiv0
1236 FUNC_START aeabi_ldiv0
1238 FUNC_END aeabi_ldiv0
1239 FUNC_END aeabi_idiv0
1240 #else
1241 FUNC_START div0
1243 FUNC_END div0
1244 #endif
1246 #endif /* L_divmodsi_tools */
1247 /* ------------------------------------------------------------------------ */
1248 #ifdef L_dvmd_lnx
1249 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1251 /* Constant taken from <asm/signal.h>. */
1252 #define SIGFPE 8
1254 #ifdef __ARM_EABI__
1255 WEAK aeabi_idiv0
1256 WEAK aeabi_ldiv0
1257 ARM_FUNC_START aeabi_idiv0
1258 ARM_FUNC_START aeabi_ldiv0
1259 #else
1260 ARM_FUNC_START div0
1261 #endif
1263 do_push {r1, lr}
1264 mov r0, #SIGFPE
1265 bl SYM(raise) __PLT__
1266 RETLDM r1
1268 #ifdef __ARM_EABI__
1269 FUNC_END aeabi_ldiv0
1270 FUNC_END aeabi_idiv0
1271 #else
1272 FUNC_END div0
1273 #endif
1275 #endif /* L_dvmd_lnx */
1276 #ifdef L_clear_cache
1277 #if defined __ARM_EABI__ && defined __linux__
1278 @ EABI GNU/Linux call to cacheflush syscall.
1279 ARM_FUNC_START clear_cache
1280 do_push {r7}
1281 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1282 movw r7, #2
1283 movt r7, #0xf
1284 #else
1285 mov r7, #0xf0000
1286 add r7, r7, #2
1287 #endif
1288 mov r2, #0
1289 swi 0
1290 do_pop {r7}
1292 FUNC_END clear_cache
1293 #else
1294 #error "This is only for ARM EABI GNU/Linux"
1295 #endif
1296 #endif /* L_clear_cache */
1297 /* ------------------------------------------------------------------------ */
1298 /* Dword shift operations. */
1299 /* All the following Dword shift variants rely on the fact that
1300 shft xxx, Reg
1301 is in fact done as
1302 shft xxx, (Reg & 255)
1303 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1304 case of logical shifts) or the sign (for asr). */
1306 #ifdef __ARMEB__
1307 #define al r1
1308 #define ah r0
1309 #else
1310 #define al r0
1311 #define ah r1
1312 #endif
1314 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1315 #ifndef __symbian__
1317 #ifdef L_lshrdi3
1319 FUNC_START lshrdi3
1320 FUNC_ALIAS aeabi_llsr lshrdi3
1322 #ifdef __thumb__
1323 lsr al, r2
1324 mov r3, ah
1325 lsr ah, r2
1326 mov ip, r3
1327 sub r2, #32
1328 lsr r3, r2
1329 orr al, r3
1330 neg r2, r2
1331 mov r3, ip
1332 lsl r3, r2
1333 orr al, r3
1335 #else
1336 subs r3, r2, #32
1337 rsb ip, r2, #32
1338 movmi al, al, lsr r2
1339 movpl al, ah, lsr r3
1340 orrmi al, al, ah, lsl ip
1341 mov ah, ah, lsr r2
1343 #endif
1344 FUNC_END aeabi_llsr
1345 FUNC_END lshrdi3
1347 #endif
1349 #ifdef L_ashrdi3
1351 FUNC_START ashrdi3
1352 FUNC_ALIAS aeabi_lasr ashrdi3
1354 #ifdef __thumb__
1355 lsr al, r2
1356 mov r3, ah
1357 asr ah, r2
1358 sub r2, #32
1359 @ If r2 is negative at this point the following step would OR
1360 @ the sign bit into all of AL. That's not what we want...
1361 bmi 1f
1362 mov ip, r3
1363 asr r3, r2
1364 orr al, r3
1365 mov r3, ip
1367 neg r2, r2
1368 lsl r3, r2
1369 orr al, r3
1371 #else
1372 subs r3, r2, #32
1373 rsb ip, r2, #32
1374 movmi al, al, lsr r2
1375 movpl al, ah, asr r3
1376 orrmi al, al, ah, lsl ip
1377 mov ah, ah, asr r2
1379 #endif
1381 FUNC_END aeabi_lasr
1382 FUNC_END ashrdi3
1384 #endif
1386 #ifdef L_ashldi3
1388 FUNC_START ashldi3
1389 FUNC_ALIAS aeabi_llsl ashldi3
1391 #ifdef __thumb__
1392 lsl ah, r2
1393 mov r3, al
1394 lsl al, r2
1395 mov ip, r3
1396 sub r2, #32
1397 lsl r3, r2
1398 orr ah, r3
1399 neg r2, r2
1400 mov r3, ip
1401 lsr r3, r2
1402 orr ah, r3
1404 #else
1405 subs r3, r2, #32
1406 rsb ip, r2, #32
1407 movmi ah, ah, lsl r2
1408 movpl ah, al, lsl r3
1409 orrmi ah, ah, al, lsr ip
1410 mov al, al, lsl r2
1412 #endif
1413 FUNC_END aeabi_llsl
1414 FUNC_END ashldi3
1416 #endif
1418 #endif /* __symbian__ */
1420 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1421 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1422 || defined(__ARM_ARCH_5TEJ__)
1423 #define HAVE_ARM_CLZ 1
1424 #endif
1426 #ifdef L_clzsi2
1427 #if defined(__ARM_ARCH_6M__)
1428 FUNC_START clzsi2
1429 mov r1, #28
1430 mov r3, #1
1431 lsl r3, r3, #16
1432 cmp r0, r3 /* 0x10000 */
1433 bcc 2f
1434 lsr r0, r0, #16
1435 sub r1, r1, #16
1436 2: lsr r3, r3, #8
1437 cmp r0, r3 /* #0x100 */
1438 bcc 2f
1439 lsr r0, r0, #8
1440 sub r1, r1, #8
1441 2: lsr r3, r3, #4
1442 cmp r0, r3 /* #0x10 */
1443 bcc 2f
1444 lsr r0, r0, #4
1445 sub r1, r1, #4
1446 2: adr r2, 1f
1447 ldrb r0, [r2, r0]
1448 add r0, r0, r1
1449 bx lr
1450 .align 2
1452 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1453 FUNC_END clzsi2
1454 #else
1455 ARM_FUNC_START clzsi2
1456 # if defined(HAVE_ARM_CLZ)
1457 clz r0, r0
1459 # else
1460 mov r1, #28
1461 cmp r0, #0x10000
1462 do_it cs, t
1463 movcs r0, r0, lsr #16
1464 subcs r1, r1, #16
1465 cmp r0, #0x100
1466 do_it cs, t
1467 movcs r0, r0, lsr #8
1468 subcs r1, r1, #8
1469 cmp r0, #0x10
1470 do_it cs, t
1471 movcs r0, r0, lsr #4
1472 subcs r1, r1, #4
1473 adr r2, 1f
1474 ldrb r0, [r2, r0]
1475 add r0, r0, r1
1477 .align 2
1479 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1480 # endif /* !HAVE_ARM_CLZ */
1481 FUNC_END clzsi2
1482 #endif
1483 #endif /* L_clzsi2 */
1485 #ifdef L_clzdi2
1486 #if !defined(HAVE_ARM_CLZ)
1488 # if defined(__ARM_ARCH_6M__)
1489 FUNC_START clzdi2
1490 push {r4, lr}
1491 # else
1492 ARM_FUNC_START clzdi2
1493 do_push {r4, lr}
1494 # endif
1495 cmp xxh, #0
1496 bne 1f
1497 # ifdef __ARMEB__
1498 mov r0, xxl
1499 bl __clzsi2
1500 add r0, r0, #32
1501 b 2f
1503 bl __clzsi2
1504 # else
1505 bl __clzsi2
1506 add r0, r0, #32
1507 b 2f
1509 mov r0, xxh
1510 bl __clzsi2
1511 # endif
1513 # if defined(__ARM_ARCH_6M__)
1514 pop {r4, pc}
1515 # else
1516 RETLDM r4
1517 # endif
1518 FUNC_END clzdi2
1520 #else /* HAVE_ARM_CLZ */
1522 ARM_FUNC_START clzdi2
1523 cmp xxh, #0
1524 do_it eq, et
1525 clzeq r0, xxl
1526 clzne r0, xxh
1527 addeq r0, r0, #32
1529 FUNC_END clzdi2
1531 #endif
1532 #endif /* L_clzdi2 */
1534 /* ------------------------------------------------------------------------ */
1535 /* These next two sections are here despite the fact that they contain Thumb
1536 assembler because their presence allows interworked code to be linked even
1537 when the GCC library is this one. */
1539 /* Do not build the interworking functions when the target architecture does
1540 not support Thumb instructions. (This can be a multilib option). */
1541 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1542 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1543 || __ARM_ARCH__ >= 6
1545 #if defined L_call_via_rX
1547 /* These labels & instructions are used by the Arm/Thumb interworking code.
1548 The address of function to be called is loaded into a register and then
1549 one of these labels is called via a BL instruction. This puts the
1550 return address into the link register with the bottom bit set, and the
1551 code here switches to the correct mode before executing the function. */
1553 .text
1554 .align 0
1555 .force_thumb
1557 .macro call_via register
1558 THUMB_FUNC_START _call_via_\register
1560 bx \register
1563 SIZE (_call_via_\register)
1564 .endm
1566 call_via r0
1567 call_via r1
1568 call_via r2
1569 call_via r3
1570 call_via r4
1571 call_via r5
1572 call_via r6
1573 call_via r7
1574 call_via r8
1575 call_via r9
1576 call_via sl
1577 call_via fp
1578 call_via ip
1579 call_via sp
1580 call_via lr
1582 #endif /* L_call_via_rX */
1584 /* Don't bother with the old interworking routines for Thumb-2. */
1585 /* ??? Maybe only omit these on "m" variants. */
1586 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1588 #if defined L_interwork_call_via_rX
1590 /* These labels & instructions are used by the Arm/Thumb interworking code,
1591 when the target address is in an unknown instruction set. The address
1592 of function to be called is loaded into a register and then one of these
1593 labels is called via a BL instruction. This puts the return address
1594 into the link register with the bottom bit set, and the code here
1595 switches to the correct mode before executing the function. Unfortunately
1596 the target code cannot be relied upon to return via a BX instruction, so
1597 instead we have to store the resturn address on the stack and allow the
1598 called function to return here instead. Upon return we recover the real
1599 return address and use a BX to get back to Thumb mode.
1601 There are three variations of this code. The first,
1602 _interwork_call_via_rN(), will push the return address onto the
1603 stack and pop it in _arm_return(). It should only be used if all
1604 arguments are passed in registers.
1606 The second, _interwork_r7_call_via_rN(), instead stores the return
1607 address at [r7, #-4]. It is the caller's responsibility to ensure
1608 that this address is valid and contains no useful data.
1610 The third, _interwork_r11_call_via_rN(), works in the same way but
1611 uses r11 instead of r7. It is useful if the caller does not really
1612 need a frame pointer. */
1614 .text
1615 .align 0
1617 .code 32
1618 .globl _arm_return
1619 LSYM(Lstart_arm_return):
1620 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1621 cfi_push 0, 0xe, -0x8, 0x8
1622 nop @ This nop is for the benefit of debuggers, so that
1623 @ backtraces will use the correct unwind information.
1624 _arm_return:
1625 RETLDM unwind=LSYM(Lstart_arm_return)
1626 cfi_end LSYM(Lend_arm_return)
1628 .globl _arm_return_r7
1629 _arm_return_r7:
1630 ldr lr, [r7, #-4]
1631 bx lr
1633 .globl _arm_return_r11
1634 _arm_return_r11:
1635 ldr lr, [r11, #-4]
1636 bx lr
1638 .macro interwork_with_frame frame, register, name, return
1639 .code 16
1641 THUMB_FUNC_START \name
1643 bx pc
1646 .code 32
1647 tst \register, #1
1648 streq lr, [\frame, #-4]
1649 adreq lr, _arm_return_\frame
1650 bx \register
1652 SIZE (\name)
1653 .endm
1655 .macro interwork register
1656 .code 16
1658 THUMB_FUNC_START _interwork_call_via_\register
1660 bx pc
1663 .code 32
1664 .globl LSYM(Lchange_\register)
1665 LSYM(Lchange_\register):
1666 tst \register, #1
1667 streq lr, [sp, #-8]!
1668 adreq lr, _arm_return
1669 bx \register
1671 SIZE (_interwork_call_via_\register)
1673 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1674 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1675 .endm
1677 interwork r0
1678 interwork r1
1679 interwork r2
1680 interwork r3
1681 interwork r4
1682 interwork r5
1683 interwork r6
1684 interwork r7
1685 interwork r8
1686 interwork r9
1687 interwork sl
1688 interwork fp
1689 interwork ip
1690 interwork sp
1692 /* The LR case has to be handled a little differently... */
1693 .code 16
1695 THUMB_FUNC_START _interwork_call_via_lr
1697 bx pc
1700 .code 32
1701 .globl .Lchange_lr
1702 .Lchange_lr:
1703 tst lr, #1
1704 stmeqdb r13!, {lr, pc}
1705 mov ip, lr
1706 adreq lr, _arm_return
1707 bx ip
1709 SIZE (_interwork_call_via_lr)
1711 #endif /* L_interwork_call_via_rX */
1712 #endif /* !__thumb2__ */
1714 /* Functions to support compact pic switch tables in thumb1 state.
1715 All these routines take an index into the table in r0. The
1716 table is at LR & ~1 (but this must be rounded up in the case
1717 of 32-bit entires). They are only permitted to clobber r12
1718 and r14 and r0 must be preserved on exit. */
1719 #ifdef L_thumb1_case_sqi
1721 .text
1722 .align 0
1723 .force_thumb
1724 .syntax unified
1725 THUMB_FUNC_START __gnu_thumb1_case_sqi
1726 push {r1}
1727 mov r1, lr
1728 lsrs r1, r1, #1
1729 lsls r1, r1, #1
1730 ldrsb r1, [r1, r0]
1731 lsls r1, r1, #1
1732 add lr, lr, r1
1733 pop {r1}
1734 bx lr
1735 SIZE (__gnu_thumb1_case_sqi)
1736 #endif
1738 #ifdef L_thumb1_case_uqi
1740 .text
1741 .align 0
1742 .force_thumb
1743 .syntax unified
1744 THUMB_FUNC_START __gnu_thumb1_case_uqi
1745 push {r1}
1746 mov r1, lr
1747 lsrs r1, r1, #1
1748 lsls r1, r1, #1
1749 ldrb r1, [r1, r0]
1750 lsls r1, r1, #1
1751 add lr, lr, r1
1752 pop {r1}
1753 bx lr
1754 SIZE (__gnu_thumb1_case_uqi)
1755 #endif
1757 #ifdef L_thumb1_case_shi
1759 .text
1760 .align 0
1761 .force_thumb
1762 .syntax unified
1763 THUMB_FUNC_START __gnu_thumb1_case_shi
1764 push {r0, r1}
1765 mov r1, lr
1766 lsrs r1, r1, #1
1767 lsls r0, r0, #1
1768 lsls r1, r1, #1
1769 ldrsh r1, [r1, r0]
1770 lsls r1, r1, #1
1771 add lr, lr, r1
1772 pop {r0, r1}
1773 bx lr
1774 SIZE (__gnu_thumb1_case_shi)
1775 #endif
1777 #ifdef L_thumb1_case_uhi
1779 .text
1780 .align 0
1781 .force_thumb
1782 .syntax unified
1783 THUMB_FUNC_START __gnu_thumb1_case_uhi
1784 push {r0, r1}
1785 mov r1, lr
1786 lsrs r1, r1, #1
1787 lsls r0, r0, #1
1788 lsls r1, r1, #1
1789 ldrh r1, [r1, r0]
1790 lsls r1, r1, #1
1791 add lr, lr, r1
1792 pop {r0, r1}
1793 bx lr
1794 SIZE (__gnu_thumb1_case_uhi)
1795 #endif
1797 #ifdef L_thumb1_case_si
1799 .text
1800 .align 0
1801 .force_thumb
1802 .syntax unified
1803 THUMB_FUNC_START __gnu_thumb1_case_si
1804 push {r0, r1}
1805 mov r1, lr
1806 adds.n r1, r1, #2 /* Align to word. */
1807 lsrs r1, r1, #2
1808 lsls r0, r0, #2
1809 lsls r1, r1, #2
1810 ldr r0, [r1, r0]
1811 adds r0, r0, r1
1812 mov lr, r0
1813 pop {r0, r1}
1814 mov pc, lr /* We know we were called from thumb code. */
1815 SIZE (__gnu_thumb1_case_si)
1816 #endif
1818 #endif /* Arch supports thumb. */
1820 #ifndef __symbian__
1821 #ifndef __ARM_ARCH_6M__
1822 #include "ieee754-df.S"
1823 #include "ieee754-sf.S"
1824 #include "bpabi.S"
1825 #else /* __ARM_ARCH_6M__ */
1826 #include "bpabi-v6m.S"
1827 #endif /* __ARM_ARCH_6M__ */
1828 #endif /* !__symbian__ */