Update concepts branch to revision 131834
[official-gcc.git] / gcc / config / arm / lib1funcs.asm
blobfe315bcb69b48d76876bc1728c693ad6d5d0be88
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
10 later version.
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
19 executable.)
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
34 .previous
35 #endif
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
43 #endif
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)
54 #ifdef __ELF__
55 #ifdef __thumb__
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. */
59 #else
60 #define __PLT__ (PLT)
61 #endif
62 #define TYPE(x) .type SYM(x),function
63 #define SIZE(x) .size SYM(x), . - SYM(x)
64 #define LSYM(x) .x
65 #else
66 #define __PLT__
67 #define TYPE(x)
68 #define SIZE(x)
69 #define LSYM(x) x
70 #endif
72 /* Function end macros. Variants for interworking. */
74 #if defined(__ARM_ARCH_2__)
75 # define __ARM_ARCH__ 2
76 #endif
78 #if defined(__ARM_ARCH_3__)
79 # define __ARM_ARCH__ 3
80 #endif
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
87 #endif
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
93 #endif
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
100 #endif
102 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
103 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
104 # define __ARM_ARCH__ 7
105 #endif
107 #ifndef __ARM_ARCH__
108 #error Unable to determine architecture.
109 #endif
111 /* How to return from a function call depends on the architecture variant. */
113 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
115 # define RET bx lr
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 */
133 #else
135 # define RET mov pc, lr
136 # define RETc(x) mov##x pc, lr
138 #endif
140 .macro cfi_pop advance, reg, cfa_offset
141 #ifdef __ELF__
142 .pushsection .debug_frame
143 .byte 0x4 /* DW_CFA_advance_loc4 */
144 .4byte \advance
145 .byte (0xc0 | \reg) /* DW_CFA_restore */
146 .byte 0xe /* DW_CFA_def_cfa_offset */
147 .uleb128 \cfa_offset
148 .popsection
149 #endif
150 .endm
151 .macro cfi_push advance, reg, offset, cfa_offset
152 #ifdef __ELF__
153 .pushsection .debug_frame
154 .byte 0x4 /* DW_CFA_advance_loc4 */
155 .4byte \advance
156 .byte (0x80 | \reg) /* DW_CFA_offset */
157 .uleb128 (\offset / -4)
158 .byte 0xe /* DW_CFA_def_cfa_offset */
159 .uleb128 \cfa_offset
160 .popsection
161 #endif
162 .endm
163 .macro cfi_start start_label, end_label
164 #ifdef __ELF__
165 .pushsection .debug_frame
166 LSYM(Lstart_frame):
167 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
168 LSYM(Lstart_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
176 .uleb128 0xd
177 .uleb128 0x0
179 .align 2
180 LSYM(Lend_cie):
181 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
182 LSYM(Lstart_fde):
183 .4byte LSYM(Lstart_frame) @ FDE CIE offset
184 .4byte \start_label @ FDE initial location
185 .4byte \end_label-\start_label @ FDE address range
186 .popsection
187 #endif
188 .endm
189 .macro cfi_end end_label
190 #ifdef __ELF__
191 .pushsection .debug_frame
192 .align 2
193 LSYM(Lend_fde):
194 .popsection
195 \end_label:
196 #endif
197 .endm
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__)
203 .ifc "\regs",""
204 ldr\cond lr, [sp], #8
205 .else
206 # if defined(__thumb2__)
207 pop\cond {\regs, lr}
208 # else
209 ldm\cond\dirn sp!, {\regs, lr}
210 # endif
211 .endif
212 .ifnc "\unwind", ""
213 /* Mark LR as restored. */
214 97: cfi_pop 97b - \unwind, 0xe, 0x0
215 .endif
216 bx\cond lr
217 #else
218 /* Caller is responsible for providing IT instruction. */
219 .ifc "\regs",""
220 ldr\cond pc, [sp], #8
221 .else
222 # if defined(__thumb2__)
223 pop\cond {\regs, pc}
224 # else
225 ldm\cond\dirn sp!, {\regs, pc}
226 # endif
227 .endif
228 #endif
229 .endm
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=""
236 it\suffix \cond
237 .endm
238 .macro shift1 op, arg0, arg1, arg2
239 \op \arg0, \arg1, \arg2
240 .endm
241 #define do_push push
242 #define do_pop pop
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
249 .endm
250 #else
251 .macro do_it cond, suffix=""
252 .endm
253 .macro shift1 op, arg0, arg1, arg2
254 mov \arg0, \arg1, \op \arg2
255 .endm
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
261 .endm
262 #endif
264 .macro ARM_LDIV0 name
265 str lr, [sp, #-8]!
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.
269 RETLDM unwind=98b
270 .endm
273 .macro THUMB_LDIV0 name
274 push { r1, lr }
275 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
276 bl SYM (__div0)
277 mov r0, #0 @ About as wrong as it could be.
278 #if defined (__INTERWORKING__)
279 pop { r1, r2 }
280 bx r2
281 #else
282 pop { r1, pc }
283 #endif
284 .endm
286 .macro FUNC_END name
287 SIZE (__\name)
288 .endm
290 .macro DIV_FUNC_END name
291 cfi_start __\name, LSYM(Lend_div0)
292 LSYM(Ldiv0):
293 #ifdef __thumb__
294 THUMB_LDIV0 \name
295 #else
296 ARM_LDIV0 \name
297 #endif
298 cfi_end LSYM(Lend_div0)
299 FUNC_END \name
300 .endm
302 .macro THUMB_FUNC_START name
303 .globl SYM (\name)
304 TYPE (\name)
305 .thumb_func
306 SYM (\name):
307 .endm
309 /* Function start macros. Variants for ARM and Thumb. */
311 #ifdef __thumb__
312 #define THUMB_FUNC .thumb_func
313 #define THUMB_CODE .force_thumb
314 # if defined(__thumb2__)
315 #define THUMB_SYNTAX .syntax divided
316 # else
317 #define THUMB_SYNTAX
318 # endif
319 #else
320 #define THUMB_FUNC
321 #define THUMB_CODE
322 #define THUMB_SYNTAX
323 #endif
325 .macro FUNC_START name
326 .text
327 .globl SYM (__\name)
328 TYPE (__\name)
329 .align 0
330 THUMB_CODE
331 THUMB_FUNC
332 THUMB_SYNTAX
333 SYM (__\name):
334 .endm
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
343 FUNC_START \name
344 .syntax unified
345 .endm
346 #define EQUIV .thumb_set
347 .macro ARM_CALL name
348 bl __\name
349 .endm
351 #elif defined(__INTERWORKING_STUBS__)
353 .macro ARM_FUNC_START name
354 FUNC_START \name
355 bx pc
357 .arm
358 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
359 directly from other local arm routines. */
360 _L__\name:
361 .endm
362 #define EQUIV .thumb_set
363 /* Branch directly to a function declared with ARM_FUNC_START.
364 Must be called in arm mode. */
365 .macro ARM_CALL name
366 bl _L__\name
367 .endm
369 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
371 #ifdef __ARM_ARCH_6M__
372 #define EQUIV .thumb_set
373 #else
374 .macro ARM_FUNC_START name
375 .text
376 .globl SYM (__\name)
377 TYPE (__\name)
378 .align 0
379 .arm
380 SYM (__\name):
381 .endm
382 #define EQUIV .set
383 .macro ARM_CALL name
384 bl __\name
385 .endm
386 #endif
388 #endif
390 .macro FUNC_ALIAS new old
391 .globl SYM (__\new)
392 #if defined (__thumb__)
393 .thumb_set SYM (__\new), SYM (__\old)
394 #else
395 .set SYM (__\new), SYM (__\old)
396 #endif
397 .endm
399 #ifndef __ARM_ARCH_6M__
400 .macro ARM_FUNC_ALIAS new old
401 .globl SYM (__\new)
402 EQUIV SYM (__\new), SYM (__\old)
403 #if defined(__INTERWORKING_STUBS__)
404 .set SYM (_L__\new), SYM (_L__\old)
405 #endif
406 .endm
407 #endif
409 #ifdef __ARMEB__
410 #define xxh r0
411 #define xxl r1
412 #define yyh r2
413 #define yyl r3
414 #else
415 #define xxh r1
416 #define xxl r0
417 #define yyh r3
418 #define yyl r2
419 #endif
421 #ifdef __thumb__
422 /* Register aliases. */
424 work .req r4 @ XXXX is this safe ?
425 dividend .req r0
426 divisor .req r1
427 overdone .req r2
428 result .req r2
429 curbit .req r3
430 #endif
431 #if 0
432 ip .req r12
433 sp .req r13
434 lr .req r14
435 pc .req r15
436 #endif
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
450 mov \result, #0
451 addne pc, pc, \curbit, lsl #2
453 .set shift, 32
454 .rept 32
455 .set shift, shift - 1
456 cmp \dividend, \divisor, lsl #shift
457 adc \result, \result, \result
458 subcs \dividend, \dividend, \divisor, lsl #shift
459 .endr
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
467 mov \curbit, #1
468 mov \divisor, \divisor, lsl \result
469 mov \curbit, \curbit, lsl \result
470 mov \result, #0
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
480 moveq \curbit, #8
481 movne \curbit, #1
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
491 blo 1b
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
499 blo 1b
501 mov \result, #0
503 #endif /* __ARM_ARCH__ < 5 */
505 @ Division loop
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
521 bne 1b
523 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
525 .endm
526 /* ------------------------------------------------------------------------ */
527 .macro ARM_DIV2_ORDER divisor, order
529 #if __ARM_ARCH__ >= 5
531 clz \order, \divisor
532 rsb \order, \order, #31
534 #else
536 cmp \divisor, #(1 << 16)
537 movhs \divisor, \divisor, lsr #16
538 movhs \order, #16
539 movlo \order, #0
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
553 #endif
555 .endm
556 /* ------------------------------------------------------------------------ */
557 .macro ARM_MOD_BODY dividend, divisor, order, spare
559 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
561 clz \order, \divisor
562 clz \spare, \dividend
563 sub \order, \order, \spare
564 rsbs \order, \order, #31
565 addne pc, pc, \order, lsl #3
567 .set shift, 32
568 .rept 32
569 .set shift, shift - 1
570 cmp \dividend, \divisor, lsl #shift
571 subcs \dividend, \dividend, \divisor, lsl #shift
572 .endr
574 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
575 #if __ARM_ARCH__ >= 5
577 clz \order, \divisor
578 clz \spare, \dividend
579 sub \order, \order, \spare
580 mov \divisor, \divisor, lsl \order
582 #else /* __ARM_ARCH__ < 5 */
584 mov \order, #0
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
594 blo 1b
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
602 blo 1b
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
609 blt 2f
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
619 cmp \dividend, #1
620 mov \divisor, \divisor, lsr #4
621 subges \order, \order, #4
622 bge 1b
624 tst \order, #3
625 teqne \dividend, #0
626 beq 5f
628 @ Either 1, 2 or 3 comparison/substractions are left.
629 2: cmn \order, #2
630 blt 4f
631 beq 3f
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__) */
644 .endm
645 /* ------------------------------------------------------------------------ */
646 .macro THUMB_DIV_MOD_BODY modulo
647 @ Load the constant 0x10000000 into our work register.
648 mov work, #1
649 lsl work, #28
650 LSYM(Loop1):
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.
655 cmp divisor, work
656 bhs LSYM(Lbignum)
657 cmp divisor, dividend
658 bhs LSYM(Lbignum)
659 lsl divisor, #4
660 lsl curbit, #4
661 b LSYM(Loop1)
662 LSYM(Lbignum):
663 @ Set work to 0x80000000
664 lsl work, #3
665 LSYM(Loop2):
666 @ For very big divisors, we must shift it a bit at a time, or
667 @ we will be in danger of overflowing.
668 cmp divisor, work
669 bhs LSYM(Loop3)
670 cmp divisor, dividend
671 bhs LSYM(Loop3)
672 lsl divisor, #1
673 lsl curbit, #1
674 b LSYM(Loop2)
675 LSYM(Loop3):
676 @ Test for possible subtractions ...
677 .if \modulo
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
680 @ afterwards.
681 mov overdone, #0
682 cmp dividend, divisor
683 blo LSYM(Lover1)
684 sub dividend, dividend, divisor
685 LSYM(Lover1):
686 lsr work, divisor, #1
687 cmp dividend, work
688 blo LSYM(Lover2)
689 sub dividend, dividend, work
690 mov ip, curbit
691 mov work, #1
692 ror curbit, work
693 orr overdone, curbit
694 mov curbit, ip
695 LSYM(Lover2):
696 lsr work, divisor, #2
697 cmp dividend, work
698 blo LSYM(Lover3)
699 sub dividend, dividend, work
700 mov ip, curbit
701 mov work, #2
702 ror curbit, work
703 orr overdone, curbit
704 mov curbit, ip
705 LSYM(Lover3):
706 lsr work, divisor, #3
707 cmp dividend, work
708 blo LSYM(Lover4)
709 sub dividend, dividend, work
710 mov ip, curbit
711 mov work, #3
712 ror curbit, work
713 orr overdone, curbit
714 mov curbit, ip
715 LSYM(Lover4):
716 mov ip, curbit
717 .else
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
722 blo LSYM(Lover1)
723 sub dividend, dividend, divisor
724 orr result, result, curbit
725 LSYM(Lover1):
726 lsr work, divisor, #1
727 cmp dividend, work
728 blo LSYM(Lover2)
729 sub dividend, dividend, work
730 lsr work, curbit, #1
731 orr result, work
732 LSYM(Lover2):
733 lsr work, divisor, #2
734 cmp dividend, work
735 blo LSYM(Lover3)
736 sub dividend, dividend, work
737 lsr work, curbit, #2
738 orr result, work
739 LSYM(Lover3):
740 lsr work, divisor, #3
741 cmp dividend, work
742 blo LSYM(Lover4)
743 sub dividend, dividend, work
744 lsr work, curbit, #3
745 orr result, work
746 LSYM(Lover4):
747 .endif
749 cmp dividend, #0 @ Early termination?
750 beq LSYM(Lover5)
751 lsr curbit, #4 @ No, any more bits to do?
752 beq LSYM(Lover5)
753 lsr divisor, #4
754 b LSYM(Loop3)
755 LSYM(Lover5):
756 .if \modulo
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.
760 mov work, #0xe
761 lsl work, #28
762 and overdone, work
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.
771 mov curbit, ip
772 mov work, #0x7
773 tst curbit, work
774 beq LSYM(Lgot_result)
776 mov curbit, ip
777 mov work, #3
778 ror curbit, work
779 tst overdone, curbit
780 beq LSYM(Lover6)
781 lsr work, divisor, #3
782 add dividend, work
783 LSYM(Lover6):
784 mov curbit, ip
785 mov work, #2
786 ror curbit, work
787 tst overdone, curbit
788 beq LSYM(Lover7)
789 lsr work, divisor, #2
790 add dividend, work
791 LSYM(Lover7):
792 mov curbit, ip
793 mov work, #1
794 ror curbit, work
795 tst overdone, curbit
796 beq LSYM(Lgot_result)
797 lsr work, divisor, #1
798 add dividend, work
799 .endif
800 LSYM(Lgot_result):
801 .endm
802 /* ------------------------------------------------------------------------ */
803 /* Start of the Real Functions */
804 /* ------------------------------------------------------------------------ */
805 #ifdef L_udivsi3
807 FUNC_START udivsi3
808 FUNC_ALIAS aeabi_uidiv udivsi3
810 #ifdef __thumb__
812 cmp divisor, #0
813 beq LSYM(Ldiv0)
814 mov curbit, #1
815 mov result, #0
817 push { work }
818 cmp dividend, divisor
819 blo LSYM(Lgot_result)
821 THUMB_DIV_MOD_BODY 0
823 mov r0, result
824 pop { work }
827 #else /* ARM version. */
829 subs r2, r1, #1
830 RETc(eq)
831 bcc LSYM(Ldiv0)
832 cmp r0, r1
833 bls 11f
834 tst r1, r2
835 beq 12f
837 ARM_DIV_BODY r0, r1, r2, r3
839 mov r0, r2
840 RET
842 11: moveq r0, #1
843 movne r0, #0
846 12: ARM_DIV2_ORDER r1, r2
848 mov r0, r0, lsr r2
851 #endif /* ARM version */
853 DIV_FUNC_END udivsi3
855 FUNC_START aeabi_uidivmod
856 #ifdef __thumb__
857 push {r0, r1, lr}
858 bl SYM(__udivsi3)
859 POP {r1, r2, r3}
860 mul r2, r0
861 sub r1, r1, r2
862 bx r3
863 #else
864 stmfd sp!, { r0, r1, lr }
865 bl SYM(__udivsi3)
866 ldmfd sp!, { r1, r2, lr }
867 mul r3, r2, r0
868 sub r1, r1, r3
870 #endif
871 FUNC_END aeabi_uidivmod
873 #endif /* L_udivsi3 */
874 /* ------------------------------------------------------------------------ */
875 #ifdef L_umodsi3
877 FUNC_START umodsi3
879 #ifdef __thumb__
881 cmp divisor, #0
882 beq LSYM(Ldiv0)
883 mov curbit, #1
884 cmp dividend, divisor
885 bhs LSYM(Lover10)
886 RET
888 LSYM(Lover10):
889 push { work }
891 THUMB_DIV_MOD_BODY 1
893 pop { work }
896 #else /* ARM version. */
898 subs r2, r1, #1 @ compare divisor with 1
899 bcc LSYM(Ldiv0)
900 cmpne r0, r1 @ compare dividend with divisor
901 moveq r0, #0
902 tsthi r1, r2 @ see if divisor is power of 2
903 andeq r0, r0, r2
904 RETc(ls)
906 ARM_MOD_BODY r0, r1, r2, r3
908 RET
910 #endif /* ARM version. */
912 DIV_FUNC_END umodsi3
914 #endif /* L_umodsi3 */
915 /* ------------------------------------------------------------------------ */
916 #ifdef L_divsi3
918 FUNC_START divsi3
919 FUNC_ALIAS aeabi_idiv divsi3
921 #ifdef __thumb__
922 cmp divisor, #0
923 beq LSYM(Ldiv0)
925 push { work }
926 mov work, dividend
927 eor work, divisor @ Save the sign of the result.
928 mov ip, work
929 mov curbit, #1
930 mov result, #0
931 cmp divisor, #0
932 bpl LSYM(Lover10)
933 neg divisor, divisor @ Loops below use unsigned.
934 LSYM(Lover10):
935 cmp dividend, #0
936 bpl LSYM(Lover11)
937 neg dividend, dividend
938 LSYM(Lover11):
939 cmp dividend, divisor
940 blo LSYM(Lgot_result)
942 THUMB_DIV_MOD_BODY 0
944 mov r0, result
945 mov work, ip
946 cmp work, #0
947 bpl LSYM(Lover12)
948 neg r0, r0
949 LSYM(Lover12):
950 pop { work }
953 #else /* ARM version. */
955 cmp r1, #0
956 eor ip, r0, r1 @ save the sign of the result.
957 beq LSYM(Ldiv0)
958 rsbmi r1, r1, #0 @ loops below use unsigned.
959 subs r2, r1, #1 @ division by 1 or -1 ?
960 beq 10f
961 movs r3, r0
962 rsbmi r3, r0, #0 @ positive dividend value
963 cmp r3, r1
964 bls 11f
965 tst r1, r2 @ divisor is power of 2 ?
966 beq 12f
968 ARM_DIV_BODY r3, r1, r0, r2
970 cmp ip, #0
971 rsbmi r0, r0, #0
972 RET
974 10: teq ip, r0 @ same sign ?
975 rsbmi r0, r0, #0
976 RET
978 11: movlo r0, #0
979 moveq r0, ip, asr #31
980 orreq r0, r0, #1
983 12: ARM_DIV2_ORDER r1, r2
985 cmp ip, #0
986 mov r0, r3, lsr r2
987 rsbmi r0, r0, #0
990 #endif /* ARM version */
992 DIV_FUNC_END divsi3
994 FUNC_START aeabi_idivmod
995 #ifdef __thumb__
996 push {r0, r1, lr}
997 bl SYM(__divsi3)
998 POP {r1, r2, r3}
999 mul r2, r0
1000 sub r1, r1, r2
1001 bx r3
1002 #else
1003 stmfd sp!, { r0, r1, lr }
1004 bl SYM(__divsi3)
1005 ldmfd sp!, { r1, r2, lr }
1006 mul r3, r2, r0
1007 sub r1, r1, r3
1009 #endif
1010 FUNC_END aeabi_idivmod
1012 #endif /* L_divsi3 */
1013 /* ------------------------------------------------------------------------ */
1014 #ifdef L_modsi3
1016 FUNC_START modsi3
1018 #ifdef __thumb__
1020 mov curbit, #1
1021 cmp divisor, #0
1022 beq LSYM(Ldiv0)
1023 bpl LSYM(Lover10)
1024 neg divisor, divisor @ Loops below use unsigned.
1025 LSYM(Lover10):
1026 push { work }
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.
1030 push { dividend }
1031 cmp dividend, #0
1032 bpl LSYM(Lover11)
1033 neg dividend, dividend
1034 LSYM(Lover11):
1035 cmp dividend, divisor
1036 blo LSYM(Lgot_result)
1038 THUMB_DIV_MOD_BODY 1
1040 pop { work }
1041 cmp work, #0
1042 bpl LSYM(Lover12)
1043 neg dividend, dividend
1044 LSYM(Lover12):
1045 pop { work }
1046 RET
1048 #else /* ARM version. */
1050 cmp r1, #0
1051 beq LSYM(Ldiv0)
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
1057 moveq r0, #0
1058 tsthi r1, r2 @ see if divisor is power of 2
1059 andeq r0, r0, r2
1060 bls 10f
1062 ARM_MOD_BODY r0, r1, r2, r3
1064 10: cmp ip, #0
1065 rsbmi r0, r0, #0
1066 RET
1068 #endif /* ARM version */
1070 DIV_FUNC_END modsi3
1072 #endif /* L_modsi3 */
1073 /* ------------------------------------------------------------------------ */
1074 #ifdef L_dvmd_tls
1076 FUNC_START div0
1077 FUNC_ALIAS aeabi_idiv0 div0
1078 FUNC_ALIAS aeabi_ldiv0 div0
1082 FUNC_END aeabi_ldiv0
1083 FUNC_END aeabi_idiv0
1084 FUNC_END div0
1086 #endif /* L_divmodsi_tools */
1087 /* ------------------------------------------------------------------------ */
1088 #ifdef L_dvmd_lnx
1089 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
1091 /* Constant taken from <asm/signal.h>. */
1092 #define SIGFPE 8
1094 ARM_FUNC_START div0
1096 do_push {r1, lr}
1097 mov r0, #SIGFPE
1098 bl SYM(raise) __PLT__
1099 RETLDM r1
1101 FUNC_END div0
1103 #endif /* L_dvmd_lnx */
1104 /* ------------------------------------------------------------------------ */
1105 /* Dword shift operations. */
1106 /* All the following Dword shift variants rely on the fact that
1107 shft xxx, Reg
1108 is in fact done as
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). */
1113 #ifdef __ARMEB__
1114 #define al r1
1115 #define ah r0
1116 #else
1117 #define al r0
1118 #define ah r1
1119 #endif
1121 /* Prevent __aeabi double-word shifts from being produced on SymbianOS. */
1122 #ifndef __symbian__
1124 #ifdef L_lshrdi3
1126 FUNC_START lshrdi3
1127 FUNC_ALIAS aeabi_llsr lshrdi3
1129 #ifdef __thumb__
1130 lsr al, r2
1131 mov r3, ah
1132 lsr ah, r2
1133 mov ip, r3
1134 sub r2, #32
1135 lsr r3, r2
1136 orr al, r3
1137 neg r2, r2
1138 mov r3, ip
1139 lsl r3, r2
1140 orr al, r3
1142 #else
1143 subs r3, r2, #32
1144 rsb ip, r2, #32
1145 movmi al, al, lsr r2
1146 movpl al, ah, lsr r3
1147 orrmi al, al, ah, lsl ip
1148 mov ah, ah, lsr r2
1150 #endif
1151 FUNC_END aeabi_llsr
1152 FUNC_END lshrdi3
1154 #endif
1156 #ifdef L_ashrdi3
1158 FUNC_START ashrdi3
1159 FUNC_ALIAS aeabi_lasr ashrdi3
1161 #ifdef __thumb__
1162 lsr al, r2
1163 mov r3, ah
1164 asr ah, r2
1165 sub r2, #32
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...
1168 bmi 1f
1169 mov ip, r3
1170 asr r3, r2
1171 orr al, r3
1172 mov r3, ip
1174 neg r2, r2
1175 lsl r3, r2
1176 orr al, r3
1178 #else
1179 subs r3, r2, #32
1180 rsb ip, r2, #32
1181 movmi al, al, lsr r2
1182 movpl al, ah, asr r3
1183 orrmi al, al, ah, lsl ip
1184 mov ah, ah, asr r2
1186 #endif
1188 FUNC_END aeabi_lasr
1189 FUNC_END ashrdi3
1191 #endif
1193 #ifdef L_ashldi3
1195 FUNC_START ashldi3
1196 FUNC_ALIAS aeabi_llsl ashldi3
1198 #ifdef __thumb__
1199 lsl ah, r2
1200 mov r3, al
1201 lsl al, r2
1202 mov ip, r3
1203 sub r2, #32
1204 lsl r3, r2
1205 orr ah, r3
1206 neg r2, r2
1207 mov r3, ip
1208 lsr r3, r2
1209 orr ah, r3
1211 #else
1212 subs r3, r2, #32
1213 rsb ip, r2, #32
1214 movmi ah, ah, lsl r2
1215 movpl ah, al, lsl r3
1216 orrmi ah, ah, al, lsr ip
1217 mov al, al, lsl r2
1219 #endif
1220 FUNC_END aeabi_llsl
1221 FUNC_END ashldi3
1223 #endif
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
1231 #endif
1233 #ifdef L_clzsi2
1234 #if defined(__ARM_ARCH_6M__)
1235 FUNC_START clzsi2
1236 mov r1, #28
1237 mov r3, #1
1238 lsl r3, r3, #16
1239 cmp r0, r3 /* 0x10000 */
1240 bcc 2f
1241 lsr r0, r0, #16
1242 sub r1, r1, #16
1243 2: lsr r3, r3, #8
1244 cmp r0, r3 /* #0x100 */
1245 bcc 2f
1246 lsr r0, r0, #8
1247 sub r1, r1, #8
1248 2: lsr r3, r3, #4
1249 cmp r0, r3 /* #0x10 */
1250 bcc 2f
1251 lsr r0, r0, #4
1252 sub r1, r1, #4
1253 2: adr r2, 1f
1254 ldrb r0, [r2, r0]
1255 add r0, r0, r1
1256 bx lr
1257 .align 2
1259 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1260 FUNC_END clzsi2
1261 #else
1262 ARM_FUNC_START clzsi2
1263 # if defined(HAVE_ARM_CLZ)
1264 clz r0, r0
1266 # else
1267 mov r1, #28
1268 cmp r0, #0x10000
1269 do_it cs, t
1270 movcs r0, r0, lsr #16
1271 subcs r1, r1, #16
1272 cmp r0, #0x100
1273 do_it cs, t
1274 movcs r0, r0, lsr #8
1275 subcs r1, r1, #8
1276 cmp r0, #0x10
1277 do_it cs, t
1278 movcs r0, r0, lsr #4
1279 subcs r1, r1, #4
1280 adr r2, 1f
1281 ldrb r0, [r2, r0]
1282 add r0, r0, r1
1283 bx lr
1284 .align 2
1286 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1287 # endif /* !HAVE_ARM_CLZ */
1288 FUNC_END clzsi2
1289 #endif
1290 #endif /* L_clzsi2 */
1292 #ifdef L_clzdi2
1293 #if !defined(HAVE_ARM_CLZ)
1295 # if defined(__ARM_ARCH_6M__)
1296 FUNC_START clzdi2
1297 push {r4, lr}
1298 # else
1299 ARM_FUNC_START clzdi2
1300 do_push {r4, lr}
1301 # endif
1302 cmp xxh, #0
1303 bne 1f
1304 # ifdef __ARMEB__
1305 mov r0, xxl
1306 bl __clzsi2
1307 add r0, r0, #32
1308 b 2f
1310 bl __clzsi2
1311 # else
1312 bl __clzsi2
1313 add r0, r0, #32
1314 b 2f
1316 mov r0, xxh
1317 bl __clzsi2
1318 # endif
1320 # if defined(__ARM_ARCH_6M__)
1321 pop {r4, pc}
1322 # else
1323 RETLDM r4
1324 # endif
1325 FUNC_END clzdi2
1327 #else /* HAVE_ARM_CLZ */
1329 ARM_FUNC_START clzdi2
1330 cmp xxh, #0
1331 do_it eq, et
1332 clzeq r0, xxl
1333 clzne r0, xxh
1334 addeq r0, r0, #32
1336 FUNC_END clzdi2
1338 #endif
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. */
1360 .text
1361 .align 0
1362 .force_thumb
1364 .macro call_via register
1365 THUMB_FUNC_START _call_via_\register
1367 bx \register
1370 SIZE (_call_via_\register)
1371 .endm
1373 call_via r0
1374 call_via r1
1375 call_via r2
1376 call_via r3
1377 call_via r4
1378 call_via r5
1379 call_via r6
1380 call_via r7
1381 call_via r8
1382 call_via r9
1383 call_via sl
1384 call_via fp
1385 call_via ip
1386 call_via sp
1387 call_via lr
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. */
1421 .text
1422 .align 0
1424 .code 32
1425 .globl _arm_return
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.
1431 _arm_return:
1432 RETLDM unwind=LSYM(Lstart_arm_return)
1433 cfi_end LSYM(Lend_arm_return)
1435 .globl _arm_return_r7
1436 _arm_return_r7:
1437 ldr lr, [r7, #-4]
1438 bx lr
1440 .globl _arm_return_r11
1441 _arm_return_r11:
1442 ldr lr, [r11, #-4]
1443 bx lr
1445 .macro interwork_with_frame frame, register, name, return
1446 .code 16
1448 THUMB_FUNC_START \name
1450 bx pc
1453 .code 32
1454 tst \register, #1
1455 streq lr, [\frame, #-4]
1456 adreq lr, _arm_return_\frame
1457 bx \register
1459 SIZE (\name)
1460 .endm
1462 .macro interwork register
1463 .code 16
1465 THUMB_FUNC_START _interwork_call_via_\register
1467 bx pc
1470 .code 32
1471 .globl LSYM(Lchange_\register)
1472 LSYM(Lchange_\register):
1473 tst \register, #1
1474 streq lr, [sp, #-8]!
1475 adreq lr, _arm_return
1476 bx \register
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
1482 .endm
1484 interwork r0
1485 interwork r1
1486 interwork r2
1487 interwork r3
1488 interwork r4
1489 interwork r5
1490 interwork r6
1491 interwork r7
1492 interwork r8
1493 interwork r9
1494 interwork sl
1495 interwork fp
1496 interwork ip
1497 interwork sp
1499 /* The LR case has to be handled a little differently... */
1500 .code 16
1502 THUMB_FUNC_START _interwork_call_via_lr
1504 bx pc
1507 .code 32
1508 .globl .Lchange_lr
1509 .Lchange_lr:
1510 tst lr, #1
1511 stmeqdb r13!, {lr, pc}
1512 mov ip, lr
1513 adreq lr, _arm_return
1514 bx ip
1516 SIZE (_interwork_call_via_lr)
1518 #endif /* L_interwork_call_via_rX */
1519 #endif /* !__thumb2__ */
1520 #endif /* Arch supports thumb. */
1522 #ifndef __symbian__
1523 #ifndef __ARM_ARCH_6M__
1524 #include "ieee754-df.S"
1525 #include "ieee754-sf.S"
1526 #include "bpabi.S"
1527 #else /* __ARM_ARCH_6M__ */
1528 #include "bpabi-v6m.S"
1529 #endif /* __ARM_ARCH_6M__ */
1530 #endif /* !__symbian__ */