1 @ libgcc routines for ARM cpu.
2 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
4 /* Copyright (C) 1995-2017 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__) || defined(__ARM_ARCH_8M_BASE__) \
112 || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8R__)
113 # define __ARM_ARCH__ 8
117 #error Unable to determine architecture.
120 /* There are times when we might prefer Thumb1 code even if ARM code is
121 permitted, for example, the code might be smaller, or there might be
122 interworking problems with switching to ARM state if interworking is
124 #if (defined(__thumb__) \
125 && !defined(__thumb2__) \
126 && (!defined(__THUMB_INTERWORK__) \
127 || defined (__OPTIMIZE_SIZE__) \
128 || !__ARM_ARCH_ISA_ARM))
129 # define __prefer_thumb__
132 #if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1
133 #define NOT_ISA_TARGET_32BIT 1
136 /* How to return from a function call depends on the architecture variant. */
138 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
141 # define RETc(x) bx##x lr
143 /* Special precautions for interworking on armv4t. */
144 # if (__ARM_ARCH__ == 4)
146 /* Always use bx, not ldr pc. */
147 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
148 # define __INTERWORKING__
149 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
151 /* Include thumb stub before arm mode code. */
152 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
153 # define __INTERWORKING_STUBS__
154 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
156 #endif /* __ARM_ARCH == 4 */
160 # define RET mov pc, lr
161 # define RETc(x) mov##x pc, lr
165 .macro cfi_pop advance, reg, cfa_offset
167 .pushsection .debug_frame
168 .byte 0x4 /* DW_CFA_advance_loc4 */
170 .byte (0xc0 | \reg) /* DW_CFA_restore */
171 .byte 0xe /* DW_CFA_def_cfa_offset */
176 .macro cfi_push advance, reg, offset, cfa_offset
178 .pushsection .debug_frame
179 .byte 0x4 /* DW_CFA_advance_loc4 */
181 .byte (0x80 | \reg) /* DW_CFA_offset */
182 .uleb128 (\offset / -4)
183 .byte 0xe /* DW_CFA_def_cfa_offset */
188 .macro cfi_start start_label, end_label
190 .pushsection .debug_frame
192 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
194 .4byte 0xffffffff @ CIE Identifier Tag
195 .byte 0x1 @ CIE Version
196 .ascii "\0" @ CIE Augmentation
197 .uleb128 0x1 @ CIE Code Alignment Factor
198 .sleb128 -4 @ CIE Data Alignment Factor
199 .byte 0xe @ CIE RA Column
200 .byte 0xc @ DW_CFA_def_cfa
206 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
208 .4byte LSYM(Lstart_frame) @ FDE CIE offset
209 .4byte \start_label @ FDE initial location
210 .4byte \end_label-\start_label @ FDE address range
214 .macro cfi_end end_label
216 .pushsection .debug_frame
224 /* Don't pass dirn, it's there just to get token pasting right. */
226 .macro RETLDM regs=, cond=, unwind=, dirn=ia
227 #if defined (__INTERWORKING__)
229 ldr\cond lr, [sp], #8
231 # if defined(__thumb2__)
234 ldm\cond\dirn sp!, {\regs, lr}
238 /* Mark LR as restored. */
239 97: cfi_pop 97b - \unwind, 0xe, 0x0
243 /* Caller is responsible for providing IT instruction. */
245 ldr\cond pc, [sp], #8
247 # if defined(__thumb2__)
250 ldm\cond\dirn sp!, {\regs, pc}
256 /* The Unified assembly syntax allows the same code to be assembled for both
257 ARM and Thumb-2. However this is only supported by recent gas, so define
258 a set of macros to allow ARM code on older assemblers. */
259 #if defined(__thumb2__)
260 .macro do_it cond, suffix=""
263 .macro shift1 op, arg0, arg1, arg2
264 \op \arg0, \arg1, \arg2
268 #define COND(op1, op2, cond) op1 ## op2 ## cond
269 /* Perform an arithmetic operation with a variable shift operand. This
270 requires two instructions and a scratch register on Thumb-2. */
271 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
272 \shiftop \tmp, \src2, \shiftreg
273 \name \dest, \src1, \tmp
276 .macro do_it cond, suffix=""
278 .macro shift1 op, arg0, arg1, arg2
279 mov \arg0, \arg1, \op \arg2
281 #define do_push stmfd sp!,
282 #define do_pop ldmfd sp!,
283 #define COND(op1, op2, cond) op1 ## cond ## op2
284 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
285 \name \dest, \src1, \src2, \shiftop \shiftreg
290 .macro ARM_LDIV0 name signed
292 .ifc \signed, unsigned
293 movne r0, #0xffffffff
295 movgt r0, #0x7fffffff
296 movlt r0, #0x80000000
298 b SYM (__aeabi_idiv0) __PLT__
301 .macro ARM_LDIV0 name signed
303 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
304 bl SYM (__div0) __PLT__
305 mov r0, #0 @ About as wrong as it could be.
312 .macro THUMB_LDIV0 name signed
313 #ifdef NOT_ISA_TARGET_32BIT
317 bl SYM(__aeabi_idiv0)
318 @ We know we are not on armv4t, so pop pc is safe.
321 #elif defined(__thumb2__)
323 .ifc \signed, unsigned
330 movgt r0, #0x7fffffff
332 movlt r0, #0x80000000
334 b.w SYM(__aeabi_idiv0) __PLT__
341 .ifc \signed, unsigned
342 movne r0, #0xffffffff
344 movgt r0, #0x7fffffff
345 movlt r0, #0x80000000
347 b SYM(__aeabi_idiv0) __PLT__
352 .macro THUMB_LDIV0 name signed
354 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
356 mov r0, #0 @ About as wrong as it could be.
357 #if defined (__INTERWORKING__)
370 .macro DIV_FUNC_END name signed
371 cfi_start __\name, LSYM(Lend_div0)
374 THUMB_LDIV0 \name \signed
376 ARM_LDIV0 \name \signed
378 cfi_end LSYM(Lend_div0)
382 .macro THUMB_FUNC_START name
389 /* Function start macros. Variants for ARM and Thumb. */
392 #define THUMB_FUNC .thumb_func
393 #define THUMB_CODE .force_thumb
394 # if defined(__thumb2__)
395 #define THUMB_SYNTAX .syntax divided
405 .macro FUNC_START name sp_section=
406 .ifc \sp_section, function_section
407 .section .text.__\name,"ax",%progbits
420 .macro ARM_SYM_START name
430 /* Special function that will always be coded in ARM assembly, even if
431 in Thumb-only compilation. */
433 #if defined(__thumb2__)
435 /* For Thumb-2 we build everything in thumb mode. */
436 .macro ARM_FUNC_START name sp_section=
437 FUNC_START \name \sp_section
440 #define EQUIV .thumb_set
445 #elif defined(__INTERWORKING_STUBS__)
447 .macro ARM_FUNC_START name
452 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
453 directly from other local arm routines. */
456 #define EQUIV .thumb_set
457 /* Branch directly to a function declared with ARM_FUNC_START.
458 Must be called in arm mode. */
463 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
465 #ifdef NOT_ISA_TARGET_32BIT
466 #define EQUIV .thumb_set
468 .macro ARM_FUNC_START name sp_section=
469 .ifc \sp_section, function_section
470 .section .text.__\name,"ax",%progbits
488 .macro FUNC_ALIAS new old
490 #if defined (__thumb__)
491 .thumb_set SYM (__\new), SYM (__\old)
493 .set SYM (__\new), SYM (__\old)
497 #ifndef NOT_ISA_TARGET_32BIT
498 .macro ARM_FUNC_ALIAS new old
500 EQUIV SYM (__\new), SYM (__\old)
501 #if defined(__INTERWORKING_STUBS__)
502 .set SYM (_L__\new), SYM (_L__\old)
526 /* Register aliases. */
528 work .req r4 @ XXXX is this safe ?
542 /* ------------------------------------------------------------------------ */
543 /* Bodies of the division and modulo routines. */
544 /* ------------------------------------------------------------------------ */
545 .macro ARM_DIV_BODY dividend, divisor, result, curbit
547 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
549 #if defined (__thumb2__)
550 clz \curbit, \dividend
551 clz \result, \divisor
552 sub \curbit, \result, \curbit
553 rsb \curbit, \curbit, #31
555 add \curbit, \result, \curbit, lsl #4
562 .set shift, shift - 1
563 cmp.w \dividend, \divisor, lsl #shift
565 adc.w \result, \result, \result
567 subcs.w \dividend, \dividend, \divisor, lsl #shift
570 clz \curbit, \dividend
571 clz \result, \divisor
572 sub \curbit, \result, \curbit
573 rsbs \curbit, \curbit, #31
574 addne \curbit, \curbit, \curbit, lsl #1
576 addne pc, pc, \curbit, lsl #2
580 .set shift, shift - 1
581 cmp \dividend, \divisor, lsl #shift
582 adc \result, \result, \result
583 subcs \dividend, \dividend, \divisor, lsl #shift
587 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
588 #if __ARM_ARCH__ >= 5
590 clz \curbit, \divisor
591 clz \result, \dividend
592 sub \result, \curbit, \result
594 mov \divisor, \divisor, lsl \result
595 mov \curbit, \curbit, lsl \result
598 #else /* __ARM_ARCH__ < 5 */
600 @ Initially shift the divisor left 3 bits if possible,
601 @ set curbit accordingly. This allows for curbit to be located
602 @ at the left end of each 4-bit nibbles in the division loop
603 @ to save one loop in most cases.
604 tst \divisor, #0xe0000000
605 moveq \divisor, \divisor, lsl #3
609 @ Unless the divisor is very big, shift it up in multiples of
610 @ four bits, since this is the amount of unwinding in the main
611 @ division loop. Continue shifting until the divisor is
612 @ larger than the dividend.
613 1: cmp \divisor, #0x10000000
614 cmplo \divisor, \dividend
615 movlo \divisor, \divisor, lsl #4
616 movlo \curbit, \curbit, lsl #4
619 @ For very big divisors, we must shift it a bit at a time, or
620 @ we will be in danger of overflowing.
621 1: cmp \divisor, #0x80000000
622 cmplo \divisor, \dividend
623 movlo \divisor, \divisor, lsl #1
624 movlo \curbit, \curbit, lsl #1
629 #endif /* __ARM_ARCH__ < 5 */
632 1: cmp \dividend, \divisor
634 subhs \dividend, \dividend, \divisor
635 orrhs \result, \result, \curbit
636 cmp \dividend, \divisor, lsr #1
638 subhs \dividend, \dividend, \divisor, lsr #1
639 orrhs \result, \result, \curbit, lsr #1
640 cmp \dividend, \divisor, lsr #2
642 subhs \dividend, \dividend, \divisor, lsr #2
643 orrhs \result, \result, \curbit, lsr #2
644 cmp \dividend, \divisor, lsr #3
646 subhs \dividend, \dividend, \divisor, lsr #3
647 orrhs \result, \result, \curbit, lsr #3
648 cmp \dividend, #0 @ Early termination?
650 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
651 movne \divisor, \divisor, lsr #4
654 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
657 /* ------------------------------------------------------------------------ */
658 .macro ARM_DIV2_ORDER divisor, order
660 #if __ARM_ARCH__ >= 5
663 rsb \order, \order, #31
667 cmp \divisor, #(1 << 16)
668 movhs \divisor, \divisor, lsr #16
672 cmp \divisor, #(1 << 8)
673 movhs \divisor, \divisor, lsr #8
674 addhs \order, \order, #8
676 cmp \divisor, #(1 << 4)
677 movhs \divisor, \divisor, lsr #4
678 addhs \order, \order, #4
680 cmp \divisor, #(1 << 2)
681 addhi \order, \order, #3
682 addls \order, \order, \divisor, lsr #1
687 /* ------------------------------------------------------------------------ */
688 .macro ARM_MOD_BODY dividend, divisor, order, spare
690 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
693 clz \spare, \dividend
694 sub \order, \order, \spare
695 rsbs \order, \order, #31
696 addne pc, pc, \order, lsl #3
700 .set shift, shift - 1
701 cmp \dividend, \divisor, lsl #shift
702 subcs \dividend, \dividend, \divisor, lsl #shift
705 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
706 #if __ARM_ARCH__ >= 5
709 clz \spare, \dividend
710 sub \order, \order, \spare
711 mov \divisor, \divisor, lsl \order
713 #else /* __ARM_ARCH__ < 5 */
717 @ Unless the divisor is very big, shift it up in multiples of
718 @ four bits, since this is the amount of unwinding in the main
719 @ division loop. Continue shifting until the divisor is
720 @ larger than the dividend.
721 1: cmp \divisor, #0x10000000
722 cmplo \divisor, \dividend
723 movlo \divisor, \divisor, lsl #4
724 addlo \order, \order, #4
727 @ For very big divisors, we must shift it a bit at a time, or
728 @ we will be in danger of overflowing.
729 1: cmp \divisor, #0x80000000
730 cmplo \divisor, \dividend
731 movlo \divisor, \divisor, lsl #1
732 addlo \order, \order, #1
735 #endif /* __ARM_ARCH__ < 5 */
737 @ Perform all needed substractions to keep only the reminder.
738 @ Do comparisons in batch of 4 first.
739 subs \order, \order, #3 @ yes, 3 is intended here
742 1: cmp \dividend, \divisor
743 subhs \dividend, \dividend, \divisor
744 cmp \dividend, \divisor, lsr #1
745 subhs \dividend, \dividend, \divisor, lsr #1
746 cmp \dividend, \divisor, lsr #2
747 subhs \dividend, \dividend, \divisor, lsr #2
748 cmp \dividend, \divisor, lsr #3
749 subhs \dividend, \dividend, \divisor, lsr #3
751 mov \divisor, \divisor, lsr #4
752 subges \order, \order, #4
759 @ Either 1, 2 or 3 comparison/substractions are left.
763 cmp \dividend, \divisor
764 subhs \dividend, \dividend, \divisor
765 mov \divisor, \divisor, lsr #1
766 3: cmp \dividend, \divisor
767 subhs \dividend, \dividend, \divisor
768 mov \divisor, \divisor, lsr #1
769 4: cmp \dividend, \divisor
770 subhs \dividend, \dividend, \divisor
773 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
776 /* ------------------------------------------------------------------------ */
777 .macro THUMB_DIV_MOD_BODY modulo
778 @ Load the constant 0x10000000 into our work register.
782 @ Unless the divisor is very big, shift it up in multiples of
783 @ four bits, since this is the amount of unwinding in the main
784 @ division loop. Continue shifting until the divisor is
785 @ larger than the dividend.
788 cmp divisor, dividend
794 @ Set work to 0x80000000
797 @ For very big divisors, we must shift it a bit at a time, or
798 @ we will be in danger of overflowing.
801 cmp divisor, dividend
807 @ Test for possible subtractions ...
809 @ ... On the final pass, this may subtract too much from the dividend,
810 @ so keep track of which subtractions are done, we can fix them up
813 cmp dividend, divisor
815 sub dividend, dividend, divisor
817 lsr work, divisor, #1
820 sub dividend, dividend, work
827 lsr work, divisor, #2
830 sub dividend, dividend, work
837 lsr work, divisor, #3
840 sub dividend, dividend, work
849 @ ... and note which bits are done in the result. On the final pass,
850 @ this may subtract too much from the dividend, but the result will be ok,
851 @ since the "bit" will have been shifted out at the bottom.
852 cmp dividend, divisor
854 sub dividend, dividend, divisor
855 orr result, result, curbit
857 lsr work, divisor, #1
860 sub dividend, dividend, work
864 lsr work, divisor, #2
867 sub dividend, dividend, work
871 lsr work, divisor, #3
874 sub dividend, dividend, work
880 cmp dividend, #0 @ Early termination?
882 lsr curbit, #4 @ No, any more bits to do?
888 @ Any subtractions that we should not have done will be recorded in
889 @ the top three bits of "overdone". Exactly which were not needed
890 @ are governed by the position of the bit, stored in ip.
894 beq LSYM(Lgot_result)
896 @ If we terminated early, because dividend became zero, then the
897 @ bit in ip will not be in the bottom nibble, and we should not
898 @ perform the additions below. We must test for this though
899 @ (rather relying upon the TSTs to prevent the additions) since
900 @ the bit in ip could be in the top two bits which might then match
901 @ with one of the smaller RORs.
905 beq LSYM(Lgot_result)
912 lsr work, divisor, #3
920 lsr work, divisor, #2
927 beq LSYM(Lgot_result)
928 lsr work, divisor, #1
934 /* If performance is preferred, the following functions are provided. */
935 #if defined(__prefer_thumb__) && !defined(__OPTIMIZE_SIZE__)
937 /* Branch to div(n), and jump to label if curbit is lo than divisior. */
938 .macro BranchToDiv n, label
939 lsr curbit, dividend, \n
944 /* Body of div(n). Shift the divisor in n bits and compare the divisor
945 and dividend. Update the dividend as the substruction result. */
947 lsr curbit, dividend, \n
950 lsl curbit, divisor, \n
951 sub dividend, dividend, curbit
953 1: adc result, result
956 /* The body of division with positive divisor. Unless the divisor is very
957 big, shift it up in multiples of four bits, since this is the amount of
958 unwinding in the main division loop. Continue shifting until the divisor
959 is larger than the dividend. */
960 .macro THUMB1_Div_Positive
962 BranchToDiv #1, LSYM(Lthumb1_div1)
963 BranchToDiv #4, LSYM(Lthumb1_div4)
964 BranchToDiv #8, LSYM(Lthumb1_div8)
965 BranchToDiv #12, LSYM(Lthumb1_div12)
966 BranchToDiv #16, LSYM(Lthumb1_div16)
967 LSYM(Lthumb1_div_large_positive):
969 lsl divisor, divisor, #8
971 lsr curbit, dividend, #16
975 lsl divisor, divisor, #8
976 beq LSYM(Ldivbyzero_waypoint)
978 1: lsr curbit, dividend, #12
980 blo LSYM(Lthumb1_div12)
981 b LSYM(Lthumb1_div16)
982 LSYM(Lthumb1_div_loop):
983 lsr divisor, divisor, #8
994 bcs LSYM(Lthumb1_div_loop)
1008 sub divisor, dividend, divisor
1010 cpy divisor, dividend
1012 1: adc result, result
1013 cpy dividend, result
1016 LSYM(Ldivbyzero_waypoint):
1020 /* The body of division with negative divisor. Similar with
1021 THUMB1_Div_Positive except that the shift steps are in multiples
1023 .macro THUMB1_Div_Negative
1024 lsr result, divisor, #31
1026 neg divisor, divisor
1028 1: asr curbit, dividend, #32
1030 neg dividend, dividend
1032 2: eor curbit, result
1035 BranchToDiv #4, LSYM(Lthumb1_div_negative4)
1036 BranchToDiv #8, LSYM(Lthumb1_div_negative8)
1037 LSYM(Lthumb1_div_large):
1039 lsl divisor, divisor, #6
1041 lsr curbit, dividend, #8
1043 blo LSYM(Lthumb1_div_negative8)
1045 lsl divisor, divisor, #6
1046 asr result, result, #6
1048 blo LSYM(Lthumb1_div_negative8)
1050 lsl divisor, divisor, #6
1051 asr result, result, #6
1053 blo LSYM(Lthumb1_div_negative8)
1055 lsl divisor, divisor, #6
1056 beq LSYM(Ldivbyzero_negative)
1057 asr result, result, #6
1058 b LSYM(Lthumb1_div_negative8)
1059 LSYM(Lthumb1_div_negative_loop):
1060 lsr divisor, divisor, #6
1061 LSYM(Lthumb1_div_negative8):
1066 LSYM(Lthumb1_div_negative4):
1069 bcs LSYM(Lthumb1_div_negative_loop)
1071 sub divisor, dividend, divisor
1073 cpy divisor, dividend
1077 asr curbit, curbit, #1
1078 cpy dividend, result
1080 neg dividend, dividend
1084 neg divisor, divisor
1088 LSYM(Ldivbyzero_negative):
1090 asr curbit, curbit, #1
1092 neg dividend, dividend
1094 #endif /* ARM Thumb version. */
1096 /* ------------------------------------------------------------------------ */
1097 /* Start of the Real Functions */
1098 /* ------------------------------------------------------------------------ */
1101 #if defined(__prefer_thumb__)
1104 FUNC_ALIAS aeabi_uidiv udivsi3
1105 #if defined(__OPTIMIZE_SIZE__)
1109 LSYM(udivsi3_skip_div0_test):
1114 cmp dividend, divisor
1115 blo LSYM(Lgot_result)
1117 THUMB_DIV_MOD_BODY 0
1123 /* Implementation of aeabi_uidiv for ARMv6m. This version is only
1124 used in ARMv6-M when we need an efficient implementation. */
1126 LSYM(udivsi3_skip_div0_test):
1129 #endif /* __OPTIMIZE_SIZE__ */
1131 #elif defined(__ARM_ARCH_EXT_IDIV__)
1133 ARM_FUNC_START udivsi3
1134 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
1142 #else /* ARM version/Thumb-2. */
1144 ARM_FUNC_START udivsi3
1145 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
1147 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
1148 check for division-by-zero a second time. */
1149 LSYM(udivsi3_skip_div0_test):
1159 ARM_DIV_BODY r0, r1, r2, r3
1169 12: ARM_DIV2_ORDER r1, r2
1174 #endif /* ARM version */
1176 DIV_FUNC_END udivsi3 unsigned
1178 #if defined(__prefer_thumb__)
1179 FUNC_START aeabi_uidivmod
1182 # if defined(__OPTIMIZE_SIZE__)
1184 bl LSYM(udivsi3_skip_div0_test)
1190 /* Both the quotient and remainder are calculated simultaneously
1191 in THUMB1_Div_Positive. There is no need to calculate the
1192 remainder again here. */
1193 b LSYM(udivsi3_skip_div0_test)
1195 # endif /* __OPTIMIZE_SIZE__ */
1197 #elif defined(__ARM_ARCH_EXT_IDIV__)
1198 ARM_FUNC_START aeabi_uidivmod
1206 ARM_FUNC_START aeabi_uidivmod
1209 stmfd sp!, { r0, r1, lr }
1210 bl LSYM(udivsi3_skip_div0_test)
1211 ldmfd sp!, { r1, r2, lr }
1216 FUNC_END aeabi_uidivmod
1218 #endif /* L_udivsi3 */
1219 /* ------------------------------------------------------------------------ */
1222 #if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1
1224 ARM_FUNC_START umodsi3
1232 #elif defined(__thumb__)
1239 cmp dividend, divisor
1246 THUMB_DIV_MOD_BODY 1
1251 #else /* ARM version. */
1255 subs r2, r1, #1 @ compare divisor with 1
1257 cmpne r0, r1 @ compare dividend with divisor
1259 tsthi r1, r2 @ see if divisor is power of 2
1263 ARM_MOD_BODY r0, r1, r2, r3
1267 #endif /* ARM version. */
1269 DIV_FUNC_END umodsi3 unsigned
1271 #endif /* L_umodsi3 */
1272 /* ------------------------------------------------------------------------ */
1275 #if defined(__prefer_thumb__)
1278 FUNC_ALIAS aeabi_idiv divsi3
1279 #if defined(__OPTIMIZE_SIZE__)
1283 LSYM(divsi3_skip_div0_test):
1286 eor work, divisor @ Save the sign of the result.
1292 neg divisor, divisor @ Loops below use unsigned.
1296 neg dividend, dividend
1298 cmp dividend, divisor
1299 blo LSYM(Lgot_result)
1301 THUMB_DIV_MOD_BODY 0
1312 /* Implementation of aeabi_idiv for ARMv6m. This version is only
1313 used in ARMv6-M when we need an efficient implementation. */
1315 LSYM(divsi3_skip_div0_test):
1316 cpy curbit, dividend
1318 bmi LSYM(Lthumb1_div_negative)
1320 LSYM(Lthumb1_div_positive):
1323 LSYM(Lthumb1_div_negative):
1326 #endif /* __OPTIMIZE_SIZE__ */
1328 #elif defined(__ARM_ARCH_EXT_IDIV__)
1330 ARM_FUNC_START divsi3
1331 ARM_FUNC_ALIAS aeabi_idiv divsi3
1338 #else /* ARM/Thumb-2 version. */
1340 ARM_FUNC_START divsi3
1341 ARM_FUNC_ALIAS aeabi_idiv divsi3
1345 LSYM(divsi3_skip_div0_test):
1346 eor ip, r0, r1 @ save the sign of the result.
1348 rsbmi r1, r1, #0 @ loops below use unsigned.
1349 subs r2, r1, #1 @ division by 1 or -1 ?
1353 rsbmi r3, r0, #0 @ positive dividend value
1356 tst r1, r2 @ divisor is power of 2 ?
1359 ARM_DIV_BODY r3, r1, r0, r2
1366 10: teq ip, r0 @ same sign ?
1374 moveq r0, ip, asr #31
1378 12: ARM_DIV2_ORDER r1, r2
1386 #endif /* ARM version */
1388 DIV_FUNC_END divsi3 signed
1390 #if defined(__prefer_thumb__)
1391 FUNC_START aeabi_idivmod
1394 # if defined(__OPTIMIZE_SIZE__)
1396 bl LSYM(divsi3_skip_div0_test)
1402 /* Both the quotient and remainder are calculated simultaneously
1403 in THUMB1_Div_Positive and THUMB1_Div_Negative. There is no
1404 need to calculate the remainder again here. */
1405 b LSYM(divsi3_skip_div0_test)
1407 # endif /* __OPTIMIZE_SIZE__ */
1409 #elif defined(__ARM_ARCH_EXT_IDIV__)
1410 ARM_FUNC_START aeabi_idivmod
1418 ARM_FUNC_START aeabi_idivmod
1421 stmfd sp!, { r0, r1, lr }
1422 bl LSYM(divsi3_skip_div0_test)
1423 ldmfd sp!, { r1, r2, lr }
1428 FUNC_END aeabi_idivmod
1430 #endif /* L_divsi3 */
1431 /* ------------------------------------------------------------------------ */
1434 #if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1
1436 ARM_FUNC_START modsi3
1445 #elif defined(__thumb__)
1453 neg divisor, divisor @ Loops below use unsigned.
1456 @ Need to save the sign of the dividend, unfortunately, we need
1457 @ work later on. Must do this after saving the original value of
1458 @ the work register, because we will pop this value off first.
1462 neg dividend, dividend
1464 cmp dividend, divisor
1465 blo LSYM(Lgot_result)
1467 THUMB_DIV_MOD_BODY 1
1472 neg dividend, dividend
1477 #else /* ARM version. */
1483 rsbmi r1, r1, #0 @ loops below use unsigned.
1484 movs ip, r0 @ preserve sign of dividend
1485 rsbmi r0, r0, #0 @ if negative make positive
1486 subs r2, r1, #1 @ compare divisor with 1
1487 cmpne r0, r1 @ compare dividend with divisor
1489 tsthi r1, r2 @ see if divisor is power of 2
1493 ARM_MOD_BODY r0, r1, r2, r3
1499 #endif /* ARM version */
1501 DIV_FUNC_END modsi3 signed
1503 #endif /* L_modsi3 */
1504 /* ------------------------------------------------------------------------ */
1510 FUNC_START aeabi_idiv0
1511 FUNC_START aeabi_ldiv0
1513 FUNC_END aeabi_ldiv0
1514 FUNC_END aeabi_idiv0
1521 #endif /* L_divmodsi_tools */
1522 /* ------------------------------------------------------------------------ */
1524 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1526 /* Constant taken from <asm/signal.h>. */
1530 cfi_start __aeabi_ldiv0, LSYM(Lend_aeabi_ldiv0)
1533 ARM_FUNC_START aeabi_idiv0
1534 ARM_FUNC_START aeabi_ldiv0
1536 98: cfi_push 98b - __aeabi_ldiv0, 0xe, -0x4, 0x8
1538 cfi_start __div0, LSYM(Lend_div0)
1541 98: cfi_push 98b - __div0, 0xe, -0x4, 0x8
1545 bl SYM(raise) __PLT__
1546 RETLDM r1 unwind=98b
1549 cfi_end LSYM(Lend_aeabi_ldiv0)
1550 FUNC_END aeabi_ldiv0
1551 FUNC_END aeabi_idiv0
1553 cfi_end LSYM(Lend_div0)
1557 #endif /* L_dvmd_lnx */
1558 #ifdef L_clear_cache
1559 #if defined __ARM_EABI__ && defined __linux__
1560 @ EABI GNU/Linux call to cacheflush syscall.
1561 ARM_FUNC_START clear_cache
1563 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1574 FUNC_END clear_cache
1576 #error "This is only for ARM EABI GNU/Linux"
1578 #endif /* L_clear_cache */
1579 /* ------------------------------------------------------------------------ */
1580 /* Dword shift operations. */
1581 /* All the following Dword shift variants rely on the fact that
1584 shft xxx, (Reg & 255)
1585 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1586 case of logical shifts) or the sign (for asr). */
1596 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1602 FUNC_ALIAS aeabi_llsr lshrdi3
1620 movmi al, al, lsr r2
1621 movpl al, ah, lsr r3
1622 orrmi al, al, ah, lsl ip
1634 FUNC_ALIAS aeabi_lasr ashrdi3
1641 @ If r2 is negative at this point the following step would OR
1642 @ the sign bit into all of AL. That's not what we want...
1656 movmi al, al, lsr r2
1657 movpl al, ah, asr r3
1658 orrmi al, al, ah, lsl ip
1671 FUNC_ALIAS aeabi_llsl ashldi3
1689 movmi ah, ah, lsl r2
1690 movpl ah, al, lsl r3
1691 orrmi ah, ah, al, lsr ip
1700 #endif /* __symbian__ */
1702 #if (__ARM_ARCH_ISA_THUMB == 2 \
1703 || (__ARM_ARCH_ISA_ARM \
1704 && (__ARM_ARCH__ > 5 \
1705 || (__ARM_ARCH__ == 5 && __ARM_ARCH_ISA_THUMB))))
1706 #define HAVE_ARM_CLZ 1
1710 #ifdef NOT_ISA_TARGET_32BIT
1715 cmp r0, r3 /* 0x10000 */
1720 cmp r0, r3 /* #0x100 */
1725 cmp r0, r3 /* #0x10 */
1735 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1738 ARM_FUNC_START clzsi2
1739 # if defined(HAVE_ARM_CLZ)
1746 movcs r0, r0, lsr #16
1750 movcs r0, r0, lsr #8
1754 movcs r0, r0, lsr #4
1762 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1763 # endif /* !HAVE_ARM_CLZ */
1766 #endif /* L_clzsi2 */
1769 #if !defined(HAVE_ARM_CLZ)
1771 # ifdef NOT_ISA_TARGET_32BIT
1775 ARM_FUNC_START clzdi2
1796 # ifdef NOT_ISA_TARGET_32BIT
1803 #else /* HAVE_ARM_CLZ */
1805 ARM_FUNC_START clzdi2
1815 #endif /* L_clzdi2 */
1818 #ifdef NOT_ISA_TARGET_32BIT
1825 cmp r0, r3 /* 0x10000 */
1830 cmp r0, r3 /* #0x100 */
1835 cmp r0, r3 /* #0x10 */
1845 .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1848 ARM_FUNC_START ctzsi2
1851 # if defined(HAVE_ARM_CLZ)
1859 movcs r0, r0, lsr #16
1863 movcs r0, r0, lsr #8
1867 movcs r0, r0, lsr #4
1875 .byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
1876 # endif /* !HAVE_ARM_CLZ */
1879 #endif /* L_clzsi2 */
1881 /* ------------------------------------------------------------------------ */
1882 /* These next two sections are here despite the fact that they contain Thumb
1883 assembler because their presence allows interworked code to be linked even
1884 when the GCC library is this one. */
1886 /* Do not build the interworking functions when the target architecture does
1887 not support Thumb instructions. (This can be a multilib option). */
1888 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1889 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1890 || __ARM_ARCH__ >= 6
1892 #if defined L_call_via_rX
1894 /* These labels & instructions are used by the Arm/Thumb interworking code.
1895 The address of function to be called is loaded into a register and then
1896 one of these labels is called via a BL instruction. This puts the
1897 return address into the link register with the bottom bit set, and the
1898 code here switches to the correct mode before executing the function. */
1904 .macro call_via register
1905 THUMB_FUNC_START _call_via_\register
1910 SIZE (_call_via_\register)
1929 #endif /* L_call_via_rX */
1931 /* Don't bother with the old interworking routines for Thumb-2. */
1932 /* ??? Maybe only omit these on "m" variants. */
1933 #if !defined(__thumb2__) && __ARM_ARCH_ISA_ARM
1935 #if defined L_interwork_call_via_rX
1937 /* These labels & instructions are used by the Arm/Thumb interworking code,
1938 when the target address is in an unknown instruction set. The address
1939 of function to be called is loaded into a register and then one of these
1940 labels is called via a BL instruction. This puts the return address
1941 into the link register with the bottom bit set, and the code here
1942 switches to the correct mode before executing the function. Unfortunately
1943 the target code cannot be relied upon to return via a BX instruction, so
1944 instead we have to store the resturn address on the stack and allow the
1945 called function to return here instead. Upon return we recover the real
1946 return address and use a BX to get back to Thumb mode.
1948 There are three variations of this code. The first,
1949 _interwork_call_via_rN(), will push the return address onto the
1950 stack and pop it in _arm_return(). It should only be used if all
1951 arguments are passed in registers.
1953 The second, _interwork_r7_call_via_rN(), instead stores the return
1954 address at [r7, #-4]. It is the caller's responsibility to ensure
1955 that this address is valid and contains no useful data.
1957 The third, _interwork_r11_call_via_rN(), works in the same way but
1958 uses r11 instead of r7. It is useful if the caller does not really
1959 need a frame pointer. */
1966 LSYM(Lstart_arm_return):
1967 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1968 cfi_push 0, 0xe, -0x8, 0x8
1969 nop @ This nop is for the benefit of debuggers, so that
1970 @ backtraces will use the correct unwind information.
1972 RETLDM unwind=LSYM(Lstart_arm_return)
1973 cfi_end LSYM(Lend_arm_return)
1975 .globl _arm_return_r7
1980 .globl _arm_return_r11
1985 .macro interwork_with_frame frame, register, name, return
1988 THUMB_FUNC_START \name
1995 streq lr, [\frame, #-4]
1996 adreq lr, _arm_return_\frame
2002 .macro interwork register
2005 THUMB_FUNC_START _interwork_call_via_\register
2011 .globl LSYM(Lchange_\register)
2012 LSYM(Lchange_\register):
2014 streq lr, [sp, #-8]!
2015 adreq lr, _arm_return
2018 SIZE (_interwork_call_via_\register)
2020 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
2021 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
2039 /* The LR case has to be handled a little differently... */
2042 THUMB_FUNC_START _interwork_call_via_lr
2051 stmeqdb r13!, {lr, pc}
2053 adreq lr, _arm_return
2056 SIZE (_interwork_call_via_lr)
2058 #endif /* L_interwork_call_via_rX */
2059 #endif /* !__thumb2__ */
2061 /* Functions to support compact pic switch tables in thumb1 state.
2062 All these routines take an index into the table in r0. The
2063 table is at LR & ~1 (but this must be rounded up in the case
2064 of 32-bit entires). They are only permitted to clobber r12
2065 and r14 and r0 must be preserved on exit. */
2066 #ifdef L_thumb1_case_sqi
2072 THUMB_FUNC_START __gnu_thumb1_case_sqi
2082 SIZE (__gnu_thumb1_case_sqi)
2085 #ifdef L_thumb1_case_uqi
2091 THUMB_FUNC_START __gnu_thumb1_case_uqi
2101 SIZE (__gnu_thumb1_case_uqi)
2104 #ifdef L_thumb1_case_shi
2110 THUMB_FUNC_START __gnu_thumb1_case_shi
2121 SIZE (__gnu_thumb1_case_shi)
2124 #ifdef L_thumb1_case_uhi
2130 THUMB_FUNC_START __gnu_thumb1_case_uhi
2141 SIZE (__gnu_thumb1_case_uhi)
2144 #ifdef L_thumb1_case_si
2150 THUMB_FUNC_START __gnu_thumb1_case_si
2153 adds.n r1, r1, #2 /* Align to word. */
2161 mov pc, lr /* We know we were called from thumb code. */
2162 SIZE (__gnu_thumb1_case_si)
2165 #endif /* Arch supports thumb. */
2167 .macro CFI_START_FUNCTION
2172 .macro CFI_END_FUNCTION
2178 /* The condition here must match the one in gcc/config/arm/elf.h. */
2179 #ifndef NOT_ISA_TARGET_32BIT
2180 #include "ieee754-df.S"
2181 #include "ieee754-sf.S"
2183 #else /* NOT_ISA_TARGET_32BIT */
2184 #include "bpabi-v6m.S"
2185 #endif /* NOT_ISA_TARGET_32BIT */
2186 #endif /* !__symbian__ */