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
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
30 #endif /* __ELF__ and __linux__ */
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. */
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
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)
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. */
66 #define TYPE(x) .type SYM(x),function
67 #define SIZE(x) .size SYM(x), . - SYM(x)
76 /* Function end macros. Variants for interworking. */
78 #if defined(__ARM_ARCH_2__)
79 # define __ARM_ARCH__ 2
82 #if defined(__ARM_ARCH_3__)
83 # define __ARM_ARCH__ 3
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
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
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
106 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
107 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
108 || defined(__ARM_ARCH_7EM__)
109 # define __ARM_ARCH__ 7
113 #error Unable to determine architecture.
116 /* There are times when we might prefer Thumb1 code even if ARM code is
117 permitted, for example, the code might be smaller, or there might be
118 interworking problems with switching to ARM state if interworking is
120 #if (defined(__thumb__) \
121 && !defined(__thumb2__) \
122 && (!defined(__THUMB_INTERWORK__) \
123 || defined (__OPTIMIZE_SIZE__) \
124 || defined(__ARM_ARCH_6M__)))
125 # define __prefer_thumb__
128 /* How to return from a function call depends on the architecture variant. */
130 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
133 # define RETc(x) bx##x lr
135 /* Special precautions for interworking on armv4t. */
136 # if (__ARM_ARCH__ == 4)
138 /* Always use bx, not ldr pc. */
139 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
140 # define __INTERWORKING__
141 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
143 /* Include thumb stub before arm mode code. */
144 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
145 # define __INTERWORKING_STUBS__
146 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
148 #endif /* __ARM_ARCH == 4 */
152 # define RET mov pc, lr
153 # define RETc(x) mov##x pc, lr
157 .macro cfi_pop advance, reg, cfa_offset
159 .pushsection .debug_frame
160 .byte 0x4 /* DW_CFA_advance_loc4 */
162 .byte (0xc0 | \reg) /* DW_CFA_restore */
163 .byte 0xe /* DW_CFA_def_cfa_offset */
168 .macro cfi_push advance, reg, offset, cfa_offset
170 .pushsection .debug_frame
171 .byte 0x4 /* DW_CFA_advance_loc4 */
173 .byte (0x80 | \reg) /* DW_CFA_offset */
174 .uleb128 (\offset / -4)
175 .byte 0xe /* DW_CFA_def_cfa_offset */
180 .macro cfi_start start_label, end_label
182 .pushsection .debug_frame
184 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
186 .4byte 0xffffffff @ CIE Identifier Tag
187 .byte 0x1 @ CIE Version
188 .ascii "\0" @ CIE Augmentation
189 .uleb128 0x1 @ CIE Code Alignment Factor
190 .sleb128 -4 @ CIE Data Alignment Factor
191 .byte 0xe @ CIE RA Column
192 .byte 0xc @ DW_CFA_def_cfa
198 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
200 .4byte LSYM(Lstart_frame) @ FDE CIE offset
201 .4byte \start_label @ FDE initial location
202 .4byte \end_label-\start_label @ FDE address range
206 .macro cfi_end end_label
208 .pushsection .debug_frame
216 /* Don't pass dirn, it's there just to get token pasting right. */
218 .macro RETLDM regs=, cond=, unwind=, dirn=ia
219 #if defined (__INTERWORKING__)
221 ldr\cond lr, [sp], #8
223 # if defined(__thumb2__)
226 ldm\cond\dirn sp!, {\regs, lr}
230 /* Mark LR as restored. */
231 97: cfi_pop 97b - \unwind, 0xe, 0x0
235 /* Caller is responsible for providing IT instruction. */
237 ldr\cond pc, [sp], #8
239 # if defined(__thumb2__)
242 ldm\cond\dirn sp!, {\regs, pc}
248 /* The Unified assembly syntax allows the same code to be assembled for both
249 ARM and Thumb-2. However this is only supported by recent gas, so define
250 a set of macros to allow ARM code on older assemblers. */
251 #if defined(__thumb2__)
252 .macro do_it cond, suffix=""
255 .macro shift1 op, arg0, arg1, arg2
256 \op \arg0, \arg1, \arg2
260 #define COND(op1, op2, cond) op1 ## op2 ## cond
261 /* Perform an arithmetic operation with a variable shift operand. This
262 requires two instructions and a scratch register on Thumb-2. */
263 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
264 \shiftop \tmp, \src2, \shiftreg
265 \name \dest, \src1, \tmp
268 .macro do_it cond, suffix=""
270 .macro shift1 op, arg0, arg1, arg2
271 mov \arg0, \arg1, \op \arg2
273 #define do_push stmfd sp!,
274 #define do_pop ldmfd sp!,
275 #define COND(op1, op2, cond) op1 ## cond ## op2
276 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
277 \name \dest, \src1, \src2, \shiftop \shiftreg
282 .macro ARM_LDIV0 name signed
284 .ifc \signed, unsigned
285 movne r0, #0xffffffff
287 movgt r0, #0x7fffffff
288 movlt r0, #0x80000000
290 b SYM (__aeabi_idiv0) __PLT__
293 .macro ARM_LDIV0 name signed
295 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
296 bl SYM (__div0) __PLT__
297 mov r0, #0 @ About as wrong as it could be.
304 .macro THUMB_LDIV0 name signed
305 #if defined(__ARM_ARCH_6M__)
306 .ifc \signed, unsigned
310 mvn r0, r0 @ 0xffffffff
318 lsr r0, r0, #1 @ 0x7fffffff
321 lsl r0, r0, #24 @ 0x80000000
329 @ We know we are not on armv4t, so pop pc is safe.
333 .word __aeabi_idiv0 - 4b
334 #elif defined(__thumb2__)
336 .ifc \signed, unsigned
343 movgt r0, #0x7fffffff
345 movlt r0, #0x80000000
347 b.w SYM(__aeabi_idiv0) __PLT__
354 .ifc \signed, unsigned
355 movne r0, #0xffffffff
357 movgt r0, #0x7fffffff
358 movlt r0, #0x80000000
360 b SYM(__aeabi_idiv0) __PLT__
365 .macro THUMB_LDIV0 name signed
367 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
369 mov r0, #0 @ About as wrong as it could be.
370 #if defined (__INTERWORKING__)
383 .macro DIV_FUNC_END name signed
384 cfi_start __\name, LSYM(Lend_div0)
387 THUMB_LDIV0 \name \signed
389 ARM_LDIV0 \name \signed
391 cfi_end LSYM(Lend_div0)
395 .macro THUMB_FUNC_START name
402 /* Function start macros. Variants for ARM and Thumb. */
405 #define THUMB_FUNC .thumb_func
406 #define THUMB_CODE .force_thumb
407 # if defined(__thumb2__)
408 #define THUMB_SYNTAX .syntax divided
418 .macro FUNC_START name
429 /* Special function that will always be coded in ARM assembly, even if
430 in Thumb-only compilation. */
432 #if defined(__thumb2__)
434 /* For Thumb-2 we build everything in thumb mode. */
435 .macro ARM_FUNC_START name
439 #define EQUIV .thumb_set
444 #elif defined(__INTERWORKING_STUBS__)
446 .macro ARM_FUNC_START name
451 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
452 directly from other local arm routines. */
455 #define EQUIV .thumb_set
456 /* Branch directly to a function declared with ARM_FUNC_START.
457 Must be called in arm mode. */
462 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
464 #ifdef __ARM_ARCH_6M__
465 #define EQUIV .thumb_set
467 .macro ARM_FUNC_START name
483 .macro FUNC_ALIAS new old
485 #if defined (__thumb__)
486 .thumb_set SYM (__\new), SYM (__\old)
488 .set SYM (__\new), SYM (__\old)
492 #ifndef __ARM_ARCH_6M__
493 .macro ARM_FUNC_ALIAS new old
495 EQUIV SYM (__\new), SYM (__\old)
496 #if defined(__INTERWORKING_STUBS__)
497 .set SYM (_L__\new), SYM (_L__\old)
521 /* Register aliases. */
523 work .req r4 @ XXXX is this safe ?
537 /* ------------------------------------------------------------------------ */
538 /* Bodies of the division and modulo routines. */
539 /* ------------------------------------------------------------------------ */
540 .macro ARM_DIV_BODY dividend, divisor, result, curbit
542 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
544 #if defined (__thumb2__)
545 clz \curbit, \dividend
546 clz \result, \divisor
547 sub \curbit, \result, \curbit
548 rsb \curbit, \curbit, #31
550 add \curbit, \result, \curbit, lsl #4
557 .set shift, shift - 1
558 cmp.w \dividend, \divisor, lsl #shift
560 adc.w \result, \result, \result
562 subcs.w \dividend, \dividend, \divisor, lsl #shift
565 clz \curbit, \dividend
566 clz \result, \divisor
567 sub \curbit, \result, \curbit
568 rsbs \curbit, \curbit, #31
569 addne \curbit, \curbit, \curbit, lsl #1
571 addne pc, pc, \curbit, lsl #2
575 .set shift, shift - 1
576 cmp \dividend, \divisor, lsl #shift
577 adc \result, \result, \result
578 subcs \dividend, \dividend, \divisor, lsl #shift
582 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
583 #if __ARM_ARCH__ >= 5
585 clz \curbit, \divisor
586 clz \result, \dividend
587 sub \result, \curbit, \result
589 mov \divisor, \divisor, lsl \result
590 mov \curbit, \curbit, lsl \result
593 #else /* __ARM_ARCH__ < 5 */
595 @ Initially shift the divisor left 3 bits if possible,
596 @ set curbit accordingly. This allows for curbit to be located
597 @ at the left end of each 4-bit nibbles in the division loop
598 @ to save one loop in most cases.
599 tst \divisor, #0xe0000000
600 moveq \divisor, \divisor, lsl #3
604 @ Unless the divisor is very big, shift it up in multiples of
605 @ four bits, since this is the amount of unwinding in the main
606 @ division loop. Continue shifting until the divisor is
607 @ larger than the dividend.
608 1: cmp \divisor, #0x10000000
609 cmplo \divisor, \dividend
610 movlo \divisor, \divisor, lsl #4
611 movlo \curbit, \curbit, lsl #4
614 @ For very big divisors, we must shift it a bit at a time, or
615 @ we will be in danger of overflowing.
616 1: cmp \divisor, #0x80000000
617 cmplo \divisor, \dividend
618 movlo \divisor, \divisor, lsl #1
619 movlo \curbit, \curbit, lsl #1
624 #endif /* __ARM_ARCH__ < 5 */
627 1: cmp \dividend, \divisor
629 subhs \dividend, \dividend, \divisor
630 orrhs \result, \result, \curbit
631 cmp \dividend, \divisor, lsr #1
633 subhs \dividend, \dividend, \divisor, lsr #1
634 orrhs \result, \result, \curbit, lsr #1
635 cmp \dividend, \divisor, lsr #2
637 subhs \dividend, \dividend, \divisor, lsr #2
638 orrhs \result, \result, \curbit, lsr #2
639 cmp \dividend, \divisor, lsr #3
641 subhs \dividend, \dividend, \divisor, lsr #3
642 orrhs \result, \result, \curbit, lsr #3
643 cmp \dividend, #0 @ Early termination?
645 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
646 movne \divisor, \divisor, lsr #4
649 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
652 /* ------------------------------------------------------------------------ */
653 .macro ARM_DIV2_ORDER divisor, order
655 #if __ARM_ARCH__ >= 5
658 rsb \order, \order, #31
662 cmp \divisor, #(1 << 16)
663 movhs \divisor, \divisor, lsr #16
667 cmp \divisor, #(1 << 8)
668 movhs \divisor, \divisor, lsr #8
669 addhs \order, \order, #8
671 cmp \divisor, #(1 << 4)
672 movhs \divisor, \divisor, lsr #4
673 addhs \order, \order, #4
675 cmp \divisor, #(1 << 2)
676 addhi \order, \order, #3
677 addls \order, \order, \divisor, lsr #1
682 /* ------------------------------------------------------------------------ */
683 .macro ARM_MOD_BODY dividend, divisor, order, spare
685 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
688 clz \spare, \dividend
689 sub \order, \order, \spare
690 rsbs \order, \order, #31
691 addne pc, pc, \order, lsl #3
695 .set shift, shift - 1
696 cmp \dividend, \divisor, lsl #shift
697 subcs \dividend, \dividend, \divisor, lsl #shift
700 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
701 #if __ARM_ARCH__ >= 5
704 clz \spare, \dividend
705 sub \order, \order, \spare
706 mov \divisor, \divisor, lsl \order
708 #else /* __ARM_ARCH__ < 5 */
712 @ Unless the divisor is very big, shift it up in multiples of
713 @ four bits, since this is the amount of unwinding in the main
714 @ division loop. Continue shifting until the divisor is
715 @ larger than the dividend.
716 1: cmp \divisor, #0x10000000
717 cmplo \divisor, \dividend
718 movlo \divisor, \divisor, lsl #4
719 addlo \order, \order, #4
722 @ For very big divisors, we must shift it a bit at a time, or
723 @ we will be in danger of overflowing.
724 1: cmp \divisor, #0x80000000
725 cmplo \divisor, \dividend
726 movlo \divisor, \divisor, lsl #1
727 addlo \order, \order, #1
730 #endif /* __ARM_ARCH__ < 5 */
732 @ Perform all needed substractions to keep only the reminder.
733 @ Do comparisons in batch of 4 first.
734 subs \order, \order, #3 @ yes, 3 is intended here
737 1: cmp \dividend, \divisor
738 subhs \dividend, \dividend, \divisor
739 cmp \dividend, \divisor, lsr #1
740 subhs \dividend, \dividend, \divisor, lsr #1
741 cmp \dividend, \divisor, lsr #2
742 subhs \dividend, \dividend, \divisor, lsr #2
743 cmp \dividend, \divisor, lsr #3
744 subhs \dividend, \dividend, \divisor, lsr #3
746 mov \divisor, \divisor, lsr #4
747 subges \order, \order, #4
754 @ Either 1, 2 or 3 comparison/substractions are left.
758 cmp \dividend, \divisor
759 subhs \dividend, \dividend, \divisor
760 mov \divisor, \divisor, lsr #1
761 3: cmp \dividend, \divisor
762 subhs \dividend, \dividend, \divisor
763 mov \divisor, \divisor, lsr #1
764 4: cmp \dividend, \divisor
765 subhs \dividend, \dividend, \divisor
768 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
771 /* ------------------------------------------------------------------------ */
772 .macro THUMB_DIV_MOD_BODY modulo
773 @ Load the constant 0x10000000 into our work register.
777 @ Unless the divisor is very big, shift it up in multiples of
778 @ four bits, since this is the amount of unwinding in the main
779 @ division loop. Continue shifting until the divisor is
780 @ larger than the dividend.
783 cmp divisor, dividend
789 @ Set work to 0x80000000
792 @ For very big divisors, we must shift it a bit at a time, or
793 @ we will be in danger of overflowing.
796 cmp divisor, dividend
802 @ Test for possible subtractions ...
804 @ ... On the final pass, this may subtract too much from the dividend,
805 @ so keep track of which subtractions are done, we can fix them up
808 cmp dividend, divisor
810 sub dividend, dividend, divisor
812 lsr work, divisor, #1
815 sub dividend, dividend, work
822 lsr work, divisor, #2
825 sub dividend, dividend, work
832 lsr work, divisor, #3
835 sub dividend, dividend, work
844 @ ... and note which bits are done in the result. On the final pass,
845 @ this may subtract too much from the dividend, but the result will be ok,
846 @ since the "bit" will have been shifted out at the bottom.
847 cmp dividend, divisor
849 sub dividend, dividend, divisor
850 orr result, result, curbit
852 lsr work, divisor, #1
855 sub dividend, dividend, work
859 lsr work, divisor, #2
862 sub dividend, dividend, work
866 lsr work, divisor, #3
869 sub dividend, dividend, work
875 cmp dividend, #0 @ Early termination?
877 lsr curbit, #4 @ No, any more bits to do?
883 @ Any subtractions that we should not have done will be recorded in
884 @ the top three bits of "overdone". Exactly which were not needed
885 @ are governed by the position of the bit, stored in ip.
889 beq LSYM(Lgot_result)
891 @ If we terminated early, because dividend became zero, then the
892 @ bit in ip will not be in the bottom nibble, and we should not
893 @ perform the additions below. We must test for this though
894 @ (rather relying upon the TSTs to prevent the additions) since
895 @ the bit in ip could be in the top two bits which might then match
896 @ with one of the smaller RORs.
900 beq LSYM(Lgot_result)
907 lsr work, divisor, #3
915 lsr work, divisor, #2
922 beq LSYM(Lgot_result)
923 lsr work, divisor, #1
928 /* ------------------------------------------------------------------------ */
929 /* Start of the Real Functions */
930 /* ------------------------------------------------------------------------ */
933 #if defined(__prefer_thumb__)
936 FUNC_ALIAS aeabi_uidiv udivsi3
940 LSYM(udivsi3_skip_div0_test):
945 cmp dividend, divisor
946 blo LSYM(Lgot_result)
954 #elif defined(__ARM_ARCH_EXT_IDIV__)
956 ARM_FUNC_START udivsi3
957 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
965 #else /* ARM version/Thumb-2. */
967 ARM_FUNC_START udivsi3
968 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
970 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
971 check for division-by-zero a second time. */
972 LSYM(udivsi3_skip_div0_test):
982 ARM_DIV_BODY r0, r1, r2, r3
992 12: ARM_DIV2_ORDER r1, r2
997 #endif /* ARM version */
999 DIV_FUNC_END udivsi3 unsigned
1001 #if defined(__prefer_thumb__)
1002 FUNC_START aeabi_uidivmod
1006 bl LSYM(udivsi3_skip_div0_test)
1011 #elif defined(__ARM_ARCH_EXT_IDIV__)
1012 ARM_FUNC_START aeabi_uidivmod
1020 ARM_FUNC_START aeabi_uidivmod
1023 stmfd sp!, { r0, r1, lr }
1024 bl LSYM(udivsi3_skip_div0_test)
1025 ldmfd sp!, { r1, r2, lr }
1030 FUNC_END aeabi_uidivmod
1032 #endif /* L_udivsi3 */
1033 /* ------------------------------------------------------------------------ */
1036 #ifdef __ARM_ARCH_EXT_IDIV__
1038 ARM_FUNC_START umodsi3
1046 #elif defined(__thumb__)
1053 cmp dividend, divisor
1060 THUMB_DIV_MOD_BODY 1
1065 #else /* ARM version. */
1069 subs r2, r1, #1 @ compare divisor with 1
1071 cmpne r0, r1 @ compare dividend with divisor
1073 tsthi r1, r2 @ see if divisor is power of 2
1077 ARM_MOD_BODY r0, r1, r2, r3
1081 #endif /* ARM version. */
1083 DIV_FUNC_END umodsi3 unsigned
1085 #endif /* L_umodsi3 */
1086 /* ------------------------------------------------------------------------ */
1089 #if defined(__prefer_thumb__)
1092 FUNC_ALIAS aeabi_idiv divsi3
1096 LSYM(divsi3_skip_div0_test):
1099 eor work, divisor @ Save the sign of the result.
1105 neg divisor, divisor @ Loops below use unsigned.
1109 neg dividend, dividend
1111 cmp dividend, divisor
1112 blo LSYM(Lgot_result)
1114 THUMB_DIV_MOD_BODY 0
1125 #elif defined(__ARM_ARCH_EXT_IDIV__)
1127 ARM_FUNC_START divsi3
1128 ARM_FUNC_ALIAS aeabi_idiv divsi3
1135 #else /* ARM/Thumb-2 version. */
1137 ARM_FUNC_START divsi3
1138 ARM_FUNC_ALIAS aeabi_idiv divsi3
1142 LSYM(divsi3_skip_div0_test):
1143 eor ip, r0, r1 @ save the sign of the result.
1145 rsbmi r1, r1, #0 @ loops below use unsigned.
1146 subs r2, r1, #1 @ division by 1 or -1 ?
1150 rsbmi r3, r0, #0 @ positive dividend value
1153 tst r1, r2 @ divisor is power of 2 ?
1156 ARM_DIV_BODY r3, r1, r0, r2
1163 10: teq ip, r0 @ same sign ?
1171 moveq r0, ip, asr #31
1175 12: ARM_DIV2_ORDER r1, r2
1183 #endif /* ARM version */
1185 DIV_FUNC_END divsi3 signed
1187 #if defined(__prefer_thumb__)
1188 FUNC_START aeabi_idivmod
1192 bl LSYM(divsi3_skip_div0_test)
1197 #elif defined(__ARM_ARCH_EXT_IDIV__)
1198 ARM_FUNC_START aeabi_idivmod
1206 ARM_FUNC_START aeabi_idivmod
1209 stmfd sp!, { r0, r1, lr }
1210 bl LSYM(divsi3_skip_div0_test)
1211 ldmfd sp!, { r1, r2, lr }
1216 FUNC_END aeabi_idivmod
1218 #endif /* L_divsi3 */
1219 /* ------------------------------------------------------------------------ */
1222 #if defined(__ARM_ARCH_EXT_IDIV__)
1224 ARM_FUNC_START modsi3
1233 #elif defined(__thumb__)
1241 neg divisor, divisor @ Loops below use unsigned.
1244 @ Need to save the sign of the dividend, unfortunately, we need
1245 @ work later on. Must do this after saving the original value of
1246 @ the work register, because we will pop this value off first.
1250 neg dividend, dividend
1252 cmp dividend, divisor
1253 blo LSYM(Lgot_result)
1255 THUMB_DIV_MOD_BODY 1
1260 neg dividend, dividend
1265 #else /* ARM version. */
1271 rsbmi r1, r1, #0 @ loops below use unsigned.
1272 movs ip, r0 @ preserve sign of dividend
1273 rsbmi r0, r0, #0 @ if negative make positive
1274 subs r2, r1, #1 @ compare divisor with 1
1275 cmpne r0, r1 @ compare dividend with divisor
1277 tsthi r1, r2 @ see if divisor is power of 2
1281 ARM_MOD_BODY r0, r1, r2, r3
1287 #endif /* ARM version */
1289 DIV_FUNC_END modsi3 signed
1291 #endif /* L_modsi3 */
1292 /* ------------------------------------------------------------------------ */
1298 FUNC_START aeabi_idiv0
1299 FUNC_START aeabi_ldiv0
1301 FUNC_END aeabi_ldiv0
1302 FUNC_END aeabi_idiv0
1309 #endif /* L_divmodsi_tools */
1310 /* ------------------------------------------------------------------------ */
1312 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1314 /* Constant taken from <asm/signal.h>. */
1320 ARM_FUNC_START aeabi_idiv0
1321 ARM_FUNC_START aeabi_ldiv0
1328 bl SYM(raise) __PLT__
1332 FUNC_END aeabi_ldiv0
1333 FUNC_END aeabi_idiv0
1338 #endif /* L_dvmd_lnx */
1339 #ifdef L_clear_cache
1340 #if defined __ARM_EABI__ && defined __linux__
1341 @ EABI GNU/Linux call to cacheflush syscall.
1342 ARM_FUNC_START clear_cache
1344 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1355 FUNC_END clear_cache
1357 #error "This is only for ARM EABI GNU/Linux"
1359 #endif /* L_clear_cache */
1360 /* ------------------------------------------------------------------------ */
1361 /* Dword shift operations. */
1362 /* All the following Dword shift variants rely on the fact that
1365 shft xxx, (Reg & 255)
1366 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1367 case of logical shifts) or the sign (for asr). */
1377 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1383 FUNC_ALIAS aeabi_llsr lshrdi3
1401 movmi al, al, lsr r2
1402 movpl al, ah, lsr r3
1403 orrmi al, al, ah, lsl ip
1415 FUNC_ALIAS aeabi_lasr ashrdi3
1422 @ If r2 is negative at this point the following step would OR
1423 @ the sign bit into all of AL. That's not what we want...
1437 movmi al, al, lsr r2
1438 movpl al, ah, asr r3
1439 orrmi al, al, ah, lsl ip
1452 FUNC_ALIAS aeabi_llsl ashldi3
1470 movmi ah, ah, lsl r2
1471 movpl ah, al, lsl r3
1472 orrmi ah, ah, al, lsr ip
1481 #endif /* __symbian__ */
1483 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1484 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1485 || defined(__ARM_ARCH_5TEJ__)
1486 #define HAVE_ARM_CLZ 1
1490 #if defined(__ARM_ARCH_6M__)
1495 cmp r0, r3 /* 0x10000 */
1500 cmp r0, r3 /* #0x100 */
1505 cmp r0, r3 /* #0x10 */
1515 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1518 ARM_FUNC_START clzsi2
1519 # if defined(HAVE_ARM_CLZ)
1526 movcs r0, r0, lsr #16
1530 movcs r0, r0, lsr #8
1534 movcs r0, r0, lsr #4
1542 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1543 # endif /* !HAVE_ARM_CLZ */
1546 #endif /* L_clzsi2 */
1549 #if !defined(HAVE_ARM_CLZ)
1551 # if defined(__ARM_ARCH_6M__)
1555 ARM_FUNC_START clzdi2
1576 # if defined(__ARM_ARCH_6M__)
1583 #else /* HAVE_ARM_CLZ */
1585 ARM_FUNC_START clzdi2
1595 #endif /* L_clzdi2 */
1598 #if defined(__ARM_ARCH_6M__)
1605 cmp r0, r3 /* 0x10000 */
1610 cmp r0, r3 /* #0x100 */
1615 cmp r0, r3 /* #0x10 */
1625 .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1628 ARM_FUNC_START ctzsi2
1631 # if defined(HAVE_ARM_CLZ)
1639 movcs r0, r0, lsr #16
1643 movcs r0, r0, lsr #8
1647 movcs r0, r0, lsr #4
1655 .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1656 # endif /* !HAVE_ARM_CLZ */
1659 #endif /* L_clzsi2 */
1661 /* ------------------------------------------------------------------------ */
1662 /* These next two sections are here despite the fact that they contain Thumb
1663 assembler because their presence allows interworked code to be linked even
1664 when the GCC library is this one. */
1666 /* Do not build the interworking functions when the target architecture does
1667 not support Thumb instructions. (This can be a multilib option). */
1668 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1669 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1670 || __ARM_ARCH__ >= 6
1672 #if defined L_call_via_rX
1674 /* These labels & instructions are used by the Arm/Thumb interworking code.
1675 The address of function to be called is loaded into a register and then
1676 one of these labels is called via a BL instruction. This puts the
1677 return address into the link register with the bottom bit set, and the
1678 code here switches to the correct mode before executing the function. */
1684 .macro call_via register
1685 THUMB_FUNC_START _call_via_\register
1690 SIZE (_call_via_\register)
1709 #endif /* L_call_via_rX */
1711 /* Don't bother with the old interworking routines for Thumb-2. */
1712 /* ??? Maybe only omit these on "m" variants. */
1713 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1715 #if defined L_interwork_call_via_rX
1717 /* These labels & instructions are used by the Arm/Thumb interworking code,
1718 when the target address is in an unknown instruction set. The address
1719 of function to be called is loaded into a register and then one of these
1720 labels is called via a BL instruction. This puts the return address
1721 into the link register with the bottom bit set, and the code here
1722 switches to the correct mode before executing the function. Unfortunately
1723 the target code cannot be relied upon to return via a BX instruction, so
1724 instead we have to store the resturn address on the stack and allow the
1725 called function to return here instead. Upon return we recover the real
1726 return address and use a BX to get back to Thumb mode.
1728 There are three variations of this code. The first,
1729 _interwork_call_via_rN(), will push the return address onto the
1730 stack and pop it in _arm_return(). It should only be used if all
1731 arguments are passed in registers.
1733 The second, _interwork_r7_call_via_rN(), instead stores the return
1734 address at [r7, #-4]. It is the caller's responsibility to ensure
1735 that this address is valid and contains no useful data.
1737 The third, _interwork_r11_call_via_rN(), works in the same way but
1738 uses r11 instead of r7. It is useful if the caller does not really
1739 need a frame pointer. */
1746 LSYM(Lstart_arm_return):
1747 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1748 cfi_push 0, 0xe, -0x8, 0x8
1749 nop @ This nop is for the benefit of debuggers, so that
1750 @ backtraces will use the correct unwind information.
1752 RETLDM unwind=LSYM(Lstart_arm_return)
1753 cfi_end LSYM(Lend_arm_return)
1755 .globl _arm_return_r7
1760 .globl _arm_return_r11
1765 .macro interwork_with_frame frame, register, name, return
1768 THUMB_FUNC_START \name
1775 streq lr, [\frame, #-4]
1776 adreq lr, _arm_return_\frame
1782 .macro interwork register
1785 THUMB_FUNC_START _interwork_call_via_\register
1791 .globl LSYM(Lchange_\register)
1792 LSYM(Lchange_\register):
1794 streq lr, [sp, #-8]!
1795 adreq lr, _arm_return
1798 SIZE (_interwork_call_via_\register)
1800 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1801 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1819 /* The LR case has to be handled a little differently... */
1822 THUMB_FUNC_START _interwork_call_via_lr
1831 stmeqdb r13!, {lr, pc}
1833 adreq lr, _arm_return
1836 SIZE (_interwork_call_via_lr)
1838 #endif /* L_interwork_call_via_rX */
1839 #endif /* !__thumb2__ */
1841 /* Functions to support compact pic switch tables in thumb1 state.
1842 All these routines take an index into the table in r0. The
1843 table is at LR & ~1 (but this must be rounded up in the case
1844 of 32-bit entires). They are only permitted to clobber r12
1845 and r14 and r0 must be preserved on exit. */
1846 #ifdef L_thumb1_case_sqi
1852 THUMB_FUNC_START __gnu_thumb1_case_sqi
1862 SIZE (__gnu_thumb1_case_sqi)
1865 #ifdef L_thumb1_case_uqi
1871 THUMB_FUNC_START __gnu_thumb1_case_uqi
1881 SIZE (__gnu_thumb1_case_uqi)
1884 #ifdef L_thumb1_case_shi
1890 THUMB_FUNC_START __gnu_thumb1_case_shi
1901 SIZE (__gnu_thumb1_case_shi)
1904 #ifdef L_thumb1_case_uhi
1910 THUMB_FUNC_START __gnu_thumb1_case_uhi
1921 SIZE (__gnu_thumb1_case_uhi)
1924 #ifdef L_thumb1_case_si
1930 THUMB_FUNC_START __gnu_thumb1_case_si
1933 adds.n r1, r1, #2 /* Align to word. */
1941 mov pc, lr /* We know we were called from thumb code. */
1942 SIZE (__gnu_thumb1_case_si)
1945 #endif /* Arch supports thumb. */
1948 #ifndef __ARM_ARCH_6M__
1949 #include "ieee754-df.S"
1950 #include "ieee754-sf.S"
1952 #else /* __ARM_ARCH_6M__ */
1953 #include "bpabi-v6m.S"
1954 #endif /* __ARM_ARCH_6M__ */
1955 #endif /* !__symbian__ */