1 @ libgcc routines for ARM cpu.
2 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
4 /* Copyright (C) 1995-2013 Free Software Foundation, Inc.
6 This file is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 /* An executable stack is *not* required for these functions. */
26 #if defined(__ELF__) && defined(__linux__)
27 .section .note.GNU-stack,"",%progbits
29 #endif /* __ELF__ and __linux__ */
32 /* Some attributes that are common to all routines in this file. */
33 /* Tag_ABI_align_needed: This code does not require 8-byte
34 alignment from the caller. */
35 /* .eabi_attribute 24, 0 -- default setting. */
36 /* Tag_ABI_align_preserved: This code preserves 8-byte
37 alignment in any callee. */
39 #endif /* __ARM_EABI__ */
40 /* ------------------------------------------------------------------------ */
42 /* We need to know what prefix to add to function names. */
44 #ifndef __USER_LABEL_PREFIX__
45 #error __USER_LABEL_PREFIX__ not defined
48 /* ANSI concatenation macros. */
50 #define CONCAT1(a, b) CONCAT2(a, b)
51 #define CONCAT2(a, b) a ## b
53 /* Use the right prefix for global labels. */
55 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
59 #define __PLT__ /* Not supported in Thumb assembler (for now). */
60 #elif defined __vxworks && !defined __PIC__
61 #define __PLT__ /* Not supported by the kernel loader. */
65 #define TYPE(x) .type SYM(x),function
66 #define SIZE(x) .size SYM(x), . - SYM(x)
75 /* Function end macros. Variants for interworking. */
77 #if defined(__ARM_ARCH_2__)
78 # define __ARM_ARCH__ 2
81 #if defined(__ARM_ARCH_3__)
82 # define __ARM_ARCH__ 3
85 #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
86 || defined(__ARM_ARCH_4T__)
87 /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
88 long multiply instructions. That includes v3M. */
89 # define __ARM_ARCH__ 4
92 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
93 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
94 || defined(__ARM_ARCH_5TEJ__)
95 # define __ARM_ARCH__ 5
98 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
99 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
100 || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
101 || defined(__ARM_ARCH_6M__)
102 # define __ARM_ARCH__ 6
105 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
106 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
107 || defined(__ARM_ARCH_7EM__)
108 # define __ARM_ARCH__ 7
111 #if defined(__ARM_ARCH_8A__)
112 # define __ARM_ARCH__ 8
116 #error Unable to determine architecture.
119 /* There are times when we might prefer Thumb1 code even if ARM code is
120 permitted, for example, the code might be smaller, or there might be
121 interworking problems with switching to ARM state if interworking is
123 #if (defined(__thumb__) \
124 && !defined(__thumb2__) \
125 && (!defined(__THUMB_INTERWORK__) \
126 || defined (__OPTIMIZE_SIZE__) \
127 || defined(__ARM_ARCH_6M__)))
128 # define __prefer_thumb__
131 /* How to return from a function call depends on the architecture variant. */
133 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
136 # define RETc(x) bx##x lr
138 /* Special precautions for interworking on armv4t. */
139 # if (__ARM_ARCH__ == 4)
141 /* Always use bx, not ldr pc. */
142 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
143 # define __INTERWORKING__
144 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
146 /* Include thumb stub before arm mode code. */
147 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
148 # define __INTERWORKING_STUBS__
149 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
151 #endif /* __ARM_ARCH == 4 */
155 # define RET mov pc, lr
156 # define RETc(x) mov##x pc, lr
160 .macro cfi_pop advance, reg, cfa_offset
162 .pushsection .debug_frame
163 .byte 0x4 /* DW_CFA_advance_loc4 */
165 .byte (0xc0 | \reg) /* DW_CFA_restore */
166 .byte 0xe /* DW_CFA_def_cfa_offset */
171 .macro cfi_push advance, reg, offset, cfa_offset
173 .pushsection .debug_frame
174 .byte 0x4 /* DW_CFA_advance_loc4 */
176 .byte (0x80 | \reg) /* DW_CFA_offset */
177 .uleb128 (\offset / -4)
178 .byte 0xe /* DW_CFA_def_cfa_offset */
183 .macro cfi_start start_label, end_label
185 .pushsection .debug_frame
187 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
189 .4byte 0xffffffff @ CIE Identifier Tag
190 .byte 0x1 @ CIE Version
191 .ascii "\0" @ CIE Augmentation
192 .uleb128 0x1 @ CIE Code Alignment Factor
193 .sleb128 -4 @ CIE Data Alignment Factor
194 .byte 0xe @ CIE RA Column
195 .byte 0xc @ DW_CFA_def_cfa
201 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
203 .4byte LSYM(Lstart_frame) @ FDE CIE offset
204 .4byte \start_label @ FDE initial location
205 .4byte \end_label-\start_label @ FDE address range
209 .macro cfi_end end_label
211 .pushsection .debug_frame
219 /* Don't pass dirn, it's there just to get token pasting right. */
221 .macro RETLDM regs=, cond=, unwind=, dirn=ia
222 #if defined (__INTERWORKING__)
224 ldr\cond lr, [sp], #8
226 # if defined(__thumb2__)
229 ldm\cond\dirn sp!, {\regs, lr}
233 /* Mark LR as restored. */
234 97: cfi_pop 97b - \unwind, 0xe, 0x0
238 /* Caller is responsible for providing IT instruction. */
240 ldr\cond pc, [sp], #8
242 # if defined(__thumb2__)
245 ldm\cond\dirn sp!, {\regs, pc}
251 /* The Unified assembly syntax allows the same code to be assembled for both
252 ARM and Thumb-2. However this is only supported by recent gas, so define
253 a set of macros to allow ARM code on older assemblers. */
254 #if defined(__thumb2__)
255 .macro do_it cond, suffix=""
258 .macro shift1 op, arg0, arg1, arg2
259 \op \arg0, \arg1, \arg2
263 #define COND(op1, op2, cond) op1 ## op2 ## cond
264 /* Perform an arithmetic operation with a variable shift operand. This
265 requires two instructions and a scratch register on Thumb-2. */
266 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
267 \shiftop \tmp, \src2, \shiftreg
268 \name \dest, \src1, \tmp
271 .macro do_it cond, suffix=""
273 .macro shift1 op, arg0, arg1, arg2
274 mov \arg0, \arg1, \op \arg2
276 #define do_push stmfd sp!,
277 #define do_pop ldmfd sp!,
278 #define COND(op1, op2, cond) op1 ## cond ## op2
279 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
280 \name \dest, \src1, \src2, \shiftop \shiftreg
285 .macro ARM_LDIV0 name signed
287 .ifc \signed, unsigned
288 movne r0, #0xffffffff
290 movgt r0, #0x7fffffff
291 movlt r0, #0x80000000
293 b SYM (__aeabi_idiv0) __PLT__
296 .macro ARM_LDIV0 name signed
298 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
299 bl SYM (__div0) __PLT__
300 mov r0, #0 @ About as wrong as it could be.
307 .macro THUMB_LDIV0 name signed
308 #if defined(__ARM_ARCH_6M__)
309 .ifc \signed, unsigned
313 mvn r0, r0 @ 0xffffffff
321 lsr r0, r0, #1 @ 0x7fffffff
324 lsl r0, r0, #24 @ 0x80000000
332 @ We know we are not on armv4t, so pop pc is safe.
336 .word __aeabi_idiv0 - 4b
337 #elif defined(__thumb2__)
339 .ifc \signed, unsigned
346 movgt r0, #0x7fffffff
348 movlt r0, #0x80000000
350 b.w SYM(__aeabi_idiv0) __PLT__
357 .ifc \signed, unsigned
358 movne r0, #0xffffffff
360 movgt r0, #0x7fffffff
361 movlt r0, #0x80000000
363 b SYM(__aeabi_idiv0) __PLT__
368 .macro THUMB_LDIV0 name signed
370 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
372 mov r0, #0 @ About as wrong as it could be.
373 #if defined (__INTERWORKING__)
386 .macro DIV_FUNC_END name signed
387 cfi_start __\name, LSYM(Lend_div0)
390 THUMB_LDIV0 \name \signed
392 ARM_LDIV0 \name \signed
394 cfi_end LSYM(Lend_div0)
398 .macro THUMB_FUNC_START name
405 /* Function start macros. Variants for ARM and Thumb. */
408 #define THUMB_FUNC .thumb_func
409 #define THUMB_CODE .force_thumb
410 # if defined(__thumb2__)
411 #define THUMB_SYNTAX .syntax divided
421 .macro FUNC_START name
432 /* Special function that will always be coded in ARM assembly, even if
433 in Thumb-only compilation. */
435 #if defined(__thumb2__)
437 /* For Thumb-2 we build everything in thumb mode. */
438 .macro ARM_FUNC_START name
442 #define EQUIV .thumb_set
447 #elif defined(__INTERWORKING_STUBS__)
449 .macro ARM_FUNC_START name
454 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
455 directly from other local arm routines. */
458 #define EQUIV .thumb_set
459 /* Branch directly to a function declared with ARM_FUNC_START.
460 Must be called in arm mode. */
465 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
467 #ifdef __ARM_ARCH_6M__
468 #define EQUIV .thumb_set
470 .macro ARM_FUNC_START name
486 .macro FUNC_ALIAS new old
488 #if defined (__thumb__)
489 .thumb_set SYM (__\new), SYM (__\old)
491 .set SYM (__\new), SYM (__\old)
495 #ifndef __ARM_ARCH_6M__
496 .macro ARM_FUNC_ALIAS new old
498 EQUIV SYM (__\new), SYM (__\old)
499 #if defined(__INTERWORKING_STUBS__)
500 .set SYM (_L__\new), SYM (_L__\old)
524 /* Register aliases. */
526 work .req r4 @ XXXX is this safe ?
540 /* ------------------------------------------------------------------------ */
541 /* Bodies of the division and modulo routines. */
542 /* ------------------------------------------------------------------------ */
543 .macro ARM_DIV_BODY dividend, divisor, result, curbit
545 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
547 #if defined (__thumb2__)
548 clz \curbit, \dividend
549 clz \result, \divisor
550 sub \curbit, \result, \curbit
551 rsb \curbit, \curbit, #31
553 add \curbit, \result, \curbit, lsl #4
560 .set shift, shift - 1
561 cmp.w \dividend, \divisor, lsl #shift
563 adc.w \result, \result, \result
565 subcs.w \dividend, \dividend, \divisor, lsl #shift
568 clz \curbit, \dividend
569 clz \result, \divisor
570 sub \curbit, \result, \curbit
571 rsbs \curbit, \curbit, #31
572 addne \curbit, \curbit, \curbit, lsl #1
574 addne pc, pc, \curbit, lsl #2
578 .set shift, shift - 1
579 cmp \dividend, \divisor, lsl #shift
580 adc \result, \result, \result
581 subcs \dividend, \dividend, \divisor, lsl #shift
585 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
586 #if __ARM_ARCH__ >= 5
588 clz \curbit, \divisor
589 clz \result, \dividend
590 sub \result, \curbit, \result
592 mov \divisor, \divisor, lsl \result
593 mov \curbit, \curbit, lsl \result
596 #else /* __ARM_ARCH__ < 5 */
598 @ Initially shift the divisor left 3 bits if possible,
599 @ set curbit accordingly. This allows for curbit to be located
600 @ at the left end of each 4-bit nibbles in the division loop
601 @ to save one loop in most cases.
602 tst \divisor, #0xe0000000
603 moveq \divisor, \divisor, lsl #3
607 @ Unless the divisor is very big, shift it up in multiples of
608 @ four bits, since this is the amount of unwinding in the main
609 @ division loop. Continue shifting until the divisor is
610 @ larger than the dividend.
611 1: cmp \divisor, #0x10000000
612 cmplo \divisor, \dividend
613 movlo \divisor, \divisor, lsl #4
614 movlo \curbit, \curbit, lsl #4
617 @ For very big divisors, we must shift it a bit at a time, or
618 @ we will be in danger of overflowing.
619 1: cmp \divisor, #0x80000000
620 cmplo \divisor, \dividend
621 movlo \divisor, \divisor, lsl #1
622 movlo \curbit, \curbit, lsl #1
627 #endif /* __ARM_ARCH__ < 5 */
630 1: cmp \dividend, \divisor
632 subhs \dividend, \dividend, \divisor
633 orrhs \result, \result, \curbit
634 cmp \dividend, \divisor, lsr #1
636 subhs \dividend, \dividend, \divisor, lsr #1
637 orrhs \result, \result, \curbit, lsr #1
638 cmp \dividend, \divisor, lsr #2
640 subhs \dividend, \dividend, \divisor, lsr #2
641 orrhs \result, \result, \curbit, lsr #2
642 cmp \dividend, \divisor, lsr #3
644 subhs \dividend, \dividend, \divisor, lsr #3
645 orrhs \result, \result, \curbit, lsr #3
646 cmp \dividend, #0 @ Early termination?
648 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
649 movne \divisor, \divisor, lsr #4
652 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
655 /* ------------------------------------------------------------------------ */
656 .macro ARM_DIV2_ORDER divisor, order
658 #if __ARM_ARCH__ >= 5
661 rsb \order, \order, #31
665 cmp \divisor, #(1 << 16)
666 movhs \divisor, \divisor, lsr #16
670 cmp \divisor, #(1 << 8)
671 movhs \divisor, \divisor, lsr #8
672 addhs \order, \order, #8
674 cmp \divisor, #(1 << 4)
675 movhs \divisor, \divisor, lsr #4
676 addhs \order, \order, #4
678 cmp \divisor, #(1 << 2)
679 addhi \order, \order, #3
680 addls \order, \order, \divisor, lsr #1
685 /* ------------------------------------------------------------------------ */
686 .macro ARM_MOD_BODY dividend, divisor, order, spare
688 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
691 clz \spare, \dividend
692 sub \order, \order, \spare
693 rsbs \order, \order, #31
694 addne pc, pc, \order, lsl #3
698 .set shift, shift - 1
699 cmp \dividend, \divisor, lsl #shift
700 subcs \dividend, \dividend, \divisor, lsl #shift
703 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
704 #if __ARM_ARCH__ >= 5
707 clz \spare, \dividend
708 sub \order, \order, \spare
709 mov \divisor, \divisor, lsl \order
711 #else /* __ARM_ARCH__ < 5 */
715 @ Unless the divisor is very big, shift it up in multiples of
716 @ four bits, since this is the amount of unwinding in the main
717 @ division loop. Continue shifting until the divisor is
718 @ larger than the dividend.
719 1: cmp \divisor, #0x10000000
720 cmplo \divisor, \dividend
721 movlo \divisor, \divisor, lsl #4
722 addlo \order, \order, #4
725 @ For very big divisors, we must shift it a bit at a time, or
726 @ we will be in danger of overflowing.
727 1: cmp \divisor, #0x80000000
728 cmplo \divisor, \dividend
729 movlo \divisor, \divisor, lsl #1
730 addlo \order, \order, #1
733 #endif /* __ARM_ARCH__ < 5 */
735 @ Perform all needed substractions to keep only the reminder.
736 @ Do comparisons in batch of 4 first.
737 subs \order, \order, #3 @ yes, 3 is intended here
740 1: cmp \dividend, \divisor
741 subhs \dividend, \dividend, \divisor
742 cmp \dividend, \divisor, lsr #1
743 subhs \dividend, \dividend, \divisor, lsr #1
744 cmp \dividend, \divisor, lsr #2
745 subhs \dividend, \dividend, \divisor, lsr #2
746 cmp \dividend, \divisor, lsr #3
747 subhs \dividend, \dividend, \divisor, lsr #3
749 mov \divisor, \divisor, lsr #4
750 subges \order, \order, #4
757 @ Either 1, 2 or 3 comparison/substractions are left.
761 cmp \dividend, \divisor
762 subhs \dividend, \dividend, \divisor
763 mov \divisor, \divisor, lsr #1
764 3: cmp \dividend, \divisor
765 subhs \dividend, \dividend, \divisor
766 mov \divisor, \divisor, lsr #1
767 4: cmp \dividend, \divisor
768 subhs \dividend, \dividend, \divisor
771 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
774 /* ------------------------------------------------------------------------ */
775 .macro THUMB_DIV_MOD_BODY modulo
776 @ Load the constant 0x10000000 into our work register.
780 @ Unless the divisor is very big, shift it up in multiples of
781 @ four bits, since this is the amount of unwinding in the main
782 @ division loop. Continue shifting until the divisor is
783 @ larger than the dividend.
786 cmp divisor, dividend
792 @ Set work to 0x80000000
795 @ For very big divisors, we must shift it a bit at a time, or
796 @ we will be in danger of overflowing.
799 cmp divisor, dividend
805 @ Test for possible subtractions ...
807 @ ... On the final pass, this may subtract too much from the dividend,
808 @ so keep track of which subtractions are done, we can fix them up
811 cmp dividend, divisor
813 sub dividend, dividend, divisor
815 lsr work, divisor, #1
818 sub dividend, dividend, work
825 lsr work, divisor, #2
828 sub dividend, dividend, work
835 lsr work, divisor, #3
838 sub dividend, dividend, work
847 @ ... and note which bits are done in the result. On the final pass,
848 @ this may subtract too much from the dividend, but the result will be ok,
849 @ since the "bit" will have been shifted out at the bottom.
850 cmp dividend, divisor
852 sub dividend, dividend, divisor
853 orr result, result, curbit
855 lsr work, divisor, #1
858 sub dividend, dividend, work
862 lsr work, divisor, #2
865 sub dividend, dividend, work
869 lsr work, divisor, #3
872 sub dividend, dividend, work
878 cmp dividend, #0 @ Early termination?
880 lsr curbit, #4 @ No, any more bits to do?
886 @ Any subtractions that we should not have done will be recorded in
887 @ the top three bits of "overdone". Exactly which were not needed
888 @ are governed by the position of the bit, stored in ip.
892 beq LSYM(Lgot_result)
894 @ If we terminated early, because dividend became zero, then the
895 @ bit in ip will not be in the bottom nibble, and we should not
896 @ perform the additions below. We must test for this though
897 @ (rather relying upon the TSTs to prevent the additions) since
898 @ the bit in ip could be in the top two bits which might then match
899 @ with one of the smaller RORs.
903 beq LSYM(Lgot_result)
910 lsr work, divisor, #3
918 lsr work, divisor, #2
925 beq LSYM(Lgot_result)
926 lsr work, divisor, #1
931 /* ------------------------------------------------------------------------ */
932 /* Start of the Real Functions */
933 /* ------------------------------------------------------------------------ */
936 #if defined(__prefer_thumb__)
939 FUNC_ALIAS aeabi_uidiv udivsi3
943 LSYM(udivsi3_skip_div0_test):
948 cmp dividend, divisor
949 blo LSYM(Lgot_result)
957 #elif defined(__ARM_ARCH_EXT_IDIV__)
959 ARM_FUNC_START udivsi3
960 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
968 #else /* ARM version/Thumb-2. */
970 ARM_FUNC_START udivsi3
971 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
973 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
974 check for division-by-zero a second time. */
975 LSYM(udivsi3_skip_div0_test):
985 ARM_DIV_BODY r0, r1, r2, r3
995 12: ARM_DIV2_ORDER r1, r2
1000 #endif /* ARM version */
1002 DIV_FUNC_END udivsi3 unsigned
1004 #if defined(__prefer_thumb__)
1005 FUNC_START aeabi_uidivmod
1009 bl LSYM(udivsi3_skip_div0_test)
1014 #elif defined(__ARM_ARCH_EXT_IDIV__)
1015 ARM_FUNC_START aeabi_uidivmod
1023 ARM_FUNC_START aeabi_uidivmod
1026 stmfd sp!, { r0, r1, lr }
1027 bl LSYM(udivsi3_skip_div0_test)
1028 ldmfd sp!, { r1, r2, lr }
1033 FUNC_END aeabi_uidivmod
1035 #endif /* L_udivsi3 */
1036 /* ------------------------------------------------------------------------ */
1039 #ifdef __ARM_ARCH_EXT_IDIV__
1041 ARM_FUNC_START umodsi3
1049 #elif defined(__thumb__)
1056 cmp dividend, divisor
1063 THUMB_DIV_MOD_BODY 1
1068 #else /* ARM version. */
1072 subs r2, r1, #1 @ compare divisor with 1
1074 cmpne r0, r1 @ compare dividend with divisor
1076 tsthi r1, r2 @ see if divisor is power of 2
1080 ARM_MOD_BODY r0, r1, r2, r3
1084 #endif /* ARM version. */
1086 DIV_FUNC_END umodsi3 unsigned
1088 #endif /* L_umodsi3 */
1089 /* ------------------------------------------------------------------------ */
1092 #if defined(__prefer_thumb__)
1095 FUNC_ALIAS aeabi_idiv divsi3
1099 LSYM(divsi3_skip_div0_test):
1102 eor work, divisor @ Save the sign of the result.
1108 neg divisor, divisor @ Loops below use unsigned.
1112 neg dividend, dividend
1114 cmp dividend, divisor
1115 blo LSYM(Lgot_result)
1117 THUMB_DIV_MOD_BODY 0
1128 #elif defined(__ARM_ARCH_EXT_IDIV__)
1130 ARM_FUNC_START divsi3
1131 ARM_FUNC_ALIAS aeabi_idiv divsi3
1138 #else /* ARM/Thumb-2 version. */
1140 ARM_FUNC_START divsi3
1141 ARM_FUNC_ALIAS aeabi_idiv divsi3
1145 LSYM(divsi3_skip_div0_test):
1146 eor ip, r0, r1 @ save the sign of the result.
1148 rsbmi r1, r1, #0 @ loops below use unsigned.
1149 subs r2, r1, #1 @ division by 1 or -1 ?
1153 rsbmi r3, r0, #0 @ positive dividend value
1156 tst r1, r2 @ divisor is power of 2 ?
1159 ARM_DIV_BODY r3, r1, r0, r2
1166 10: teq ip, r0 @ same sign ?
1174 moveq r0, ip, asr #31
1178 12: ARM_DIV2_ORDER r1, r2
1186 #endif /* ARM version */
1188 DIV_FUNC_END divsi3 signed
1190 #if defined(__prefer_thumb__)
1191 FUNC_START aeabi_idivmod
1195 bl LSYM(divsi3_skip_div0_test)
1200 #elif defined(__ARM_ARCH_EXT_IDIV__)
1201 ARM_FUNC_START aeabi_idivmod
1209 ARM_FUNC_START aeabi_idivmod
1212 stmfd sp!, { r0, r1, lr }
1213 bl LSYM(divsi3_skip_div0_test)
1214 ldmfd sp!, { r1, r2, lr }
1219 FUNC_END aeabi_idivmod
1221 #endif /* L_divsi3 */
1222 /* ------------------------------------------------------------------------ */
1225 #if defined(__ARM_ARCH_EXT_IDIV__)
1227 ARM_FUNC_START modsi3
1236 #elif defined(__thumb__)
1244 neg divisor, divisor @ Loops below use unsigned.
1247 @ Need to save the sign of the dividend, unfortunately, we need
1248 @ work later on. Must do this after saving the original value of
1249 @ the work register, because we will pop this value off first.
1253 neg dividend, dividend
1255 cmp dividend, divisor
1256 blo LSYM(Lgot_result)
1258 THUMB_DIV_MOD_BODY 1
1263 neg dividend, dividend
1268 #else /* ARM version. */
1274 rsbmi r1, r1, #0 @ loops below use unsigned.
1275 movs ip, r0 @ preserve sign of dividend
1276 rsbmi r0, r0, #0 @ if negative make positive
1277 subs r2, r1, #1 @ compare divisor with 1
1278 cmpne r0, r1 @ compare dividend with divisor
1280 tsthi r1, r2 @ see if divisor is power of 2
1284 ARM_MOD_BODY r0, r1, r2, r3
1290 #endif /* ARM version */
1292 DIV_FUNC_END modsi3 signed
1294 #endif /* L_modsi3 */
1295 /* ------------------------------------------------------------------------ */
1301 FUNC_START aeabi_idiv0
1302 FUNC_START aeabi_ldiv0
1304 FUNC_END aeabi_ldiv0
1305 FUNC_END aeabi_idiv0
1312 #endif /* L_divmodsi_tools */
1313 /* ------------------------------------------------------------------------ */
1315 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1317 /* Constant taken from <asm/signal.h>. */
1323 ARM_FUNC_START aeabi_idiv0
1324 ARM_FUNC_START aeabi_ldiv0
1331 bl SYM(raise) __PLT__
1335 FUNC_END aeabi_ldiv0
1336 FUNC_END aeabi_idiv0
1341 #endif /* L_dvmd_lnx */
1342 #ifdef L_clear_cache
1343 #if defined __ARM_EABI__ && defined __linux__
1344 @ EABI GNU/Linux call to cacheflush syscall.
1345 ARM_FUNC_START clear_cache
1347 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1358 FUNC_END clear_cache
1360 #error "This is only for ARM EABI GNU/Linux"
1362 #endif /* L_clear_cache */
1363 /* ------------------------------------------------------------------------ */
1364 /* Dword shift operations. */
1365 /* All the following Dword shift variants rely on the fact that
1368 shft xxx, (Reg & 255)
1369 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1370 case of logical shifts) or the sign (for asr). */
1380 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1386 FUNC_ALIAS aeabi_llsr lshrdi3
1404 movmi al, al, lsr r2
1405 movpl al, ah, lsr r3
1406 orrmi al, al, ah, lsl ip
1418 FUNC_ALIAS aeabi_lasr ashrdi3
1425 @ If r2 is negative at this point the following step would OR
1426 @ the sign bit into all of AL. That's not what we want...
1440 movmi al, al, lsr r2
1441 movpl al, ah, asr r3
1442 orrmi al, al, ah, lsl ip
1455 FUNC_ALIAS aeabi_llsl ashldi3
1473 movmi ah, ah, lsl r2
1474 movpl ah, al, lsl r3
1475 orrmi ah, ah, al, lsr ip
1484 #endif /* __symbian__ */
1486 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1487 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1488 || defined(__ARM_ARCH_5TEJ__)
1489 #define HAVE_ARM_CLZ 1
1493 #if defined(__ARM_ARCH_6M__)
1498 cmp r0, r3 /* 0x10000 */
1503 cmp r0, r3 /* #0x100 */
1508 cmp r0, r3 /* #0x10 */
1518 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1521 ARM_FUNC_START clzsi2
1522 # if defined(HAVE_ARM_CLZ)
1529 movcs r0, r0, lsr #16
1533 movcs r0, r0, lsr #8
1537 movcs r0, r0, lsr #4
1545 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1546 # endif /* !HAVE_ARM_CLZ */
1549 #endif /* L_clzsi2 */
1552 #if !defined(HAVE_ARM_CLZ)
1554 # if defined(__ARM_ARCH_6M__)
1558 ARM_FUNC_START clzdi2
1579 # if defined(__ARM_ARCH_6M__)
1586 #else /* HAVE_ARM_CLZ */
1588 ARM_FUNC_START clzdi2
1598 #endif /* L_clzdi2 */
1601 #if defined(__ARM_ARCH_6M__)
1608 cmp r0, r3 /* 0x10000 */
1613 cmp r0, r3 /* #0x100 */
1618 cmp r0, r3 /* #0x10 */
1628 .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1631 ARM_FUNC_START ctzsi2
1634 # if defined(HAVE_ARM_CLZ)
1642 movcs r0, r0, lsr #16
1646 movcs r0, r0, lsr #8
1650 movcs r0, r0, lsr #4
1658 .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1659 # endif /* !HAVE_ARM_CLZ */
1662 #endif /* L_clzsi2 */
1664 /* ------------------------------------------------------------------------ */
1665 /* These next two sections are here despite the fact that they contain Thumb
1666 assembler because their presence allows interworked code to be linked even
1667 when the GCC library is this one. */
1669 /* Do not build the interworking functions when the target architecture does
1670 not support Thumb instructions. (This can be a multilib option). */
1671 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1672 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1673 || __ARM_ARCH__ >= 6
1675 #if defined L_call_via_rX
1677 /* These labels & instructions are used by the Arm/Thumb interworking code.
1678 The address of function to be called is loaded into a register and then
1679 one of these labels is called via a BL instruction. This puts the
1680 return address into the link register with the bottom bit set, and the
1681 code here switches to the correct mode before executing the function. */
1687 .macro call_via register
1688 THUMB_FUNC_START _call_via_\register
1693 SIZE (_call_via_\register)
1712 #endif /* L_call_via_rX */
1714 /* Don't bother with the old interworking routines for Thumb-2. */
1715 /* ??? Maybe only omit these on "m" variants. */
1716 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1718 #if defined L_interwork_call_via_rX
1720 /* These labels & instructions are used by the Arm/Thumb interworking code,
1721 when the target address is in an unknown instruction set. The address
1722 of function to be called is loaded into a register and then one of these
1723 labels is called via a BL instruction. This puts the return address
1724 into the link register with the bottom bit set, and the code here
1725 switches to the correct mode before executing the function. Unfortunately
1726 the target code cannot be relied upon to return via a BX instruction, so
1727 instead we have to store the resturn address on the stack and allow the
1728 called function to return here instead. Upon return we recover the real
1729 return address and use a BX to get back to Thumb mode.
1731 There are three variations of this code. The first,
1732 _interwork_call_via_rN(), will push the return address onto the
1733 stack and pop it in _arm_return(). It should only be used if all
1734 arguments are passed in registers.
1736 The second, _interwork_r7_call_via_rN(), instead stores the return
1737 address at [r7, #-4]. It is the caller's responsibility to ensure
1738 that this address is valid and contains no useful data.
1740 The third, _interwork_r11_call_via_rN(), works in the same way but
1741 uses r11 instead of r7. It is useful if the caller does not really
1742 need a frame pointer. */
1749 LSYM(Lstart_arm_return):
1750 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1751 cfi_push 0, 0xe, -0x8, 0x8
1752 nop @ This nop is for the benefit of debuggers, so that
1753 @ backtraces will use the correct unwind information.
1755 RETLDM unwind=LSYM(Lstart_arm_return)
1756 cfi_end LSYM(Lend_arm_return)
1758 .globl _arm_return_r7
1763 .globl _arm_return_r11
1768 .macro interwork_with_frame frame, register, name, return
1771 THUMB_FUNC_START \name
1778 streq lr, [\frame, #-4]
1779 adreq lr, _arm_return_\frame
1785 .macro interwork register
1788 THUMB_FUNC_START _interwork_call_via_\register
1794 .globl LSYM(Lchange_\register)
1795 LSYM(Lchange_\register):
1797 streq lr, [sp, #-8]!
1798 adreq lr, _arm_return
1801 SIZE (_interwork_call_via_\register)
1803 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1804 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1822 /* The LR case has to be handled a little differently... */
1825 THUMB_FUNC_START _interwork_call_via_lr
1834 stmeqdb r13!, {lr, pc}
1836 adreq lr, _arm_return
1839 SIZE (_interwork_call_via_lr)
1841 #endif /* L_interwork_call_via_rX */
1842 #endif /* !__thumb2__ */
1844 /* Functions to support compact pic switch tables in thumb1 state.
1845 All these routines take an index into the table in r0. The
1846 table is at LR & ~1 (but this must be rounded up in the case
1847 of 32-bit entires). They are only permitted to clobber r12
1848 and r14 and r0 must be preserved on exit. */
1849 #ifdef L_thumb1_case_sqi
1855 THUMB_FUNC_START __gnu_thumb1_case_sqi
1865 SIZE (__gnu_thumb1_case_sqi)
1868 #ifdef L_thumb1_case_uqi
1874 THUMB_FUNC_START __gnu_thumb1_case_uqi
1884 SIZE (__gnu_thumb1_case_uqi)
1887 #ifdef L_thumb1_case_shi
1893 THUMB_FUNC_START __gnu_thumb1_case_shi
1904 SIZE (__gnu_thumb1_case_shi)
1907 #ifdef L_thumb1_case_uhi
1913 THUMB_FUNC_START __gnu_thumb1_case_uhi
1924 SIZE (__gnu_thumb1_case_uhi)
1927 #ifdef L_thumb1_case_si
1933 THUMB_FUNC_START __gnu_thumb1_case_si
1936 adds.n r1, r1, #2 /* Align to word. */
1944 mov pc, lr /* We know we were called from thumb code. */
1945 SIZE (__gnu_thumb1_case_si)
1948 #endif /* Arch supports thumb. */
1951 #ifndef __ARM_ARCH_6M__
1952 #include "ieee754-df.S"
1953 #include "ieee754-sf.S"
1955 #else /* __ARM_ARCH_6M__ */
1956 #include "bpabi-v6m.S"
1957 #endif /* __ARM_ARCH_6M__ */
1958 #endif /* !__symbian__ */