* config.gcc: Add armv6{k,z,zk}
[official-gcc.git] / gcc / config / arm / lib1funcs.asm
bloba432ef22fa8dc57fa3ca0169e7b402bb4d3df930
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
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, 59 Temple Place - Suite 330,
29 Boston, MA 02111-1307, 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 /* How to return from a function call depends on the architecture variant. */
92 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
94 # define RET bx lr
95 # define RETc(x) bx##x lr
97 # if (__ARM_ARCH__ == 4) \
98 && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
99 # define __INTERWORKING__
100 # endif
102 #else
104 # define RET mov pc, lr
105 # define RETc(x) mov##x pc, lr
107 #endif
109 /* Don't pass dirn, it's there just to get token pasting right. */
111 .macro RETLDM regs=, cond=, dirn=ia
112 #if defined (__INTERWORKING__)
113 .ifc "\regs",""
114 ldr\cond lr, [sp], #4
115 .else
116 ldm\cond\dirn sp!, {\regs, lr}
117 .endif
118 bx\cond lr
119 #else
120 .ifc "\regs",""
121 ldr\cond pc, [sp], #4
122 .else
123 ldm\cond\dirn sp!, {\regs, pc}
124 .endif
125 #endif
126 .endm
129 .macro ARM_LDIV0
130 LSYM(Ldiv0):
131 str lr, [sp, #-4]!
132 bl SYM (__div0) __PLT__
133 mov r0, #0 @ About as wrong as it could be.
134 RETLDM
135 .endm
138 .macro THUMB_LDIV0
139 LSYM(Ldiv0):
140 push { lr }
141 bl SYM (__div0)
142 mov r0, #0 @ About as wrong as it could be.
143 #if defined (__INTERWORKING__)
144 pop { r1 }
145 bx r1
146 #else
147 pop { pc }
148 #endif
149 .endm
151 .macro FUNC_END name
152 SIZE (__\name)
153 .endm
155 .macro DIV_FUNC_END name
156 LSYM(Ldiv0):
157 #ifdef __thumb__
158 THUMB_LDIV0
159 #else
160 ARM_LDIV0
161 #endif
162 FUNC_END \name
163 .endm
165 .macro THUMB_FUNC_START name
166 .globl SYM (\name)
167 TYPE (\name)
168 .thumb_func
169 SYM (\name):
170 .endm
172 /* Function start macros. Variants for ARM and Thumb. */
174 #ifdef __thumb__
175 #define THUMB_FUNC .thumb_func
176 #define THUMB_CODE .force_thumb
177 #else
178 #define THUMB_FUNC
179 #define THUMB_CODE
180 #endif
182 .macro FUNC_START name
183 .text
184 .globl SYM (__\name)
185 TYPE (__\name)
186 .align 0
187 THUMB_CODE
188 THUMB_FUNC
189 SYM (__\name):
190 .endm
192 /* Special function that will always be coded in ARM assembly, even if
193 in Thumb-only compilation. */
195 #if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
196 .macro ARM_FUNC_START name
197 FUNC_START \name
198 bx pc
200 .arm
201 /* A hook to tell gdb that we've switched to ARM mode. Also used to call
202 directly from other local arm routines. */
203 _L__\name:
204 .endm
205 #define EQUIV .thumb_set
206 /* Branch directly to a function declared with ARM_FUNC_START.
207 Must be called in arm mode. */
208 .macro ARM_CALL name
209 bl _L__\name
210 .endm
211 #else
212 .macro ARM_FUNC_START name
213 .text
214 .globl SYM (__\name)
215 TYPE (__\name)
216 .align 0
217 .arm
218 SYM (__\name):
219 .endm
220 #define EQUIV .set
221 .macro ARM_CALL name
222 bl __\name
223 .endm
224 #endif
226 .macro ARM_FUNC_ALIAS new old
227 .globl SYM (__\new)
228 EQUIV SYM (__\new), SYM (__\old)
229 #ifdef __thumb__
230 .set SYM (_L__\new), SYM (_L__\old)
231 #endif
232 .endm
234 #ifdef __thumb__
235 /* Register aliases. */
237 work .req r4 @ XXXX is this safe ?
238 dividend .req r0
239 divisor .req r1
240 overdone .req r2
241 result .req r2
242 curbit .req r3
243 #endif
244 #if 0
245 ip .req r12
246 sp .req r13
247 lr .req r14
248 pc .req r15
249 #endif
251 /* ------------------------------------------------------------------------ */
252 /* Bodies of the division and modulo routines. */
253 /* ------------------------------------------------------------------------ */
254 .macro ARM_DIV_BODY dividend, divisor, result, curbit
256 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
258 clz \curbit, \dividend
259 clz \result, \divisor
260 sub \curbit, \result, \curbit
261 rsbs \curbit, \curbit, #31
262 addne \curbit, \curbit, \curbit, lsl #1
263 mov \result, #0
264 addne pc, pc, \curbit, lsl #2
266 .set shift, 32
267 .rept 32
268 .set shift, shift - 1
269 cmp \dividend, \divisor, lsl #shift
270 adc \result, \result, \result
271 subcs \dividend, \dividend, \divisor, lsl #shift
272 .endr
274 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
275 #if __ARM_ARCH__ >= 5
277 clz \curbit, \divisor
278 clz \result, \dividend
279 sub \result, \curbit, \result
280 mov \curbit, #1
281 mov \divisor, \divisor, lsl \result
282 mov \curbit, \curbit, lsl \result
283 mov \result, #0
285 #else /* __ARM_ARCH__ < 5 */
287 @ Initially shift the divisor left 3 bits if possible,
288 @ set curbit accordingly. This allows for curbit to be located
289 @ at the left end of each 4 bit nibbles in the division loop
290 @ to save one loop in most cases.
291 tst \divisor, #0xe0000000
292 moveq \divisor, \divisor, lsl #3
293 moveq \curbit, #8
294 movne \curbit, #1
296 @ Unless the divisor is very big, shift it up in multiples of
297 @ four bits, since this is the amount of unwinding in the main
298 @ division loop. Continue shifting until the divisor is
299 @ larger than the dividend.
300 1: cmp \divisor, #0x10000000
301 cmplo \divisor, \dividend
302 movlo \divisor, \divisor, lsl #4
303 movlo \curbit, \curbit, lsl #4
304 blo 1b
306 @ For very big divisors, we must shift it a bit at a time, or
307 @ we will be in danger of overflowing.
308 1: cmp \divisor, #0x80000000
309 cmplo \divisor, \dividend
310 movlo \divisor, \divisor, lsl #1
311 movlo \curbit, \curbit, lsl #1
312 blo 1b
314 mov \result, #0
316 #endif /* __ARM_ARCH__ < 5 */
318 @ Division loop
319 1: cmp \dividend, \divisor
320 subhs \dividend, \dividend, \divisor
321 orrhs \result, \result, \curbit
322 cmp \dividend, \divisor, lsr #1
323 subhs \dividend, \dividend, \divisor, lsr #1
324 orrhs \result, \result, \curbit, lsr #1
325 cmp \dividend, \divisor, lsr #2
326 subhs \dividend, \dividend, \divisor, lsr #2
327 orrhs \result, \result, \curbit, lsr #2
328 cmp \dividend, \divisor, lsr #3
329 subhs \dividend, \dividend, \divisor, lsr #3
330 orrhs \result, \result, \curbit, lsr #3
331 cmp \dividend, #0 @ Early termination?
332 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
333 movne \divisor, \divisor, lsr #4
334 bne 1b
336 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
338 .endm
339 /* ------------------------------------------------------------------------ */
340 .macro ARM_DIV2_ORDER divisor, order
342 #if __ARM_ARCH__ >= 5
344 clz \order, \divisor
345 rsb \order, \order, #31
347 #else
349 cmp \divisor, #(1 << 16)
350 movhs \divisor, \divisor, lsr #16
351 movhs \order, #16
352 movlo \order, #0
354 cmp \divisor, #(1 << 8)
355 movhs \divisor, \divisor, lsr #8
356 addhs \order, \order, #8
358 cmp \divisor, #(1 << 4)
359 movhs \divisor, \divisor, lsr #4
360 addhs \order, \order, #4
362 cmp \divisor, #(1 << 2)
363 addhi \order, \order, #3
364 addls \order, \order, \divisor, lsr #1
366 #endif
368 .endm
369 /* ------------------------------------------------------------------------ */
370 .macro ARM_MOD_BODY dividend, divisor, order, spare
372 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
374 clz \order, \divisor
375 clz \spare, \dividend
376 sub \order, \order, \spare
377 rsbs \order, \order, #31
378 addne pc, pc, \order, lsl #3
380 .set shift, 32
381 .rept 32
382 .set shift, shift - 1
383 cmp \dividend, \divisor, lsl #shift
384 subcs \dividend, \dividend, \divisor, lsl #shift
385 .endr
387 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
388 #if __ARM_ARCH__ >= 5
390 clz \order, \divisor
391 clz \spare, \dividend
392 sub \order, \order, \spare
393 mov \divisor, \divisor, lsl \order
395 #else /* __ARM_ARCH__ < 5 */
397 mov \order, #0
399 @ Unless the divisor is very big, shift it up in multiples of
400 @ four bits, since this is the amount of unwinding in the main
401 @ division loop. Continue shifting until the divisor is
402 @ larger than the dividend.
403 1: cmp \divisor, #0x10000000
404 cmplo \divisor, \dividend
405 movlo \divisor, \divisor, lsl #4
406 addlo \order, \order, #4
407 blo 1b
409 @ For very big divisors, we must shift it a bit at a time, or
410 @ we will be in danger of overflowing.
411 1: cmp \divisor, #0x80000000
412 cmplo \divisor, \dividend
413 movlo \divisor, \divisor, lsl #1
414 addlo \order, \order, #1
415 blo 1b
417 #endif /* __ARM_ARCH__ < 5 */
419 @ Perform all needed substractions to keep only the reminder.
420 @ Do comparisons in batch of 4 first.
421 subs \order, \order, #3 @ yes, 3 is intended here
422 blt 2f
424 1: cmp \dividend, \divisor
425 subhs \dividend, \dividend, \divisor
426 cmp \dividend, \divisor, lsr #1
427 subhs \dividend, \dividend, \divisor, lsr #1
428 cmp \dividend, \divisor, lsr #2
429 subhs \dividend, \dividend, \divisor, lsr #2
430 cmp \dividend, \divisor, lsr #3
431 subhs \dividend, \dividend, \divisor, lsr #3
432 cmp \dividend, #1
433 mov \divisor, \divisor, lsr #4
434 subges \order, \order, #4
435 bge 1b
437 tst \order, #3
438 teqne \dividend, #0
439 beq 5f
441 @ Either 1, 2 or 3 comparison/substractions are left.
442 2: cmn \order, #2
443 blt 4f
444 beq 3f
445 cmp \dividend, \divisor
446 subhs \dividend, \dividend, \divisor
447 mov \divisor, \divisor, lsr #1
448 3: cmp \dividend, \divisor
449 subhs \dividend, \dividend, \divisor
450 mov \divisor, \divisor, lsr #1
451 4: cmp \dividend, \divisor
452 subhs \dividend, \dividend, \divisor
455 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
457 .endm
458 /* ------------------------------------------------------------------------ */
459 .macro THUMB_DIV_MOD_BODY modulo
460 @ Load the constant 0x10000000 into our work register.
461 mov work, #1
462 lsl work, #28
463 LSYM(Loop1):
464 @ Unless the divisor is very big, shift it up in multiples of
465 @ four bits, since this is the amount of unwinding in the main
466 @ division loop. Continue shifting until the divisor is
467 @ larger than the dividend.
468 cmp divisor, work
469 bhs LSYM(Lbignum)
470 cmp divisor, dividend
471 bhs LSYM(Lbignum)
472 lsl divisor, #4
473 lsl curbit, #4
474 b LSYM(Loop1)
475 LSYM(Lbignum):
476 @ Set work to 0x80000000
477 lsl work, #3
478 LSYM(Loop2):
479 @ For very big divisors, we must shift it a bit at a time, or
480 @ we will be in danger of overflowing.
481 cmp divisor, work
482 bhs LSYM(Loop3)
483 cmp divisor, dividend
484 bhs LSYM(Loop3)
485 lsl divisor, #1
486 lsl curbit, #1
487 b LSYM(Loop2)
488 LSYM(Loop3):
489 @ Test for possible subtractions ...
490 .if \modulo
491 @ ... On the final pass, this may subtract too much from the dividend,
492 @ so keep track of which subtractions are done, we can fix them up
493 @ afterwards.
494 mov overdone, #0
495 cmp dividend, divisor
496 blo LSYM(Lover1)
497 sub dividend, dividend, divisor
498 LSYM(Lover1):
499 lsr work, divisor, #1
500 cmp dividend, work
501 blo LSYM(Lover2)
502 sub dividend, dividend, work
503 mov ip, curbit
504 mov work, #1
505 ror curbit, work
506 orr overdone, curbit
507 mov curbit, ip
508 LSYM(Lover2):
509 lsr work, divisor, #2
510 cmp dividend, work
511 blo LSYM(Lover3)
512 sub dividend, dividend, work
513 mov ip, curbit
514 mov work, #2
515 ror curbit, work
516 orr overdone, curbit
517 mov curbit, ip
518 LSYM(Lover3):
519 lsr work, divisor, #3
520 cmp dividend, work
521 blo LSYM(Lover4)
522 sub dividend, dividend, work
523 mov ip, curbit
524 mov work, #3
525 ror curbit, work
526 orr overdone, curbit
527 mov curbit, ip
528 LSYM(Lover4):
529 mov ip, curbit
530 .else
531 @ ... and note which bits are done in the result. On the final pass,
532 @ this may subtract too much from the dividend, but the result will be ok,
533 @ since the "bit" will have been shifted out at the bottom.
534 cmp dividend, divisor
535 blo LSYM(Lover1)
536 sub dividend, dividend, divisor
537 orr result, result, curbit
538 LSYM(Lover1):
539 lsr work, divisor, #1
540 cmp dividend, work
541 blo LSYM(Lover2)
542 sub dividend, dividend, work
543 lsr work, curbit, #1
544 orr result, work
545 LSYM(Lover2):
546 lsr work, divisor, #2
547 cmp dividend, work
548 blo LSYM(Lover3)
549 sub dividend, dividend, work
550 lsr work, curbit, #2
551 orr result, work
552 LSYM(Lover3):
553 lsr work, divisor, #3
554 cmp dividend, work
555 blo LSYM(Lover4)
556 sub dividend, dividend, work
557 lsr work, curbit, #3
558 orr result, work
559 LSYM(Lover4):
560 .endif
562 cmp dividend, #0 @ Early termination?
563 beq LSYM(Lover5)
564 lsr curbit, #4 @ No, any more bits to do?
565 beq LSYM(Lover5)
566 lsr divisor, #4
567 b LSYM(Loop3)
568 LSYM(Lover5):
569 .if \modulo
570 @ Any subtractions that we should not have done will be recorded in
571 @ the top three bits of "overdone". Exactly which were not needed
572 @ are governed by the position of the bit, stored in ip.
573 mov work, #0xe
574 lsl work, #28
575 and overdone, work
576 beq LSYM(Lgot_result)
578 @ If we terminated early, because dividend became zero, then the
579 @ bit in ip will not be in the bottom nibble, and we should not
580 @ perform the additions below. We must test for this though
581 @ (rather relying upon the TSTs to prevent the additions) since
582 @ the bit in ip could be in the top two bits which might then match
583 @ with one of the smaller RORs.
584 mov curbit, ip
585 mov work, #0x7
586 tst curbit, work
587 beq LSYM(Lgot_result)
589 mov curbit, ip
590 mov work, #3
591 ror curbit, work
592 tst overdone, curbit
593 beq LSYM(Lover6)
594 lsr work, divisor, #3
595 add dividend, work
596 LSYM(Lover6):
597 mov curbit, ip
598 mov work, #2
599 ror curbit, work
600 tst overdone, curbit
601 beq LSYM(Lover7)
602 lsr work, divisor, #2
603 add dividend, work
604 LSYM(Lover7):
605 mov curbit, ip
606 mov work, #1
607 ror curbit, work
608 tst overdone, curbit
609 beq LSYM(Lgot_result)
610 lsr work, divisor, #1
611 add dividend, work
612 .endif
613 LSYM(Lgot_result):
614 .endm
615 /* ------------------------------------------------------------------------ */
616 /* Start of the Real Functions */
617 /* ------------------------------------------------------------------------ */
618 #ifdef L_udivsi3
620 FUNC_START udivsi3
622 #ifdef __thumb__
624 cmp divisor, #0
625 beq LSYM(Ldiv0)
626 mov curbit, #1
627 mov result, #0
629 push { work }
630 cmp dividend, divisor
631 blo LSYM(Lgot_result)
633 THUMB_DIV_MOD_BODY 0
635 mov r0, result
636 pop { work }
639 #else /* ARM version. */
641 subs r2, r1, #1
642 RETc(eq)
643 bcc LSYM(Ldiv0)
644 cmp r0, r1
645 bls 11f
646 tst r1, r2
647 beq 12f
649 ARM_DIV_BODY r0, r1, r2, r3
651 mov r0, r2
652 RET
654 11: moveq r0, #1
655 movne r0, #0
658 12: ARM_DIV2_ORDER r1, r2
660 mov r0, r0, lsr r2
663 #endif /* ARM version */
665 DIV_FUNC_END udivsi3
667 FUNC_START aeabi_uidivmod
668 #ifdef __thumb__
669 push {r0, r1, lr}
670 bl SYM(__udivsi3)
671 POP {r1, r2, r3}
672 mul r2, r0
673 sub r1, r1, r2
674 bx r3
675 #else
676 stmfd sp!, { r0, r1, lr }
677 bl SYM(__udivsi3)
678 ldmfd sp!, { r1, r2, lr }
679 mul r3, r2, r0
680 sub r1, r1, r3
682 #endif
683 FUNC_END aeabi_uidivmod
685 #endif /* L_udivsi3 */
686 /* ------------------------------------------------------------------------ */
687 #ifdef L_umodsi3
689 FUNC_START umodsi3
691 #ifdef __thumb__
693 cmp divisor, #0
694 beq LSYM(Ldiv0)
695 mov curbit, #1
696 cmp dividend, divisor
697 bhs LSYM(Lover10)
698 RET
700 LSYM(Lover10):
701 push { work }
703 THUMB_DIV_MOD_BODY 1
705 pop { work }
708 #else /* ARM version. */
710 subs r2, r1, #1 @ compare divisor with 1
711 bcc LSYM(Ldiv0)
712 cmpne r0, r1 @ compare dividend with divisor
713 moveq r0, #0
714 tsthi r1, r2 @ see if divisor is power of 2
715 andeq r0, r0, r2
716 RETc(ls)
718 ARM_MOD_BODY r0, r1, r2, r3
720 RET
722 #endif /* ARM version. */
724 DIV_FUNC_END umodsi3
726 #endif /* L_umodsi3 */
727 /* ------------------------------------------------------------------------ */
728 #ifdef L_divsi3
730 FUNC_START divsi3
732 #ifdef __thumb__
733 cmp divisor, #0
734 beq LSYM(Ldiv0)
736 push { work }
737 mov work, dividend
738 eor work, divisor @ Save the sign of the result.
739 mov ip, work
740 mov curbit, #1
741 mov result, #0
742 cmp divisor, #0
743 bpl LSYM(Lover10)
744 neg divisor, divisor @ Loops below use unsigned.
745 LSYM(Lover10):
746 cmp dividend, #0
747 bpl LSYM(Lover11)
748 neg dividend, dividend
749 LSYM(Lover11):
750 cmp dividend, divisor
751 blo LSYM(Lgot_result)
753 THUMB_DIV_MOD_BODY 0
755 mov r0, result
756 mov work, ip
757 cmp work, #0
758 bpl LSYM(Lover12)
759 neg r0, r0
760 LSYM(Lover12):
761 pop { work }
764 #else /* ARM version. */
766 cmp r1, #0
767 eor ip, r0, r1 @ save the sign of the result.
768 beq LSYM(Ldiv0)
769 rsbmi r1, r1, #0 @ loops below use unsigned.
770 subs r2, r1, #1 @ division by 1 or -1 ?
771 beq 10f
772 movs r3, r0
773 rsbmi r3, r0, #0 @ positive dividend value
774 cmp r3, r1
775 bls 11f
776 tst r1, r2 @ divisor is power of 2 ?
777 beq 12f
779 ARM_DIV_BODY r3, r1, r0, r2
781 cmp ip, #0
782 rsbmi r0, r0, #0
783 RET
785 10: teq ip, r0 @ same sign ?
786 rsbmi r0, r0, #0
787 RET
789 11: movlo r0, #0
790 moveq r0, ip, asr #31
791 orreq r0, r0, #1
794 12: ARM_DIV2_ORDER r1, r2
796 cmp ip, #0
797 mov r0, r3, lsr r2
798 rsbmi r0, r0, #0
801 #endif /* ARM version */
803 DIV_FUNC_END divsi3
805 FUNC_START aeabi_idivmod
806 #ifdef __thumb__
807 push {r0, r1, lr}
808 bl SYM(__divsi3)
809 POP {r1, r2, r3}
810 mul r2, r0
811 sub r1, r1, r2
812 bx r3
813 #else
814 stmfd sp!, { r0, r1, lr }
815 bl SYM(__divsi3)
816 ldmfd sp!, { r1, r2, lr }
817 mul r3, r2, r0
818 sub r1, r1, r3
820 #endif
821 FUNC_END aeabi_idivmod
823 #endif /* L_divsi3 */
824 /* ------------------------------------------------------------------------ */
825 #ifdef L_modsi3
827 FUNC_START modsi3
829 #ifdef __thumb__
831 mov curbit, #1
832 cmp divisor, #0
833 beq LSYM(Ldiv0)
834 bpl LSYM(Lover10)
835 neg divisor, divisor @ Loops below use unsigned.
836 LSYM(Lover10):
837 push { work }
838 @ Need to save the sign of the dividend, unfortunately, we need
839 @ work later on. Must do this after saving the original value of
840 @ the work register, because we will pop this value off first.
841 push { dividend }
842 cmp dividend, #0
843 bpl LSYM(Lover11)
844 neg dividend, dividend
845 LSYM(Lover11):
846 cmp dividend, divisor
847 blo LSYM(Lgot_result)
849 THUMB_DIV_MOD_BODY 1
851 pop { work }
852 cmp work, #0
853 bpl LSYM(Lover12)
854 neg dividend, dividend
855 LSYM(Lover12):
856 pop { work }
857 RET
859 #else /* ARM version. */
861 cmp r1, #0
862 beq LSYM(Ldiv0)
863 rsbmi r1, r1, #0 @ loops below use unsigned.
864 movs ip, r0 @ preserve sign of dividend
865 rsbmi r0, r0, #0 @ if negative make positive
866 subs r2, r1, #1 @ compare divisor with 1
867 cmpne r0, r1 @ compare dividend with divisor
868 moveq r0, #0
869 tsthi r1, r2 @ see if divisor is power of 2
870 andeq r0, r0, r2
871 bls 10f
873 ARM_MOD_BODY r0, r1, r2, r3
875 10: cmp ip, #0
876 rsbmi r0, r0, #0
877 RET
879 #endif /* ARM version */
881 DIV_FUNC_END modsi3
883 #endif /* L_modsi3 */
884 /* ------------------------------------------------------------------------ */
885 #ifdef L_dvmd_tls
887 FUNC_START div0
888 ARM_FUNC_ALIAS aeabi_idiv0 div0
889 ARM_FUNC_ALIAS aeabi_ldiv0 div0
893 FUNC_END aeabi_ldiv0
894 FUNC_END aeabi_idiv0
895 FUNC_END div0
897 #endif /* L_divmodsi_tools */
898 /* ------------------------------------------------------------------------ */
899 #ifdef L_dvmd_lnx
900 @ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
902 /* Constants taken from <asm/unistd.h> and <asm/signal.h> */
903 #define SIGFPE 8
904 #define __NR_SYSCALL_BASE 0x900000
905 #define __NR_getpid (__NR_SYSCALL_BASE+ 20)
906 #define __NR_kill (__NR_SYSCALL_BASE+ 37)
908 .code 32
909 FUNC_START div0
911 stmfd sp!, {r1, lr}
912 swi __NR_getpid
913 cmn r0, #1000
914 RETLDM r1 hs
915 mov r1, #SIGFPE
916 swi __NR_kill
917 RETLDM r1
919 FUNC_END div0
921 #endif /* L_dvmd_lnx */
922 /* ------------------------------------------------------------------------ */
923 /* Dword shift operations. */
924 /* All the following Dword shift variants rely on the fact that
925 shft xxx, Reg
926 is in fact done as
927 shft xxx, (Reg & 255)
928 so for Reg value in (32...63) and (-1...-31) we will get zero (in the
929 case of logical shifts) or the sign (for asr). */
931 #ifdef __ARMEB__
932 #define al r1
933 #define ah r0
934 #else
935 #define al r0
936 #define ah r1
937 #endif
939 #ifdef L_lshrdi3
941 FUNC_START lshrdi3
942 ARM_FUNC_ALIAS aeabi_llsr lshrdi3
944 #ifdef __thumb__
945 lsr al, r2
946 mov r3, ah
947 lsr ah, r2
948 mov ip, r3
949 sub r2, #32
950 lsr r3, r2
951 orr al, r3
952 neg r2, r2
953 mov r3, ip
954 lsl r3, r2
955 orr al, r3
957 #else
958 subs r3, r2, #32
959 rsb ip, r2, #32
960 movmi al, al, lsr r2
961 movpl al, ah, lsr r3
962 orrmi al, al, ah, lsl ip
963 mov ah, ah, lsr r2
965 #endif
966 FUNC_END aeabi_llsr
967 FUNC_END lshrdi3
969 #endif
971 #ifdef L_ashrdi3
973 FUNC_START ashrdi3
974 ARM_FUNC_ALIAS aeabi_lasr ashrdi3
976 #ifdef __thumb__
977 lsr al, r2
978 mov r3, ah
979 asr ah, r2
980 sub r2, #32
981 @ If r2 is negative at this point the following step would OR
982 @ the sign bit into all of AL. That's not what we want...
983 bmi 1f
984 mov ip, r3
985 asr r3, r2
986 orr al, r3
987 mov r3, ip
989 neg r2, r2
990 lsl r3, r2
991 orr al, r3
993 #else
994 subs r3, r2, #32
995 rsb ip, r2, #32
996 movmi al, al, lsr r2
997 movpl al, ah, asr r3
998 orrmi al, al, ah, lsl ip
999 mov ah, ah, asr r2
1001 #endif
1003 FUNC_END aeabi_lasr
1004 FUNC_END ashrdi3
1006 #endif
1008 #ifdef L_ashldi3
1010 FUNC_START ashldi3
1011 ARM_FUNC_ALIAS aeabi_llsl ashldi3
1013 #ifdef __thumb__
1014 lsl ah, r2
1015 mov r3, al
1016 lsl al, r2
1017 mov ip, r3
1018 sub r2, #32
1019 lsl r3, r2
1020 orr ah, r3
1021 neg r2, r2
1022 mov r3, ip
1023 lsr r3, r2
1024 orr ah, r3
1026 #else
1027 subs r3, r2, #32
1028 rsb ip, r2, #32
1029 movmi ah, ah, lsl r2
1030 movpl ah, al, lsl r3
1031 orrmi ah, ah, al, lsr ip
1032 mov al, al, lsl r2
1034 #endif
1035 FUNC_END aeabi_llsl
1036 FUNC_END ashldi3
1038 #endif
1040 /* ------------------------------------------------------------------------ */
1041 /* These next two sections are here despite the fact that they contain Thumb
1042 assembler because their presence allows interworked code to be linked even
1043 when the GCC library is this one. */
1045 /* Do not build the interworking functions when the target architecture does
1046 not support Thumb instructions. (This can be a multilib option). */
1047 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1048 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1049 || __ARM_ARCH__ >= 6
1051 #if defined L_call_via_rX
1053 /* These labels & instructions are used by the Arm/Thumb interworking code.
1054 The address of function to be called is loaded into a register and then
1055 one of these labels is called via a BL instruction. This puts the
1056 return address into the link register with the bottom bit set, and the
1057 code here switches to the correct mode before executing the function. */
1059 .text
1060 .align 0
1061 .force_thumb
1063 .macro call_via register
1064 THUMB_FUNC_START _call_via_\register
1066 bx \register
1069 SIZE (_call_via_\register)
1070 .endm
1072 call_via r0
1073 call_via r1
1074 call_via r2
1075 call_via r3
1076 call_via r4
1077 call_via r5
1078 call_via r6
1079 call_via r7
1080 call_via r8
1081 call_via r9
1082 call_via sl
1083 call_via fp
1084 call_via ip
1085 call_via sp
1086 call_via lr
1088 #endif /* L_call_via_rX */
1090 #if defined L_interwork_call_via_rX
1092 /* These labels & instructions are used by the Arm/Thumb interworking code,
1093 when the target address is in an unknown instruction set. The address
1094 of function to be called is loaded into a register and then one of these
1095 labels is called via a BL instruction. This puts the return address
1096 into the link register with the bottom bit set, and the code here
1097 switches to the correct mode before executing the function. Unfortunately
1098 the target code cannot be relied upon to return via a BX instruction, so
1099 instead we have to store the resturn address on the stack and allow the
1100 called function to return here instead. Upon return we recover the real
1101 return address and use a BX to get back to Thumb mode. */
1103 .text
1104 .align 0
1106 .code 32
1107 .globl _arm_return
1108 _arm_return:
1109 RETLDM
1110 .code 16
1112 .macro interwork register
1113 .code 16
1115 THUMB_FUNC_START _interwork_call_via_\register
1117 bx pc
1120 .code 32
1121 .globl LSYM(Lchange_\register)
1122 LSYM(Lchange_\register):
1123 tst \register, #1
1124 streq lr, [sp, #-4]!
1125 adreq lr, _arm_return
1126 bx \register
1128 SIZE (_interwork_call_via_\register)
1129 .endm
1131 interwork r0
1132 interwork r1
1133 interwork r2
1134 interwork r3
1135 interwork r4
1136 interwork r5
1137 interwork r6
1138 interwork r7
1139 interwork r8
1140 interwork r9
1141 interwork sl
1142 interwork fp
1143 interwork ip
1144 interwork sp
1146 /* The LR case has to be handled a little differently... */
1147 .code 16
1149 THUMB_FUNC_START _interwork_call_via_lr
1151 bx pc
1154 .code 32
1155 .globl .Lchange_lr
1156 .Lchange_lr:
1157 tst lr, #1
1158 stmeqdb r13!, {lr}
1159 mov ip, lr
1160 adreq lr, _arm_return
1161 bx ip
1163 SIZE (_interwork_call_via_lr)
1165 #endif /* L_interwork_call_via_rX */
1166 #endif /* Arch supports thumb. */
1168 #ifndef __symbian__
1169 #include "ieee754-df.S"
1170 #include "ieee754-sf.S"
1171 #include "bpabi.S"
1172 #endif /* __symbian__ */