comparison gcc/config/arm/lib1funcs.asm @ 0:a06113de4d67

first commit
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2009 14:47:48 +0900
parents
children 77e2b8dfacca
comparison
equal deleted inserted replaced
-1:000000000000 0:a06113de4d67
1 @ libgcc routines for ARM cpu.
2 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
3
4 /* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008,
5 2009 Free Software Foundation, Inc.
6
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
10 later version.
11
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.
16
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.
20
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/>. */
25
26 /* An executable stack is *not* required for these functions. */
27 #if defined(__ELF__) && defined(__linux__)
28 .section .note.GNU-stack,"",%progbits
29 .previous
30 #endif
31
32 /* ------------------------------------------------------------------------ */
33
34 /* We need to know what prefix to add to function names. */
35
36 #ifndef __USER_LABEL_PREFIX__
37 #error __USER_LABEL_PREFIX__ not defined
38 #endif
39
40 /* ANSI concatenation macros. */
41
42 #define CONCAT1(a, b) CONCAT2(a, b)
43 #define CONCAT2(a, b) a ## b
44
45 /* Use the right prefix for global labels. */
46
47 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
48
49 #ifdef __ELF__
50 #ifdef __thumb__
51 #define __PLT__ /* Not supported in Thumb assembler (for now). */
52 #elif defined __vxworks && !defined __PIC__
53 #define __PLT__ /* Not supported by the kernel loader. */
54 #else
55 #define __PLT__ (PLT)
56 #endif
57 #define TYPE(x) .type SYM(x),function
58 #define SIZE(x) .size SYM(x), . - SYM(x)
59 #define LSYM(x) .x
60 #else
61 #define __PLT__
62 #define TYPE(x)
63 #define SIZE(x)
64 #define LSYM(x) x
65 #endif
66
67 /* Function end macros. Variants for interworking. */
68
69 #if defined(__ARM_ARCH_2__)
70 # define __ARM_ARCH__ 2
71 #endif
72
73 #if defined(__ARM_ARCH_3__)
74 # define __ARM_ARCH__ 3
75 #endif
76
77 #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
78 || defined(__ARM_ARCH_4T__)
79 /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
80 long multiply instructions. That includes v3M. */
81 # define __ARM_ARCH__ 4
82 #endif
83
84 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
85 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
86 || defined(__ARM_ARCH_5TEJ__)
87 # define __ARM_ARCH__ 5
88 #endif
89
90 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
91 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
92 || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
93 || defined(__ARM_ARCH_6M__)
94 # define __ARM_ARCH__ 6
95 #endif
96
97 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
98 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
99 # define __ARM_ARCH__ 7
100 #endif
101
102 #ifndef __ARM_ARCH__
103 #error Unable to determine architecture.
104 #endif
105
106 /* How to return from a function call depends on the architecture variant. */
107
108 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
109
110 # define RET bx lr
111 # define RETc(x) bx##x lr
112
113 /* Special precautions for interworking on armv4t. */
114 # if (__ARM_ARCH__ == 4)
115
116 /* Always use bx, not ldr pc. */
117 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
118 # define __INTERWORKING__
119 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
120
121 /* Include thumb stub before arm mode code. */
122 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
123 # define __INTERWORKING_STUBS__
124 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
125
126 #endif /* __ARM_ARCH == 4 */
127
128 #else
129
130 # define RET mov pc, lr
131 # define RETc(x) mov##x pc, lr
132
133 #endif
134
135 .macro cfi_pop advance, reg, cfa_offset
136 #ifdef __ELF__
137 .pushsection .debug_frame
138 .byte 0x4 /* DW_CFA_advance_loc4 */
139 .4byte \advance
140 .byte (0xc0 | \reg) /* DW_CFA_restore */
141 .byte 0xe /* DW_CFA_def_cfa_offset */
142 .uleb128 \cfa_offset
143 .popsection
144 #endif
145 .endm
146 .macro cfi_push advance, reg, offset, cfa_offset
147 #ifdef __ELF__
148 .pushsection .debug_frame
149 .byte 0x4 /* DW_CFA_advance_loc4 */
150 .4byte \advance
151 .byte (0x80 | \reg) /* DW_CFA_offset */
152 .uleb128 (\offset / -4)
153 .byte 0xe /* DW_CFA_def_cfa_offset */
154 .uleb128 \cfa_offset
155 .popsection
156 #endif
157 .endm
158 .macro cfi_start start_label, end_label
159 #ifdef __ELF__
160 .pushsection .debug_frame
161 LSYM(Lstart_frame):
162 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
163 LSYM(Lstart_cie):
164 .4byte 0xffffffff @ CIE Identifier Tag
165 .byte 0x1 @ CIE Version
166 .ascii "\0" @ CIE Augmentation
167 .uleb128 0x1 @ CIE Code Alignment Factor
168 .sleb128 -4 @ CIE Data Alignment Factor
169 .byte 0xe @ CIE RA Column
170 .byte 0xc @ DW_CFA_def_cfa
171 .uleb128 0xd
172 .uleb128 0x0
173
174 .align 2
175 LSYM(Lend_cie):
176 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
177 LSYM(Lstart_fde):
178 .4byte LSYM(Lstart_frame) @ FDE CIE offset
179 .4byte \start_label @ FDE initial location
180 .4byte \end_label-\start_label @ FDE address range
181 .popsection
182 #endif
183 .endm
184 .macro cfi_end end_label
185 #ifdef __ELF__
186 .pushsection .debug_frame
187 .align 2
188 LSYM(Lend_fde):
189 .popsection
190 \end_label:
191 #endif
192 .endm
193
194 /* Don't pass dirn, it's there just to get token pasting right. */
195
196 .macro RETLDM regs=, cond=, unwind=, dirn=ia
197 #if defined (__INTERWORKING__)
198 .ifc "\regs",""
199 ldr\cond lr, [sp], #8
200 .else
201 # if defined(__thumb2__)
202 pop\cond {\regs, lr}
203 # else
204 ldm\cond\dirn sp!, {\regs, lr}
205 # endif
206 .endif
207 .ifnc "\unwind", ""
208 /* Mark LR as restored. */
209 97: cfi_pop 97b - \unwind, 0xe, 0x0
210 .endif
211 bx\cond lr
212 #else
213 /* Caller is responsible for providing IT instruction. */
214 .ifc "\regs",""
215 ldr\cond pc, [sp], #8
216 .else
217 # if defined(__thumb2__)
218 pop\cond {\regs, pc}
219 # else
220 ldm\cond\dirn sp!, {\regs, pc}
221 # endif
222 .endif
223 #endif
224 .endm
225
226 /* The Unified assembly syntax allows the same code to be assembled for both
227 ARM and Thumb-2. However this is only supported by recent gas, so define
228 a set of macros to allow ARM code on older assemblers. */
229 #if defined(__thumb2__)
230 .macro do_it cond, suffix=""
231 it\suffix \cond
232 .endm
233 .macro shift1 op, arg0, arg1, arg2
234 \op \arg0, \arg1, \arg2
235 .endm
236 #define do_push push
237 #define do_pop pop
238 #define COND(op1, op2, cond) op1 ## op2 ## cond
239 /* Perform an arithmetic operation with a variable shift operand. This
240 requires two instructions and a scratch register on Thumb-2. */
241 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
242 \shiftop \tmp, \src2, \shiftreg
243 \name \dest, \src1, \tmp
244 .endm
245 #else
246 .macro do_it cond, suffix=""
247 .endm
248 .macro shift1 op, arg0, arg1, arg2
249 mov \arg0, \arg1, \op \arg2
250 .endm
251 #define do_push stmfd sp!,
252 #define do_pop ldmfd sp!,
253 #define COND(op1, op2, cond) op1 ## cond ## op2
254 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
255 \name \dest, \src1, \src2, \shiftop \shiftreg
256 .endm
257 #endif
258
259 .macro ARM_LDIV0 name
260 str lr, [sp, #-8]!
261 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
262 bl SYM (__div0) __PLT__
263 mov r0, #0 @ About as wrong as it could be.
264 RETLDM unwind=98b
265 .endm
266
267
268 .macro THUMB_LDIV0 name
269 push { r1, lr }
270 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
271 bl SYM (__div0)
272 mov r0, #0 @ About as wrong as it could be.
273 #if defined (__INTERWORKING__)
274 pop { r1, r2 }
275 bx r2
276 #else
277 pop { r1, pc }
278 #endif
279 .endm
280
281 .macro FUNC_END name
282 SIZE (__\name)
283 .endm
284
285 .macro DIV_FUNC_END name
286 cfi_start __\name, LSYM(Lend_div0)
287 LSYM(Ldiv0):
288 #ifdef __thumb__
289 THUMB_LDIV0 \name
290 #else
291 ARM_LDIV0 \name
292 #endif
293 cfi_end LSYM(Lend_div0)
294 FUNC_END \name
295 .endm
296
297 .macro THUMB_FUNC_START name
298 .globl SYM (\name)
299 TYPE (\name)
300 .thumb_func
301 SYM (\name):
302 .endm
303
304 /* Function start macros. Variants for ARM and Thumb. */
305
306 #ifdef __thumb__
307 #define THUMB_FUNC .thumb_func
308 #define THUMB_CODE .force_thumb
309 # if defined(__thumb2__)
310 #define THUMB_SYNTAX .syntax divided
311 # else
312 #define THUMB_SYNTAX
313 # endif
314 #else
315 #define THUMB_FUNC
316 #define THUMB_CODE
317 #define THUMB_SYNTAX
318 #endif
319
320 .macro FUNC_START name
321 .text
322 .globl SYM (__\name)
323 TYPE (__\name)
324 .align 0
325 THUMB_CODE
326 THUMB_FUNC
327 THUMB_SYNTAX
328 SYM (__\name):
329 .endm
330
331 /* Special function that will always be coded in ARM assembly, even if
332 in Thumb-only compilation. */
333
334 #if defined(__thumb2__)
335
336 /* For Thumb-2 we build everything in thumb mode. */
337 .macro ARM_FUNC_START name
338 FUNC_START \name
339 .syntax unified
340 .endm
341 #define EQUIV .thumb_set
342 .macro ARM_CALL name
343 bl __\name
344 .endm
345
346 #elif defined(__INTERWORKING_STUBS__)
347
348 .macro ARM_FUNC_START name
349 FUNC_START \name
350 bx pc
351 nop
352 .arm
353 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
354 directly from other local arm routines. */
355 _L__\name:
356 .endm
357 #define EQUIV .thumb_set
358 /* Branch directly to a function declared with ARM_FUNC_START.
359 Must be called in arm mode. */
360 .macro ARM_CALL name
361 bl _L__\name
362 .endm
363
364 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
365
366 #ifdef __ARM_ARCH_6M__
367 #define EQUIV .thumb_set
368 #else
369 .macro ARM_FUNC_START name
370 .text
371 .globl SYM (__\name)
372 TYPE (__\name)
373 .align 0
374 .arm
375 SYM (__\name):
376 .endm
377 #define EQUIV .set
378 .macro ARM_CALL name
379 bl __\name
380 .endm
381 #endif
382
383 #endif
384
385 .macro FUNC_ALIAS new old
386 .globl SYM (__\new)
387 #if defined (__thumb__)
388 .thumb_set SYM (__\new), SYM (__\old)
389 #else
390 .set SYM (__\new), SYM (__\old)
391 #endif
392 .endm
393
394 #ifndef __ARM_ARCH_6M__
395 .macro ARM_FUNC_ALIAS new old
396 .globl SYM (__\new)
397 EQUIV SYM (__\new), SYM (__\old)
398 #if defined(__INTERWORKING_STUBS__)
399 .set SYM (_L__\new), SYM (_L__\old)
400 #endif
401 .endm
402 #endif
403
404 #ifdef __ARMEB__
405 #define xxh r0
406 #define xxl r1
407 #define yyh r2
408 #define yyl r3
409 #else
410 #define xxh r1
411 #define xxl r0
412 #define yyh r3
413 #define yyl r2
414 #endif
415
416 #ifdef __thumb__
417 /* Register aliases. */
418
419 work .req r4 @ XXXX is this safe ?
420 dividend .req r0
421 divisor .req r1
422 overdone .req r2
423 result .req r2
424 curbit .req r3
425 #endif
426 #if 0
427 ip .req r12
428 sp .req r13
429 lr .req r14
430 pc .req r15
431 #endif
432
433 /* ------------------------------------------------------------------------ */
434 /* Bodies of the division and modulo routines. */
435 /* ------------------------------------------------------------------------ */
436 .macro ARM_DIV_BODY dividend, divisor, result, curbit
437
438 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
439
440 clz \curbit, \dividend
441 clz \result, \divisor
442 sub \curbit, \result, \curbit
443 rsbs \curbit, \curbit, #31
444 addne \curbit, \curbit, \curbit, lsl #1
445 mov \result, #0
446 addne pc, pc, \curbit, lsl #2
447 nop
448 .set shift, 32
449 .rept 32
450 .set shift, shift - 1
451 cmp \dividend, \divisor, lsl #shift
452 adc \result, \result, \result
453 subcs \dividend, \dividend, \divisor, lsl #shift
454 .endr
455
456 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
457 #if __ARM_ARCH__ >= 5
458
459 clz \curbit, \divisor
460 clz \result, \dividend
461 sub \result, \curbit, \result
462 mov \curbit, #1
463 mov \divisor, \divisor, lsl \result
464 mov \curbit, \curbit, lsl \result
465 mov \result, #0
466
467 #else /* __ARM_ARCH__ < 5 */
468
469 @ Initially shift the divisor left 3 bits if possible,
470 @ set curbit accordingly. This allows for curbit to be located
471 @ at the left end of each 4-bit nibbles in the division loop
472 @ to save one loop in most cases.
473 tst \divisor, #0xe0000000
474 moveq \divisor, \divisor, lsl #3
475 moveq \curbit, #8
476 movne \curbit, #1
477
478 @ Unless the divisor is very big, shift it up in multiples of
479 @ four bits, since this is the amount of unwinding in the main
480 @ division loop. Continue shifting until the divisor is
481 @ larger than the dividend.
482 1: cmp \divisor, #0x10000000
483 cmplo \divisor, \dividend
484 movlo \divisor, \divisor, lsl #4
485 movlo \curbit, \curbit, lsl #4
486 blo 1b
487
488 @ For very big divisors, we must shift it a bit at a time, or
489 @ we will be in danger of overflowing.
490 1: cmp \divisor, #0x80000000
491 cmplo \divisor, \dividend
492 movlo \divisor, \divisor, lsl #1
493 movlo \curbit, \curbit, lsl #1
494 blo 1b
495
496 mov \result, #0
497
498 #endif /* __ARM_ARCH__ < 5 */
499
500 @ Division loop
501 1: cmp \dividend, \divisor
502 subhs \dividend, \dividend, \divisor
503 orrhs \result, \result, \curbit
504 cmp \dividend, \divisor, lsr #1
505 subhs \dividend, \dividend, \divisor, lsr #1
506 orrhs \result, \result, \curbit, lsr #1
507 cmp \dividend, \divisor, lsr #2
508 subhs \dividend, \dividend, \divisor, lsr #2
509 orrhs \result, \result, \curbit, lsr #2
510 cmp \dividend, \divisor, lsr #3
511 subhs \dividend, \dividend, \divisor, lsr #3
512 orrhs \result, \result, \curbit, lsr #3
513 cmp \dividend, #0 @ Early termination?
514 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
515 movne \divisor, \divisor, lsr #4
516 bne 1b
517
518 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
519
520 .endm
521 /* ------------------------------------------------------------------------ */
522 .macro ARM_DIV2_ORDER divisor, order
523
524 #if __ARM_ARCH__ >= 5
525
526 clz \order, \divisor
527 rsb \order, \order, #31
528
529 #else
530
531 cmp \divisor, #(1 << 16)
532 movhs \divisor, \divisor, lsr #16
533 movhs \order, #16
534 movlo \order, #0
535
536 cmp \divisor, #(1 << 8)
537 movhs \divisor, \divisor, lsr #8
538 addhs \order, \order, #8
539
540 cmp \divisor, #(1 << 4)
541 movhs \divisor, \divisor, lsr #4
542 addhs \order, \order, #4
543
544 cmp \divisor, #(1 << 2)
545 addhi \order, \order, #3
546 addls \order, \order, \divisor, lsr #1
547
548 #endif
549
550 .endm
551 /* ------------------------------------------------------------------------ */
552 .macro ARM_MOD_BODY dividend, divisor, order, spare
553
554 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
555
556 clz \order, \divisor
557 clz \spare, \dividend
558 sub \order, \order, \spare
559 rsbs \order, \order, #31
560 addne pc, pc, \order, lsl #3
561 nop
562 .set shift, 32
563 .rept 32
564 .set shift, shift - 1
565 cmp \dividend, \divisor, lsl #shift
566 subcs \dividend, \dividend, \divisor, lsl #shift
567 .endr
568
569 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
570 #if __ARM_ARCH__ >= 5
571
572 clz \order, \divisor
573 clz \spare, \dividend
574 sub \order, \order, \spare
575 mov \divisor, \divisor, lsl \order
576
577 #else /* __ARM_ARCH__ < 5 */
578
579 mov \order, #0
580
581 @ Unless the divisor is very big, shift it up in multiples of
582 @ four bits, since this is the amount of unwinding in the main
583 @ division loop. Continue shifting until the divisor is
584 @ larger than the dividend.
585 1: cmp \divisor, #0x10000000
586 cmplo \divisor, \dividend
587 movlo \divisor, \divisor, lsl #4
588 addlo \order, \order, #4
589 blo 1b
590
591 @ For very big divisors, we must shift it a bit at a time, or
592 @ we will be in danger of overflowing.
593 1: cmp \divisor, #0x80000000
594 cmplo \divisor, \dividend
595 movlo \divisor, \divisor, lsl #1
596 addlo \order, \order, #1
597 blo 1b
598
599 #endif /* __ARM_ARCH__ < 5 */
600
601 @ Perform all needed substractions to keep only the reminder.
602 @ Do comparisons in batch of 4 first.
603 subs \order, \order, #3 @ yes, 3 is intended here
604 blt 2f
605
606 1: cmp \dividend, \divisor
607 subhs \dividend, \dividend, \divisor
608 cmp \dividend, \divisor, lsr #1
609 subhs \dividend, \dividend, \divisor, lsr #1
610 cmp \dividend, \divisor, lsr #2
611 subhs \dividend, \dividend, \divisor, lsr #2
612 cmp \dividend, \divisor, lsr #3
613 subhs \dividend, \dividend, \divisor, lsr #3
614 cmp \dividend, #1
615 mov \divisor, \divisor, lsr #4
616 subges \order, \order, #4
617 bge 1b
618
619 tst \order, #3
620 teqne \dividend, #0
621 beq 5f
622
623 @ Either 1, 2 or 3 comparison/substractions are left.
624 2: cmn \order, #2
625 blt 4f
626 beq 3f
627 cmp \dividend, \divisor
628 subhs \dividend, \dividend, \divisor
629 mov \divisor, \divisor, lsr #1
630 3: cmp \dividend, \divisor
631 subhs \dividend, \dividend, \divisor
632 mov \divisor, \divisor, lsr #1
633 4: cmp \dividend, \divisor
634 subhs \dividend, \dividend, \divisor
635 5:
636
637 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
638
639 .endm
640 /* ------------------------------------------------------------------------ */
641 .macro THUMB_DIV_MOD_BODY modulo
642 @ Load the constant 0x10000000 into our work register.
643 mov work, #1
644 lsl work, #28
645 LSYM(Loop1):
646 @ Unless the divisor is very big, shift it up in multiples of
647 @ four bits, since this is the amount of unwinding in the main
648 @ division loop. Continue shifting until the divisor is
649 @ larger than the dividend.
650 cmp divisor, work
651 bhs LSYM(Lbignum)
652 cmp divisor, dividend
653 bhs LSYM(Lbignum)
654 lsl divisor, #4
655 lsl curbit, #4
656 b LSYM(Loop1)
657 LSYM(Lbignum):
658 @ Set work to 0x80000000
659 lsl work, #3
660 LSYM(Loop2):
661 @ For very big divisors, we must shift it a bit at a time, or
662 @ we will be in danger of overflowing.
663 cmp divisor, work
664 bhs LSYM(Loop3)
665 cmp divisor, dividend
666 bhs LSYM(Loop3)
667 lsl divisor, #1
668 lsl curbit, #1
669 b LSYM(Loop2)
670 LSYM(Loop3):
671 @ Test for possible subtractions ...
672 .if \modulo
673 @ ... On the final pass, this may subtract too much from the dividend,
674 @ so keep track of which subtractions are done, we can fix them up
675 @ afterwards.
676 mov overdone, #0
677 cmp dividend, divisor
678 blo LSYM(Lover1)
679 sub dividend, dividend, divisor
680 LSYM(Lover1):
681 lsr work, divisor, #1
682 cmp dividend, work
683 blo LSYM(Lover2)
684 sub dividend, dividend, work
685 mov ip, curbit
686 mov work, #1
687 ror curbit, work
688 orr overdone, curbit
689 mov curbit, ip
690 LSYM(Lover2):
691 lsr work, divisor, #2
692 cmp dividend, work
693 blo LSYM(Lover3)
694 sub dividend, dividend, work
695 mov ip, curbit
696 mov work, #2
697 ror curbit, work
698 orr overdone, curbit
699 mov curbit, ip
700 LSYM(Lover3):
701 lsr work, divisor, #3
702 cmp dividend, work
703 blo LSYM(Lover4)
704 sub dividend, dividend, work
705 mov ip, curbit
706 mov work, #3
707 ror curbit, work
708 orr overdone, curbit
709 mov curbit, ip
710 LSYM(Lover4):
711 mov ip, curbit
712 .else
713 @ ... and note which bits are done in the result. On the final pass,
714 @ this may subtract too much from the dividend, but the result will be ok,
715 @ since the "bit" will have been shifted out at the bottom.
716 cmp dividend, divisor
717 blo LSYM(Lover1)
718 sub dividend, dividend, divisor
719 orr result, result, curbit
720 LSYM(Lover1):
721 lsr work, divisor, #1
722 cmp dividend, work
723 blo LSYM(Lover2)
724 sub dividend, dividend, work
725 lsr work, curbit, #1
726 orr result, work
727 LSYM(Lover2):
728 lsr work, divisor, #2
729 cmp dividend, work
730 blo LSYM(Lover3)
731 sub dividend, dividend, work
732 lsr work, curbit, #2
733 orr result, work
734 LSYM(Lover3):
735 lsr work, divisor, #3
736 cmp dividend, work
737 blo LSYM(Lover4)
738 sub dividend, dividend, work
739 lsr work, curbit, #3
740 orr result, work
741 LSYM(Lover4):
742 .endif
743
744 cmp dividend, #0 @ Early termination?
745 beq LSYM(Lover5)
746 lsr curbit, #4 @ No, any more bits to do?
747 beq LSYM(Lover5)
748 lsr divisor, #4
749 b LSYM(Loop3)
750 LSYM(Lover5):
751 .if \modulo
752 @ Any subtractions that we should not have done will be recorded in
753 @ the top three bits of "overdone". Exactly which were not needed
754 @ are governed by the position of the bit, stored in ip.
755 mov work, #0xe
756 lsl work, #28
757 and overdone, work
758 beq LSYM(Lgot_result)
759
760 @ If we terminated early, because dividend became zero, then the
761 @ bit in ip will not be in the bottom nibble, and we should not
762 @ perform the additions below. We must test for this though
763 @ (rather relying upon the TSTs to prevent the additions) since
764 @ the bit in ip could be in the top two bits which might then match
765 @ with one of the smaller RORs.
766 mov curbit, ip
767 mov work, #0x7
768 tst curbit, work
769 beq LSYM(Lgot_result)
770
771 mov curbit, ip
772 mov work, #3
773 ror curbit, work
774 tst overdone, curbit
775 beq LSYM(Lover6)
776 lsr work, divisor, #3
777 add dividend, work
778 LSYM(Lover6):
779 mov curbit, ip
780 mov work, #2
781 ror curbit, work
782 tst overdone, curbit
783 beq LSYM(Lover7)
784 lsr work, divisor, #2
785 add dividend, work
786 LSYM(Lover7):
787 mov curbit, ip
788 mov work, #1
789 ror curbit, work
790 tst overdone, curbit
791 beq LSYM(Lgot_result)
792 lsr work, divisor, #1
793 add dividend, work
794 .endif
795 LSYM(Lgot_result):
796 .endm
797 /* ------------------------------------------------------------------------ */
798 /* Start of the Real Functions */
799 /* ------------------------------------------------------------------------ */
800 #ifdef L_udivsi3
801
802 FUNC_START udivsi3
803 FUNC_ALIAS aeabi_uidiv udivsi3
804
805 #ifdef __thumb__
806
807 cmp divisor, #0
808 beq LSYM(Ldiv0)
809 mov curbit, #1
810 mov result, #0
811
812 push { work }
813 cmp dividend, divisor
814 blo LSYM(Lgot_result)
815
816 THUMB_DIV_MOD_BODY 0
817
818 mov r0, result
819 pop { work }
820 RET
821
822 #else /* ARM version. */
823
824 subs r2, r1, #1
825 RETc(eq)
826 bcc LSYM(Ldiv0)
827 cmp r0, r1
828 bls 11f
829 tst r1, r2
830 beq 12f
831
832 ARM_DIV_BODY r0, r1, r2, r3
833
834 mov r0, r2
835 RET
836
837 11: moveq r0, #1
838 movne r0, #0
839 RET
840
841 12: ARM_DIV2_ORDER r1, r2
842
843 mov r0, r0, lsr r2
844 RET
845
846 #endif /* ARM version */
847
848 DIV_FUNC_END udivsi3
849
850 FUNC_START aeabi_uidivmod
851 #ifdef __thumb__
852 push {r0, r1, lr}
853 bl SYM(__udivsi3)
854 POP {r1, r2, r3}
855 mul r2, r0
856 sub r1, r1, r2
857 bx r3
858 #else
859 stmfd sp!, { r0, r1, lr }
860 bl SYM(__udivsi3)
861 ldmfd sp!, { r1, r2, lr }
862 mul r3, r2, r0
863 sub r1, r1, r3
864 RET
865 #endif
866 FUNC_END aeabi_uidivmod
867
868 #endif /* L_udivsi3 */
869 /* ------------------------------------------------------------------------ */
870 #ifdef L_umodsi3
871
872 FUNC_START umodsi3
873
874 #ifdef __thumb__
875
876 cmp divisor, #0
877 beq LSYM(Ldiv0)
878 mov curbit, #1
879 cmp dividend, divisor
880 bhs LSYM(Lover10)
881 RET
882
883 LSYM(Lover10):
884 push { work }
885
886 THUMB_DIV_MOD_BODY 1
887
888 pop { work }
889 RET
890
891 #else /* ARM version. */
892
893 subs r2, r1, #1 @ compare divisor with 1
894 bcc LSYM(Ldiv0)
895 cmpne r0, r1 @ compare dividend with divisor
896 moveq r0, #0
897 tsthi r1, r2 @ see if divisor is power of 2
898 andeq r0, r0, r2
899 RETc(ls)
900
901 ARM_MOD_BODY r0, r1, r2, r3
902
903 RET
904
905 #endif /* ARM version. */
906
907 DIV_FUNC_END umodsi3
908
909 #endif /* L_umodsi3 */
910 /* ------------------------------------------------------------------------ */
911 #ifdef L_divsi3
912
913 FUNC_START divsi3
914 FUNC_ALIAS aeabi_idiv divsi3
915
916 #ifdef __thumb__
917 cmp divisor, #0
918 beq LSYM(Ldiv0)
919
920 push { work }
921 mov work, dividend
922 eor work, divisor @ Save the sign of the result.
923 mov ip, work
924 mov curbit, #1
925 mov result, #0
926 cmp divisor, #0
927 bpl LSYM(Lover10)
928 neg divisor, divisor @ Loops below use unsigned.
929 LSYM(Lover10):
930 cmp dividend, #0
931 bpl LSYM(Lover11)
932 neg dividend, dividend
933 LSYM(Lover11):
934 cmp dividend, divisor
935 blo LSYM(Lgot_result)
936
937 THUMB_DIV_MOD_BODY 0
938
939 mov r0, result
940 mov work, ip
941 cmp work, #0
942 bpl LSYM(Lover12)
943 neg r0, r0
944 LSYM(Lover12):
945 pop { work }
946 RET
947
948 #else /* ARM version. */
949
950 cmp r1, #0
951 eor ip, r0, r1 @ save the sign of the result.
952 beq LSYM(Ldiv0)
953 rsbmi r1, r1, #0 @ loops below use unsigned.
954 subs r2, r1, #1 @ division by 1 or -1 ?
955 beq 10f
956 movs r3, r0
957 rsbmi r3, r0, #0 @ positive dividend value
958 cmp r3, r1
959 bls 11f
960 tst r1, r2 @ divisor is power of 2 ?
961 beq 12f
962
963 ARM_DIV_BODY r3, r1, r0, r2
964
965 cmp ip, #0
966 rsbmi r0, r0, #0
967 RET
968
969 10: teq ip, r0 @ same sign ?
970 rsbmi r0, r0, #0
971 RET
972
973 11: movlo r0, #0
974 moveq r0, ip, asr #31
975 orreq r0, r0, #1
976 RET
977
978 12: ARM_DIV2_ORDER r1, r2
979
980 cmp ip, #0
981 mov r0, r3, lsr r2
982 rsbmi r0, r0, #0
983 RET
984
985 #endif /* ARM version */
986
987 DIV_FUNC_END divsi3
988
989 FUNC_START aeabi_idivmod
990 #ifdef __thumb__
991 push {r0, r1, lr}
992 bl SYM(__divsi3)
993 POP {r1, r2, r3}
994 mul r2, r0
995 sub r1, r1, r2
996 bx r3
997 #else
998 stmfd sp!, { r0, r1, lr }
999 bl SYM(__divsi3)
1000 ldmfd sp!, { r1, r2, lr }
1001 mul r3, r2, r0
1002 sub r1, r1, r3
1003 RET
1004 #endif
1005 FUNC_END aeabi_idivmod
1006
1007 #endif /* L_divsi3 */
1008 /* ------------------------------------------------------------------------ */
1009 #ifdef L_modsi3
1010
1011 FUNC_START modsi3
1012
1013 #ifdef __thumb__
1014
1015 mov curbit, #1
1016 cmp divisor, #0
1017 beq LSYM(Ldiv0)
1018 bpl LSYM(Lover10)
1019 neg divisor, divisor @ Loops below use unsigned.
1020 LSYM(Lover10):
1021 push { work }
1022 @ Need to save the sign of the dividend, unfortunately, we need
1023 @ work later on. Must do this after saving the original value of
1024 @ the work register, because we will pop this value off first.
1025 push { dividend }
1026 cmp dividend, #0
1027 bpl LSYM(Lover11)
1028 neg dividend, dividend
1029 LSYM(Lover11):
1030 cmp dividend, divisor
1031 blo LSYM(Lgot_result)
1032
1033 THUMB_DIV_MOD_BODY 1
1034
1035 pop { work }
1036 cmp work, #0
1037 bpl LSYM(Lover12)
1038 neg dividend, dividend
1039 LSYM(Lover12):
1040 pop { work }
1041 RET
1042
1043 #else /* ARM version. */
1044
1045 cmp r1, #0
1046 beq LSYM(Ldiv0)
1047 rsbmi r1, r1, #0 @ loops below use unsigned.
1048 movs ip, r0 @ preserve sign of dividend
1049 rsbmi r0, r0, #0 @ if negative make positive
1050 subs r2, r1, #1 @ compare divisor with 1
1051 cmpne r0, r1 @ compare dividend with divisor
1052 moveq r0, #0
1053 tsthi r1, r2 @ see if divisor is power of 2
1054 andeq r0, r0, r2
1055 bls 10f
1056
1057 ARM_MOD_BODY r0, r1, r2, r3
1058
1059 10: cmp ip, #0
1060 rsbmi r0, r0, #0
1061 RET
1062
1063 #endif /* ARM version */
1064
1065 DIV_FUNC_END modsi3
1066
1067 #endif /* L_modsi3 */
1068 /* ------------------------------------------------------------------------ */
1069 #ifdef L_dvmd_tls
1070
1071 FUNC_START div0
1072 FUNC_ALIAS aeabi_idiv0 div0
1073 FUNC_ALIAS aeabi_ldiv0 div0
1074
1075 RET
1076
1077 FUNC_END aeabi_ldiv0
1078 FUNC_END aeabi_idiv0
1079 FUNC_END div0
1080
1081 #endif /* L_divmodsi_tools */
1082 /* ------------------------------------------------------------------------ */
1083 #ifdef L_dvmd_lnx
1084 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1085
1086 /* Constant taken from <asm/signal.h>. */
1087 #define SIGFPE 8
1088
1089 ARM_FUNC_START div0
1090
1091 do_push {r1, lr}
1092 mov r0, #SIGFPE
1093 bl SYM(raise) __PLT__
1094 RETLDM r1
1095
1096 FUNC_END div0
1097
1098 #endif /* L_dvmd_lnx */
1099 /* ------------------------------------------------------------------------ */
1100 /* Dword shift operations. */
1101 /* All the following Dword shift variants rely on the fact that
1102 shft xxx, Reg
1103 is in fact done as
1104 shft xxx, (Reg & 255)
1105 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1106 case of logical shifts) or the sign (for asr). */
1107
1108 #ifdef __ARMEB__
1109 #define al r1
1110 #define ah r0
1111 #else
1112 #define al r0
1113 #define ah r1
1114 #endif
1115
1116 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1117 #ifndef __symbian__
1118
1119 #ifdef L_lshrdi3
1120
1121 FUNC_START lshrdi3
1122 FUNC_ALIAS aeabi_llsr lshrdi3
1123
1124 #ifdef __thumb__
1125 lsr al, r2
1126 mov r3, ah
1127 lsr ah, r2
1128 mov ip, r3
1129 sub r2, #32
1130 lsr r3, r2
1131 orr al, r3
1132 neg r2, r2
1133 mov r3, ip
1134 lsl r3, r2
1135 orr al, r3
1136 RET
1137 #else
1138 subs r3, r2, #32
1139 rsb ip, r2, #32
1140 movmi al, al, lsr r2
1141 movpl al, ah, lsr r3
1142 orrmi al, al, ah, lsl ip
1143 mov ah, ah, lsr r2
1144 RET
1145 #endif
1146 FUNC_END aeabi_llsr
1147 FUNC_END lshrdi3
1148
1149 #endif
1150
1151 #ifdef L_ashrdi3
1152
1153 FUNC_START ashrdi3
1154 FUNC_ALIAS aeabi_lasr ashrdi3
1155
1156 #ifdef __thumb__
1157 lsr al, r2
1158 mov r3, ah
1159 asr ah, r2
1160 sub r2, #32
1161 @ If r2 is negative at this point the following step would OR
1162 @ the sign bit into all of AL. That's not what we want...
1163 bmi 1f
1164 mov ip, r3
1165 asr r3, r2
1166 orr al, r3
1167 mov r3, ip
1168 1:
1169 neg r2, r2
1170 lsl r3, r2
1171 orr al, r3
1172 RET
1173 #else
1174 subs r3, r2, #32
1175 rsb ip, r2, #32
1176 movmi al, al, lsr r2
1177 movpl al, ah, asr r3
1178 orrmi al, al, ah, lsl ip
1179 mov ah, ah, asr r2
1180 RET
1181 #endif
1182
1183 FUNC_END aeabi_lasr
1184 FUNC_END ashrdi3
1185
1186 #endif
1187
1188 #ifdef L_ashldi3
1189
1190 FUNC_START ashldi3
1191 FUNC_ALIAS aeabi_llsl ashldi3
1192
1193 #ifdef __thumb__
1194 lsl ah, r2
1195 mov r3, al
1196 lsl al, r2
1197 mov ip, r3
1198 sub r2, #32
1199 lsl r3, r2
1200 orr ah, r3
1201 neg r2, r2
1202 mov r3, ip
1203 lsr r3, r2
1204 orr ah, r3
1205 RET
1206 #else
1207 subs r3, r2, #32
1208 rsb ip, r2, #32
1209 movmi ah, ah, lsl r2
1210 movpl ah, al, lsl r3
1211 orrmi ah, ah, al, lsr ip
1212 mov al, al, lsl r2
1213 RET
1214 #endif
1215 FUNC_END aeabi_llsl
1216 FUNC_END ashldi3
1217
1218 #endif
1219
1220 #endif /* __symbian__ */
1221
1222 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1223 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1224 || defined(__ARM_ARCH_5TEJ__)
1225 #define HAVE_ARM_CLZ 1
1226 #endif
1227
1228 #ifdef L_clzsi2
1229 #if defined(__ARM_ARCH_6M__)
1230 FUNC_START clzsi2
1231 mov r1, #28
1232 mov r3, #1
1233 lsl r3, r3, #16
1234 cmp r0, r3 /* 0x10000 */
1235 bcc 2f
1236 lsr r0, r0, #16
1237 sub r1, r1, #16
1238 2: lsr r3, r3, #8
1239 cmp r0, r3 /* #0x100 */
1240 bcc 2f
1241 lsr r0, r0, #8
1242 sub r1, r1, #8
1243 2: lsr r3, r3, #4
1244 cmp r0, r3 /* #0x10 */
1245 bcc 2f
1246 lsr r0, r0, #4
1247 sub r1, r1, #4
1248 2: adr r2, 1f
1249 ldrb r0, [r2, r0]
1250 add r0, r0, r1
1251 bx lr
1252 .align 2
1253 1:
1254 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1255 FUNC_END clzsi2
1256 #else
1257 ARM_FUNC_START clzsi2
1258 # if defined(HAVE_ARM_CLZ)
1259 clz r0, r0
1260 RET
1261 # else
1262 mov r1, #28
1263 cmp r0, #0x10000
1264 do_it cs, t
1265 movcs r0, r0, lsr #16
1266 subcs r1, r1, #16
1267 cmp r0, #0x100
1268 do_it cs, t
1269 movcs r0, r0, lsr #8
1270 subcs r1, r1, #8
1271 cmp r0, #0x10
1272 do_it cs, t
1273 movcs r0, r0, lsr #4
1274 subcs r1, r1, #4
1275 adr r2, 1f
1276 ldrb r0, [r2, r0]
1277 add r0, r0, r1
1278 RET
1279 .align 2
1280 1:
1281 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1282 # endif /* !HAVE_ARM_CLZ */
1283 FUNC_END clzsi2
1284 #endif
1285 #endif /* L_clzsi2 */
1286
1287 #ifdef L_clzdi2
1288 #if !defined(HAVE_ARM_CLZ)
1289
1290 # if defined(__ARM_ARCH_6M__)
1291 FUNC_START clzdi2
1292 push {r4, lr}
1293 # else
1294 ARM_FUNC_START clzdi2
1295 do_push {r4, lr}
1296 # endif
1297 cmp xxh, #0
1298 bne 1f
1299 # ifdef __ARMEB__
1300 mov r0, xxl
1301 bl __clzsi2
1302 add r0, r0, #32
1303 b 2f
1304 1:
1305 bl __clzsi2
1306 # else
1307 bl __clzsi2
1308 add r0, r0, #32
1309 b 2f
1310 1:
1311 mov r0, xxh
1312 bl __clzsi2
1313 # endif
1314 2:
1315 # if defined(__ARM_ARCH_6M__)
1316 pop {r4, pc}
1317 # else
1318 RETLDM r4
1319 # endif
1320 FUNC_END clzdi2
1321
1322 #else /* HAVE_ARM_CLZ */
1323
1324 ARM_FUNC_START clzdi2
1325 cmp xxh, #0
1326 do_it eq, et
1327 clzeq r0, xxl
1328 clzne r0, xxh
1329 addeq r0, r0, #32
1330 RET
1331 FUNC_END clzdi2
1332
1333 #endif
1334 #endif /* L_clzdi2 */
1335
1336 /* ------------------------------------------------------------------------ */
1337 /* These next two sections are here despite the fact that they contain Thumb
1338 assembler because their presence allows interworked code to be linked even
1339 when the GCC library is this one. */
1340
1341 /* Do not build the interworking functions when the target architecture does
1342 not support Thumb instructions. (This can be a multilib option). */
1343 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1344 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1345 || __ARM_ARCH__ >= 6
1346
1347 #if defined L_call_via_rX
1348
1349 /* These labels & instructions are used by the Arm/Thumb interworking code.
1350 The address of function to be called is loaded into a register and then
1351 one of these labels is called via a BL instruction. This puts the
1352 return address into the link register with the bottom bit set, and the
1353 code here switches to the correct mode before executing the function. */
1354
1355 .text
1356 .align 0
1357 .force_thumb
1358
1359 .macro call_via register
1360 THUMB_FUNC_START _call_via_\register
1361
1362 bx \register
1363 nop
1364
1365 SIZE (_call_via_\register)
1366 .endm
1367
1368 call_via r0
1369 call_via r1
1370 call_via r2
1371 call_via r3
1372 call_via r4
1373 call_via r5
1374 call_via r6
1375 call_via r7
1376 call_via r8
1377 call_via r9
1378 call_via sl
1379 call_via fp
1380 call_via ip
1381 call_via sp
1382 call_via lr
1383
1384 #endif /* L_call_via_rX */
1385
1386 /* Don't bother with the old interworking routines for Thumb-2. */
1387 /* ??? Maybe only omit these on "m" variants. */
1388 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1389
1390 #if defined L_interwork_call_via_rX
1391
1392 /* These labels & instructions are used by the Arm/Thumb interworking code,
1393 when the target address is in an unknown instruction set. The address
1394 of function to be called is loaded into a register and then one of these
1395 labels is called via a BL instruction. This puts the return address
1396 into the link register with the bottom bit set, and the code here
1397 switches to the correct mode before executing the function. Unfortunately
1398 the target code cannot be relied upon to return via a BX instruction, so
1399 instead we have to store the resturn address on the stack and allow the
1400 called function to return here instead. Upon return we recover the real
1401 return address and use a BX to get back to Thumb mode.
1402
1403 There are three variations of this code. The first,
1404 _interwork_call_via_rN(), will push the return address onto the
1405 stack and pop it in _arm_return(). It should only be used if all
1406 arguments are passed in registers.
1407
1408 The second, _interwork_r7_call_via_rN(), instead stores the return
1409 address at [r7, #-4]. It is the caller's responsibility to ensure
1410 that this address is valid and contains no useful data.
1411
1412 The third, _interwork_r11_call_via_rN(), works in the same way but
1413 uses r11 instead of r7. It is useful if the caller does not really
1414 need a frame pointer. */
1415
1416 .text
1417 .align 0
1418
1419 .code 32
1420 .globl _arm_return
1421 LSYM(Lstart_arm_return):
1422 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1423 cfi_push 0, 0xe, -0x8, 0x8
1424 nop @ This nop is for the benefit of debuggers, so that
1425 @ backtraces will use the correct unwind information.
1426 _arm_return:
1427 RETLDM unwind=LSYM(Lstart_arm_return)
1428 cfi_end LSYM(Lend_arm_return)
1429
1430 .globl _arm_return_r7
1431 _arm_return_r7:
1432 ldr lr, [r7, #-4]
1433 bx lr
1434
1435 .globl _arm_return_r11
1436 _arm_return_r11:
1437 ldr lr, [r11, #-4]
1438 bx lr
1439
1440 .macro interwork_with_frame frame, register, name, return
1441 .code 16
1442
1443 THUMB_FUNC_START \name
1444
1445 bx pc
1446 nop
1447
1448 .code 32
1449 tst \register, #1
1450 streq lr, [\frame, #-4]
1451 adreq lr, _arm_return_\frame
1452 bx \register
1453
1454 SIZE (\name)
1455 .endm
1456
1457 .macro interwork register
1458 .code 16
1459
1460 THUMB_FUNC_START _interwork_call_via_\register
1461
1462 bx pc
1463 nop
1464
1465 .code 32
1466 .globl LSYM(Lchange_\register)
1467 LSYM(Lchange_\register):
1468 tst \register, #1
1469 streq lr, [sp, #-8]!
1470 adreq lr, _arm_return
1471 bx \register
1472
1473 SIZE (_interwork_call_via_\register)
1474
1475 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1476 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1477 .endm
1478
1479 interwork r0
1480 interwork r1
1481 interwork r2
1482 interwork r3
1483 interwork r4
1484 interwork r5
1485 interwork r6
1486 interwork r7
1487 interwork r8
1488 interwork r9
1489 interwork sl
1490 interwork fp
1491 interwork ip
1492 interwork sp
1493
1494 /* The LR case has to be handled a little differently... */
1495 .code 16
1496
1497 THUMB_FUNC_START _interwork_call_via_lr
1498
1499 bx pc
1500 nop
1501
1502 .code 32
1503 .globl .Lchange_lr
1504 .Lchange_lr:
1505 tst lr, #1
1506 stmeqdb r13!, {lr, pc}
1507 mov ip, lr
1508 adreq lr, _arm_return
1509 bx ip
1510
1511 SIZE (_interwork_call_via_lr)
1512
1513 #endif /* L_interwork_call_via_rX */
1514 #endif /* !__thumb2__ */
1515 #endif /* Arch supports thumb. */
1516
1517 #ifndef __symbian__
1518 #ifndef __ARM_ARCH_6M__
1519 #include "ieee754-df.S"
1520 #include "ieee754-sf.S"
1521 #include "bpabi.S"
1522 #else /* __ARM_ARCH_6M__ */
1523 #include "bpabi-v6m.S"
1524 #endif /* __ARM_ARCH_6M__ */
1525 #endif /* !__symbian__ */