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 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_align8_needed: This code does not require 8-byte
35 alignment from the caller. */
36 /* .eabi_attribute 24, 0 -- default setting. */
37 /* Tag_ABI_align8_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 # define __ARM_ARCH__ 7
112 #error Unable to determine architecture.
115 /* There are times when we might prefer Thumb1 code even if ARM code is
116 permitted, for example, the code might be smaller, or there might be
117 interworking problems with switching to ARM state if interworking is
119 #if (defined(__thumb__) \
120 && !defined(__thumb2__) \
121 && (!defined(__THUMB_INTERWORK__) \
122 || defined (__OPTIMIZE_SIZE__) \
123 || defined(__ARM_ARCH_6M__)))
124 # define __prefer_thumb__
127 /* How to return from a function call depends on the architecture variant. */
129 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
132 # define RETc(x) bx##x lr
134 /* Special precautions for interworking on armv4t. */
135 # if (__ARM_ARCH__ == 4)
137 /* Always use bx, not ldr pc. */
138 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
139 # define __INTERWORKING__
140 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
142 /* Include thumb stub before arm mode code. */
143 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
144 # define __INTERWORKING_STUBS__
145 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
147 #endif /* __ARM_ARCH == 4 */
151 # define RET mov pc, lr
152 # define RETc(x) mov##x pc, lr
156 .macro cfi_pop advance, reg, cfa_offset
158 .pushsection .debug_frame
159 .byte 0x4 /* DW_CFA_advance_loc4 */
161 .byte (0xc0 | \reg) /* DW_CFA_restore */
162 .byte 0xe /* DW_CFA_def_cfa_offset */
167 .macro cfi_push advance, reg, offset, cfa_offset
169 .pushsection .debug_frame
170 .byte 0x4 /* DW_CFA_advance_loc4 */
172 .byte (0x80 | \reg) /* DW_CFA_offset */
173 .uleb128 (\offset / -4)
174 .byte 0xe /* DW_CFA_def_cfa_offset */
179 .macro cfi_start start_label, end_label
181 .pushsection .debug_frame
183 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
185 .4byte 0xffffffff @ CIE Identifier Tag
186 .byte 0x1 @ CIE Version
187 .ascii "\0" @ CIE Augmentation
188 .uleb128 0x1 @ CIE Code Alignment Factor
189 .sleb128 -4 @ CIE Data Alignment Factor
190 .byte 0xe @ CIE RA Column
191 .byte 0xc @ DW_CFA_def_cfa
197 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
199 .4byte LSYM(Lstart_frame) @ FDE CIE offset
200 .4byte \start_label @ FDE initial location
201 .4byte \end_label-\start_label @ FDE address range
205 .macro cfi_end end_label
207 .pushsection .debug_frame
215 /* Don't pass dirn, it's there just to get token pasting right. */
217 .macro RETLDM regs=, cond=, unwind=, dirn=ia
218 #if defined (__INTERWORKING__)
220 ldr\cond lr, [sp], #8
222 # if defined(__thumb2__)
225 ldm\cond\dirn sp!, {\regs, lr}
229 /* Mark LR as restored. */
230 97: cfi_pop 97b - \unwind, 0xe, 0x0
234 /* Caller is responsible for providing IT instruction. */
236 ldr\cond pc, [sp], #8
238 # if defined(__thumb2__)
241 ldm\cond\dirn sp!, {\regs, pc}
247 /* The Unified assembly syntax allows the same code to be assembled for both
248 ARM and Thumb-2. However this is only supported by recent gas, so define
249 a set of macros to allow ARM code on older assemblers. */
250 #if defined(__thumb2__)
251 .macro do_it cond, suffix=""
254 .macro shift1 op, arg0, arg1, arg2
255 \op \arg0, \arg1, \arg2
259 #define COND(op1, op2, cond) op1 ## op2 ## cond
260 /* Perform an arithmetic operation with a variable shift operand. This
261 requires two instructions and a scratch register on Thumb-2. */
262 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
263 \shiftop \tmp, \src2, \shiftreg
264 \name \dest, \src1, \tmp
267 .macro do_it cond, suffix=""
269 .macro shift1 op, arg0, arg1, arg2
270 mov \arg0, \arg1, \op \arg2
272 #define do_push stmfd sp!,
273 #define do_pop ldmfd sp!,
274 #define COND(op1, op2, cond) op1 ## cond ## op2
275 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
276 \name \dest, \src1, \src2, \shiftop \shiftreg
281 .macro ARM_LDIV0 name signed
283 .ifc \signed, unsigned
284 movne r0, #0xffffffff
286 movgt r0, #0x7fffffff
287 movlt r0, #0x80000000
289 b SYM (__aeabi_idiv0) __PLT__
292 .macro ARM_LDIV0 name signed
294 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
295 bl SYM (__div0) __PLT__
296 mov r0, #0 @ About as wrong as it could be.
303 .macro THUMB_LDIV0 name signed
304 #if defined(__ARM_ARCH_6M__)
305 .ifc \signed, unsigned
309 mvn r0, r0 @ 0xffffffff
317 lsr r0, r0, #1 @ 0x7fffffff
320 lsl r0, r0, #24 @ 0x80000000
328 @ We know we are not on armv4t, so pop pc is safe.
332 .word __aeabi_idiv0 - 4b
333 #elif defined(__thumb2__)
335 .ifc \signed, unsigned
342 movgt r0, #0x7fffffff
344 movlt r0, #0x80000000
346 b.w SYM(__aeabi_idiv0) __PLT__
353 .ifc \signed, unsigned
354 movne r0, #0xffffffff
356 movgt r0, #0x7fffffff
357 movlt r0, #0x80000000
359 b SYM(__aeabi_idiv0) __PLT__
364 .macro THUMB_LDIV0 name signed
366 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
368 mov r0, #0 @ About as wrong as it could be.
369 #if defined (__INTERWORKING__)
382 .macro DIV_FUNC_END name signed
383 cfi_start __\name, LSYM(Lend_div0)
386 THUMB_LDIV0 \name \signed
388 ARM_LDIV0 \name \signed
390 cfi_end LSYM(Lend_div0)
394 .macro THUMB_FUNC_START name
401 /* Function start macros. Variants for ARM and Thumb. */
404 #define THUMB_FUNC .thumb_func
405 #define THUMB_CODE .force_thumb
406 # if defined(__thumb2__)
407 #define THUMB_SYNTAX .syntax divided
417 .macro FUNC_START name
428 /* Special function that will always be coded in ARM assembly, even if
429 in Thumb-only compilation. */
431 #if defined(__thumb2__)
433 /* For Thumb-2 we build everything in thumb mode. */
434 .macro ARM_FUNC_START name
438 #define EQUIV .thumb_set
443 #elif defined(__INTERWORKING_STUBS__)
445 .macro ARM_FUNC_START name
450 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
451 directly from other local arm routines. */
454 #define EQUIV .thumb_set
455 /* Branch directly to a function declared with ARM_FUNC_START.
456 Must be called in arm mode. */
461 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
463 #ifdef __ARM_ARCH_6M__
464 #define EQUIV .thumb_set
466 .macro ARM_FUNC_START name
482 .macro FUNC_ALIAS new old
484 #if defined (__thumb__)
485 .thumb_set SYM (__\new), SYM (__\old)
487 .set SYM (__\new), SYM (__\old)
491 #ifndef __ARM_ARCH_6M__
492 .macro ARM_FUNC_ALIAS new old
494 EQUIV SYM (__\new), SYM (__\old)
495 #if defined(__INTERWORKING_STUBS__)
496 .set SYM (_L__\new), SYM (_L__\old)
520 /* Register aliases. */
522 work .req r4 @ XXXX is this safe ?
536 /* ------------------------------------------------------------------------ */
537 /* Bodies of the division and modulo routines. */
538 /* ------------------------------------------------------------------------ */
539 .macro ARM_DIV_BODY dividend, divisor, result, curbit
541 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
543 #if defined (__thumb2__)
544 clz \curbit, \dividend
545 clz \result, \divisor
546 sub \curbit, \result, \curbit
547 rsb \curbit, \curbit, #31
549 add \curbit, \result, \curbit, lsl #4
556 .set shift, shift - 1
557 cmp.w \dividend, \divisor, lsl #shift
559 adc.w \result, \result, \result
561 subcs.w \dividend, \dividend, \divisor, lsl #shift
564 clz \curbit, \dividend
565 clz \result, \divisor
566 sub \curbit, \result, \curbit
567 rsbs \curbit, \curbit, #31
568 addne \curbit, \curbit, \curbit, lsl #1
570 addne pc, pc, \curbit, lsl #2
574 .set shift, shift - 1
575 cmp \dividend, \divisor, lsl #shift
576 adc \result, \result, \result
577 subcs \dividend, \dividend, \divisor, lsl #shift
581 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
582 #if __ARM_ARCH__ >= 5
584 clz \curbit, \divisor
585 clz \result, \dividend
586 sub \result, \curbit, \result
588 mov \divisor, \divisor, lsl \result
589 mov \curbit, \curbit, lsl \result
592 #else /* __ARM_ARCH__ < 5 */
594 @ Initially shift the divisor left 3 bits if possible,
595 @ set curbit accordingly. This allows for curbit to be located
596 @ at the left end of each 4-bit nibbles in the division loop
597 @ to save one loop in most cases.
598 tst \divisor, #0xe0000000
599 moveq \divisor, \divisor, lsl #3
603 @ Unless the divisor is very big, shift it up in multiples of
604 @ four bits, since this is the amount of unwinding in the main
605 @ division loop. Continue shifting until the divisor is
606 @ larger than the dividend.
607 1: cmp \divisor, #0x10000000
608 cmplo \divisor, \dividend
609 movlo \divisor, \divisor, lsl #4
610 movlo \curbit, \curbit, lsl #4
613 @ For very big divisors, we must shift it a bit at a time, or
614 @ we will be in danger of overflowing.
615 1: cmp \divisor, #0x80000000
616 cmplo \divisor, \dividend
617 movlo \divisor, \divisor, lsl #1
618 movlo \curbit, \curbit, lsl #1
623 #endif /* __ARM_ARCH__ < 5 */
626 1: cmp \dividend, \divisor
628 subhs \dividend, \dividend, \divisor
629 orrhs \result, \result, \curbit
630 cmp \dividend, \divisor, lsr #1
632 subhs \dividend, \dividend, \divisor, lsr #1
633 orrhs \result, \result, \curbit, lsr #1
634 cmp \dividend, \divisor, lsr #2
636 subhs \dividend, \dividend, \divisor, lsr #2
637 orrhs \result, \result, \curbit, lsr #2
638 cmp \dividend, \divisor, lsr #3
640 subhs \dividend, \dividend, \divisor, lsr #3
641 orrhs \result, \result, \curbit, lsr #3
642 cmp \dividend, #0 @ Early termination?
644 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
645 movne \divisor, \divisor, lsr #4
648 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
651 /* ------------------------------------------------------------------------ */
652 .macro ARM_DIV2_ORDER divisor, order
654 #if __ARM_ARCH__ >= 5
657 rsb \order, \order, #31
661 cmp \divisor, #(1 << 16)
662 movhs \divisor, \divisor, lsr #16
666 cmp \divisor, #(1 << 8)
667 movhs \divisor, \divisor, lsr #8
668 addhs \order, \order, #8
670 cmp \divisor, #(1 << 4)
671 movhs \divisor, \divisor, lsr #4
672 addhs \order, \order, #4
674 cmp \divisor, #(1 << 2)
675 addhi \order, \order, #3
676 addls \order, \order, \divisor, lsr #1
681 /* ------------------------------------------------------------------------ */
682 .macro ARM_MOD_BODY dividend, divisor, order, spare
684 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
687 clz \spare, \dividend
688 sub \order, \order, \spare
689 rsbs \order, \order, #31
690 addne pc, pc, \order, lsl #3
694 .set shift, shift - 1
695 cmp \dividend, \divisor, lsl #shift
696 subcs \dividend, \dividend, \divisor, lsl #shift
699 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
700 #if __ARM_ARCH__ >= 5
703 clz \spare, \dividend
704 sub \order, \order, \spare
705 mov \divisor, \divisor, lsl \order
707 #else /* __ARM_ARCH__ < 5 */
711 @ Unless the divisor is very big, shift it up in multiples of
712 @ four bits, since this is the amount of unwinding in the main
713 @ division loop. Continue shifting until the divisor is
714 @ larger than the dividend.
715 1: cmp \divisor, #0x10000000
716 cmplo \divisor, \dividend
717 movlo \divisor, \divisor, lsl #4
718 addlo \order, \order, #4
721 @ For very big divisors, we must shift it a bit at a time, or
722 @ we will be in danger of overflowing.
723 1: cmp \divisor, #0x80000000
724 cmplo \divisor, \dividend
725 movlo \divisor, \divisor, lsl #1
726 addlo \order, \order, #1
729 #endif /* __ARM_ARCH__ < 5 */
731 @ Perform all needed substractions to keep only the reminder.
732 @ Do comparisons in batch of 4 first.
733 subs \order, \order, #3 @ yes, 3 is intended here
736 1: cmp \dividend, \divisor
737 subhs \dividend, \dividend, \divisor
738 cmp \dividend, \divisor, lsr #1
739 subhs \dividend, \dividend, \divisor, lsr #1
740 cmp \dividend, \divisor, lsr #2
741 subhs \dividend, \dividend, \divisor, lsr #2
742 cmp \dividend, \divisor, lsr #3
743 subhs \dividend, \dividend, \divisor, lsr #3
745 mov \divisor, \divisor, lsr #4
746 subges \order, \order, #4
753 @ Either 1, 2 or 3 comparison/substractions are left.
757 cmp \dividend, \divisor
758 subhs \dividend, \dividend, \divisor
759 mov \divisor, \divisor, lsr #1
760 3: cmp \dividend, \divisor
761 subhs \dividend, \dividend, \divisor
762 mov \divisor, \divisor, lsr #1
763 4: cmp \dividend, \divisor
764 subhs \dividend, \dividend, \divisor
767 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
770 /* ------------------------------------------------------------------------ */
771 .macro THUMB_DIV_MOD_BODY modulo
772 @ Load the constant 0x10000000 into our work register.
776 @ Unless the divisor is very big, shift it up in multiples of
777 @ four bits, since this is the amount of unwinding in the main
778 @ division loop. Continue shifting until the divisor is
779 @ larger than the dividend.
782 cmp divisor, dividend
788 @ Set work to 0x80000000
791 @ For very big divisors, we must shift it a bit at a time, or
792 @ we will be in danger of overflowing.
795 cmp divisor, dividend
801 @ Test for possible subtractions ...
803 @ ... On the final pass, this may subtract too much from the dividend,
804 @ so keep track of which subtractions are done, we can fix them up
807 cmp dividend, divisor
809 sub dividend, dividend, divisor
811 lsr work, divisor, #1
814 sub dividend, dividend, work
821 lsr work, divisor, #2
824 sub dividend, dividend, work
831 lsr work, divisor, #3
834 sub dividend, dividend, work
843 @ ... and note which bits are done in the result. On the final pass,
844 @ this may subtract too much from the dividend, but the result will be ok,
845 @ since the "bit" will have been shifted out at the bottom.
846 cmp dividend, divisor
848 sub dividend, dividend, divisor
849 orr result, result, curbit
851 lsr work, divisor, #1
854 sub dividend, dividend, work
858 lsr work, divisor, #2
861 sub dividend, dividend, work
865 lsr work, divisor, #3
868 sub dividend, dividend, work
874 cmp dividend, #0 @ Early termination?
876 lsr curbit, #4 @ No, any more bits to do?
882 @ Any subtractions that we should not have done will be recorded in
883 @ the top three bits of "overdone". Exactly which were not needed
884 @ are governed by the position of the bit, stored in ip.
888 beq LSYM(Lgot_result)
890 @ If we terminated early, because dividend became zero, then the
891 @ bit in ip will not be in the bottom nibble, and we should not
892 @ perform the additions below. We must test for this though
893 @ (rather relying upon the TSTs to prevent the additions) since
894 @ the bit in ip could be in the top two bits which might then match
895 @ with one of the smaller RORs.
899 beq LSYM(Lgot_result)
906 lsr work, divisor, #3
914 lsr work, divisor, #2
921 beq LSYM(Lgot_result)
922 lsr work, divisor, #1
927 /* ------------------------------------------------------------------------ */
928 /* Start of the Real Functions */
929 /* ------------------------------------------------------------------------ */
932 #if defined(__prefer_thumb__)
935 FUNC_ALIAS aeabi_uidiv udivsi3
939 LSYM(udivsi3_skip_div0_test):
944 cmp dividend, divisor
945 blo LSYM(Lgot_result)
953 #else /* ARM version/Thumb-2. */
955 ARM_FUNC_START udivsi3
956 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
958 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
959 check for division-by-zero a second time. */
960 LSYM(udivsi3_skip_div0_test):
970 ARM_DIV_BODY r0, r1, r2, r3
980 12: ARM_DIV2_ORDER r1, r2
985 #endif /* ARM version */
987 DIV_FUNC_END udivsi3 unsigned
989 #if defined(__prefer_thumb__)
990 FUNC_START aeabi_uidivmod
994 bl LSYM(udivsi3_skip_div0_test)
1000 ARM_FUNC_START aeabi_uidivmod
1003 stmfd sp!, { r0, r1, lr }
1004 bl LSYM(udivsi3_skip_div0_test)
1005 ldmfd sp!, { r1, r2, lr }
1010 FUNC_END aeabi_uidivmod
1012 #endif /* L_udivsi3 */
1013 /* ------------------------------------------------------------------------ */
1023 cmp dividend, divisor
1030 THUMB_DIV_MOD_BODY 1
1035 #else /* ARM version. */
1037 subs r2, r1, #1 @ compare divisor with 1
1039 cmpne r0, r1 @ compare dividend with divisor
1041 tsthi r1, r2 @ see if divisor is power of 2
1045 ARM_MOD_BODY r0, r1, r2, r3
1049 #endif /* ARM version. */
1051 DIV_FUNC_END umodsi3 unsigned
1053 #endif /* L_umodsi3 */
1054 /* ------------------------------------------------------------------------ */
1057 #if defined(__prefer_thumb__)
1060 FUNC_ALIAS aeabi_idiv divsi3
1064 LSYM(divsi3_skip_div0_test):
1067 eor work, divisor @ Save the sign of the result.
1073 neg divisor, divisor @ Loops below use unsigned.
1077 neg dividend, dividend
1079 cmp dividend, divisor
1080 blo LSYM(Lgot_result)
1082 THUMB_DIV_MOD_BODY 0
1093 #else /* ARM/Thumb-2 version. */
1095 ARM_FUNC_START divsi3
1096 ARM_FUNC_ALIAS aeabi_idiv divsi3
1100 LSYM(divsi3_skip_div0_test):
1101 eor ip, r0, r1 @ save the sign of the result.
1103 rsbmi r1, r1, #0 @ loops below use unsigned.
1104 subs r2, r1, #1 @ division by 1 or -1 ?
1108 rsbmi r3, r0, #0 @ positive dividend value
1111 tst r1, r2 @ divisor is power of 2 ?
1114 ARM_DIV_BODY r3, r1, r0, r2
1121 10: teq ip, r0 @ same sign ?
1129 moveq r0, ip, asr #31
1133 12: ARM_DIV2_ORDER r1, r2
1141 #endif /* ARM version */
1143 DIV_FUNC_END divsi3 signed
1145 #if defined(__prefer_thumb__)
1146 FUNC_START aeabi_idivmod
1150 bl LSYM(divsi3_skip_div0_test)
1156 ARM_FUNC_START aeabi_idivmod
1159 stmfd sp!, { r0, r1, lr }
1160 bl LSYM(divsi3_skip_div0_test)
1161 ldmfd sp!, { r1, r2, lr }
1166 FUNC_END aeabi_idivmod
1168 #endif /* L_divsi3 */
1169 /* ------------------------------------------------------------------------ */
1180 neg divisor, divisor @ Loops below use unsigned.
1183 @ Need to save the sign of the dividend, unfortunately, we need
1184 @ work later on. Must do this after saving the original value of
1185 @ the work register, because we will pop this value off first.
1189 neg dividend, dividend
1191 cmp dividend, divisor
1192 blo LSYM(Lgot_result)
1194 THUMB_DIV_MOD_BODY 1
1199 neg dividend, dividend
1204 #else /* ARM version. */
1208 rsbmi r1, r1, #0 @ loops below use unsigned.
1209 movs ip, r0 @ preserve sign of dividend
1210 rsbmi r0, r0, #0 @ if negative make positive
1211 subs r2, r1, #1 @ compare divisor with 1
1212 cmpne r0, r1 @ compare dividend with divisor
1214 tsthi r1, r2 @ see if divisor is power of 2
1218 ARM_MOD_BODY r0, r1, r2, r3
1224 #endif /* ARM version */
1226 DIV_FUNC_END modsi3 signed
1228 #endif /* L_modsi3 */
1229 /* ------------------------------------------------------------------------ */
1235 FUNC_START aeabi_idiv0
1236 FUNC_START aeabi_ldiv0
1238 FUNC_END aeabi_ldiv0
1239 FUNC_END aeabi_idiv0
1246 #endif /* L_divmodsi_tools */
1247 /* ------------------------------------------------------------------------ */
1249 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1251 /* Constant taken from <asm/signal.h>. */
1257 ARM_FUNC_START aeabi_idiv0
1258 ARM_FUNC_START aeabi_ldiv0
1265 bl SYM(raise) __PLT__
1269 FUNC_END aeabi_ldiv0
1270 FUNC_END aeabi_idiv0
1275 #endif /* L_dvmd_lnx */
1276 #ifdef L_clear_cache
1277 #if defined __ARM_EABI__ && defined __linux__
1278 @ EABI GNU/Linux call to cacheflush syscall.
1279 ARM_FUNC_START clear_cache
1281 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1292 FUNC_END clear_cache
1294 #error "This is only for ARM EABI GNU/Linux"
1296 #endif /* L_clear_cache */
1297 /* ------------------------------------------------------------------------ */
1298 /* Dword shift operations. */
1299 /* All the following Dword shift variants rely on the fact that
1302 shft xxx, (Reg & 255)
1303 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1304 case of logical shifts) or the sign (for asr). */
1314 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1320 FUNC_ALIAS aeabi_llsr lshrdi3
1338 movmi al, al, lsr r2
1339 movpl al, ah, lsr r3
1340 orrmi al, al, ah, lsl ip
1352 FUNC_ALIAS aeabi_lasr ashrdi3
1359 @ If r2 is negative at this point the following step would OR
1360 @ the sign bit into all of AL. That's not what we want...
1374 movmi al, al, lsr r2
1375 movpl al, ah, asr r3
1376 orrmi al, al, ah, lsl ip
1389 FUNC_ALIAS aeabi_llsl ashldi3
1407 movmi ah, ah, lsl r2
1408 movpl ah, al, lsl r3
1409 orrmi ah, ah, al, lsr ip
1418 #endif /* __symbian__ */
1420 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1421 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1422 || defined(__ARM_ARCH_5TEJ__)
1423 #define HAVE_ARM_CLZ 1
1427 #if defined(__ARM_ARCH_6M__)
1432 cmp r0, r3 /* 0x10000 */
1437 cmp r0, r3 /* #0x100 */
1442 cmp r0, r3 /* #0x10 */
1452 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1455 ARM_FUNC_START clzsi2
1456 # if defined(HAVE_ARM_CLZ)
1463 movcs r0, r0, lsr #16
1467 movcs r0, r0, lsr #8
1471 movcs r0, r0, lsr #4
1479 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1480 # endif /* !HAVE_ARM_CLZ */
1483 #endif /* L_clzsi2 */
1486 #if !defined(HAVE_ARM_CLZ)
1488 # if defined(__ARM_ARCH_6M__)
1492 ARM_FUNC_START clzdi2
1513 # if defined(__ARM_ARCH_6M__)
1520 #else /* HAVE_ARM_CLZ */
1522 ARM_FUNC_START clzdi2
1532 #endif /* L_clzdi2 */
1534 /* ------------------------------------------------------------------------ */
1535 /* These next two sections are here despite the fact that they contain Thumb
1536 assembler because their presence allows interworked code to be linked even
1537 when the GCC library is this one. */
1539 /* Do not build the interworking functions when the target architecture does
1540 not support Thumb instructions. (This can be a multilib option). */
1541 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1542 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1543 || __ARM_ARCH__ >= 6
1545 #if defined L_call_via_rX
1547 /* These labels & instructions are used by the Arm/Thumb interworking code.
1548 The address of function to be called is loaded into a register and then
1549 one of these labels is called via a BL instruction. This puts the
1550 return address into the link register with the bottom bit set, and the
1551 code here switches to the correct mode before executing the function. */
1557 .macro call_via register
1558 THUMB_FUNC_START _call_via_\register
1563 SIZE (_call_via_\register)
1582 #endif /* L_call_via_rX */
1584 /* Don't bother with the old interworking routines for Thumb-2. */
1585 /* ??? Maybe only omit these on "m" variants. */
1586 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1588 #if defined L_interwork_call_via_rX
1590 /* These labels & instructions are used by the Arm/Thumb interworking code,
1591 when the target address is in an unknown instruction set. The address
1592 of function to be called is loaded into a register and then one of these
1593 labels is called via a BL instruction. This puts the return address
1594 into the link register with the bottom bit set, and the code here
1595 switches to the correct mode before executing the function. Unfortunately
1596 the target code cannot be relied upon to return via a BX instruction, so
1597 instead we have to store the resturn address on the stack and allow the
1598 called function to return here instead. Upon return we recover the real
1599 return address and use a BX to get back to Thumb mode.
1601 There are three variations of this code. The first,
1602 _interwork_call_via_rN(), will push the return address onto the
1603 stack and pop it in _arm_return(). It should only be used if all
1604 arguments are passed in registers.
1606 The second, _interwork_r7_call_via_rN(), instead stores the return
1607 address at [r7, #-4]. It is the caller's responsibility to ensure
1608 that this address is valid and contains no useful data.
1610 The third, _interwork_r11_call_via_rN(), works in the same way but
1611 uses r11 instead of r7. It is useful if the caller does not really
1612 need a frame pointer. */
1619 LSYM(Lstart_arm_return):
1620 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1621 cfi_push 0, 0xe, -0x8, 0x8
1622 nop @ This nop is for the benefit of debuggers, so that
1623 @ backtraces will use the correct unwind information.
1625 RETLDM unwind=LSYM(Lstart_arm_return)
1626 cfi_end LSYM(Lend_arm_return)
1628 .globl _arm_return_r7
1633 .globl _arm_return_r11
1638 .macro interwork_with_frame frame, register, name, return
1641 THUMB_FUNC_START \name
1648 streq lr, [\frame, #-4]
1649 adreq lr, _arm_return_\frame
1655 .macro interwork register
1658 THUMB_FUNC_START _interwork_call_via_\register
1664 .globl LSYM(Lchange_\register)
1665 LSYM(Lchange_\register):
1667 streq lr, [sp, #-8]!
1668 adreq lr, _arm_return
1671 SIZE (_interwork_call_via_\register)
1673 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1674 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1692 /* The LR case has to be handled a little differently... */
1695 THUMB_FUNC_START _interwork_call_via_lr
1704 stmeqdb r13!, {lr, pc}
1706 adreq lr, _arm_return
1709 SIZE (_interwork_call_via_lr)
1711 #endif /* L_interwork_call_via_rX */
1712 #endif /* !__thumb2__ */
1714 /* Functions to support compact pic switch tables in thumb1 state.
1715 All these routines take an index into the table in r0. The
1716 table is at LR & ~1 (but this must be rounded up in the case
1717 of 32-bit entires). They are only permitted to clobber r12
1718 and r14 and r0 must be preserved on exit. */
1719 #ifdef L_thumb1_case_sqi
1725 THUMB_FUNC_START __gnu_thumb1_case_sqi
1735 SIZE (__gnu_thumb1_case_sqi)
1738 #ifdef L_thumb1_case_uqi
1744 THUMB_FUNC_START __gnu_thumb1_case_uqi
1754 SIZE (__gnu_thumb1_case_uqi)
1757 #ifdef L_thumb1_case_shi
1763 THUMB_FUNC_START __gnu_thumb1_case_shi
1774 SIZE (__gnu_thumb1_case_shi)
1777 #ifdef L_thumb1_case_uhi
1783 THUMB_FUNC_START __gnu_thumb1_case_uhi
1794 SIZE (__gnu_thumb1_case_uhi)
1797 #ifdef L_thumb1_case_si
1803 THUMB_FUNC_START __gnu_thumb1_case_si
1806 adds.n r1, r1, #2 /* Align to word. */
1814 mov pc, lr /* We know we were called from thumb code. */
1815 SIZE (__gnu_thumb1_case_si)
1818 #endif /* Arch supports thumb. */
1821 #ifndef __ARM_ARCH_6M__
1822 #include "ieee754-df.S"
1823 #include "ieee754-sf.S"
1825 #else /* __ARM_ARCH_6M__ */
1826 #include "bpabi-v6m.S"
1827 #endif /* __ARM_ARCH_6M__ */
1828 #endif /* !__symbian__ */