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 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 2, or (at your option) any
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
21 This file is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; see the file COPYING. If not, write to
28 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA. */
31 /* An executable stack is *not* required for these functions. */
32 #if defined(__ELF__) && defined(__linux__)
33 .section .note.GNU-stack,"",%progbits
37 /* ------------------------------------------------------------------------ */
39 /* We need to know what prefix to add to function names. */
41 #ifndef __USER_LABEL_PREFIX__
42 #error __USER_LABEL_PREFIX__ not defined
45 /* ANSI concatenation macros. */
47 #define CONCAT1(a, b) CONCAT2(a, b)
48 #define CONCAT2(a, b) a ## b
50 /* Use the right prefix for global labels. */
52 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
56 #define __PLT__ /* Not supported in Thumb assembler (for now). */
57 #elif defined __vxworks && !defined __PIC__
58 #define __PLT__ /* Not supported by the kernel loader. */
62 #define TYPE(x) .type SYM(x),function
63 #define SIZE(x) .size SYM(x), . - SYM(x)
72 /* Function end macros. Variants for interworking. */
74 #if defined(__ARM_ARCH_2__)
75 # define __ARM_ARCH__ 2
78 #if defined(__ARM_ARCH_3__)
79 # define __ARM_ARCH__ 3
82 #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
83 || defined(__ARM_ARCH_4T__)
84 /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
85 long multiply instructions. That includes v3M. */
86 # define __ARM_ARCH__ 4
89 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
90 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
91 || defined(__ARM_ARCH_5TEJ__)
92 # define __ARM_ARCH__ 5
95 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
96 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
97 || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
98 || defined(__ARM_ARCH_6M__)
99 # define __ARM_ARCH__ 6
102 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
103 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
104 # define __ARM_ARCH__ 7
108 #error Unable to determine architecture.
111 /* How to return from a function call depends on the architecture variant. */
113 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
116 # define RETc(x) bx##x lr
118 /* Special precautions for interworking on armv4t. */
119 # if (__ARM_ARCH__ == 4)
121 /* Always use bx, not ldr pc. */
122 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
123 # define __INTERWORKING__
124 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
126 /* Include thumb stub before arm mode code. */
127 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
128 # define __INTERWORKING_STUBS__
129 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
131 #endif /* __ARM_ARCH == 4 */
135 # define RET mov pc, lr
136 # define RETc(x) mov##x pc, lr
140 .macro cfi_pop advance, reg, cfa_offset
142 .pushsection .debug_frame
143 .byte 0x4 /* DW_CFA_advance_loc4 */
145 .byte (0xc0 | \reg) /* DW_CFA_restore */
146 .byte 0xe /* DW_CFA_def_cfa_offset */
151 .macro cfi_push advance, reg, offset, cfa_offset
153 .pushsection .debug_frame
154 .byte 0x4 /* DW_CFA_advance_loc4 */
156 .byte (0x80 | \reg) /* DW_CFA_offset */
157 .uleb128 (\offset / -4)
158 .byte 0xe /* DW_CFA_def_cfa_offset */
163 .macro cfi_start start_label, end_label
165 .pushsection .debug_frame
167 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
169 .4byte 0xffffffff @ CIE Identifier Tag
170 .byte 0x1 @ CIE Version
171 .ascii "\0" @ CIE Augmentation
172 .uleb128 0x1 @ CIE Code Alignment Factor
173 .sleb128 -4 @ CIE Data Alignment Factor
174 .byte 0xe @ CIE RA Column
175 .byte 0xc @ DW_CFA_def_cfa
181 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
183 .4byte LSYM(Lstart_frame) @ FDE CIE offset
184 .4byte \start_label @ FDE initial location
185 .4byte \end_label-\start_label @ FDE address range
189 .macro cfi_end end_label
191 .pushsection .debug_frame
199 /* Don't pass dirn, it's there just to get token pasting right. */
201 .macro RETLDM regs=, cond=, unwind=, dirn=ia
202 #if defined (__INTERWORKING__)
204 ldr\cond lr, [sp], #8
206 # if defined(__thumb2__)
209 ldm\cond\dirn sp!, {\regs, lr}
213 /* Mark LR as restored. */
214 97: cfi_pop 97b - \unwind, 0xe, 0x0
218 /* Caller is responsible for providing IT instruction. */
220 ldr\cond pc, [sp], #8
222 # if defined(__thumb2__)
225 ldm\cond\dirn sp!, {\regs, pc}
231 /* The Unified assembly syntax allows the same code to be assembled for both
232 ARM and Thumb-2. However this is only supported by recent gas, so define
233 a set of macros to allow ARM code on older assemblers. */
234 #if defined(__thumb2__)
235 .macro do_it cond, suffix=""
238 .macro shift1 op, arg0, arg1, arg2
239 \op \arg0, \arg1, \arg2
243 #define COND(op1, op2, cond) op1 ## op2 ## cond
244 /* Perform an arithmetic operation with a variable shift operand. This
245 requires two instructions and a scratch register on Thumb-2. */
246 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
247 \shiftop \tmp, \src2, \shiftreg
248 \name \dest, \src1, \tmp
251 .macro do_it cond, suffix=""
253 .macro shift1 op, arg0, arg1, arg2
254 mov \arg0, \arg1, \op \arg2
256 #define do_push stmfd sp!,
257 #define do_pop ldmfd sp!,
258 #define COND(op1, op2, cond) op1 ## cond ## op2
259 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
260 \name \dest, \src1, \src2, \shiftop \shiftreg
264 .macro ARM_LDIV0 name
266 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
267 bl SYM (__div0) __PLT__
268 mov r0, #0 @ About as wrong as it could be.
273 .macro THUMB_LDIV0 name
275 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
277 mov r0, #0 @ About as wrong as it could be.
278 #if defined (__INTERWORKING__)
290 .macro DIV_FUNC_END name
291 cfi_start __\name, LSYM(Lend_div0)
298 cfi_end LSYM(Lend_div0)
302 .macro THUMB_FUNC_START name
309 /* Function start macros. Variants for ARM and Thumb. */
312 #define THUMB_FUNC .thumb_func
313 #define THUMB_CODE .force_thumb
314 # if defined(__thumb2__)
315 #define THUMB_SYNTAX .syntax divided
325 .macro FUNC_START name
336 /* Special function that will always be coded in ARM assembly, even if
337 in Thumb-only compilation. */
339 #if defined(__thumb2__)
341 /* For Thumb-2 we build everything in thumb mode. */
342 .macro ARM_FUNC_START name
346 #define EQUIV .thumb_set
351 #elif defined(__INTERWORKING_STUBS__)
353 .macro ARM_FUNC_START name
358 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
359 directly from other local arm routines. */
362 #define EQUIV .thumb_set
363 /* Branch directly to a function declared with ARM_FUNC_START.
364 Must be called in arm mode. */
369 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
371 #ifdef __ARM_ARCH_6M__
372 #define EQUIV .thumb_set
374 .macro ARM_FUNC_START name
390 .macro FUNC_ALIAS new old
392 #if defined (__thumb__)
393 .thumb_set SYM (__\new), SYM (__\old)
395 .set SYM (__\new), SYM (__\old)
399 #ifndef __ARM_ARCH_6M__
400 .macro ARM_FUNC_ALIAS new old
402 EQUIV SYM (__\new), SYM (__\old)
403 #if defined(__INTERWORKING_STUBS__)
404 .set SYM (_L__\new), SYM (_L__\old)
422 /* Register aliases. */
424 work .req r4 @ XXXX is this safe ?
438 /* ------------------------------------------------------------------------ */
439 /* Bodies of the division and modulo routines. */
440 /* ------------------------------------------------------------------------ */
441 .macro ARM_DIV_BODY dividend, divisor, result, curbit
443 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
445 clz \curbit, \dividend
446 clz \result, \divisor
447 sub \curbit, \result, \curbit
448 rsbs \curbit, \curbit, #31
449 addne \curbit, \curbit, \curbit, lsl #1
451 addne pc, pc, \curbit, lsl #2
455 .set shift, shift - 1
456 cmp \dividend, \divisor, lsl #shift
457 adc \result, \result, \result
458 subcs \dividend, \dividend, \divisor, lsl #shift
461 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
462 #if __ARM_ARCH__ >= 5
464 clz \curbit, \divisor
465 clz \result, \dividend
466 sub \result, \curbit, \result
468 mov \divisor, \divisor, lsl \result
469 mov \curbit, \curbit, lsl \result
472 #else /* __ARM_ARCH__ < 5 */
474 @ Initially shift the divisor left 3 bits if possible,
475 @ set curbit accordingly. This allows for curbit to be located
476 @ at the left end of each 4-bit nibbles in the division loop
477 @ to save one loop in most cases.
478 tst \divisor, #0xe0000000
479 moveq \divisor, \divisor, lsl #3
483 @ Unless the divisor is very big, shift it up in multiples of
484 @ four bits, since this is the amount of unwinding in the main
485 @ division loop. Continue shifting until the divisor is
486 @ larger than the dividend.
487 1: cmp \divisor, #0x10000000
488 cmplo \divisor, \dividend
489 movlo \divisor, \divisor, lsl #4
490 movlo \curbit, \curbit, lsl #4
493 @ For very big divisors, we must shift it a bit at a time, or
494 @ we will be in danger of overflowing.
495 1: cmp \divisor, #0x80000000
496 cmplo \divisor, \dividend
497 movlo \divisor, \divisor, lsl #1
498 movlo \curbit, \curbit, lsl #1
503 #endif /* __ARM_ARCH__ < 5 */
506 1: cmp \dividend, \divisor
507 subhs \dividend, \dividend, \divisor
508 orrhs \result, \result, \curbit
509 cmp \dividend, \divisor, lsr #1
510 subhs \dividend, \dividend, \divisor, lsr #1
511 orrhs \result, \result, \curbit, lsr #1
512 cmp \dividend, \divisor, lsr #2
513 subhs \dividend, \dividend, \divisor, lsr #2
514 orrhs \result, \result, \curbit, lsr #2
515 cmp \dividend, \divisor, lsr #3
516 subhs \dividend, \dividend, \divisor, lsr #3
517 orrhs \result, \result, \curbit, lsr #3
518 cmp \dividend, #0 @ Early termination?
519 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
520 movne \divisor, \divisor, lsr #4
523 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
526 /* ------------------------------------------------------------------------ */
527 .macro ARM_DIV2_ORDER divisor, order
529 #if __ARM_ARCH__ >= 5
532 rsb \order, \order, #31
536 cmp \divisor, #(1 << 16)
537 movhs \divisor, \divisor, lsr #16
541 cmp \divisor, #(1 << 8)
542 movhs \divisor, \divisor, lsr #8
543 addhs \order, \order, #8
545 cmp \divisor, #(1 << 4)
546 movhs \divisor, \divisor, lsr #4
547 addhs \order, \order, #4
549 cmp \divisor, #(1 << 2)
550 addhi \order, \order, #3
551 addls \order, \order, \divisor, lsr #1
556 /* ------------------------------------------------------------------------ */
557 .macro ARM_MOD_BODY dividend, divisor, order, spare
559 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
562 clz \spare, \dividend
563 sub \order, \order, \spare
564 rsbs \order, \order, #31
565 addne pc, pc, \order, lsl #3
569 .set shift, shift - 1
570 cmp \dividend, \divisor, lsl #shift
571 subcs \dividend, \dividend, \divisor, lsl #shift
574 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
575 #if __ARM_ARCH__ >= 5
578 clz \spare, \dividend
579 sub \order, \order, \spare
580 mov \divisor, \divisor, lsl \order
582 #else /* __ARM_ARCH__ < 5 */
586 @ Unless the divisor is very big, shift it up in multiples of
587 @ four bits, since this is the amount of unwinding in the main
588 @ division loop. Continue shifting until the divisor is
589 @ larger than the dividend.
590 1: cmp \divisor, #0x10000000
591 cmplo \divisor, \dividend
592 movlo \divisor, \divisor, lsl #4
593 addlo \order, \order, #4
596 @ For very big divisors, we must shift it a bit at a time, or
597 @ we will be in danger of overflowing.
598 1: cmp \divisor, #0x80000000
599 cmplo \divisor, \dividend
600 movlo \divisor, \divisor, lsl #1
601 addlo \order, \order, #1
604 #endif /* __ARM_ARCH__ < 5 */
606 @ Perform all needed substractions to keep only the reminder.
607 @ Do comparisons in batch of 4 first.
608 subs \order, \order, #3 @ yes, 3 is intended here
611 1: cmp \dividend, \divisor
612 subhs \dividend, \dividend, \divisor
613 cmp \dividend, \divisor, lsr #1
614 subhs \dividend, \dividend, \divisor, lsr #1
615 cmp \dividend, \divisor, lsr #2
616 subhs \dividend, \dividend, \divisor, lsr #2
617 cmp \dividend, \divisor, lsr #3
618 subhs \dividend, \dividend, \divisor, lsr #3
620 mov \divisor, \divisor, lsr #4
621 subges \order, \order, #4
628 @ Either 1, 2 or 3 comparison/substractions are left.
632 cmp \dividend, \divisor
633 subhs \dividend, \dividend, \divisor
634 mov \divisor, \divisor, lsr #1
635 3: cmp \dividend, \divisor
636 subhs \dividend, \dividend, \divisor
637 mov \divisor, \divisor, lsr #1
638 4: cmp \dividend, \divisor
639 subhs \dividend, \dividend, \divisor
642 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
645 /* ------------------------------------------------------------------------ */
646 .macro THUMB_DIV_MOD_BODY modulo
647 @ Load the constant 0x10000000 into our work register.
651 @ Unless the divisor is very big, shift it up in multiples of
652 @ four bits, since this is the amount of unwinding in the main
653 @ division loop. Continue shifting until the divisor is
654 @ larger than the dividend.
657 cmp divisor, dividend
663 @ Set work to 0x80000000
666 @ For very big divisors, we must shift it a bit at a time, or
667 @ we will be in danger of overflowing.
670 cmp divisor, dividend
676 @ Test for possible subtractions ...
678 @ ... On the final pass, this may subtract too much from the dividend,
679 @ so keep track of which subtractions are done, we can fix them up
682 cmp dividend, divisor
684 sub dividend, dividend, divisor
686 lsr work, divisor, #1
689 sub dividend, dividend, work
696 lsr work, divisor, #2
699 sub dividend, dividend, work
706 lsr work, divisor, #3
709 sub dividend, dividend, work
718 @ ... and note which bits are done in the result. On the final pass,
719 @ this may subtract too much from the dividend, but the result will be ok,
720 @ since the "bit" will have been shifted out at the bottom.
721 cmp dividend, divisor
723 sub dividend, dividend, divisor
724 orr result, result, curbit
726 lsr work, divisor, #1
729 sub dividend, dividend, work
733 lsr work, divisor, #2
736 sub dividend, dividend, work
740 lsr work, divisor, #3
743 sub dividend, dividend, work
749 cmp dividend, #0 @ Early termination?
751 lsr curbit, #4 @ No, any more bits to do?
757 @ Any subtractions that we should not have done will be recorded in
758 @ the top three bits of "overdone". Exactly which were not needed
759 @ are governed by the position of the bit, stored in ip.
763 beq LSYM(Lgot_result)
765 @ If we terminated early, because dividend became zero, then the
766 @ bit in ip will not be in the bottom nibble, and we should not
767 @ perform the additions below. We must test for this though
768 @ (rather relying upon the TSTs to prevent the additions) since
769 @ the bit in ip could be in the top two bits which might then match
770 @ with one of the smaller RORs.
774 beq LSYM(Lgot_result)
781 lsr work, divisor, #3
789 lsr work, divisor, #2
796 beq LSYM(Lgot_result)
797 lsr work, divisor, #1
802 /* ------------------------------------------------------------------------ */
803 /* Start of the Real Functions */
804 /* ------------------------------------------------------------------------ */
808 FUNC_ALIAS aeabi_uidiv udivsi3
818 cmp dividend, divisor
819 blo LSYM(Lgot_result)
827 #else /* ARM version. */
837 ARM_DIV_BODY r0, r1, r2, r3
846 12: ARM_DIV2_ORDER r1, r2
851 #endif /* ARM version */
855 FUNC_START aeabi_uidivmod
864 stmfd sp!, { r0, r1, lr }
866 ldmfd sp!, { r1, r2, lr }
871 FUNC_END aeabi_uidivmod
873 #endif /* L_udivsi3 */
874 /* ------------------------------------------------------------------------ */
884 cmp dividend, divisor
896 #else /* ARM version. */
898 subs r2, r1, #1 @ compare divisor with 1
900 cmpne r0, r1 @ compare dividend with divisor
902 tsthi r1, r2 @ see if divisor is power of 2
906 ARM_MOD_BODY r0, r1, r2, r3
910 #endif /* ARM version. */
914 #endif /* L_umodsi3 */
915 /* ------------------------------------------------------------------------ */
919 FUNC_ALIAS aeabi_idiv divsi3
927 eor work, divisor @ Save the sign of the result.
933 neg divisor, divisor @ Loops below use unsigned.
937 neg dividend, dividend
939 cmp dividend, divisor
940 blo LSYM(Lgot_result)
953 #else /* ARM version. */
956 eor ip, r0, r1 @ save the sign of the result.
958 rsbmi r1, r1, #0 @ loops below use unsigned.
959 subs r2, r1, #1 @ division by 1 or -1 ?
962 rsbmi r3, r0, #0 @ positive dividend value
965 tst r1, r2 @ divisor is power of 2 ?
968 ARM_DIV_BODY r3, r1, r0, r2
974 10: teq ip, r0 @ same sign ?
979 moveq r0, ip, asr #31
983 12: ARM_DIV2_ORDER r1, r2
990 #endif /* ARM version */
994 FUNC_START aeabi_idivmod
1003 stmfd sp!, { r0, r1, lr }
1005 ldmfd sp!, { r1, r2, lr }
1010 FUNC_END aeabi_idivmod
1012 #endif /* L_divsi3 */
1013 /* ------------------------------------------------------------------------ */
1024 neg divisor, divisor @ Loops below use unsigned.
1027 @ Need to save the sign of the dividend, unfortunately, we need
1028 @ work later on. Must do this after saving the original value of
1029 @ the work register, because we will pop this value off first.
1033 neg dividend, dividend
1035 cmp dividend, divisor
1036 blo LSYM(Lgot_result)
1038 THUMB_DIV_MOD_BODY 1
1043 neg dividend, dividend
1048 #else /* ARM version. */
1052 rsbmi r1, r1, #0 @ loops below use unsigned.
1053 movs ip, r0 @ preserve sign of dividend
1054 rsbmi r0, r0, #0 @ if negative make positive
1055 subs r2, r1, #1 @ compare divisor with 1
1056 cmpne r0, r1 @ compare dividend with divisor
1058 tsthi r1, r2 @ see if divisor is power of 2
1062 ARM_MOD_BODY r0, r1, r2, r3
1068 #endif /* ARM version */
1072 #endif /* L_modsi3 */
1073 /* ------------------------------------------------------------------------ */
1077 FUNC_ALIAS aeabi_idiv0 div0
1078 FUNC_ALIAS aeabi_ldiv0 div0
1082 FUNC_END aeabi_ldiv0
1083 FUNC_END aeabi_idiv0
1086 #endif /* L_divmodsi_tools */
1087 /* ------------------------------------------------------------------------ */
1089 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1091 /* Constant taken from <asm/signal.h>. */
1098 bl SYM(raise) __PLT__
1103 #endif /* L_dvmd_lnx */
1104 /* ------------------------------------------------------------------------ */
1105 /* Dword shift operations. */
1106 /* All the following Dword shift variants rely on the fact that
1109 shft xxx, (Reg & 255)
1110 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1111 case of logical shifts) or the sign (for asr). */
1121 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1127 FUNC_ALIAS aeabi_llsr lshrdi3
1145 movmi al, al, lsr r2
1146 movpl al, ah, lsr r3
1147 orrmi al, al, ah, lsl ip
1159 FUNC_ALIAS aeabi_lasr ashrdi3
1166 @ If r2 is negative at this point the following step would OR
1167 @ the sign bit into all of AL. That's not what we want...
1181 movmi al, al, lsr r2
1182 movpl al, ah, asr r3
1183 orrmi al, al, ah, lsl ip
1196 FUNC_ALIAS aeabi_llsl ashldi3
1214 movmi ah, ah, lsl r2
1215 movpl ah, al, lsl r3
1216 orrmi ah, ah, al, lsr ip
1225 #endif /* __symbian__ */
1227 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1228 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1229 || defined(__ARM_ARCH_5TEJ__)
1230 #define HAVE_ARM_CLZ 1
1234 #if defined(__ARM_ARCH_6M__)
1239 cmp r0, r3 /* 0x10000 */
1244 cmp r0, r3 /* #0x100 */
1249 cmp r0, r3 /* #0x10 */
1259 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1262 ARM_FUNC_START clzsi2
1263 # if defined(HAVE_ARM_CLZ)
1270 movcs r0, r0, lsr #16
1274 movcs r0, r0, lsr #8
1278 movcs r0, r0, lsr #4
1286 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1287 # endif /* !HAVE_ARM_CLZ */
1290 #endif /* L_clzsi2 */
1293 #if !defined(HAVE_ARM_CLZ)
1295 # if defined(__ARM_ARCH_6M__)
1299 ARM_FUNC_START clzdi2
1320 # if defined(__ARM_ARCH_6M__)
1327 #else /* HAVE_ARM_CLZ */
1329 ARM_FUNC_START clzdi2
1339 #endif /* L_clzdi2 */
1341 /* ------------------------------------------------------------------------ */
1342 /* These next two sections are here despite the fact that they contain Thumb
1343 assembler because their presence allows interworked code to be linked even
1344 when the GCC library is this one. */
1346 /* Do not build the interworking functions when the target architecture does
1347 not support Thumb instructions. (This can be a multilib option). */
1348 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1349 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1350 || __ARM_ARCH__ >= 6
1352 #if defined L_call_via_rX
1354 /* These labels & instructions are used by the Arm/Thumb interworking code.
1355 The address of function to be called is loaded into a register and then
1356 one of these labels is called via a BL instruction. This puts the
1357 return address into the link register with the bottom bit set, and the
1358 code here switches to the correct mode before executing the function. */
1364 .macro call_via register
1365 THUMB_FUNC_START _call_via_\register
1370 SIZE (_call_via_\register)
1389 #endif /* L_call_via_rX */
1391 /* Don't bother with the old interworking routines for Thumb-2. */
1392 /* ??? Maybe only omit these on "m" variants. */
1393 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1395 #if defined L_interwork_call_via_rX
1397 /* These labels & instructions are used by the Arm/Thumb interworking code,
1398 when the target address is in an unknown instruction set. The address
1399 of function to be called is loaded into a register and then one of these
1400 labels is called via a BL instruction. This puts the return address
1401 into the link register with the bottom bit set, and the code here
1402 switches to the correct mode before executing the function. Unfortunately
1403 the target code cannot be relied upon to return via a BX instruction, so
1404 instead we have to store the resturn address on the stack and allow the
1405 called function to return here instead. Upon return we recover the real
1406 return address and use a BX to get back to Thumb mode.
1408 There are three variations of this code. The first,
1409 _interwork_call_via_rN(), will push the return address onto the
1410 stack and pop it in _arm_return(). It should only be used if all
1411 arguments are passed in registers.
1413 The second, _interwork_r7_call_via_rN(), instead stores the return
1414 address at [r7, #-4]. It is the caller's responsibility to ensure
1415 that this address is valid and contains no useful data.
1417 The third, _interwork_r11_call_via_rN(), works in the same way but
1418 uses r11 instead of r7. It is useful if the caller does not really
1419 need a frame pointer. */
1426 LSYM(Lstart_arm_return):
1427 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1428 cfi_push 0, 0xe, -0x8, 0x8
1429 nop @ This nop is for the benefit of debuggers, so that
1430 @ backtraces will use the correct unwind information.
1432 RETLDM unwind=LSYM(Lstart_arm_return)
1433 cfi_end LSYM(Lend_arm_return)
1435 .globl _arm_return_r7
1440 .globl _arm_return_r11
1445 .macro interwork_with_frame frame, register, name, return
1448 THUMB_FUNC_START \name
1455 streq lr, [\frame, #-4]
1456 adreq lr, _arm_return_\frame
1462 .macro interwork register
1465 THUMB_FUNC_START _interwork_call_via_\register
1471 .globl LSYM(Lchange_\register)
1472 LSYM(Lchange_\register):
1474 streq lr, [sp, #-8]!
1475 adreq lr, _arm_return
1478 SIZE (_interwork_call_via_\register)
1480 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1481 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1499 /* The LR case has to be handled a little differently... */
1502 THUMB_FUNC_START _interwork_call_via_lr
1511 stmeqdb r13!, {lr, pc}
1513 adreq lr, _arm_return
1516 SIZE (_interwork_call_via_lr)
1518 #endif /* L_interwork_call_via_rX */
1519 #endif /* !__thumb2__ */
1520 #endif /* Arch supports thumb. */
1523 #ifndef __ARM_ARCH_6M__
1524 #include "ieee754-df.S"
1525 #include "ieee754-sf.S"
1527 #else /* __ARM_ARCH_6M__ */
1528 #include "bpabi-v6m.S"
1529 #endif /* __ARM_ARCH_6M__ */
1530 #endif /* !__symbian__ */