2011-03-21 Daniel Jacobowitz <dan@codesourcery.com>
[official-gcc.git] / gcc / config / arm / lib1funcs.asm
blob2e76c01df4b3b127f51b45d74efd49c1aaf9def9
1 @ libgcc routines for ARM cpu.
2 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
4 /* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008,
5 2009, 2010 Free Software Foundation, Inc.
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
10 later version.
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
29 .previous
30 #endif /* __ELF__ and __linux__ */
32 #ifdef __ARM_EABI__
33 /* Some attributes that are common to all routines in this file. */
34 /* Tag_ABI_align_needed: This code does not require 8-byte
35 alignment from the caller. */
36 /* .eabi_attribute 24, 0 -- default setting. */
37 /* Tag_ABI_align_preserved: This code preserves 8-byte
38 alignment in any callee. */
39 .eabi_attribute 25, 1
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
47 #endif
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)
58 #ifdef __ELF__
59 #ifdef __thumb__
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. */
63 #else
64 #define __PLT__ (PLT)
65 #endif
66 #define TYPE(x) .type SYM(x),function
67 #define SIZE(x) .size SYM(x), . - SYM(x)
68 #define LSYM(x) .x
69 #else
70 #define __PLT__
71 #define TYPE(x)
72 #define SIZE(x)
73 #define LSYM(x) x
74 #endif
76 /* Function end macros. Variants for interworking. */
78 #if defined(__ARM_ARCH_2__)
79 # define __ARM_ARCH__ 2
80 #endif
82 #if defined(__ARM_ARCH_3__)
83 # define __ARM_ARCH__ 3
84 #endif
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
91 #endif
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
97 #endif
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
104 #endif
106 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
107 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
108 || defined(__ARM_ARCH_7EM__)
109 # define __ARM_ARCH__ 7
110 #endif
112 #ifndef __ARM_ARCH__
113 #error Unable to determine architecture.
114 #endif
116 /* There are times when we might prefer Thumb1 code even if ARM code is
117 permitted, for example, the code might be smaller, or there might be
118 interworking problems with switching to ARM state if interworking is
119 disabled. */
120 #if (defined(__thumb__) \
121 && !defined(__thumb2__) \
122 && (!defined(__THUMB_INTERWORK__) \
123 || defined (__OPTIMIZE_SIZE__) \
124 || defined(__ARM_ARCH_6M__)))
125 # define __prefer_thumb__
126 #endif
128 /* How to return from a function call depends on the architecture variant. */
130 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
132 # define RET bx lr
133 # define RETc(x) bx##x lr
135 /* Special precautions for interworking on armv4t. */
136 # if (__ARM_ARCH__ == 4)
138 /* Always use bx, not ldr pc. */
139 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
140 # define __INTERWORKING__
141 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
143 /* Include thumb stub before arm mode code. */
144 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
145 # define __INTERWORKING_STUBS__
146 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
148 #endif /* __ARM_ARCH == 4 */
150 #else
152 # define RET mov pc, lr
153 # define RETc(x) mov##x pc, lr
155 #endif
157 .macro cfi_pop advance, reg, cfa_offset
158 #ifdef __ELF__
159 .pushsection .debug_frame
160 .byte 0x4 /* DW_CFA_advance_loc4 */
161 .4byte \advance
162 .byte (0xc0 | \reg) /* DW_CFA_restore */
163 .byte 0xe /* DW_CFA_def_cfa_offset */
164 .uleb128 \cfa_offset
165 .popsection
166 #endif
167 .endm
168 .macro cfi_push advance, reg, offset, cfa_offset
169 #ifdef __ELF__
170 .pushsection .debug_frame
171 .byte 0x4 /* DW_CFA_advance_loc4 */
172 .4byte \advance
173 .byte (0x80 | \reg) /* DW_CFA_offset */
174 .uleb128 (\offset / -4)
175 .byte 0xe /* DW_CFA_def_cfa_offset */
176 .uleb128 \cfa_offset
177 .popsection
178 #endif
179 .endm
180 .macro cfi_start start_label, end_label
181 #ifdef __ELF__
182 .pushsection .debug_frame
183 LSYM(Lstart_frame):
184 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
185 LSYM(Lstart_cie):
186 .4byte 0xffffffff @ CIE Identifier Tag
187 .byte 0x1 @ CIE Version
188 .ascii "\0" @ CIE Augmentation
189 .uleb128 0x1 @ CIE Code Alignment Factor
190 .sleb128 -4 @ CIE Data Alignment Factor
191 .byte 0xe @ CIE RA Column
192 .byte 0xc @ DW_CFA_def_cfa
193 .uleb128 0xd
194 .uleb128 0x0
196 .align 2
197 LSYM(Lend_cie):
198 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
199 LSYM(Lstart_fde):
200 .4byte LSYM(Lstart_frame) @ FDE CIE offset
201 .4byte \start_label @ FDE initial location
202 .4byte \end_label-\start_label @ FDE address range
203 .popsection
204 #endif
205 .endm
206 .macro cfi_end end_label
207 #ifdef __ELF__
208 .pushsection .debug_frame
209 .align 2
210 LSYM(Lend_fde):
211 .popsection
212 \end_label:
213 #endif
214 .endm
216 /* Don't pass dirn, it's there just to get token pasting right. */
218 .macro RETLDM regs=, cond=, unwind=, dirn=ia
219 #if defined (__INTERWORKING__)
220 .ifc "\regs",""
221 ldr\cond lr, [sp], #8
222 .else
223 # if defined(__thumb2__)
224 pop\cond {\regs, lr}
225 # else
226 ldm\cond\dirn sp!, {\regs, lr}
227 # endif
228 .endif
229 .ifnc "\unwind", ""
230 /* Mark LR as restored. */
231 97: cfi_pop 97b - \unwind, 0xe, 0x0
232 .endif
233 bx\cond lr
234 #else
235 /* Caller is responsible for providing IT instruction. */
236 .ifc "\regs",""
237 ldr\cond pc, [sp], #8
238 .else
239 # if defined(__thumb2__)
240 pop\cond {\regs, pc}
241 # else
242 ldm\cond\dirn sp!, {\regs, pc}
243 # endif
244 .endif
245 #endif
246 .endm
248 /* The Unified assembly syntax allows the same code to be assembled for both
249 ARM and Thumb-2. However this is only supported by recent gas, so define
250 a set of macros to allow ARM code on older assemblers. */
251 #if defined(__thumb2__)
252 .macro do_it cond, suffix=""
253 it\suffix \cond
254 .endm
255 .macro shift1 op, arg0, arg1, arg2
256 \op \arg0, \arg1, \arg2
257 .endm
258 #define do_push push
259 #define do_pop pop
260 #define COND(op1, op2, cond) op1 ## op2 ## cond
261 /* Perform an arithmetic operation with a variable shift operand. This
262 requires two instructions and a scratch register on Thumb-2. */
263 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
264 \shiftop \tmp, \src2, \shiftreg
265 \name \dest, \src1, \tmp
266 .endm
267 #else
268 .macro do_it cond, suffix=""
269 .endm
270 .macro shift1 op, arg0, arg1, arg2
271 mov \arg0, \arg1, \op \arg2
272 .endm
273 #define do_push stmfd sp!,
274 #define do_pop ldmfd sp!,
275 #define COND(op1, op2, cond) op1 ## cond ## op2
276 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
277 \name \dest, \src1, \src2, \shiftop \shiftreg
278 .endm
279 #endif
281 #ifdef __ARM_EABI__
282 .macro ARM_LDIV0 name signed
283 cmp r0, #0
284 .ifc \signed, unsigned
285 movne r0, #0xffffffff
286 .else
287 movgt r0, #0x7fffffff
288 movlt r0, #0x80000000
289 .endif
290 b SYM (__aeabi_idiv0) __PLT__
291 .endm
292 #else
293 .macro ARM_LDIV0 name signed
294 str lr, [sp, #-8]!
295 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
296 bl SYM (__div0) __PLT__
297 mov r0, #0 @ About as wrong as it could be.
298 RETLDM unwind=98b
299 .endm
300 #endif
303 #ifdef __ARM_EABI__
304 .macro THUMB_LDIV0 name signed
305 #if defined(__ARM_ARCH_6M__)
306 .ifc \signed, unsigned
307 cmp r0, #0
308 beq 1f
309 mov r0, #0
310 mvn r0, r0 @ 0xffffffff
312 .else
313 cmp r0, #0
314 beq 2f
315 blt 3f
316 mov r0, #0
317 mvn r0, r0
318 lsr r0, r0, #1 @ 0x7fffffff
319 b 2f
320 3: mov r0, #0x80
321 lsl r0, r0, #24 @ 0x80000000
323 .endif
324 push {r0, r1, r2}
325 ldr r0, 4f
326 adr r1, 4f
327 add r0, r1
328 str r0, [sp, #8]
329 @ We know we are not on armv4t, so pop pc is safe.
330 pop {r0, r1, pc}
331 .align 2
333 .word __aeabi_idiv0 - 4b
334 #elif defined(__thumb2__)
335 .syntax unified
336 .ifc \signed, unsigned
337 cbz r0, 1f
338 mov r0, #0xffffffff
340 .else
341 cmp r0, #0
342 do_it gt
343 movgt r0, #0x7fffffff
344 do_it lt
345 movlt r0, #0x80000000
346 .endif
347 b.w SYM(__aeabi_idiv0) __PLT__
348 #else
349 .align 2
350 bx pc
352 .arm
353 cmp r0, #0
354 .ifc \signed, unsigned
355 movne r0, #0xffffffff
356 .else
357 movgt r0, #0x7fffffff
358 movlt r0, #0x80000000
359 .endif
360 b SYM(__aeabi_idiv0) __PLT__
361 .thumb
362 #endif
363 .endm
364 #else
365 .macro THUMB_LDIV0 name signed
366 push { r1, lr }
367 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
368 bl SYM (__div0)
369 mov r0, #0 @ About as wrong as it could be.
370 #if defined (__INTERWORKING__)
371 pop { r1, r2 }
372 bx r2
373 #else
374 pop { r1, pc }
375 #endif
376 .endm
377 #endif
379 .macro FUNC_END name
380 SIZE (__\name)
381 .endm
383 .macro DIV_FUNC_END name signed
384 cfi_start __\name, LSYM(Lend_div0)
385 LSYM(Ldiv0):
386 #ifdef __thumb__
387 THUMB_LDIV0 \name \signed
388 #else
389 ARM_LDIV0 \name \signed
390 #endif
391 cfi_end LSYM(Lend_div0)
392 FUNC_END \name
393 .endm
395 .macro THUMB_FUNC_START name
396 .globl SYM (\name)
397 TYPE (\name)
398 .thumb_func
399 SYM (\name):
400 .endm
402 /* Function start macros. Variants for ARM and Thumb. */
404 #ifdef __thumb__
405 #define THUMB_FUNC .thumb_func
406 #define THUMB_CODE .force_thumb
407 # if defined(__thumb2__)
408 #define THUMB_SYNTAX .syntax divided
409 # else
410 #define THUMB_SYNTAX
411 # endif
412 #else
413 #define THUMB_FUNC
414 #define THUMB_CODE
415 #define THUMB_SYNTAX
416 #endif
418 .macro FUNC_START name
419 .text
420 .globl SYM (__\name)
421 TYPE (__\name)
422 .align 0
423 THUMB_CODE
424 THUMB_FUNC
425 THUMB_SYNTAX
426 SYM (__\name):
427 .endm
429 /* Special function that will always be coded in ARM assembly, even if
430 in Thumb-only compilation. */
432 #if defined(__thumb2__)
434 /* For Thumb-2 we build everything in thumb mode. */
435 .macro ARM_FUNC_START name
436 FUNC_START \name
437 .syntax unified
438 .endm
439 #define EQUIV .thumb_set
440 .macro ARM_CALL name
441 bl __\name
442 .endm
444 #elif defined(__INTERWORKING_STUBS__)
446 .macro ARM_FUNC_START name
447 FUNC_START \name
448 bx pc
450 .arm
451 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
452 directly from other local arm routines. */
453 _L__\name:
454 .endm
455 #define EQUIV .thumb_set
456 /* Branch directly to a function declared with ARM_FUNC_START.
457 Must be called in arm mode. */
458 .macro ARM_CALL name
459 bl _L__\name
460 .endm
462 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
464 #ifdef __ARM_ARCH_6M__
465 #define EQUIV .thumb_set
466 #else
467 .macro ARM_FUNC_START name
468 .text
469 .globl SYM (__\name)
470 TYPE (__\name)
471 .align 0
472 .arm
473 SYM (__\name):
474 .endm
475 #define EQUIV .set
476 .macro ARM_CALL name
477 bl __\name
478 .endm
479 #endif
481 #endif
483 .macro FUNC_ALIAS new old
484 .globl SYM (__\new)
485 #if defined (__thumb__)
486 .thumb_set SYM (__\new), SYM (__\old)
487 #else
488 .set SYM (__\new), SYM (__\old)
489 #endif
490 .endm
492 #ifndef __ARM_ARCH_6M__
493 .macro ARM_FUNC_ALIAS new old
494 .globl SYM (__\new)
495 EQUIV SYM (__\new), SYM (__\old)
496 #if defined(__INTERWORKING_STUBS__)
497 .set SYM (_L__\new), SYM (_L__\old)
498 #endif
499 .endm
500 #endif
502 #ifdef __ARMEB__
503 #define xxh r0
504 #define xxl r1
505 #define yyh r2
506 #define yyl r3
507 #else
508 #define xxh r1
509 #define xxl r0
510 #define yyh r3
511 #define yyl r2
512 #endif
514 #ifdef __ARM_EABI__
515 .macro WEAK name
516 .weak SYM (__\name)
517 .endm
518 #endif
520 #ifdef __thumb__
521 /* Register aliases. */
523 work .req r4 @ XXXX is this safe ?
524 dividend .req r0
525 divisor .req r1
526 overdone .req r2
527 result .req r2
528 curbit .req r3
529 #endif
530 #if 0
531 ip .req r12
532 sp .req r13
533 lr .req r14
534 pc .req r15
535 #endif
537 /* ------------------------------------------------------------------------ */
538 /* Bodies of the division and modulo routines. */
539 /* ------------------------------------------------------------------------ */
540 .macro ARM_DIV_BODY dividend, divisor, result, curbit
542 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
544 #if defined (__thumb2__)
545 clz \curbit, \dividend
546 clz \result, \divisor
547 sub \curbit, \result, \curbit
548 rsb \curbit, \curbit, #31
549 adr \result, 1f
550 add \curbit, \result, \curbit, lsl #4
551 mov \result, #0
552 mov pc, \curbit
553 .p2align 3
555 .set shift, 32
556 .rept 32
557 .set shift, shift - 1
558 cmp.w \dividend, \divisor, lsl #shift
559 nop.n
560 adc.w \result, \result, \result
561 it cs
562 subcs.w \dividend, \dividend, \divisor, lsl #shift
563 .endr
564 #else
565 clz \curbit, \dividend
566 clz \result, \divisor
567 sub \curbit, \result, \curbit
568 rsbs \curbit, \curbit, #31
569 addne \curbit, \curbit, \curbit, lsl #1
570 mov \result, #0
571 addne pc, pc, \curbit, lsl #2
573 .set shift, 32
574 .rept 32
575 .set shift, shift - 1
576 cmp \dividend, \divisor, lsl #shift
577 adc \result, \result, \result
578 subcs \dividend, \dividend, \divisor, lsl #shift
579 .endr
580 #endif
582 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
583 #if __ARM_ARCH__ >= 5
585 clz \curbit, \divisor
586 clz \result, \dividend
587 sub \result, \curbit, \result
588 mov \curbit, #1
589 mov \divisor, \divisor, lsl \result
590 mov \curbit, \curbit, lsl \result
591 mov \result, #0
593 #else /* __ARM_ARCH__ < 5 */
595 @ Initially shift the divisor left 3 bits if possible,
596 @ set curbit accordingly. This allows for curbit to be located
597 @ at the left end of each 4-bit nibbles in the division loop
598 @ to save one loop in most cases.
599 tst \divisor, #0xe0000000
600 moveq \divisor, \divisor, lsl #3
601 moveq \curbit, #8
602 movne \curbit, #1
604 @ Unless the divisor is very big, shift it up in multiples of
605 @ four bits, since this is the amount of unwinding in the main
606 @ division loop. Continue shifting until the divisor is
607 @ larger than the dividend.
608 1: cmp \divisor, #0x10000000
609 cmplo \divisor, \dividend
610 movlo \divisor, \divisor, lsl #4
611 movlo \curbit, \curbit, lsl #4
612 blo 1b
614 @ For very big divisors, we must shift it a bit at a time, or
615 @ we will be in danger of overflowing.
616 1: cmp \divisor, #0x80000000
617 cmplo \divisor, \dividend
618 movlo \divisor, \divisor, lsl #1
619 movlo \curbit, \curbit, lsl #1
620 blo 1b
622 mov \result, #0
624 #endif /* __ARM_ARCH__ < 5 */
626 @ Division loop
627 1: cmp \dividend, \divisor
628 do_it hs, t
629 subhs \dividend, \dividend, \divisor
630 orrhs \result, \result, \curbit
631 cmp \dividend, \divisor, lsr #1
632 do_it hs, t
633 subhs \dividend, \dividend, \divisor, lsr #1
634 orrhs \result, \result, \curbit, lsr #1
635 cmp \dividend, \divisor, lsr #2
636 do_it hs, t
637 subhs \dividend, \dividend, \divisor, lsr #2
638 orrhs \result, \result, \curbit, lsr #2
639 cmp \dividend, \divisor, lsr #3
640 do_it hs, t
641 subhs \dividend, \dividend, \divisor, lsr #3
642 orrhs \result, \result, \curbit, lsr #3
643 cmp \dividend, #0 @ Early termination?
644 do_it ne, t
645 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
646 movne \divisor, \divisor, lsr #4
647 bne 1b
649 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
651 .endm
652 /* ------------------------------------------------------------------------ */
653 .macro ARM_DIV2_ORDER divisor, order
655 #if __ARM_ARCH__ >= 5
657 clz \order, \divisor
658 rsb \order, \order, #31
660 #else
662 cmp \divisor, #(1 << 16)
663 movhs \divisor, \divisor, lsr #16
664 movhs \order, #16
665 movlo \order, #0
667 cmp \divisor, #(1 << 8)
668 movhs \divisor, \divisor, lsr #8
669 addhs \order, \order, #8
671 cmp \divisor, #(1 << 4)
672 movhs \divisor, \divisor, lsr #4
673 addhs \order, \order, #4
675 cmp \divisor, #(1 << 2)
676 addhi \order, \order, #3
677 addls \order, \order, \divisor, lsr #1
679 #endif
681 .endm
682 /* ------------------------------------------------------------------------ */
683 .macro ARM_MOD_BODY dividend, divisor, order, spare
685 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
687 clz \order, \divisor
688 clz \spare, \dividend
689 sub \order, \order, \spare
690 rsbs \order, \order, #31
691 addne pc, pc, \order, lsl #3
693 .set shift, 32
694 .rept 32
695 .set shift, shift - 1
696 cmp \dividend, \divisor, lsl #shift
697 subcs \dividend, \dividend, \divisor, lsl #shift
698 .endr
700 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
701 #if __ARM_ARCH__ >= 5
703 clz \order, \divisor
704 clz \spare, \dividend
705 sub \order, \order, \spare
706 mov \divisor, \divisor, lsl \order
708 #else /* __ARM_ARCH__ < 5 */
710 mov \order, #0
712 @ Unless the divisor is very big, shift it up in multiples of
713 @ four bits, since this is the amount of unwinding in the main
714 @ division loop. Continue shifting until the divisor is
715 @ larger than the dividend.
716 1: cmp \divisor, #0x10000000
717 cmplo \divisor, \dividend
718 movlo \divisor, \divisor, lsl #4
719 addlo \order, \order, #4
720 blo 1b
722 @ For very big divisors, we must shift it a bit at a time, or
723 @ we will be in danger of overflowing.
724 1: cmp \divisor, #0x80000000
725 cmplo \divisor, \dividend
726 movlo \divisor, \divisor, lsl #1
727 addlo \order, \order, #1
728 blo 1b
730 #endif /* __ARM_ARCH__ < 5 */
732 @ Perform all needed substractions to keep only the reminder.
733 @ Do comparisons in batch of 4 first.
734 subs \order, \order, #3 @ yes, 3 is intended here
735 blt 2f
737 1: cmp \dividend, \divisor
738 subhs \dividend, \dividend, \divisor
739 cmp \dividend, \divisor, lsr #1
740 subhs \dividend, \dividend, \divisor, lsr #1
741 cmp \dividend, \divisor, lsr #2
742 subhs \dividend, \dividend, \divisor, lsr #2
743 cmp \dividend, \divisor, lsr #3
744 subhs \dividend, \dividend, \divisor, lsr #3
745 cmp \dividend, #1
746 mov \divisor, \divisor, lsr #4
747 subges \order, \order, #4
748 bge 1b
750 tst \order, #3
751 teqne \dividend, #0
752 beq 5f
754 @ Either 1, 2 or 3 comparison/substractions are left.
755 2: cmn \order, #2
756 blt 4f
757 beq 3f
758 cmp \dividend, \divisor
759 subhs \dividend, \dividend, \divisor
760 mov \divisor, \divisor, lsr #1
761 3: cmp \dividend, \divisor
762 subhs \dividend, \dividend, \divisor
763 mov \divisor, \divisor, lsr #1
764 4: cmp \dividend, \divisor
765 subhs \dividend, \dividend, \divisor
768 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
770 .endm
771 /* ------------------------------------------------------------------------ */
772 .macro THUMB_DIV_MOD_BODY modulo
773 @ Load the constant 0x10000000 into our work register.
774 mov work, #1
775 lsl work, #28
776 LSYM(Loop1):
777 @ Unless the divisor is very big, shift it up in multiples of
778 @ four bits, since this is the amount of unwinding in the main
779 @ division loop. Continue shifting until the divisor is
780 @ larger than the dividend.
781 cmp divisor, work
782 bhs LSYM(Lbignum)
783 cmp divisor, dividend
784 bhs LSYM(Lbignum)
785 lsl divisor, #4
786 lsl curbit, #4
787 b LSYM(Loop1)
788 LSYM(Lbignum):
789 @ Set work to 0x80000000
790 lsl work, #3
791 LSYM(Loop2):
792 @ For very big divisors, we must shift it a bit at a time, or
793 @ we will be in danger of overflowing.
794 cmp divisor, work
795 bhs LSYM(Loop3)
796 cmp divisor, dividend
797 bhs LSYM(Loop3)
798 lsl divisor, #1
799 lsl curbit, #1
800 b LSYM(Loop2)
801 LSYM(Loop3):
802 @ Test for possible subtractions ...
803 .if \modulo
804 @ ... On the final pass, this may subtract too much from the dividend,
805 @ so keep track of which subtractions are done, we can fix them up
806 @ afterwards.
807 mov overdone, #0
808 cmp dividend, divisor
809 blo LSYM(Lover1)
810 sub dividend, dividend, divisor
811 LSYM(Lover1):
812 lsr work, divisor, #1
813 cmp dividend, work
814 blo LSYM(Lover2)
815 sub dividend, dividend, work
816 mov ip, curbit
817 mov work, #1
818 ror curbit, work
819 orr overdone, curbit
820 mov curbit, ip
821 LSYM(Lover2):
822 lsr work, divisor, #2
823 cmp dividend, work
824 blo LSYM(Lover3)
825 sub dividend, dividend, work
826 mov ip, curbit
827 mov work, #2
828 ror curbit, work
829 orr overdone, curbit
830 mov curbit, ip
831 LSYM(Lover3):
832 lsr work, divisor, #3
833 cmp dividend, work
834 blo LSYM(Lover4)
835 sub dividend, dividend, work
836 mov ip, curbit
837 mov work, #3
838 ror curbit, work
839 orr overdone, curbit
840 mov curbit, ip
841 LSYM(Lover4):
842 mov ip, curbit
843 .else
844 @ ... and note which bits are done in the result. On the final pass,
845 @ this may subtract too much from the dividend, but the result will be ok,
846 @ since the "bit" will have been shifted out at the bottom.
847 cmp dividend, divisor
848 blo LSYM(Lover1)
849 sub dividend, dividend, divisor
850 orr result, result, curbit
851 LSYM(Lover1):
852 lsr work, divisor, #1
853 cmp dividend, work
854 blo LSYM(Lover2)
855 sub dividend, dividend, work
856 lsr work, curbit, #1
857 orr result, work
858 LSYM(Lover2):
859 lsr work, divisor, #2
860 cmp dividend, work
861 blo LSYM(Lover3)
862 sub dividend, dividend, work
863 lsr work, curbit, #2
864 orr result, work
865 LSYM(Lover3):
866 lsr work, divisor, #3
867 cmp dividend, work
868 blo LSYM(Lover4)
869 sub dividend, dividend, work
870 lsr work, curbit, #3
871 orr result, work
872 LSYM(Lover4):
873 .endif
875 cmp dividend, #0 @ Early termination?
876 beq LSYM(Lover5)
877 lsr curbit, #4 @ No, any more bits to do?
878 beq LSYM(Lover5)
879 lsr divisor, #4
880 b LSYM(Loop3)
881 LSYM(Lover5):
882 .if \modulo
883 @ Any subtractions that we should not have done will be recorded in
884 @ the top three bits of "overdone". Exactly which were not needed
885 @ are governed by the position of the bit, stored in ip.
886 mov work, #0xe
887 lsl work, #28
888 and overdone, work
889 beq LSYM(Lgot_result)
891 @ If we terminated early, because dividend became zero, then the
892 @ bit in ip will not be in the bottom nibble, and we should not
893 @ perform the additions below. We must test for this though
894 @ (rather relying upon the TSTs to prevent the additions) since
895 @ the bit in ip could be in the top two bits which might then match
896 @ with one of the smaller RORs.
897 mov curbit, ip
898 mov work, #0x7
899 tst curbit, work
900 beq LSYM(Lgot_result)
902 mov curbit, ip
903 mov work, #3
904 ror curbit, work
905 tst overdone, curbit
906 beq LSYM(Lover6)
907 lsr work, divisor, #3
908 add dividend, work
909 LSYM(Lover6):
910 mov curbit, ip
911 mov work, #2
912 ror curbit, work
913 tst overdone, curbit
914 beq LSYM(Lover7)
915 lsr work, divisor, #2
916 add dividend, work
917 LSYM(Lover7):
918 mov curbit, ip
919 mov work, #1
920 ror curbit, work
921 tst overdone, curbit
922 beq LSYM(Lgot_result)
923 lsr work, divisor, #1
924 add dividend, work
925 .endif
926 LSYM(Lgot_result):
927 .endm
928 /* ------------------------------------------------------------------------ */
929 /* Start of the Real Functions */
930 /* ------------------------------------------------------------------------ */
931 #ifdef L_udivsi3
933 #if defined(__prefer_thumb__)
935 FUNC_START udivsi3
936 FUNC_ALIAS aeabi_uidiv udivsi3
938 cmp divisor, #0
939 beq LSYM(Ldiv0)
940 LSYM(udivsi3_skip_div0_test):
941 mov curbit, #1
942 mov result, #0
944 push { work }
945 cmp dividend, divisor
946 blo LSYM(Lgot_result)
948 THUMB_DIV_MOD_BODY 0
950 mov r0, result
951 pop { work }
954 #else /* ARM version/Thumb-2. */
956 ARM_FUNC_START udivsi3
957 ARM_FUNC_ALIAS aeabi_uidiv udivsi3
959 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
960 check for division-by-zero a second time. */
961 LSYM(udivsi3_skip_div0_test):
962 subs r2, r1, #1
963 do_it eq
964 RETc(eq)
965 bcc LSYM(Ldiv0)
966 cmp r0, r1
967 bls 11f
968 tst r1, r2
969 beq 12f
971 ARM_DIV_BODY r0, r1, r2, r3
973 mov r0, r2
974 RET
976 11: do_it eq, e
977 moveq r0, #1
978 movne r0, #0
981 12: ARM_DIV2_ORDER r1, r2
983 mov r0, r0, lsr r2
986 #endif /* ARM version */
988 DIV_FUNC_END udivsi3 unsigned
990 #if defined(__prefer_thumb__)
991 FUNC_START aeabi_uidivmod
992 cmp r1, #0
993 beq LSYM(Ldiv0)
994 push {r0, r1, lr}
995 bl LSYM(udivsi3_skip_div0_test)
996 POP {r1, r2, r3}
997 mul r2, r0
998 sub r1, r1, r2
999 bx r3
1000 #else
1001 ARM_FUNC_START aeabi_uidivmod
1002 cmp r1, #0
1003 beq LSYM(Ldiv0)
1004 stmfd sp!, { r0, r1, lr }
1005 bl LSYM(udivsi3_skip_div0_test)
1006 ldmfd sp!, { r1, r2, lr }
1007 mul r3, r2, r0
1008 sub r1, r1, r3
1010 #endif
1011 FUNC_END aeabi_uidivmod
1013 #endif /* L_udivsi3 */
1014 /* ------------------------------------------------------------------------ */
1015 #ifdef L_umodsi3
1017 FUNC_START umodsi3
1019 #ifdef __thumb__
1021 cmp divisor, #0
1022 beq LSYM(Ldiv0)
1023 mov curbit, #1
1024 cmp dividend, divisor
1025 bhs LSYM(Lover10)
1026 RET
1028 LSYM(Lover10):
1029 push { work }
1031 THUMB_DIV_MOD_BODY 1
1033 pop { work }
1036 #else /* ARM version. */
1038 subs r2, r1, #1 @ compare divisor with 1
1039 bcc LSYM(Ldiv0)
1040 cmpne r0, r1 @ compare dividend with divisor
1041 moveq r0, #0
1042 tsthi r1, r2 @ see if divisor is power of 2
1043 andeq r0, r0, r2
1044 RETc(ls)
1046 ARM_MOD_BODY r0, r1, r2, r3
1048 RET
1050 #endif /* ARM version. */
1052 DIV_FUNC_END umodsi3 unsigned
1054 #endif /* L_umodsi3 */
1055 /* ------------------------------------------------------------------------ */
1056 #ifdef L_divsi3
1058 #if defined(__prefer_thumb__)
1060 FUNC_START divsi3
1061 FUNC_ALIAS aeabi_idiv divsi3
1063 cmp divisor, #0
1064 beq LSYM(Ldiv0)
1065 LSYM(divsi3_skip_div0_test):
1066 push { work }
1067 mov work, dividend
1068 eor work, divisor @ Save the sign of the result.
1069 mov ip, work
1070 mov curbit, #1
1071 mov result, #0
1072 cmp divisor, #0
1073 bpl LSYM(Lover10)
1074 neg divisor, divisor @ Loops below use unsigned.
1075 LSYM(Lover10):
1076 cmp dividend, #0
1077 bpl LSYM(Lover11)
1078 neg dividend, dividend
1079 LSYM(Lover11):
1080 cmp dividend, divisor
1081 blo LSYM(Lgot_result)
1083 THUMB_DIV_MOD_BODY 0
1085 mov r0, result
1086 mov work, ip
1087 cmp work, #0
1088 bpl LSYM(Lover12)
1089 neg r0, r0
1090 LSYM(Lover12):
1091 pop { work }
1094 #else /* ARM/Thumb-2 version. */
1096 ARM_FUNC_START divsi3
1097 ARM_FUNC_ALIAS aeabi_idiv divsi3
1099 cmp r1, #0
1100 beq LSYM(Ldiv0)
1101 LSYM(divsi3_skip_div0_test):
1102 eor ip, r0, r1 @ save the sign of the result.
1103 do_it mi
1104 rsbmi r1, r1, #0 @ loops below use unsigned.
1105 subs r2, r1, #1 @ division by 1 or -1 ?
1106 beq 10f
1107 movs r3, r0
1108 do_it mi
1109 rsbmi r3, r0, #0 @ positive dividend value
1110 cmp r3, r1
1111 bls 11f
1112 tst r1, r2 @ divisor is power of 2 ?
1113 beq 12f
1115 ARM_DIV_BODY r3, r1, r0, r2
1117 cmp ip, #0
1118 do_it mi
1119 rsbmi r0, r0, #0
1120 RET
1122 10: teq ip, r0 @ same sign ?
1123 do_it mi
1124 rsbmi r0, r0, #0
1125 RET
1127 11: do_it lo
1128 movlo r0, #0
1129 do_it eq,t
1130 moveq r0, ip, asr #31
1131 orreq r0, r0, #1
1134 12: ARM_DIV2_ORDER r1, r2
1136 cmp ip, #0
1137 mov r0, r3, lsr r2
1138 do_it mi
1139 rsbmi r0, r0, #0
1142 #endif /* ARM version */
1144 DIV_FUNC_END divsi3 signed
1146 #if defined(__prefer_thumb__)
1147 FUNC_START aeabi_idivmod
1148 cmp r1, #0
1149 beq LSYM(Ldiv0)
1150 push {r0, r1, lr}
1151 bl LSYM(divsi3_skip_div0_test)
1152 POP {r1, r2, r3}
1153 mul r2, r0
1154 sub r1, r1, r2
1155 bx r3
1156 #else
1157 ARM_FUNC_START aeabi_idivmod
1158 cmp r1, #0
1159 beq LSYM(Ldiv0)
1160 stmfd sp!, { r0, r1, lr }
1161 bl LSYM(divsi3_skip_div0_test)
1162 ldmfd sp!, { r1, r2, lr }
1163 mul r3, r2, r0
1164 sub r1, r1, r3
1166 #endif
1167 FUNC_END aeabi_idivmod
1169 #endif /* L_divsi3 */
1170 /* ------------------------------------------------------------------------ */
1171 #ifdef L_modsi3
1173 FUNC_START modsi3
1175 #ifdef __thumb__
1177 mov curbit, #1
1178 cmp divisor, #0
1179 beq LSYM(Ldiv0)
1180 bpl LSYM(Lover10)
1181 neg divisor, divisor @ Loops below use unsigned.
1182 LSYM(Lover10):
1183 push { work }
1184 @ Need to save the sign of the dividend, unfortunately, we need
1185 @ work later on. Must do this after saving the original value of
1186 @ the work register, because we will pop this value off first.
1187 push { dividend }
1188 cmp dividend, #0
1189 bpl LSYM(Lover11)
1190 neg dividend, dividend
1191 LSYM(Lover11):
1192 cmp dividend, divisor
1193 blo LSYM(Lgot_result)
1195 THUMB_DIV_MOD_BODY 1
1197 pop { work }
1198 cmp work, #0
1199 bpl LSYM(Lover12)
1200 neg dividend, dividend
1201 LSYM(Lover12):
1202 pop { work }
1203 RET
1205 #else /* ARM version. */
1207 cmp r1, #0
1208 beq LSYM(Ldiv0)
1209 rsbmi r1, r1, #0 @ loops below use unsigned.
1210 movs ip, r0 @ preserve sign of dividend
1211 rsbmi r0, r0, #0 @ if negative make positive
1212 subs r2, r1, #1 @ compare divisor with 1
1213 cmpne r0, r1 @ compare dividend with divisor
1214 moveq r0, #0
1215 tsthi r1, r2 @ see if divisor is power of 2
1216 andeq r0, r0, r2
1217 bls 10f
1219 ARM_MOD_BODY r0, r1, r2, r3
1221 10: cmp ip, #0
1222 rsbmi r0, r0, #0
1223 RET
1225 #endif /* ARM version */
1227 DIV_FUNC_END modsi3 signed
1229 #endif /* L_modsi3 */
1230 /* ------------------------------------------------------------------------ */
1231 #ifdef L_dvmd_tls
1233 #ifdef __ARM_EABI__
1234 WEAK aeabi_idiv0
1235 WEAK aeabi_ldiv0
1236 FUNC_START aeabi_idiv0
1237 FUNC_START aeabi_ldiv0
1239 FUNC_END aeabi_ldiv0
1240 FUNC_END aeabi_idiv0
1241 #else
1242 FUNC_START div0
1244 FUNC_END div0
1245 #endif
1247 #endif /* L_divmodsi_tools */
1248 /* ------------------------------------------------------------------------ */
1249 #ifdef L_dvmd_lnx
1250 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1252 /* Constant taken from <asm/signal.h>. */
1253 #define SIGFPE 8
1255 #ifdef __ARM_EABI__
1256 WEAK aeabi_idiv0
1257 WEAK aeabi_ldiv0
1258 ARM_FUNC_START aeabi_idiv0
1259 ARM_FUNC_START aeabi_ldiv0
1260 #else
1261 ARM_FUNC_START div0
1262 #endif
1264 do_push {r1, lr}
1265 mov r0, #SIGFPE
1266 bl SYM(raise) __PLT__
1267 RETLDM r1
1269 #ifdef __ARM_EABI__
1270 FUNC_END aeabi_ldiv0
1271 FUNC_END aeabi_idiv0
1272 #else
1273 FUNC_END div0
1274 #endif
1276 #endif /* L_dvmd_lnx */
1277 #ifdef L_clear_cache
1278 #if defined __ARM_EABI__ && defined __linux__
1279 @ EABI GNU/Linux call to cacheflush syscall.
1280 ARM_FUNC_START clear_cache
1281 do_push {r7}
1282 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1283 movw r7, #2
1284 movt r7, #0xf
1285 #else
1286 mov r7, #0xf0000
1287 add r7, r7, #2
1288 #endif
1289 mov r2, #0
1290 swi 0
1291 do_pop {r7}
1293 FUNC_END clear_cache
1294 #else
1295 #error "This is only for ARM EABI GNU/Linux"
1296 #endif
1297 #endif /* L_clear_cache */
1298 /* ------------------------------------------------------------------------ */
1299 /* Dword shift operations. */
1300 /* All the following Dword shift variants rely on the fact that
1301 shft xxx, Reg
1302 is in fact done as
1303 shft xxx, (Reg & 255)
1304 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1305 case of logical shifts) or the sign (for asr). */
1307 #ifdef __ARMEB__
1308 #define al r1
1309 #define ah r0
1310 #else
1311 #define al r0
1312 #define ah r1
1313 #endif
1315 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1316 #ifndef __symbian__
1318 #ifdef L_lshrdi3
1320 FUNC_START lshrdi3
1321 FUNC_ALIAS aeabi_llsr lshrdi3
1323 #ifdef __thumb__
1324 lsr al, r2
1325 mov r3, ah
1326 lsr ah, r2
1327 mov ip, r3
1328 sub r2, #32
1329 lsr r3, r2
1330 orr al, r3
1331 neg r2, r2
1332 mov r3, ip
1333 lsl r3, r2
1334 orr al, r3
1336 #else
1337 subs r3, r2, #32
1338 rsb ip, r2, #32
1339 movmi al, al, lsr r2
1340 movpl al, ah, lsr r3
1341 orrmi al, al, ah, lsl ip
1342 mov ah, ah, lsr r2
1344 #endif
1345 FUNC_END aeabi_llsr
1346 FUNC_END lshrdi3
1348 #endif
1350 #ifdef L_ashrdi3
1352 FUNC_START ashrdi3
1353 FUNC_ALIAS aeabi_lasr ashrdi3
1355 #ifdef __thumb__
1356 lsr al, r2
1357 mov r3, ah
1358 asr ah, r2
1359 sub r2, #32
1360 @ If r2 is negative at this point the following step would OR
1361 @ the sign bit into all of AL. That's not what we want...
1362 bmi 1f
1363 mov ip, r3
1364 asr r3, r2
1365 orr al, r3
1366 mov r3, ip
1368 neg r2, r2
1369 lsl r3, r2
1370 orr al, r3
1372 #else
1373 subs r3, r2, #32
1374 rsb ip, r2, #32
1375 movmi al, al, lsr r2
1376 movpl al, ah, asr r3
1377 orrmi al, al, ah, lsl ip
1378 mov ah, ah, asr r2
1380 #endif
1382 FUNC_END aeabi_lasr
1383 FUNC_END ashrdi3
1385 #endif
1387 #ifdef L_ashldi3
1389 FUNC_START ashldi3
1390 FUNC_ALIAS aeabi_llsl ashldi3
1392 #ifdef __thumb__
1393 lsl ah, r2
1394 mov r3, al
1395 lsl al, r2
1396 mov ip, r3
1397 sub r2, #32
1398 lsl r3, r2
1399 orr ah, r3
1400 neg r2, r2
1401 mov r3, ip
1402 lsr r3, r2
1403 orr ah, r3
1405 #else
1406 subs r3, r2, #32
1407 rsb ip, r2, #32
1408 movmi ah, ah, lsl r2
1409 movpl ah, al, lsl r3
1410 orrmi ah, ah, al, lsr ip
1411 mov al, al, lsl r2
1413 #endif
1414 FUNC_END aeabi_llsl
1415 FUNC_END ashldi3
1417 #endif
1419 #endif /* __symbian__ */
1421 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1422 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1423 || defined(__ARM_ARCH_5TEJ__)
1424 #define HAVE_ARM_CLZ 1
1425 #endif
1427 #ifdef L_clzsi2
1428 #if defined(__ARM_ARCH_6M__)
1429 FUNC_START clzsi2
1430 mov r1, #28
1431 mov r3, #1
1432 lsl r3, r3, #16
1433 cmp r0, r3 /* 0x10000 */
1434 bcc 2f
1435 lsr r0, r0, #16
1436 sub r1, r1, #16
1437 2: lsr r3, r3, #8
1438 cmp r0, r3 /* #0x100 */
1439 bcc 2f
1440 lsr r0, r0, #8
1441 sub r1, r1, #8
1442 2: lsr r3, r3, #4
1443 cmp r0, r3 /* #0x10 */
1444 bcc 2f
1445 lsr r0, r0, #4
1446 sub r1, r1, #4
1447 2: adr r2, 1f
1448 ldrb r0, [r2, r0]
1449 add r0, r0, r1
1450 bx lr
1451 .align 2
1453 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1454 FUNC_END clzsi2
1455 #else
1456 ARM_FUNC_START clzsi2
1457 # if defined(HAVE_ARM_CLZ)
1458 clz r0, r0
1460 # else
1461 mov r1, #28
1462 cmp r0, #0x10000
1463 do_it cs, t
1464 movcs r0, r0, lsr #16
1465 subcs r1, r1, #16
1466 cmp r0, #0x100
1467 do_it cs, t
1468 movcs r0, r0, lsr #8
1469 subcs r1, r1, #8
1470 cmp r0, #0x10
1471 do_it cs, t
1472 movcs r0, r0, lsr #4
1473 subcs r1, r1, #4
1474 adr r2, 1f
1475 ldrb r0, [r2, r0]
1476 add r0, r0, r1
1478 .align 2
1480 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1481 # endif /* !HAVE_ARM_CLZ */
1482 FUNC_END clzsi2
1483 #endif
1484 #endif /* L_clzsi2 */
1486 #ifdef L_clzdi2
1487 #if !defined(HAVE_ARM_CLZ)
1489 # if defined(__ARM_ARCH_6M__)
1490 FUNC_START clzdi2
1491 push {r4, lr}
1492 # else
1493 ARM_FUNC_START clzdi2
1494 do_push {r4, lr}
1495 # endif
1496 cmp xxh, #0
1497 bne 1f
1498 # ifdef __ARMEB__
1499 mov r0, xxl
1500 bl __clzsi2
1501 add r0, r0, #32
1502 b 2f
1504 bl __clzsi2
1505 # else
1506 bl __clzsi2
1507 add r0, r0, #32
1508 b 2f
1510 mov r0, xxh
1511 bl __clzsi2
1512 # endif
1514 # if defined(__ARM_ARCH_6M__)
1515 pop {r4, pc}
1516 # else
1517 RETLDM r4
1518 # endif
1519 FUNC_END clzdi2
1521 #else /* HAVE_ARM_CLZ */
1523 ARM_FUNC_START clzdi2
1524 cmp xxh, #0
1525 do_it eq, et
1526 clzeq r0, xxl
1527 clzne r0, xxh
1528 addeq r0, r0, #32
1530 FUNC_END clzdi2
1532 #endif
1533 #endif /* L_clzdi2 */
1535 /* ------------------------------------------------------------------------ */
1536 /* These next two sections are here despite the fact that they contain Thumb
1537 assembler because their presence allows interworked code to be linked even
1538 when the GCC library is this one. */
1540 /* Do not build the interworking functions when the target architecture does
1541 not support Thumb instructions. (This can be a multilib option). */
1542 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1543 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1544 || __ARM_ARCH__ >= 6
1546 #if defined L_call_via_rX
1548 /* These labels & instructions are used by the Arm/Thumb interworking code.
1549 The address of function to be called is loaded into a register and then
1550 one of these labels is called via a BL instruction. This puts the
1551 return address into the link register with the bottom bit set, and the
1552 code here switches to the correct mode before executing the function. */
1554 .text
1555 .align 0
1556 .force_thumb
1558 .macro call_via register
1559 THUMB_FUNC_START _call_via_\register
1561 bx \register
1564 SIZE (_call_via_\register)
1565 .endm
1567 call_via r0
1568 call_via r1
1569 call_via r2
1570 call_via r3
1571 call_via r4
1572 call_via r5
1573 call_via r6
1574 call_via r7
1575 call_via r8
1576 call_via r9
1577 call_via sl
1578 call_via fp
1579 call_via ip
1580 call_via sp
1581 call_via lr
1583 #endif /* L_call_via_rX */
1585 /* Don't bother with the old interworking routines for Thumb-2. */
1586 /* ??? Maybe only omit these on "m" variants. */
1587 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1589 #if defined L_interwork_call_via_rX
1591 /* These labels & instructions are used by the Arm/Thumb interworking code,
1592 when the target address is in an unknown instruction set. The address
1593 of function to be called is loaded into a register and then one of these
1594 labels is called via a BL instruction. This puts the return address
1595 into the link register with the bottom bit set, and the code here
1596 switches to the correct mode before executing the function. Unfortunately
1597 the target code cannot be relied upon to return via a BX instruction, so
1598 instead we have to store the resturn address on the stack and allow the
1599 called function to return here instead. Upon return we recover the real
1600 return address and use a BX to get back to Thumb mode.
1602 There are three variations of this code. The first,
1603 _interwork_call_via_rN(), will push the return address onto the
1604 stack and pop it in _arm_return(). It should only be used if all
1605 arguments are passed in registers.
1607 The second, _interwork_r7_call_via_rN(), instead stores the return
1608 address at [r7, #-4]. It is the caller's responsibility to ensure
1609 that this address is valid and contains no useful data.
1611 The third, _interwork_r11_call_via_rN(), works in the same way but
1612 uses r11 instead of r7. It is useful if the caller does not really
1613 need a frame pointer. */
1615 .text
1616 .align 0
1618 .code 32
1619 .globl _arm_return
1620 LSYM(Lstart_arm_return):
1621 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1622 cfi_push 0, 0xe, -0x8, 0x8
1623 nop @ This nop is for the benefit of debuggers, so that
1624 @ backtraces will use the correct unwind information.
1625 _arm_return:
1626 RETLDM unwind=LSYM(Lstart_arm_return)
1627 cfi_end LSYM(Lend_arm_return)
1629 .globl _arm_return_r7
1630 _arm_return_r7:
1631 ldr lr, [r7, #-4]
1632 bx lr
1634 .globl _arm_return_r11
1635 _arm_return_r11:
1636 ldr lr, [r11, #-4]
1637 bx lr
1639 .macro interwork_with_frame frame, register, name, return
1640 .code 16
1642 THUMB_FUNC_START \name
1644 bx pc
1647 .code 32
1648 tst \register, #1
1649 streq lr, [\frame, #-4]
1650 adreq lr, _arm_return_\frame
1651 bx \register
1653 SIZE (\name)
1654 .endm
1656 .macro interwork register
1657 .code 16
1659 THUMB_FUNC_START _interwork_call_via_\register
1661 bx pc
1664 .code 32
1665 .globl LSYM(Lchange_\register)
1666 LSYM(Lchange_\register):
1667 tst \register, #1
1668 streq lr, [sp, #-8]!
1669 adreq lr, _arm_return
1670 bx \register
1672 SIZE (_interwork_call_via_\register)
1674 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1675 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1676 .endm
1678 interwork r0
1679 interwork r1
1680 interwork r2
1681 interwork r3
1682 interwork r4
1683 interwork r5
1684 interwork r6
1685 interwork r7
1686 interwork r8
1687 interwork r9
1688 interwork sl
1689 interwork fp
1690 interwork ip
1691 interwork sp
1693 /* The LR case has to be handled a little differently... */
1694 .code 16
1696 THUMB_FUNC_START _interwork_call_via_lr
1698 bx pc
1701 .code 32
1702 .globl .Lchange_lr
1703 .Lchange_lr:
1704 tst lr, #1
1705 stmeqdb r13!, {lr, pc}
1706 mov ip, lr
1707 adreq lr, _arm_return
1708 bx ip
1710 SIZE (_interwork_call_via_lr)
1712 #endif /* L_interwork_call_via_rX */
1713 #endif /* !__thumb2__ */
1715 /* Functions to support compact pic switch tables in thumb1 state.
1716 All these routines take an index into the table in r0. The
1717 table is at LR & ~1 (but this must be rounded up in the case
1718 of 32-bit entires). They are only permitted to clobber r12
1719 and r14 and r0 must be preserved on exit. */
1720 #ifdef L_thumb1_case_sqi
1722 .text
1723 .align 0
1724 .force_thumb
1725 .syntax unified
1726 THUMB_FUNC_START __gnu_thumb1_case_sqi
1727 push {r1}
1728 mov r1, lr
1729 lsrs r1, r1, #1
1730 lsls r1, r1, #1
1731 ldrsb r1, [r1, r0]
1732 lsls r1, r1, #1
1733 add lr, lr, r1
1734 pop {r1}
1735 bx lr
1736 SIZE (__gnu_thumb1_case_sqi)
1737 #endif
1739 #ifdef L_thumb1_case_uqi
1741 .text
1742 .align 0
1743 .force_thumb
1744 .syntax unified
1745 THUMB_FUNC_START __gnu_thumb1_case_uqi
1746 push {r1}
1747 mov r1, lr
1748 lsrs r1, r1, #1
1749 lsls r1, r1, #1
1750 ldrb r1, [r1, r0]
1751 lsls r1, r1, #1
1752 add lr, lr, r1
1753 pop {r1}
1754 bx lr
1755 SIZE (__gnu_thumb1_case_uqi)
1756 #endif
1758 #ifdef L_thumb1_case_shi
1760 .text
1761 .align 0
1762 .force_thumb
1763 .syntax unified
1764 THUMB_FUNC_START __gnu_thumb1_case_shi
1765 push {r0, r1}
1766 mov r1, lr
1767 lsrs r1, r1, #1
1768 lsls r0, r0, #1
1769 lsls r1, r1, #1
1770 ldrsh r1, [r1, r0]
1771 lsls r1, r1, #1
1772 add lr, lr, r1
1773 pop {r0, r1}
1774 bx lr
1775 SIZE (__gnu_thumb1_case_shi)
1776 #endif
1778 #ifdef L_thumb1_case_uhi
1780 .text
1781 .align 0
1782 .force_thumb
1783 .syntax unified
1784 THUMB_FUNC_START __gnu_thumb1_case_uhi
1785 push {r0, r1}
1786 mov r1, lr
1787 lsrs r1, r1, #1
1788 lsls r0, r0, #1
1789 lsls r1, r1, #1
1790 ldrh r1, [r1, r0]
1791 lsls r1, r1, #1
1792 add lr, lr, r1
1793 pop {r0, r1}
1794 bx lr
1795 SIZE (__gnu_thumb1_case_uhi)
1796 #endif
1798 #ifdef L_thumb1_case_si
1800 .text
1801 .align 0
1802 .force_thumb
1803 .syntax unified
1804 THUMB_FUNC_START __gnu_thumb1_case_si
1805 push {r0, r1}
1806 mov r1, lr
1807 adds.n r1, r1, #2 /* Align to word. */
1808 lsrs r1, r1, #2
1809 lsls r0, r0, #2
1810 lsls r1, r1, #2
1811 ldr r0, [r1, r0]
1812 adds r0, r0, r1
1813 mov lr, r0
1814 pop {r0, r1}
1815 mov pc, lr /* We know we were called from thumb code. */
1816 SIZE (__gnu_thumb1_case_si)
1817 #endif
1819 #endif /* Arch supports thumb. */
1821 #ifndef __symbian__
1822 #ifndef __ARM_ARCH_6M__
1823 #include "ieee754-df.S"
1824 #include "ieee754-sf.S"
1825 #include "bpabi.S"
1826 #else /* __ARM_ARCH_6M__ */
1827 #include "bpabi-v6m.S"
1828 #endif /* __ARM_ARCH_6M__ */
1829 #endif /* !__symbian__ */