2005-08-12 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / config / arm / lib1funcs.asm
blob952eb562a92c96d9f789582127868165fd4649ea
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
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. */
30 /* ------------------------------------------------------------------------ */
32 /* We need to know what prefix to add to function names. */
34 #ifndef __USER_LABEL_PREFIX__
35 #error __USER_LABEL_PREFIX__ not defined
36 #endif
38 /* ANSI concatenation macros. */
40 #define CONCAT1(a, b) CONCAT2(a, b)
41 #define CONCAT2(a, b) a ## b
43 /* Use the right prefix for global labels. */
45 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
47 #ifdef __ELF__
48 #ifdef __thumb__
49 #define __PLT__ /* Not supported in Thumb assembler (for now). */
50 #else
51 #define __PLT__ (PLT)
52 #endif
53 #define TYPE(x) .type SYM(x),function
54 #define SIZE(x) .size SYM(x), . - SYM(x)
55 #define LSYM(x) .x
56 #else
57 #define __PLT__
58 #define TYPE(x)
59 #define SIZE(x)
60 #define LSYM(x) x
61 #endif
63 /* Function end macros. Variants for interworking. */
65 @ This selects the minimum architecture level required.
66 #define __ARM_ARCH__ 3
68 #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
69 || defined(__ARM_ARCH_4T__)
70 /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
71 long multiply instructions. That includes v3M. */
72 # undef __ARM_ARCH__
73 # define __ARM_ARCH__ 4
74 #endif
76 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
77 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
78 || defined(__ARM_ARCH_5TEJ__)
79 # undef __ARM_ARCH__
80 # define __ARM_ARCH__ 5
81 #endif
83 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
84 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
85 || defined(__ARM_ARCH_6ZK__)
86 # undef __ARM_ARCH__
87 # define __ARM_ARCH__ 6
88 #endif
90 #ifndef __ARM_ARCH__
91 #error Unable to determine architecture.
92 #endif
94 /* How to return from a function call depends on the architecture variant. */
96 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
98 # define RET bx lr
99 # define RETc(x) bx##x lr
101 /* Special precautions for interworking on armv4t. */
102 # if (__ARM_ARCH__ == 4)
104 /* Always use bx, not ldr pc. */
105 # if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
106 # define __INTERWORKING__
107 # endif /* __THUMB__ || __THUMB_INTERWORK__ */
109 /* Include thumb stub before arm mode code. */
110 # if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
111 # define __INTERWORKING_STUBS__
112 # endif /* __thumb__ && !__THUMB_INTERWORK__ */
114 #endif /* __ARM_ARCH == 4 */
116 #else
118 # define RET mov pc, lr
119 # define RETc(x) mov##x pc, lr
121 #endif
123 .macro cfi_pop advance, reg, cfa_offset
124 #ifdef __ELF__
125 .pushsection .debug_frame
126 .byte 0x4 /* DW_CFA_advance_loc4 */
127 .4byte \advance
128 .byte (0xc0 | \reg) /* DW_CFA_restore */
129 .byte 0xe /* DW_CFA_def_cfa_offset */
130 .uleb128 \cfa_offset
131 .popsection
132 #endif
133 .endm
134 .macro cfi_push advance, reg, offset, cfa_offset
135 #ifdef __ELF__
136 .pushsection .debug_frame
137 .byte 0x4 /* DW_CFA_advance_loc4 */
138 .4byte \advance
139 .byte (0x80 | \reg) /* DW_CFA_offset */
140 .uleb128 (\offset / -4)
141 .byte 0xe /* DW_CFA_def_cfa_offset */
142 .uleb128 \cfa_offset
143 .popsection
144 #endif
145 .endm
146 .macro cfi_start start_label, end_label
147 #ifdef __ELF__
148 .pushsection .debug_frame
149 LSYM(Lstart_frame):
150 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
151 LSYM(Lstart_cie):
152 .4byte 0xffffffff @ CIE Identifier Tag
153 .byte 0x1 @ CIE Version
154 .ascii "\0" @ CIE Augmentation
155 .uleb128 0x1 @ CIE Code Alignment Factor
156 .sleb128 -4 @ CIE Data Alignment Factor
157 .byte 0xe @ CIE RA Column
158 .byte 0xc @ DW_CFA_def_cfa
159 .uleb128 0xd
160 .uleb128 0x0
162 .align 2
163 LSYM(Lend_cie):
164 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
165 LSYM(Lstart_fde):
166 .4byte LSYM(Lstart_frame) @ FDE CIE offset
167 .4byte \start_label @ FDE initial location
168 .4byte \end_label-\start_label @ FDE address range
169 .popsection
170 #endif
171 .endm
172 .macro cfi_end end_label
173 #ifdef __ELF__
174 .pushsection .debug_frame
175 .align 2
176 LSYM(Lend_fde):
177 .popsection
178 \end_label:
179 #endif
180 .endm
182 /* Don't pass dirn, it's there just to get token pasting right. */
184 .macro RETLDM regs=, cond=, unwind=, dirn=ia
185 #if defined (__INTERWORKING__)
186 .ifc "\regs",""
187 ldr\cond lr, [sp], #8
188 .else
189 ldm\cond\dirn sp!, {\regs, lr}
190 .endif
191 .ifnc "\unwind", ""
192 /* Mark LR as restored. */
193 97: cfi_pop 97b - \unwind, 0xe, 0x0
194 .endif
195 bx\cond lr
196 #else
197 .ifc "\regs",""
198 ldr\cond pc, [sp], #8
199 .else
200 ldm\cond\dirn sp!, {\regs, pc}
201 .endif
202 #endif
203 .endm
206 .macro ARM_LDIV0 name
207 str lr, [sp, #-8]!
208 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
209 bl SYM (__div0) __PLT__
210 mov r0, #0 @ About as wrong as it could be.
211 RETLDM unwind=98b
212 .endm
215 .macro THUMB_LDIV0 name
216 push { r1, lr }
217 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
218 bl SYM (__div0)
219 mov r0, #0 @ About as wrong as it could be.
220 #if defined (__INTERWORKING__)
221 pop { r1, r2 }
222 bx r2
223 #else
224 pop { r1, pc }
225 #endif
226 .endm
228 .macro FUNC_END name
229 SIZE (__\name)
230 .endm
232 .macro DIV_FUNC_END name
233 cfi_start __\name, LSYM(Lend_div0)
234 LSYM(Ldiv0):
235 #ifdef __thumb__
236 THUMB_LDIV0 \name
237 #else
238 ARM_LDIV0 \name
239 #endif
240 cfi_end LSYM(Lend_div0)
241 FUNC_END \name
242 .endm
244 .macro THUMB_FUNC_START name
245 .globl SYM (\name)
246 TYPE (\name)
247 .thumb_func
248 SYM (\name):
249 .endm
251 /* Function start macros. Variants for ARM and Thumb. */
253 #ifdef __thumb__
254 #define THUMB_FUNC .thumb_func
255 #define THUMB_CODE .force_thumb
256 #else
257 #define THUMB_FUNC
258 #define THUMB_CODE
259 #endif
261 .macro FUNC_START name
262 .text
263 .globl SYM (__\name)
264 TYPE (__\name)
265 .align 0
266 THUMB_CODE
267 THUMB_FUNC
268 SYM (__\name):
269 .endm
271 /* Special function that will always be coded in ARM assembly, even if
272 in Thumb-only compilation. */
274 #if defined(__INTERWORKING_STUBS__)
275 .macro ARM_FUNC_START name
276 FUNC_START \name
277 bx pc
279 .arm
280 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
281 directly from other local arm routines. */
282 _L__\name:
283 .endm
284 #define EQUIV .thumb_set
285 /* Branch directly to a function declared with ARM_FUNC_START.
286 Must be called in arm mode. */
287 .macro ARM_CALL name
288 bl _L__\name
289 .endm
290 #else
291 .macro ARM_FUNC_START name
292 .text
293 .globl SYM (__\name)
294 TYPE (__\name)
295 .align 0
296 .arm
297 SYM (__\name):
298 .endm
299 #define EQUIV .set
300 .macro ARM_CALL name
301 bl __\name
302 .endm
303 #endif
305 .macro FUNC_ALIAS new old
306 .globl SYM (__\new)
307 #if defined (__thumb__)
308 .thumb_set SYM (__\new), SYM (__\old)
309 #else
310 .set SYM (__\new), SYM (__\old)
311 #endif
312 .endm
314 .macro ARM_FUNC_ALIAS new old
315 .globl SYM (__\new)
316 EQUIV SYM (__\new), SYM (__\old)
317 #if defined(__INTERWORKING_STUBS__)
318 .set SYM (_L__\new), SYM (_L__\old)
319 #endif
320 .endm
322 #ifdef __thumb__
323 /* Register aliases. */
325 work .req r4 @ XXXX is this safe ?
326 dividend .req r0
327 divisor .req r1
328 overdone .req r2
329 result .req r2
330 curbit .req r3
331 #endif
332 #if 0
333 ip .req r12
334 sp .req r13
335 lr .req r14
336 pc .req r15
337 #endif
339 /* ------------------------------------------------------------------------ */
340 /* Bodies of the division and modulo routines. */
341 /* ------------------------------------------------------------------------ */
342 .macro ARM_DIV_BODY dividend, divisor, result, curbit
344 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
346 clz \curbit, \dividend
347 clz \result, \divisor
348 sub \curbit, \result, \curbit
349 rsbs \curbit, \curbit, #31
350 addne \curbit, \curbit, \curbit, lsl #1
351 mov \result, #0
352 addne pc, pc, \curbit, lsl #2
354 .set shift, 32
355 .rept 32
356 .set shift, shift - 1
357 cmp \dividend, \divisor, lsl #shift
358 adc \result, \result, \result
359 subcs \dividend, \dividend, \divisor, lsl #shift
360 .endr
362 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
363 #if __ARM_ARCH__ >= 5
365 clz \curbit, \divisor
366 clz \result, \dividend
367 sub \result, \curbit, \result
368 mov \curbit, #1
369 mov \divisor, \divisor, lsl \result
370 mov \curbit, \curbit, lsl \result
371 mov \result, #0
373 #else /* __ARM_ARCH__ < 5 */
375 @ Initially shift the divisor left 3 bits if possible,
376 @ set curbit accordingly. This allows for curbit to be located
377 @ at the left end of each 4 bit nibbles in the division loop
378 @ to save one loop in most cases.
379 tst \divisor, #0xe0000000
380 moveq \divisor, \divisor, lsl #3
381 moveq \curbit, #8
382 movne \curbit, #1
384 @ Unless the divisor is very big, shift it up in multiples of
385 @ four bits, since this is the amount of unwinding in the main
386 @ division loop. Continue shifting until the divisor is
387 @ larger than the dividend.
388 1: cmp \divisor, #0x10000000
389 cmplo \divisor, \dividend
390 movlo \divisor, \divisor, lsl #4
391 movlo \curbit, \curbit, lsl #4
392 blo 1b
394 @ For very big divisors, we must shift it a bit at a time, or
395 @ we will be in danger of overflowing.
396 1: cmp \divisor, #0x80000000
397 cmplo \divisor, \dividend
398 movlo \divisor, \divisor, lsl #1
399 movlo \curbit, \curbit, lsl #1
400 blo 1b
402 mov \result, #0
404 #endif /* __ARM_ARCH__ < 5 */
406 @ Division loop
407 1: cmp \dividend, \divisor
408 subhs \dividend, \dividend, \divisor
409 orrhs \result, \result, \curbit
410 cmp \dividend, \divisor, lsr #1
411 subhs \dividend, \dividend, \divisor, lsr #1
412 orrhs \result, \result, \curbit, lsr #1
413 cmp \dividend, \divisor, lsr #2
414 subhs \dividend, \dividend, \divisor, lsr #2
415 orrhs \result, \result, \curbit, lsr #2
416 cmp \dividend, \divisor, lsr #3
417 subhs \dividend, \dividend, \divisor, lsr #3
418 orrhs \result, \result, \curbit, lsr #3
419 cmp \dividend, #0 @ Early termination?
420 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
421 movne \divisor, \divisor, lsr #4
422 bne 1b
424 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
426 .endm
427 /* ------------------------------------------------------------------------ */
428 .macro ARM_DIV2_ORDER divisor, order
430 #if __ARM_ARCH__ >= 5
432 clz \order, \divisor
433 rsb \order, \order, #31
435 #else
437 cmp \divisor, #(1 << 16)
438 movhs \divisor, \divisor, lsr #16
439 movhs \order, #16
440 movlo \order, #0
442 cmp \divisor, #(1 << 8)
443 movhs \divisor, \divisor, lsr #8
444 addhs \order, \order, #8
446 cmp \divisor, #(1 << 4)
447 movhs \divisor, \divisor, lsr #4
448 addhs \order, \order, #4
450 cmp \divisor, #(1 << 2)
451 addhi \order, \order, #3
452 addls \order, \order, \divisor, lsr #1
454 #endif
456 .endm
457 /* ------------------------------------------------------------------------ */
458 .macro ARM_MOD_BODY dividend, divisor, order, spare
460 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
462 clz \order, \divisor
463 clz \spare, \dividend
464 sub \order, \order, \spare
465 rsbs \order, \order, #31
466 addne pc, pc, \order, lsl #3
468 .set shift, 32
469 .rept 32
470 .set shift, shift - 1
471 cmp \dividend, \divisor, lsl #shift
472 subcs \dividend, \dividend, \divisor, lsl #shift
473 .endr
475 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
476 #if __ARM_ARCH__ >= 5
478 clz \order, \divisor
479 clz \spare, \dividend
480 sub \order, \order, \spare
481 mov \divisor, \divisor, lsl \order
483 #else /* __ARM_ARCH__ < 5 */
485 mov \order, #0
487 @ Unless the divisor is very big, shift it up in multiples of
488 @ four bits, since this is the amount of unwinding in the main
489 @ division loop. Continue shifting until the divisor is
490 @ larger than the dividend.
491 1: cmp \divisor, #0x10000000
492 cmplo \divisor, \dividend
493 movlo \divisor, \divisor, lsl #4
494 addlo \order, \order, #4
495 blo 1b
497 @ For very big divisors, we must shift it a bit at a time, or
498 @ we will be in danger of overflowing.
499 1: cmp \divisor, #0x80000000
500 cmplo \divisor, \dividend
501 movlo \divisor, \divisor, lsl #1
502 addlo \order, \order, #1
503 blo 1b
505 #endif /* __ARM_ARCH__ < 5 */
507 @ Perform all needed substractions to keep only the reminder.
508 @ Do comparisons in batch of 4 first.
509 subs \order, \order, #3 @ yes, 3 is intended here
510 blt 2f
512 1: cmp \dividend, \divisor
513 subhs \dividend, \dividend, \divisor
514 cmp \dividend, \divisor, lsr #1
515 subhs \dividend, \dividend, \divisor, lsr #1
516 cmp \dividend, \divisor, lsr #2
517 subhs \dividend, \dividend, \divisor, lsr #2
518 cmp \dividend, \divisor, lsr #3
519 subhs \dividend, \dividend, \divisor, lsr #3
520 cmp \dividend, #1
521 mov \divisor, \divisor, lsr #4
522 subges \order, \order, #4
523 bge 1b
525 tst \order, #3
526 teqne \dividend, #0
527 beq 5f
529 @ Either 1, 2 or 3 comparison/substractions are left.
530 2: cmn \order, #2
531 blt 4f
532 beq 3f
533 cmp \dividend, \divisor
534 subhs \dividend, \dividend, \divisor
535 mov \divisor, \divisor, lsr #1
536 3: cmp \dividend, \divisor
537 subhs \dividend, \dividend, \divisor
538 mov \divisor, \divisor, lsr #1
539 4: cmp \dividend, \divisor
540 subhs \dividend, \dividend, \divisor
543 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
545 .endm
546 /* ------------------------------------------------------------------------ */
547 .macro THUMB_DIV_MOD_BODY modulo
548 @ Load the constant 0x10000000 into our work register.
549 mov work, #1
550 lsl work, #28
551 LSYM(Loop1):
552 @ Unless the divisor is very big, shift it up in multiples of
553 @ four bits, since this is the amount of unwinding in the main
554 @ division loop. Continue shifting until the divisor is
555 @ larger than the dividend.
556 cmp divisor, work
557 bhs LSYM(Lbignum)
558 cmp divisor, dividend
559 bhs LSYM(Lbignum)
560 lsl divisor, #4
561 lsl curbit, #4
562 b LSYM(Loop1)
563 LSYM(Lbignum):
564 @ Set work to 0x80000000
565 lsl work, #3
566 LSYM(Loop2):
567 @ For very big divisors, we must shift it a bit at a time, or
568 @ we will be in danger of overflowing.
569 cmp divisor, work
570 bhs LSYM(Loop3)
571 cmp divisor, dividend
572 bhs LSYM(Loop3)
573 lsl divisor, #1
574 lsl curbit, #1
575 b LSYM(Loop2)
576 LSYM(Loop3):
577 @ Test for possible subtractions ...
578 .if \modulo
579 @ ... On the final pass, this may subtract too much from the dividend,
580 @ so keep track of which subtractions are done, we can fix them up
581 @ afterwards.
582 mov overdone, #0
583 cmp dividend, divisor
584 blo LSYM(Lover1)
585 sub dividend, dividend, divisor
586 LSYM(Lover1):
587 lsr work, divisor, #1
588 cmp dividend, work
589 blo LSYM(Lover2)
590 sub dividend, dividend, work
591 mov ip, curbit
592 mov work, #1
593 ror curbit, work
594 orr overdone, curbit
595 mov curbit, ip
596 LSYM(Lover2):
597 lsr work, divisor, #2
598 cmp dividend, work
599 blo LSYM(Lover3)
600 sub dividend, dividend, work
601 mov ip, curbit
602 mov work, #2
603 ror curbit, work
604 orr overdone, curbit
605 mov curbit, ip
606 LSYM(Lover3):
607 lsr work, divisor, #3
608 cmp dividend, work
609 blo LSYM(Lover4)
610 sub dividend, dividend, work
611 mov ip, curbit
612 mov work, #3
613 ror curbit, work
614 orr overdone, curbit
615 mov curbit, ip
616 LSYM(Lover4):
617 mov ip, curbit
618 .else
619 @ ... and note which bits are done in the result. On the final pass,
620 @ this may subtract too much from the dividend, but the result will be ok,
621 @ since the "bit" will have been shifted out at the bottom.
622 cmp dividend, divisor
623 blo LSYM(Lover1)
624 sub dividend, dividend, divisor
625 orr result, result, curbit
626 LSYM(Lover1):
627 lsr work, divisor, #1
628 cmp dividend, work
629 blo LSYM(Lover2)
630 sub dividend, dividend, work
631 lsr work, curbit, #1
632 orr result, work
633 LSYM(Lover2):
634 lsr work, divisor, #2
635 cmp dividend, work
636 blo LSYM(Lover3)
637 sub dividend, dividend, work
638 lsr work, curbit, #2
639 orr result, work
640 LSYM(Lover3):
641 lsr work, divisor, #3
642 cmp dividend, work
643 blo LSYM(Lover4)
644 sub dividend, dividend, work
645 lsr work, curbit, #3
646 orr result, work
647 LSYM(Lover4):
648 .endif
650 cmp dividend, #0 @ Early termination?
651 beq LSYM(Lover5)
652 lsr curbit, #4 @ No, any more bits to do?
653 beq LSYM(Lover5)
654 lsr divisor, #4
655 b LSYM(Loop3)
656 LSYM(Lover5):
657 .if \modulo
658 @ Any subtractions that we should not have done will be recorded in
659 @ the top three bits of "overdone". Exactly which were not needed
660 @ are governed by the position of the bit, stored in ip.
661 mov work, #0xe
662 lsl work, #28
663 and overdone, work
664 beq LSYM(Lgot_result)
666 @ If we terminated early, because dividend became zero, then the
667 @ bit in ip will not be in the bottom nibble, and we should not
668 @ perform the additions below. We must test for this though
669 @ (rather relying upon the TSTs to prevent the additions) since
670 @ the bit in ip could be in the top two bits which might then match
671 @ with one of the smaller RORs.
672 mov curbit, ip
673 mov work, #0x7
674 tst curbit, work
675 beq LSYM(Lgot_result)
677 mov curbit, ip
678 mov work, #3
679 ror curbit, work
680 tst overdone, curbit
681 beq LSYM(Lover6)
682 lsr work, divisor, #3
683 add dividend, work
684 LSYM(Lover6):
685 mov curbit, ip
686 mov work, #2
687 ror curbit, work
688 tst overdone, curbit
689 beq LSYM(Lover7)
690 lsr work, divisor, #2
691 add dividend, work
692 LSYM(Lover7):
693 mov curbit, ip
694 mov work, #1
695 ror curbit, work
696 tst overdone, curbit
697 beq LSYM(Lgot_result)
698 lsr work, divisor, #1
699 add dividend, work
700 .endif
701 LSYM(Lgot_result):
702 .endm
703 /* ------------------------------------------------------------------------ */
704 /* Start of the Real Functions */
705 /* ------------------------------------------------------------------------ */
706 #ifdef L_udivsi3
708 FUNC_START udivsi3
709 FUNC_ALIAS aeabi_uidiv udivsi3
711 #ifdef __thumb__
713 cmp divisor, #0
714 beq LSYM(Ldiv0)
715 mov curbit, #1
716 mov result, #0
718 push { work }
719 cmp dividend, divisor
720 blo LSYM(Lgot_result)
722 THUMB_DIV_MOD_BODY 0
724 mov r0, result
725 pop { work }
728 #else /* ARM version. */
730 subs r2, r1, #1
731 RETc(eq)
732 bcc LSYM(Ldiv0)
733 cmp r0, r1
734 bls 11f
735 tst r1, r2
736 beq 12f
738 ARM_DIV_BODY r0, r1, r2, r3
740 mov r0, r2
741 RET
743 11: moveq r0, #1
744 movne r0, #0
747 12: ARM_DIV2_ORDER r1, r2
749 mov r0, r0, lsr r2
752 #endif /* ARM version */
754 DIV_FUNC_END udivsi3
756 FUNC_START aeabi_uidivmod
757 #ifdef __thumb__
758 push {r0, r1, lr}
759 bl SYM(__udivsi3)
760 POP {r1, r2, r3}
761 mul r2, r0
762 sub r1, r1, r2
763 bx r3
764 #else
765 stmfd sp!, { r0, r1, lr }
766 bl SYM(__udivsi3)
767 ldmfd sp!, { r1, r2, lr }
768 mul r3, r2, r0
769 sub r1, r1, r3
771 #endif
772 FUNC_END aeabi_uidivmod
774 #endif /* L_udivsi3 */
775 /* ------------------------------------------------------------------------ */
776 #ifdef L_umodsi3
778 FUNC_START umodsi3
780 #ifdef __thumb__
782 cmp divisor, #0
783 beq LSYM(Ldiv0)
784 mov curbit, #1
785 cmp dividend, divisor
786 bhs LSYM(Lover10)
787 RET
789 LSYM(Lover10):
790 push { work }
792 THUMB_DIV_MOD_BODY 1
794 pop { work }
797 #else /* ARM version. */
799 subs r2, r1, #1 @ compare divisor with 1
800 bcc LSYM(Ldiv0)
801 cmpne r0, r1 @ compare dividend with divisor
802 moveq r0, #0
803 tsthi r1, r2 @ see if divisor is power of 2
804 andeq r0, r0, r2
805 RETc(ls)
807 ARM_MOD_BODY r0, r1, r2, r3
809 RET
811 #endif /* ARM version. */
813 DIV_FUNC_END umodsi3
815 #endif /* L_umodsi3 */
816 /* ------------------------------------------------------------------------ */
817 #ifdef L_divsi3
819 FUNC_START divsi3
820 FUNC_ALIAS aeabi_idiv divsi3
822 #ifdef __thumb__
823 cmp divisor, #0
824 beq LSYM(Ldiv0)
826 push { work }
827 mov work, dividend
828 eor work, divisor @ Save the sign of the result.
829 mov ip, work
830 mov curbit, #1
831 mov result, #0
832 cmp divisor, #0
833 bpl LSYM(Lover10)
834 neg divisor, divisor @ Loops below use unsigned.
835 LSYM(Lover10):
836 cmp dividend, #0
837 bpl LSYM(Lover11)
838 neg dividend, dividend
839 LSYM(Lover11):
840 cmp dividend, divisor
841 blo LSYM(Lgot_result)
843 THUMB_DIV_MOD_BODY 0
845 mov r0, result
846 mov work, ip
847 cmp work, #0
848 bpl LSYM(Lover12)
849 neg r0, r0
850 LSYM(Lover12):
851 pop { work }
854 #else /* ARM version. */
856 cmp r1, #0
857 eor ip, r0, r1 @ save the sign of the result.
858 beq LSYM(Ldiv0)
859 rsbmi r1, r1, #0 @ loops below use unsigned.
860 subs r2, r1, #1 @ division by 1 or -1 ?
861 beq 10f
862 movs r3, r0
863 rsbmi r3, r0, #0 @ positive dividend value
864 cmp r3, r1
865 bls 11f
866 tst r1, r2 @ divisor is power of 2 ?
867 beq 12f
869 ARM_DIV_BODY r3, r1, r0, r2
871 cmp ip, #0
872 rsbmi r0, r0, #0
873 RET
875 10: teq ip, r0 @ same sign ?
876 rsbmi r0, r0, #0
877 RET
879 11: movlo r0, #0
880 moveq r0, ip, asr #31
881 orreq r0, r0, #1
884 12: ARM_DIV2_ORDER r1, r2
886 cmp ip, #0
887 mov r0, r3, lsr r2
888 rsbmi r0, r0, #0
891 #endif /* ARM version */
893 DIV_FUNC_END divsi3
895 FUNC_START aeabi_idivmod
896 #ifdef __thumb__
897 push {r0, r1, lr}
898 bl SYM(__divsi3)
899 POP {r1, r2, r3}
900 mul r2, r0
901 sub r1, r1, r2
902 bx r3
903 #else
904 stmfd sp!, { r0, r1, lr }
905 bl SYM(__divsi3)
906 ldmfd sp!, { r1, r2, lr }
907 mul r3, r2, r0
908 sub r1, r1, r3
910 #endif
911 FUNC_END aeabi_idivmod
913 #endif /* L_divsi3 */
914 /* ------------------------------------------------------------------------ */
915 #ifdef L_modsi3
917 FUNC_START modsi3
919 #ifdef __thumb__
921 mov curbit, #1
922 cmp divisor, #0
923 beq LSYM(Ldiv0)
924 bpl LSYM(Lover10)
925 neg divisor, divisor @ Loops below use unsigned.
926 LSYM(Lover10):
927 push { work }
928 @ Need to save the sign of the dividend, unfortunately, we need
929 @ work later on. Must do this after saving the original value of
930 @ the work register, because we will pop this value off first.
931 push { dividend }
932 cmp dividend, #0
933 bpl LSYM(Lover11)
934 neg dividend, dividend
935 LSYM(Lover11):
936 cmp dividend, divisor
937 blo LSYM(Lgot_result)
939 THUMB_DIV_MOD_BODY 1
941 pop { work }
942 cmp work, #0
943 bpl LSYM(Lover12)
944 neg dividend, dividend
945 LSYM(Lover12):
946 pop { work }
947 RET
949 #else /* ARM version. */
951 cmp r1, #0
952 beq LSYM(Ldiv0)
953 rsbmi r1, r1, #0 @ loops below use unsigned.
954 movs ip, r0 @ preserve sign of dividend
955 rsbmi r0, r0, #0 @ if negative make positive
956 subs r2, r1, #1 @ compare divisor with 1
957 cmpne r0, r1 @ compare dividend with divisor
958 moveq r0, #0
959 tsthi r1, r2 @ see if divisor is power of 2
960 andeq r0, r0, r2
961 bls 10f
963 ARM_MOD_BODY r0, r1, r2, r3
965 10: cmp ip, #0
966 rsbmi r0, r0, #0
967 RET
969 #endif /* ARM version */
971 DIV_FUNC_END modsi3
973 #endif /* L_modsi3 */
974 /* ------------------------------------------------------------------------ */
975 #ifdef L_dvmd_tls
977 FUNC_START div0
978 FUNC_ALIAS aeabi_idiv0 div0
979 FUNC_ALIAS aeabi_ldiv0 div0
983 FUNC_END aeabi_ldiv0
984 FUNC_END aeabi_idiv0
985 FUNC_END div0
987 #endif /* L_divmodsi_tools */
988 /* ------------------------------------------------------------------------ */
989 #ifdef L_dvmd_lnx
990 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
992 /* Constants taken from <asm/unistd.h> and <asm/signal.h> */
993 #define SIGFPE 8
994 #define __NR_SYSCALL_BASE 0x900000
995 #define __NR_getpid (__NR_SYSCALL_BASE+ 20)
996 #define __NR_kill (__NR_SYSCALL_BASE+ 37)
997 #define __NR_gettid (__NR_SYSCALL_BASE+ 224)
998 #define __NR_tkill (__NR_SYSCALL_BASE+ 238)
1000 .code 32
1001 FUNC_START div0
1003 stmfd sp!, {r1, lr}
1004 swi __NR_gettid
1005 cmn r0, #1000
1006 swihs __NR_getpid
1007 cmnhs r0, #1000
1008 RETLDM r1 hs
1009 mov ip, r0
1010 mov r1, #SIGFPE
1011 swi __NR_tkill
1012 movs r0, r0
1013 movne r0, ip
1014 swine __NR_kill
1015 RETLDM r1
1017 FUNC_END div0
1019 #endif /* L_dvmd_lnx */
1020 /* ------------------------------------------------------------------------ */
1021 /* Dword shift operations. */
1022 /* All the following Dword shift variants rely on the fact that
1023 shft xxx, Reg
1024 is in fact done as
1025 shft xxx, (Reg & 255)
1026 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1027 case of logical shifts) or the sign (for asr). */
1029 #ifdef __ARMEB__
1030 #define al r1
1031 #define ah r0
1032 #else
1033 #define al r0
1034 #define ah r1
1035 #endif
1037 #ifdef L_lshrdi3
1039 FUNC_START lshrdi3
1040 FUNC_ALIAS aeabi_llsr lshrdi3
1042 #ifdef __thumb__
1043 lsr al, r2
1044 mov r3, ah
1045 lsr ah, r2
1046 mov ip, r3
1047 sub r2, #32
1048 lsr r3, r2
1049 orr al, r3
1050 neg r2, r2
1051 mov r3, ip
1052 lsl r3, r2
1053 orr al, r3
1055 #else
1056 subs r3, r2, #32
1057 rsb ip, r2, #32
1058 movmi al, al, lsr r2
1059 movpl al, ah, lsr r3
1060 orrmi al, al, ah, lsl ip
1061 mov ah, ah, lsr r2
1063 #endif
1064 FUNC_END aeabi_llsr
1065 FUNC_END lshrdi3
1067 #endif
1069 #ifdef L_ashrdi3
1071 FUNC_START ashrdi3
1072 FUNC_ALIAS aeabi_lasr ashrdi3
1074 #ifdef __thumb__
1075 lsr al, r2
1076 mov r3, ah
1077 asr ah, r2
1078 sub r2, #32
1079 @ If r2 is negative at this point the following step would OR
1080 @ the sign bit into all of AL. That's not what we want...
1081 bmi 1f
1082 mov ip, r3
1083 asr r3, r2
1084 orr al, r3
1085 mov r3, ip
1087 neg r2, r2
1088 lsl r3, r2
1089 orr al, r3
1091 #else
1092 subs r3, r2, #32
1093 rsb ip, r2, #32
1094 movmi al, al, lsr r2
1095 movpl al, ah, asr r3
1096 orrmi al, al, ah, lsl ip
1097 mov ah, ah, asr r2
1099 #endif
1101 FUNC_END aeabi_lasr
1102 FUNC_END ashrdi3
1104 #endif
1106 #ifdef L_ashldi3
1108 FUNC_START ashldi3
1109 FUNC_ALIAS aeabi_llsl ashldi3
1111 #ifdef __thumb__
1112 lsl ah, r2
1113 mov r3, al
1114 lsl al, r2
1115 mov ip, r3
1116 sub r2, #32
1117 lsl r3, r2
1118 orr ah, r3
1119 neg r2, r2
1120 mov r3, ip
1121 lsr r3, r2
1122 orr ah, r3
1124 #else
1125 subs r3, r2, #32
1126 rsb ip, r2, #32
1127 movmi ah, ah, lsl r2
1128 movpl ah, al, lsl r3
1129 orrmi ah, ah, al, lsr ip
1130 mov al, al, lsl r2
1132 #endif
1133 FUNC_END aeabi_llsl
1134 FUNC_END ashldi3
1136 #endif
1138 /* ------------------------------------------------------------------------ */
1139 /* These next two sections are here despite the fact that they contain Thumb
1140 assembler because their presence allows interworked code to be linked even
1141 when the GCC library is this one. */
1143 /* Do not build the interworking functions when the target architecture does
1144 not support Thumb instructions. (This can be a multilib option). */
1145 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1146 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1147 || __ARM_ARCH__ >= 6
1149 #if defined L_call_via_rX
1151 /* These labels & instructions are used by the Arm/Thumb interworking code.
1152 The address of function to be called is loaded into a register and then
1153 one of these labels is called via a BL instruction. This puts the
1154 return address into the link register with the bottom bit set, and the
1155 code here switches to the correct mode before executing the function. */
1157 .text
1158 .align 0
1159 .force_thumb
1161 .macro call_via register
1162 THUMB_FUNC_START _call_via_\register
1164 bx \register
1167 SIZE (_call_via_\register)
1168 .endm
1170 call_via r0
1171 call_via r1
1172 call_via r2
1173 call_via r3
1174 call_via r4
1175 call_via r5
1176 call_via r6
1177 call_via r7
1178 call_via r8
1179 call_via r9
1180 call_via sl
1181 call_via fp
1182 call_via ip
1183 call_via sp
1184 call_via lr
1186 #endif /* L_call_via_rX */
1188 #if defined L_interwork_call_via_rX
1190 /* These labels & instructions are used by the Arm/Thumb interworking code,
1191 when the target address is in an unknown instruction set. The address
1192 of function to be called is loaded into a register and then one of these
1193 labels is called via a BL instruction. This puts the return address
1194 into the link register with the bottom bit set, and the code here
1195 switches to the correct mode before executing the function. Unfortunately
1196 the target code cannot be relied upon to return via a BX instruction, so
1197 instead we have to store the resturn address on the stack and allow the
1198 called function to return here instead. Upon return we recover the real
1199 return address and use a BX to get back to Thumb mode.
1201 There are three variations of this code. The first,
1202 _interwork_call_via_rN(), will push the return address onto the
1203 stack and pop it in _arm_return(). It should only be used if all
1204 arguments are passed in registers.
1206 The second, _interwork_r7_call_via_rN(), instead stores the return
1207 address at [r7, #-4]. It is the caller's responsibility to ensure
1208 that this address is valid and contains no useful data.
1210 The third, _interwork_r11_call_via_rN(), works in the same way but
1211 uses r11 instead of r7. It is useful if the caller does not really
1212 need a frame pointer. */
1214 .text
1215 .align 0
1217 .code 32
1218 .globl _arm_return
1219 LSYM(Lstart_arm_return):
1220 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1221 cfi_push 0, 0xe, -0x8, 0x8
1222 nop @ This nop is for the benefit of debuggers, so that
1223 @ backtraces will use the correct unwind information.
1224 _arm_return:
1225 RETLDM unwind=LSYM(Lstart_arm_return)
1226 cfi_end LSYM(Lend_arm_return)
1228 .globl _arm_return_r7
1229 _arm_return_r7:
1230 ldr lr, [r7, #-4]
1231 bx lr
1233 .globl _arm_return_r11
1234 _arm_return_r11:
1235 ldr lr, [r11, #-4]
1236 bx lr
1238 .macro interwork_with_frame frame, register, name, return
1239 .code 16
1241 THUMB_FUNC_START \name
1243 bx pc
1246 .code 32
1247 tst \register, #1
1248 streq lr, [\frame, #-4]
1249 adreq lr, _arm_return_\frame
1250 bx \register
1252 SIZE (\name)
1253 .endm
1255 .macro interwork register
1256 .code 16
1258 THUMB_FUNC_START _interwork_call_via_\register
1260 bx pc
1263 .code 32
1264 .globl LSYM(Lchange_\register)
1265 LSYM(Lchange_\register):
1266 tst \register, #1
1267 streq lr, [sp, #-8]!
1268 adreq lr, _arm_return
1269 bx \register
1271 SIZE (_interwork_call_via_\register)
1273 interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1274 interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1275 .endm
1277 interwork r0
1278 interwork r1
1279 interwork r2
1280 interwork r3
1281 interwork r4
1282 interwork r5
1283 interwork r6
1284 interwork r7
1285 interwork r8
1286 interwork r9
1287 interwork sl
1288 interwork fp
1289 interwork ip
1290 interwork sp
1292 /* The LR case has to be handled a little differently... */
1293 .code 16
1295 THUMB_FUNC_START _interwork_call_via_lr
1297 bx pc
1300 .code 32
1301 .globl .Lchange_lr
1302 .Lchange_lr:
1303 tst lr, #1
1304 stmeqdb r13!, {lr, pc}
1305 mov ip, lr
1306 adreq lr, _arm_return
1307 bx ip
1309 SIZE (_interwork_call_via_lr)
1311 #endif /* L_interwork_call_via_rX */
1312 #endif /* Arch supports thumb. */
1314 #ifndef __symbian__
1315 #include "ieee754-df.S"
1316 #include "ieee754-sf.S"
1317 #include "bpabi.S"
1318 #include "libunwind.S"
1319 #endif /* __symbian__ */