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 #else /* ARM version/Thumb-2. */
956 ARM_FUNC_START udivsi3
957 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
959 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
960 check for division-by-zero a second time. */
961 LSYM(udivsi3_skip_div0_test):
971 ARM_DIV_BODY r0, r1, r2, r3
981 12: ARM_DIV2_ORDER r1, r2
986 #endif /* ARM version */
988 DIV_FUNC_END udivsi3 unsigned
990 #if defined(__prefer_thumb__)
991 FUNC_START aeabi_uidivmod
995 bl LSYM(udivsi3_skip_div0_test)
1001 ARM_FUNC_START aeabi_uidivmod
1004 stmfd sp!, { r0, r1, lr }
1005 bl LSYM(udivsi3_skip_div0_test)
1006 ldmfd sp!, { r1, r2, lr }
1011 FUNC_END aeabi_uidivmod
1013 #endif /* L_udivsi3 */
1014 /* ------------------------------------------------------------------------ */
1024 cmp dividend, divisor
1031 THUMB_DIV_MOD_BODY 1
1036 #else /* ARM version. */
1038 subs r2, r1, #1 @ compare divisor with 1
1040 cmpne r0, r1 @ compare dividend with divisor
1042 tsthi r1, r2 @ see if divisor is power of 2
1046 ARM_MOD_BODY r0, r1, r2, r3
1050 #endif /* ARM version. */
1052 DIV_FUNC_END umodsi3 unsigned
1054 #endif /* L_umodsi3 */
1055 /* ------------------------------------------------------------------------ */
1058 #if defined(__prefer_thumb__)
1061 FUNC_ALIAS aeabi_idiv divsi3
1065 LSYM(divsi3_skip_div0_test):
1068 eor work, divisor @ Save the sign of the result.
1074 neg divisor, divisor @ Loops below use unsigned.
1078 neg dividend, dividend
1080 cmp dividend, divisor
1081 blo LSYM(Lgot_result)
1083 THUMB_DIV_MOD_BODY 0
1094 #else /* ARM/Thumb-2 version. */
1096 ARM_FUNC_START divsi3
1097 ARM_FUNC_ALIAS aeabi_idiv divsi3
1101 LSYM(divsi3_skip_div0_test):
1102 eor ip, r0, r1 @ save the sign of the result.
1104 rsbmi r1, r1, #0 @ loops below use unsigned.
1105 subs r2, r1, #1 @ division by 1 or -1 ?
1109 rsbmi r3, r0, #0 @ positive dividend value
1112 tst r1, r2 @ divisor is power of 2 ?
1115 ARM_DIV_BODY r3, r1, r0, r2
1122 10: teq ip, r0 @ same sign ?
1130 moveq r0, ip, asr #31
1134 12: ARM_DIV2_ORDER r1, r2
1142 #endif /* ARM version */
1144 DIV_FUNC_END divsi3 signed
1146 #if defined(__prefer_thumb__)
1147 FUNC_START aeabi_idivmod
1151 bl LSYM(divsi3_skip_div0_test)
1157 ARM_FUNC_START aeabi_idivmod
1160 stmfd sp!, { r0, r1, lr }
1161 bl LSYM(divsi3_skip_div0_test)
1162 ldmfd sp!, { r1, r2, lr }
1167 FUNC_END aeabi_idivmod
1169 #endif /* L_divsi3 */
1170 /* ------------------------------------------------------------------------ */
1181 neg divisor, divisor @ Loops below use unsigned.
1184 @ Need to save the sign of the dividend, unfortunately, we need
1185 @ work later on. Must do this after saving the original value of
1186 @ the work register, because we will pop this value off first.
1190 neg dividend, dividend
1192 cmp dividend, divisor
1193 blo LSYM(Lgot_result)
1195 THUMB_DIV_MOD_BODY 1
1200 neg dividend, dividend
1205 #else /* ARM version. */
1209 rsbmi r1, r1, #0 @ loops below use unsigned.
1210 movs ip, r0 @ preserve sign of dividend
1211 rsbmi r0, r0, #0 @ if negative make positive
1212 subs r2, r1, #1 @ compare divisor with 1
1213 cmpne r0, r1 @ compare dividend with divisor
1215 tsthi r1, r2 @ see if divisor is power of 2
1219 ARM_MOD_BODY r0, r1, r2, r3
1225 #endif /* ARM version */
1227 DIV_FUNC_END modsi3 signed
1229 #endif /* L_modsi3 */
1230 /* ------------------------------------------------------------------------ */
1236 FUNC_START aeabi_idiv0
1237 FUNC_START aeabi_ldiv0
1239 FUNC_END aeabi_ldiv0
1240 FUNC_END aeabi_idiv0
1247 #endif /* L_divmodsi_tools */
1248 /* ------------------------------------------------------------------------ */
1250 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1252 /* Constant taken from <asm/signal.h>. */
1258 ARM_FUNC_START aeabi_idiv0
1259 ARM_FUNC_START aeabi_ldiv0
1266 bl SYM(raise) __PLT__
1270 FUNC_END aeabi_ldiv0
1271 FUNC_END aeabi_idiv0
1276 #endif /* L_dvmd_lnx */
1277 #ifdef L_clear_cache
1278 #if defined __ARM_EABI__ && defined __linux__
1279 @ EABI GNU/Linux call to cacheflush syscall.
1280 ARM_FUNC_START clear_cache
1282 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1293 FUNC_END clear_cache
1295 #error "This is only for ARM EABI GNU/Linux"
1297 #endif /* L_clear_cache */
1298 /* ------------------------------------------------------------------------ */
1299 /* Dword shift operations. */
1300 /* All the following Dword shift variants rely on the fact that
1303 shft xxx, (Reg & 255)
1304 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1305 case of logical shifts) or the sign (for asr). */
1315 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1321 FUNC_ALIAS aeabi_llsr lshrdi3
1339 movmi al, al, lsr r2
1340 movpl al, ah, lsr r3
1341 orrmi al, al, ah, lsl ip
1353 FUNC_ALIAS aeabi_lasr ashrdi3
1360 @ If r2 is negative at this point the following step would OR
1361 @ the sign bit into all of AL. That's not what we want...
1375 movmi al, al, lsr r2
1376 movpl al, ah, asr r3
1377 orrmi al, al, ah, lsl ip
1390 FUNC_ALIAS aeabi_llsl ashldi3
1408 movmi ah, ah, lsl r2
1409 movpl ah, al, lsl r3
1410 orrmi ah, ah, al, lsr ip
1419 #endif /* __symbian__ */
1421 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1422 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1423 || defined(__ARM_ARCH_5TEJ__)
1424 #define HAVE_ARM_CLZ 1
1428 #if defined(__ARM_ARCH_6M__)
1433 cmp r0, r3 /* 0x10000 */
1438 cmp r0, r3 /* #0x100 */
1443 cmp r0, r3 /* #0x10 */
1453 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1456 ARM_FUNC_START clzsi2
1457 # if defined(HAVE_ARM_CLZ)
1464 movcs r0, r0, lsr #16
1468 movcs r0, r0, lsr #8
1472 movcs r0, r0, lsr #4
1480 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1481 # endif /* !HAVE_ARM_CLZ */
1484 #endif /* L_clzsi2 */
1487 #if !defined(HAVE_ARM_CLZ)
1489 # if defined(__ARM_ARCH_6M__)
1493 ARM_FUNC_START clzdi2
1514 # if defined(__ARM_ARCH_6M__)
1521 #else /* HAVE_ARM_CLZ */
1523 ARM_FUNC_START clzdi2
1533 #endif /* L_clzdi2 */
1535 /* ------------------------------------------------------------------------ */
1536 /* These next two sections are here despite the fact that they contain Thumb
1537 assembler because their presence allows interworked code to be linked even
1538 when the GCC library is this one. */
1540 /* Do not build the interworking functions when the target architecture does
1541 not support Thumb instructions. (This can be a multilib option). */
1542 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1543 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1544 || __ARM_ARCH__ >= 6
1546 #if defined L_call_via_rX
1548 /* These labels & instructions are used by the Arm/Thumb interworking code.
1549 The address of function to be called is loaded into a register and then
1550 one of these labels is called via a BL instruction. This puts the
1551 return address into the link register with the bottom bit set, and the
1552 code here switches to the correct mode before executing the function. */
1558 .macro call_via register
1559 THUMB_FUNC_START _call_via_\register
1564 SIZE (_call_via_\register)
1583 #endif /* L_call_via_rX */
1585 /* Don't bother with the old interworking routines for Thumb-2. */
1586 /* ??? Maybe only omit these on "m" variants. */
1587 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1589 #if defined L_interwork_call_via_rX
1591 /* These labels & instructions are used by the Arm/Thumb interworking code,
1592 when the target address is in an unknown instruction set. The address
1593 of function to be called is loaded into a register and then one of these
1594 labels is called via a BL instruction. This puts the return address
1595 into the link register with the bottom bit set, and the code here
1596 switches to the correct mode before executing the function. Unfortunately
1597 the target code cannot be relied upon to return via a BX instruction, so
1598 instead we have to store the resturn address on the stack and allow the
1599 called function to return here instead. Upon return we recover the real
1600 return address and use a BX to get back to Thumb mode.
1602 There are three variations of this code. The first,
1603 _interwork_call_via_rN(), will push the return address onto the
1604 stack and pop it in _arm_return(). It should only be used if all
1605 arguments are passed in registers.
1607 The second, _interwork_r7_call_via_rN(), instead stores the return
1608 address at [r7, #-4]. It is the caller's responsibility to ensure
1609 that this address is valid and contains no useful data.
1611 The third, _interwork_r11_call_via_rN(), works in the same way but
1612 uses r11 instead of r7. It is useful if the caller does not really
1613 need a frame pointer. */
1620 LSYM(Lstart_arm_return):
1621 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1622 cfi_push 0, 0xe, -0x8, 0x8
1623 nop @ This nop is for the benefit of debuggers, so that
1624 @ backtraces will use the correct unwind information.
1626 RETLDM unwind=LSYM(Lstart_arm_return)
1627 cfi_end LSYM(Lend_arm_return)
1629 .globl _arm_return_r7
1634 .globl _arm_return_r11
1639 .macro interwork_with_frame frame, register, name, return
1642 THUMB_FUNC_START \name
1649 streq lr, [\frame, #-4]
1650 adreq lr, _arm_return_\frame
1656 .macro interwork register
1659 THUMB_FUNC_START _interwork_call_via_\register
1665 .globl LSYM(Lchange_\register)
1666 LSYM(Lchange_\register):
1668 streq lr, [sp, #-8]!
1669 adreq lr, _arm_return
1672 SIZE (_interwork_call_via_\register)
1674 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1675 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1693 /* The LR case has to be handled a little differently... */
1696 THUMB_FUNC_START _interwork_call_via_lr
1705 stmeqdb r13!, {lr, pc}
1707 adreq lr, _arm_return
1710 SIZE (_interwork_call_via_lr)
1712 #endif /* L_interwork_call_via_rX */
1713 #endif /* !__thumb2__ */
1715 /* Functions to support compact pic switch tables in thumb1 state.
1716 All these routines take an index into the table in r0. The
1717 table is at LR & ~1 (but this must be rounded up in the case
1718 of 32-bit entires). They are only permitted to clobber r12
1719 and r14 and r0 must be preserved on exit. */
1720 #ifdef L_thumb1_case_sqi
1726 THUMB_FUNC_START __gnu_thumb1_case_sqi
1736 SIZE (__gnu_thumb1_case_sqi)
1739 #ifdef L_thumb1_case_uqi
1745 THUMB_FUNC_START __gnu_thumb1_case_uqi
1755 SIZE (__gnu_thumb1_case_uqi)
1758 #ifdef L_thumb1_case_shi
1764 THUMB_FUNC_START __gnu_thumb1_case_shi
1775 SIZE (__gnu_thumb1_case_shi)
1778 #ifdef L_thumb1_case_uhi
1784 THUMB_FUNC_START __gnu_thumb1_case_uhi
1795 SIZE (__gnu_thumb1_case_uhi)
1798 #ifdef L_thumb1_case_si
1804 THUMB_FUNC_START __gnu_thumb1_case_si
1807 adds.n r1, r1, #2 /* Align to word. */
1815 mov pc, lr /* We know we were called from thumb code. */
1816 SIZE (__gnu_thumb1_case_si)
1819 #endif /* Arch supports thumb. */
1822 #ifndef __ARM_ARCH_6M__
1823 #include "ieee754-df.S"
1824 #include "ieee754-sf.S"
1826 #else /* __ARM_ARCH_6M__ */
1827 #include "bpabi-v6m.S"
1828 #endif /* __ARM_ARCH_6M__ */
1829 #endif /* !__symbian__ */