OSDN Git Service

Merge from csl-arm-branch.
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / lib1funcs.asm
1 @ libgcc routines for ARM cpu.
2 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
3
4 /* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004
5    Free Software Foundation, Inc.
6
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
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.)
20
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.
25
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 /* ------------------------------------------------------------------------ */
31
32 /* We need to know what prefix to add to function names.  */
33
34 #ifndef __USER_LABEL_PREFIX__
35 #error  __USER_LABEL_PREFIX__ not defined
36 #endif
37
38 /* ANSI concatenation macros.  */
39
40 #define CONCAT1(a, b) CONCAT2(a, b)
41 #define CONCAT2(a, b) a ## b
42
43 /* Use the right prefix for global labels.  */
44
45 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
46
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
62
63 /* Function end macros.  Variants for 26 bit APCS and interworking.  */
64
65 @ This selects the minimum architecture level required.
66 #define __ARM_ARCH__ 3
67
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
75         
76 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
77         || defined(__ARM_ARCH_5TE__)
78 # undef __ARM_ARCH__
79 # define __ARM_ARCH__ 5
80 #endif
81
82 /* How to return from a function call depends on the architecture variant.  */
83
84 #ifdef __APCS_26__
85
86 # define RET            movs    pc, lr
87 # define RETc(x)        mov##x##s       pc, lr
88
89 #elif (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
90
91 # define RET            bx      lr
92 # define RETc(x)        bx##x   lr
93
94 # if (__ARM_ARCH__ == 4) \
95         && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
96 #  define __INTERWORKING__
97 # endif
98
99 #else
100
101 # define RET            mov     pc, lr
102 # define RETc(x)        mov##x  pc, lr
103
104 #endif
105
106 /* Don't pass dirn, it's there just to get token pasting right.  */
107
108 .macro  RETLDM  regs=, cond=, dirn=ia
109 #ifdef __APCS_26__
110         .ifc "\regs",""
111         ldm\cond\dirn   sp!, {pc}^
112         .else
113         ldm\cond\dirn   sp!, {\regs, pc}^
114         .endif
115 #elif defined (__INTERWORKING__)
116         .ifc "\regs",""
117         ldr\cond        lr, [sp], #4
118         .else
119         ldm\cond\dirn   sp!, {\regs, lr}
120         .endif
121         bx\cond lr
122 #else
123         .ifc "\regs",""
124         ldr\cond        pc, [sp], #4
125         .else
126         ldm\cond\dirn   sp!, {\regs, pc}
127         .endif
128 #endif
129 .endm
130
131
132 .macro ARM_LDIV0
133 LSYM(Ldiv0):
134         str     lr, [sp, #-4]!
135         bl      SYM (__div0) __PLT__
136         mov     r0, #0                  @ About as wrong as it could be.
137         RETLDM
138 .endm
139
140
141 .macro THUMB_LDIV0
142 LSYM(Ldiv0):
143         push    { lr }
144         bl      SYM (__div0)
145         mov     r0, #0                  @ About as wrong as it could be.
146 #if defined (__INTERWORKING__)
147         pop     { r1 }
148         bx      r1
149 #else
150         pop     { pc }
151 #endif
152 .endm
153
154 .macro FUNC_END name
155         SIZE (__\name)
156 .endm
157
158 .macro DIV_FUNC_END name
159 LSYM(Ldiv0):
160 #ifdef __thumb__
161         THUMB_LDIV0
162 #else
163         ARM_LDIV0
164 #endif
165         FUNC_END \name
166 .endm
167
168 .macro THUMB_FUNC_START name
169         .globl  SYM (\name)
170         TYPE    (\name)
171         .thumb_func
172 SYM (\name):
173 .endm
174
175 /* Function start macros.  Variants for ARM and Thumb.  */
176
177 #ifdef __thumb__
178 #define THUMB_FUNC .thumb_func
179 #define THUMB_CODE .force_thumb
180 #else
181 #define THUMB_FUNC
182 #define THUMB_CODE
183 #endif
184         
185 .macro FUNC_START name
186         .text
187         .globl SYM (__\name)
188         TYPE (__\name)
189         .align 0
190         THUMB_CODE
191         THUMB_FUNC
192 SYM (__\name):
193 .endm
194
195 /* Special function that will always be coded in ARM assembly, even if
196    in Thumb-only compilation.  */
197
198 #if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
199 .macro  ARM_FUNC_START name
200         FUNC_START \name
201         bx      pc
202         nop
203         .arm
204 _L__\name:              /* A hook to tell gdb that we've switched to ARM */
205 .endm
206 #define EQUIV .thumb_set
207 #else
208 .macro  ARM_FUNC_START name
209         .text
210         .globl SYM (__\name)
211         TYPE (__\name)
212         .align 0
213         .arm
214 SYM (__\name):
215 .endm
216 #define EQUIV .set
217 #endif
218
219 .macro  ARM_FUNC_ALIAS new old
220         .globl  SYM (__\new)
221         EQUIV   SYM (__\new), SYM (__\old)
222 .endm
223
224 #ifdef __thumb__
225 /* Register aliases.  */
226
227 work            .req    r4      @ XXXX is this safe ?
228 dividend        .req    r0
229 divisor         .req    r1
230 overdone        .req    r2
231 result          .req    r2
232 curbit          .req    r3
233 #endif
234 #if 0
235 ip              .req    r12
236 sp              .req    r13
237 lr              .req    r14
238 pc              .req    r15
239 #endif
240
241 /* ------------------------------------------------------------------------ */
242 /*              Bodies of the division and modulo routines.                 */
243 /* ------------------------------------------------------------------------ */  
244 .macro ARM_DIV_BODY dividend, divisor, result, curbit
245
246 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
247
248         clz     \curbit, \dividend
249         clz     \result, \divisor
250         sub     \curbit, \result, \curbit
251         rsbs    \curbit, \curbit, #31
252         addne   \curbit, \curbit, \curbit, lsl #1
253         mov     \result, #0
254         addne   pc, pc, \curbit, lsl #2
255         nop
256         .set    shift, 32
257         .rept   32
258         .set    shift, shift - 1
259         cmp     \dividend, \divisor, lsl #shift
260         adc     \result, \result, \result
261         subcs   \dividend, \dividend, \divisor, lsl #shift
262         .endr
263
264 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
265 #if __ARM_ARCH__ >= 5
266
267         clz     \curbit, \divisor
268         clz     \result, \dividend
269         sub     \result, \curbit, \result
270         mov     \curbit, #1
271         mov     \divisor, \divisor, lsl \result
272         mov     \curbit, \curbit, lsl \result
273         mov     \result, #0
274         
275 #else /* __ARM_ARCH__ < 5 */
276
277         @ Initially shift the divisor left 3 bits if possible,
278         @ set curbit accordingly.  This allows for curbit to be located
279         @ at the left end of each 4 bit nibbles in the division loop
280         @ to save one loop in most cases.
281         tst     \divisor, #0xe0000000
282         moveq   \divisor, \divisor, lsl #3
283         moveq   \curbit, #8
284         movne   \curbit, #1
285
286         @ Unless the divisor is very big, shift it up in multiples of
287         @ four bits, since this is the amount of unwinding in the main
288         @ division loop.  Continue shifting until the divisor is 
289         @ larger than the dividend.
290 1:      cmp     \divisor, #0x10000000
291         cmplo   \divisor, \dividend
292         movlo   \divisor, \divisor, lsl #4
293         movlo   \curbit, \curbit, lsl #4
294         blo     1b
295
296         @ For very big divisors, we must shift it a bit at a time, or
297         @ we will be in danger of overflowing.
298 1:      cmp     \divisor, #0x80000000
299         cmplo   \divisor, \dividend
300         movlo   \divisor, \divisor, lsl #1
301         movlo   \curbit, \curbit, lsl #1
302         blo     1b
303
304         mov     \result, #0
305
306 #endif /* __ARM_ARCH__ < 5 */
307
308         @ Division loop
309 1:      cmp     \dividend, \divisor
310         subhs   \dividend, \dividend, \divisor
311         orrhs   \result,   \result,   \curbit
312         cmp     \dividend, \divisor,  lsr #1
313         subhs   \dividend, \dividend, \divisor, lsr #1
314         orrhs   \result,   \result,   \curbit,  lsr #1
315         cmp     \dividend, \divisor,  lsr #2
316         subhs   \dividend, \dividend, \divisor, lsr #2
317         orrhs   \result,   \result,   \curbit,  lsr #2
318         cmp     \dividend, \divisor,  lsr #3
319         subhs   \dividend, \dividend, \divisor, lsr #3
320         orrhs   \result,   \result,   \curbit,  lsr #3
321         cmp     \dividend, #0                   @ Early termination?
322         movnes  \curbit,   \curbit,  lsr #4     @ No, any more bits to do?
323         movne   \divisor,  \divisor, lsr #4
324         bne     1b
325
326 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
327
328 .endm
329 /* ------------------------------------------------------------------------ */  
330 .macro ARM_DIV2_ORDER divisor, order
331
332 #if __ARM_ARCH__ >= 5
333
334         clz     \order, \divisor
335         rsb     \order, \order, #31
336
337 #else
338
339         cmp     \divisor, #(1 << 16)
340         movhs   \divisor, \divisor, lsr #16
341         movhs   \order, #16
342         movlo   \order, #0
343
344         cmp     \divisor, #(1 << 8)
345         movhs   \divisor, \divisor, lsr #8
346         addhs   \order, \order, #8
347
348         cmp     \divisor, #(1 << 4)
349         movhs   \divisor, \divisor, lsr #4
350         addhs   \order, \order, #4
351
352         cmp     \divisor, #(1 << 2)
353         addhi   \order, \order, #3
354         addls   \order, \order, \divisor, lsr #1
355
356 #endif
357
358 .endm
359 /* ------------------------------------------------------------------------ */
360 .macro ARM_MOD_BODY dividend, divisor, order, spare
361
362 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
363
364         clz     \order, \divisor
365         clz     \spare, \dividend
366         sub     \order, \order, \spare
367         rsbs    \order, \order, #31
368         addne   pc, pc, \order, lsl #3
369         nop
370         .set    shift, 32
371         .rept   32
372         .set    shift, shift - 1
373         cmp     \dividend, \divisor, lsl #shift
374         subcs   \dividend, \dividend, \divisor, lsl #shift
375         .endr
376
377 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
378 #if __ARM_ARCH__ >= 5
379
380         clz     \order, \divisor
381         clz     \spare, \dividend
382         sub     \order, \order, \spare
383         mov     \divisor, \divisor, lsl \order
384         
385 #else /* __ARM_ARCH__ < 5 */
386
387         mov     \order, #0
388
389         @ Unless the divisor is very big, shift it up in multiples of
390         @ four bits, since this is the amount of unwinding in the main
391         @ division loop.  Continue shifting until the divisor is 
392         @ larger than the dividend.
393 1:      cmp     \divisor, #0x10000000
394         cmplo   \divisor, \dividend
395         movlo   \divisor, \divisor, lsl #4
396         addlo   \order, \order, #4
397         blo     1b
398
399         @ For very big divisors, we must shift it a bit at a time, or
400         @ we will be in danger of overflowing.
401 1:      cmp     \divisor, #0x80000000
402         cmplo   \divisor, \dividend
403         movlo   \divisor, \divisor, lsl #1
404         addlo   \order, \order, #1
405         blo     1b
406
407 #endif /* __ARM_ARCH__ < 5 */
408
409         @ Perform all needed substractions to keep only the reminder.
410         @ Do comparisons in batch of 4 first.
411         subs    \order, \order, #3              @ yes, 3 is intended here
412         blt     2f
413
414 1:      cmp     \dividend, \divisor
415         subhs   \dividend, \dividend, \divisor
416         cmp     \dividend, \divisor,  lsr #1
417         subhs   \dividend, \dividend, \divisor, lsr #1
418         cmp     \dividend, \divisor,  lsr #2
419         subhs   \dividend, \dividend, \divisor, lsr #2
420         cmp     \dividend, \divisor,  lsr #3
421         subhs   \dividend, \dividend, \divisor, lsr #3
422         cmp     \dividend, #1
423         mov     \divisor, \divisor, lsr #4
424         subges  \order, \order, #4
425         bge     1b
426
427         tst     \order, #3
428         teqne   \dividend, #0
429         beq     5f
430
431         @ Either 1, 2 or 3 comparison/substractions are left.
432 2:      cmn     \order, #2
433         blt     4f
434         beq     3f
435         cmp     \dividend, \divisor
436         subhs   \dividend, \dividend, \divisor
437         mov     \divisor,  \divisor,  lsr #1
438 3:      cmp     \dividend, \divisor
439         subhs   \dividend, \dividend, \divisor
440         mov     \divisor,  \divisor,  lsr #1
441 4:      cmp     \dividend, \divisor
442         subhs   \dividend, \dividend, \divisor
443 5:
444
445 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
446
447 .endm
448 /* ------------------------------------------------------------------------ */
449 .macro THUMB_DIV_MOD_BODY modulo
450         @ Load the constant 0x10000000 into our work register.
451         mov     work, #1
452         lsl     work, #28
453 LSYM(Loop1):
454         @ Unless the divisor is very big, shift it up in multiples of
455         @ four bits, since this is the amount of unwinding in the main
456         @ division loop.  Continue shifting until the divisor is 
457         @ larger than the dividend.
458         cmp     divisor, work
459         bhs     LSYM(Lbignum)
460         cmp     divisor, dividend
461         bhs     LSYM(Lbignum)
462         lsl     divisor, #4
463         lsl     curbit,  #4
464         b       LSYM(Loop1)
465 LSYM(Lbignum):
466         @ Set work to 0x80000000
467         lsl     work, #3
468 LSYM(Loop2):
469         @ For very big divisors, we must shift it a bit at a time, or
470         @ we will be in danger of overflowing.
471         cmp     divisor, work
472         bhs     LSYM(Loop3)
473         cmp     divisor, dividend
474         bhs     LSYM(Loop3)
475         lsl     divisor, #1
476         lsl     curbit,  #1
477         b       LSYM(Loop2)
478 LSYM(Loop3):
479         @ Test for possible subtractions ...
480   .if \modulo
481         @ ... On the final pass, this may subtract too much from the dividend, 
482         @ so keep track of which subtractions are done, we can fix them up 
483         @ afterwards.
484         mov     overdone, #0
485         cmp     dividend, divisor
486         blo     LSYM(Lover1)
487         sub     dividend, dividend, divisor
488 LSYM(Lover1):
489         lsr     work, divisor, #1
490         cmp     dividend, work
491         blo     LSYM(Lover2)
492         sub     dividend, dividend, work
493         mov     ip, curbit
494         mov     work, #1
495         ror     curbit, work
496         orr     overdone, curbit
497         mov     curbit, ip
498 LSYM(Lover2):
499         lsr     work, divisor, #2
500         cmp     dividend, work
501         blo     LSYM(Lover3)
502         sub     dividend, dividend, work
503         mov     ip, curbit
504         mov     work, #2
505         ror     curbit, work
506         orr     overdone, curbit
507         mov     curbit, ip
508 LSYM(Lover3):
509         lsr     work, divisor, #3
510         cmp     dividend, work
511         blo     LSYM(Lover4)
512         sub     dividend, dividend, work
513         mov     ip, curbit
514         mov     work, #3
515         ror     curbit, work
516         orr     overdone, curbit
517         mov     curbit, ip
518 LSYM(Lover4):
519         mov     ip, curbit
520   .else
521         @ ... and note which bits are done in the result.  On the final pass,
522         @ this may subtract too much from the dividend, but the result will be ok,
523         @ since the "bit" will have been shifted out at the bottom.
524         cmp     dividend, divisor
525         blo     LSYM(Lover1)
526         sub     dividend, dividend, divisor
527         orr     result, result, curbit
528 LSYM(Lover1):
529         lsr     work, divisor, #1
530         cmp     dividend, work
531         blo     LSYM(Lover2)
532         sub     dividend, dividend, work
533         lsr     work, curbit, #1
534         orr     result, work
535 LSYM(Lover2):
536         lsr     work, divisor, #2
537         cmp     dividend, work
538         blo     LSYM(Lover3)
539         sub     dividend, dividend, work
540         lsr     work, curbit, #2
541         orr     result, work
542 LSYM(Lover3):
543         lsr     work, divisor, #3
544         cmp     dividend, work
545         blo     LSYM(Lover4)
546         sub     dividend, dividend, work
547         lsr     work, curbit, #3
548         orr     result, work
549 LSYM(Lover4):
550   .endif
551         
552         cmp     dividend, #0                    @ Early termination?
553         beq     LSYM(Lover5)
554         lsr     curbit,  #4                     @ No, any more bits to do?
555         beq     LSYM(Lover5)
556         lsr     divisor, #4
557         b       LSYM(Loop3)
558 LSYM(Lover5):
559   .if \modulo
560         @ Any subtractions that we should not have done will be recorded in
561         @ the top three bits of "overdone".  Exactly which were not needed
562         @ are governed by the position of the bit, stored in ip.
563         mov     work, #0xe
564         lsl     work, #28
565         and     overdone, work
566         beq     LSYM(Lgot_result)
567         
568         @ If we terminated early, because dividend became zero, then the 
569         @ bit in ip will not be in the bottom nibble, and we should not
570         @ perform the additions below.  We must test for this though
571         @ (rather relying upon the TSTs to prevent the additions) since
572         @ the bit in ip could be in the top two bits which might then match
573         @ with one of the smaller RORs.
574         mov     curbit, ip
575         mov     work, #0x7
576         tst     curbit, work
577         beq     LSYM(Lgot_result)
578         
579         mov     curbit, ip
580         mov     work, #3
581         ror     curbit, work
582         tst     overdone, curbit
583         beq     LSYM(Lover6)
584         lsr     work, divisor, #3
585         add     dividend, work
586 LSYM(Lover6):
587         mov     curbit, ip
588         mov     work, #2
589         ror     curbit, work
590         tst     overdone, curbit
591         beq     LSYM(Lover7)
592         lsr     work, divisor, #2
593         add     dividend, work
594 LSYM(Lover7):
595         mov     curbit, ip
596         mov     work, #1
597         ror     curbit, work
598         tst     overdone, curbit
599         beq     LSYM(Lgot_result)
600         lsr     work, divisor, #1
601         add     dividend, work
602   .endif
603 LSYM(Lgot_result):
604 .endm   
605 /* ------------------------------------------------------------------------ */
606 /*              Start of the Real Functions                                 */
607 /* ------------------------------------------------------------------------ */
608 #ifdef L_udivsi3
609
610         FUNC_START udivsi3
611
612 #ifdef __thumb__
613
614         cmp     divisor, #0
615         beq     LSYM(Ldiv0)
616         mov     curbit, #1
617         mov     result, #0
618         
619         push    { work }
620         cmp     dividend, divisor
621         blo     LSYM(Lgot_result)
622
623         THUMB_DIV_MOD_BODY 0
624         
625         mov     r0, result
626         pop     { work }
627         RET
628
629 #else /* ARM version.  */
630
631         subs    r2, r1, #1
632         RETc(eq)
633         bcc     LSYM(Ldiv0)
634         cmp     r0, r1
635         bls     11f
636         tst     r1, r2
637         beq     12f
638         
639         ARM_DIV_BODY r0, r1, r2, r3
640         
641         mov     r0, r2
642         RET     
643
644 11:     moveq   r0, #1
645         movne   r0, #0
646         RET
647
648 12:     ARM_DIV2_ORDER r1, r2
649
650         mov     r0, r0, lsr r2
651         RET
652
653 #endif /* ARM version */
654
655         DIV_FUNC_END udivsi3
656
657 #endif /* L_udivsi3 */
658 /* ------------------------------------------------------------------------ */
659 #ifdef L_umodsi3
660
661         FUNC_START umodsi3
662
663 #ifdef __thumb__
664
665         cmp     divisor, #0
666         beq     LSYM(Ldiv0)
667         mov     curbit, #1
668         cmp     dividend, divisor
669         bhs     LSYM(Lover10)
670         RET     
671
672 LSYM(Lover10):
673         push    { work }
674
675         THUMB_DIV_MOD_BODY 1
676         
677         pop     { work }
678         RET
679         
680 #else  /* ARM version.  */
681         
682         subs    r2, r1, #1                      @ compare divisor with 1
683         bcc     LSYM(Ldiv0)
684         cmpne   r0, r1                          @ compare dividend with divisor
685         moveq   r0, #0
686         tsthi   r1, r2                          @ see if divisor is power of 2
687         andeq   r0, r0, r2
688         RETc(ls)
689
690         ARM_MOD_BODY r0, r1, r2, r3
691         
692         RET     
693
694 #endif /* ARM version.  */
695         
696         DIV_FUNC_END umodsi3
697
698 #endif /* L_umodsi3 */
699 /* ------------------------------------------------------------------------ */
700 #ifdef L_divsi3
701
702         FUNC_START divsi3       
703
704 #ifdef __thumb__
705         cmp     divisor, #0
706         beq     LSYM(Ldiv0)
707         
708         push    { work }
709         mov     work, dividend
710         eor     work, divisor           @ Save the sign of the result.
711         mov     ip, work
712         mov     curbit, #1
713         mov     result, #0
714         cmp     divisor, #0
715         bpl     LSYM(Lover10)
716         neg     divisor, divisor        @ Loops below use unsigned.
717 LSYM(Lover10):
718         cmp     dividend, #0
719         bpl     LSYM(Lover11)
720         neg     dividend, dividend
721 LSYM(Lover11):
722         cmp     dividend, divisor
723         blo     LSYM(Lgot_result)
724
725         THUMB_DIV_MOD_BODY 0
726         
727         mov     r0, result
728         mov     work, ip
729         cmp     work, #0
730         bpl     LSYM(Lover12)
731         neg     r0, r0
732 LSYM(Lover12):
733         pop     { work }
734         RET
735
736 #else /* ARM version.  */
737         
738         cmp     r1, #0
739         eor     ip, r0, r1                      @ save the sign of the result.
740         beq     LSYM(Ldiv0)
741         rsbmi   r1, r1, #0                      @ loops below use unsigned.
742         subs    r2, r1, #1                      @ division by 1 or -1 ?
743         beq     10f
744         movs    r3, r0
745         rsbmi   r3, r0, #0                      @ positive dividend value
746         cmp     r3, r1
747         bls     11f
748         tst     r1, r2                          @ divisor is power of 2 ?
749         beq     12f
750
751         ARM_DIV_BODY r3, r1, r0, r2
752         
753         cmp     ip, #0
754         rsbmi   r0, r0, #0
755         RET     
756
757 10:     teq     ip, r0                          @ same sign ?
758         rsbmi   r0, r0, #0
759         RET     
760
761 11:     movlo   r0, #0
762         moveq   r0, ip, asr #31
763         orreq   r0, r0, #1
764         RET
765
766 12:     ARM_DIV2_ORDER r1, r2
767
768         cmp     ip, #0
769         mov     r0, r3, lsr r2
770         rsbmi   r0, r0, #0
771         RET
772
773 #endif /* ARM version */
774         
775         DIV_FUNC_END divsi3
776
777 #endif /* L_divsi3 */
778 /* ------------------------------------------------------------------------ */
779 #ifdef L_modsi3
780
781         FUNC_START modsi3
782
783 #ifdef __thumb__
784
785         mov     curbit, #1
786         cmp     divisor, #0
787         beq     LSYM(Ldiv0)
788         bpl     LSYM(Lover10)
789         neg     divisor, divisor                @ Loops below use unsigned.
790 LSYM(Lover10):
791         push    { work }
792         @ Need to save the sign of the dividend, unfortunately, we need
793         @ work later on.  Must do this after saving the original value of
794         @ the work register, because we will pop this value off first.
795         push    { dividend }
796         cmp     dividend, #0
797         bpl     LSYM(Lover11)
798         neg     dividend, dividend
799 LSYM(Lover11):
800         cmp     dividend, divisor
801         blo     LSYM(Lgot_result)
802
803         THUMB_DIV_MOD_BODY 1
804                 
805         pop     { work }
806         cmp     work, #0
807         bpl     LSYM(Lover12)
808         neg     dividend, dividend
809 LSYM(Lover12):
810         pop     { work }
811         RET     
812
813 #else /* ARM version.  */
814         
815         cmp     r1, #0
816         beq     LSYM(Ldiv0)
817         rsbmi   r1, r1, #0                      @ loops below use unsigned.
818         movs    ip, r0                          @ preserve sign of dividend
819         rsbmi   r0, r0, #0                      @ if negative make positive
820         subs    r2, r1, #1                      @ compare divisor with 1
821         cmpne   r0, r1                          @ compare dividend with divisor
822         moveq   r0, #0
823         tsthi   r1, r2                          @ see if divisor is power of 2
824         andeq   r0, r0, r2
825         bls     10f
826
827         ARM_MOD_BODY r0, r1, r2, r3
828
829 10:     cmp     ip, #0
830         rsbmi   r0, r0, #0
831         RET     
832
833 #endif /* ARM version */
834         
835         DIV_FUNC_END modsi3
836
837 #endif /* L_modsi3 */
838 /* ------------------------------------------------------------------------ */
839 #ifdef L_dvmd_tls
840
841         FUNC_START div0
842
843         RET
844
845         FUNC_END div0
846         
847 #endif /* L_divmodsi_tools */
848 /* ------------------------------------------------------------------------ */
849 #ifdef L_dvmd_lnx
850 @ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
851
852 /* Constants taken from <asm/unistd.h> and <asm/signal.h> */
853 #define SIGFPE  8
854 #define __NR_SYSCALL_BASE       0x900000
855 #define __NR_getpid                     (__NR_SYSCALL_BASE+ 20)
856 #define __NR_kill                       (__NR_SYSCALL_BASE+ 37)
857
858         .code   32
859         FUNC_START div0
860
861         stmfd   sp!, {r1, lr}
862         swi     __NR_getpid
863         cmn     r0, #1000
864         RETLDM  r1 hs
865         mov     r1, #SIGFPE
866         swi     __NR_kill
867         RETLDM  r1
868
869         FUNC_END div0
870         
871 #endif /* L_dvmd_lnx */
872 /* ------------------------------------------------------------------------ */
873 /* These next two sections are here despite the fact that they contain Thumb 
874    assembler because their presence allows interworked code to be linked even
875    when the GCC library is this one.  */
876                 
877 /* Do not build the interworking functions when the target architecture does 
878    not support Thumb instructions.  (This can be a multilib option).  */
879 #if defined L_call_via_rX && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
880
881 /* These labels & instructions are used by the Arm/Thumb interworking code. 
882    The address of function to be called is loaded into a register and then 
883    one of these labels is called via a BL instruction.  This puts the 
884    return address into the link register with the bottom bit set, and the 
885    code here switches to the correct mode before executing the function.  */
886         
887         .text
888         .align 0
889         .force_thumb
890
891 .macro call_via register
892         THUMB_FUNC_START _call_via_\register
893
894         bx      \register
895         nop
896
897         SIZE    (_call_via_\register)
898 .endm
899
900         call_via r0
901         call_via r1
902         call_via r2
903         call_via r3
904         call_via r4
905         call_via r5
906         call_via r6
907         call_via r7
908         call_via r8
909         call_via r9
910         call_via sl
911         call_via fp
912         call_via ip
913         call_via sp
914         call_via lr
915
916 #endif /* L_call_via_rX */
917 /* ------------------------------------------------------------------------ */
918 /* Do not build the interworking functions when the target architecture does 
919    not support Thumb instructions.  (This can be a multilib option).  */
920 #if defined L_interwork_call_via_rX && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
921
922 /* These labels & instructions are used by the Arm/Thumb interworking code,
923    when the target address is in an unknown instruction set.  The address 
924    of function to be called is loaded into a register and then one of these
925    labels is called via a BL instruction.  This puts the return address 
926    into the link register with the bottom bit set, and the code here 
927    switches to the correct mode before executing the function.  Unfortunately
928    the target code cannot be relied upon to return via a BX instruction, so
929    instead we have to store the resturn address on the stack and allow the
930    called function to return here instead.  Upon return we recover the real
931    return address and use a BX to get back to Thumb mode.  */
932         
933         .text
934         .align 0
935
936         .code   32
937         .globl _arm_return
938 _arm_return:
939         RETLDM
940         .code   16
941
942 .macro interwork register
943         .code   16
944
945         THUMB_FUNC_START _interwork_call_via_\register
946
947         bx      pc
948         nop
949
950         .code   32
951         .globl LSYM(Lchange_\register)
952 LSYM(Lchange_\register):
953         tst     \register, #1
954         streq   lr, [sp, #-4]!
955         adreq   lr, _arm_return
956         bx      \register
957
958         SIZE    (_interwork_call_via_\register)
959 .endm
960         
961         interwork r0
962         interwork r1
963         interwork r2
964         interwork r3
965         interwork r4
966         interwork r5
967         interwork r6
968         interwork r7
969         interwork r8
970         interwork r9
971         interwork sl
972         interwork fp
973         interwork ip
974         interwork sp
975         
976         /* The LR case has to be handled a little differently...  */
977         .code 16
978
979         THUMB_FUNC_START _interwork_call_via_lr
980
981         bx      pc
982         nop
983         
984         .code 32
985         .globl .Lchange_lr
986 .Lchange_lr:
987         tst     lr, #1
988         stmeqdb r13!, {lr}
989         mov     ip, lr
990         adreq   lr, _arm_return
991         bx      ip
992         
993         SIZE    (_interwork_call_via_lr)
994         
995 #endif /* L_interwork_call_via_rX */
996
997 #include "ieee754-df.S"
998 #include "ieee754-sf.S"
999