]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gcc/config/arm/lib1funcs.asm
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / 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, 2005
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, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, 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 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_5E__) || defined(__ARM_ARCH_5TE__) \
78         || defined(__ARM_ARCH_5TEJ__)
79 # undef __ARM_ARCH__
80 # define __ARM_ARCH__ 5
81 #endif
82
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
89
90 #ifndef __ARM_ARCH__
91 #error Unable to determine architecture.
92 #endif
93
94 /* How to return from a function call depends on the architecture variant.  */
95
96 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
97
98 # define RET            bx      lr
99 # define RETc(x)        bx##x   lr
100
101 /* Special precautions for interworking on armv4t.  */
102 # if (__ARM_ARCH__ == 4)
103
104 /* Always use bx, not ldr pc.  */
105 #  if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
106 #    define __INTERWORKING__
107 #   endif /* __THUMB__ || __THUMB_INTERWORK__ */
108
109 /* Include thumb stub before arm mode code.  */
110 #  if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
111 #   define __INTERWORKING_STUBS__
112 #  endif /* __thumb__ && !__THUMB_INTERWORK__ */
113
114 #endif /* __ARM_ARCH == 4 */
115
116 #else
117
118 # define RET            mov     pc, lr
119 # define RETc(x)        mov##x  pc, lr
120
121 #endif
122
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
161
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
181
182 /* Don't pass dirn, it's there just to get token pasting right.  */
183
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
204
205
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
213
214
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
227
228 .macro FUNC_END name
229         SIZE (__\name)
230 .endm
231
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
243
244 .macro THUMB_FUNC_START name
245         .globl  SYM (\name)
246         TYPE    (\name)
247         .thumb_func
248 SYM (\name):
249 .endm
250
251 /* Function start macros.  Variants for ARM and Thumb.  */
252
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
260         
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
270
271 /* Special function that will always be coded in ARM assembly, even if
272    in Thumb-only compilation.  */
273
274 #if defined(__INTERWORKING_STUBS__)
275 .macro  ARM_FUNC_START name
276         FUNC_START \name
277         bx      pc
278         nop
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
304
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
313
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
321
322 #ifdef __thumb__
323 /* Register aliases.  */
324
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
338
339 /* ------------------------------------------------------------------------ */
340 /*              Bodies of the division and modulo routines.                 */
341 /* ------------------------------------------------------------------------ */  
342 .macro ARM_DIV_BODY dividend, divisor, result, curbit
343
344 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
345
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
353         nop
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
361
362 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
363 #if __ARM_ARCH__ >= 5
364
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
372         
373 #else /* __ARM_ARCH__ < 5 */
374
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
383
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
393
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
401
402         mov     \result, #0
403
404 #endif /* __ARM_ARCH__ < 5 */
405
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
423
424 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
425
426 .endm
427 /* ------------------------------------------------------------------------ */  
428 .macro ARM_DIV2_ORDER divisor, order
429
430 #if __ARM_ARCH__ >= 5
431
432         clz     \order, \divisor
433         rsb     \order, \order, #31
434
435 #else
436
437         cmp     \divisor, #(1 << 16)
438         movhs   \divisor, \divisor, lsr #16
439         movhs   \order, #16
440         movlo   \order, #0
441
442         cmp     \divisor, #(1 << 8)
443         movhs   \divisor, \divisor, lsr #8
444         addhs   \order, \order, #8
445
446         cmp     \divisor, #(1 << 4)
447         movhs   \divisor, \divisor, lsr #4
448         addhs   \order, \order, #4
449
450         cmp     \divisor, #(1 << 2)
451         addhi   \order, \order, #3
452         addls   \order, \order, \divisor, lsr #1
453
454 #endif
455
456 .endm
457 /* ------------------------------------------------------------------------ */
458 .macro ARM_MOD_BODY dividend, divisor, order, spare
459
460 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
461
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
467         nop
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
474
475 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
476 #if __ARM_ARCH__ >= 5
477
478         clz     \order, \divisor
479         clz     \spare, \dividend
480         sub     \order, \order, \spare
481         mov     \divisor, \divisor, lsl \order
482         
483 #else /* __ARM_ARCH__ < 5 */
484
485         mov     \order, #0
486
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
496
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
504
505 #endif /* __ARM_ARCH__ < 5 */
506
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
511
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
524
525         tst     \order, #3
526         teqne   \dividend, #0
527         beq     5f
528
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
541 5:
542
543 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
544
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
649         
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)
665         
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)
676         
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
707
708         FUNC_START udivsi3
709         FUNC_ALIAS aeabi_uidiv udivsi3
710
711 #ifdef __thumb__
712
713         cmp     divisor, #0
714         beq     LSYM(Ldiv0)
715         mov     curbit, #1
716         mov     result, #0
717         
718         push    { work }
719         cmp     dividend, divisor
720         blo     LSYM(Lgot_result)
721
722         THUMB_DIV_MOD_BODY 0
723         
724         mov     r0, result
725         pop     { work }
726         RET
727
728 #else /* ARM version.  */
729
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
737         
738         ARM_DIV_BODY r0, r1, r2, r3
739         
740         mov     r0, r2
741         RET     
742
743 11:     moveq   r0, #1
744         movne   r0, #0
745         RET
746
747 12:     ARM_DIV2_ORDER r1, r2
748
749         mov     r0, r0, lsr r2
750         RET
751
752 #endif /* ARM version */
753
754         DIV_FUNC_END udivsi3
755
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
770         RET
771 #endif
772         FUNC_END aeabi_uidivmod
773         
774 #endif /* L_udivsi3 */
775 /* ------------------------------------------------------------------------ */
776 #ifdef L_umodsi3
777
778         FUNC_START umodsi3
779
780 #ifdef __thumb__
781
782         cmp     divisor, #0
783         beq     LSYM(Ldiv0)
784         mov     curbit, #1
785         cmp     dividend, divisor
786         bhs     LSYM(Lover10)
787         RET     
788
789 LSYM(Lover10):
790         push    { work }
791
792         THUMB_DIV_MOD_BODY 1
793         
794         pop     { work }
795         RET
796         
797 #else  /* ARM version.  */
798         
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)
806
807         ARM_MOD_BODY r0, r1, r2, r3
808         
809         RET     
810
811 #endif /* ARM version.  */
812         
813         DIV_FUNC_END umodsi3
814
815 #endif /* L_umodsi3 */
816 /* ------------------------------------------------------------------------ */
817 #ifdef L_divsi3
818
819         FUNC_START divsi3       
820         FUNC_ALIAS aeabi_idiv divsi3
821
822 #ifdef __thumb__
823         cmp     divisor, #0
824         beq     LSYM(Ldiv0)
825         
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)
842
843         THUMB_DIV_MOD_BODY 0
844         
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 }
852         RET
853
854 #else /* ARM version.  */
855         
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
868
869         ARM_DIV_BODY r3, r1, r0, r2
870         
871         cmp     ip, #0
872         rsbmi   r0, r0, #0
873         RET     
874
875 10:     teq     ip, r0                          @ same sign ?
876         rsbmi   r0, r0, #0
877         RET     
878
879 11:     movlo   r0, #0
880         moveq   r0, ip, asr #31
881         orreq   r0, r0, #1
882         RET
883
884 12:     ARM_DIV2_ORDER r1, r2
885
886         cmp     ip, #0
887         mov     r0, r3, lsr r2
888         rsbmi   r0, r0, #0
889         RET
890
891 #endif /* ARM version */
892         
893         DIV_FUNC_END divsi3
894
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
909         RET
910 #endif
911         FUNC_END aeabi_idivmod
912         
913 #endif /* L_divsi3 */
914 /* ------------------------------------------------------------------------ */
915 #ifdef L_modsi3
916
917         FUNC_START modsi3
918
919 #ifdef __thumb__
920
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)
938
939         THUMB_DIV_MOD_BODY 1
940                 
941         pop     { work }
942         cmp     work, #0
943         bpl     LSYM(Lover12)
944         neg     dividend, dividend
945 LSYM(Lover12):
946         pop     { work }
947         RET     
948
949 #else /* ARM version.  */
950         
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
962
963         ARM_MOD_BODY r0, r1, r2, r3
964
965 10:     cmp     ip, #0
966         rsbmi   r0, r0, #0
967         RET     
968
969 #endif /* ARM version */
970         
971         DIV_FUNC_END modsi3
972
973 #endif /* L_modsi3 */
974 /* ------------------------------------------------------------------------ */
975 #ifdef L_dvmd_tls
976
977         FUNC_START div0
978         FUNC_ALIAS aeabi_idiv0 div0
979         FUNC_ALIAS aeabi_ldiv0 div0
980
981         RET
982
983         FUNC_END aeabi_ldiv0
984         FUNC_END aeabi_idiv0
985         FUNC_END div0
986         
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
991
992 /* Constant taken from <asm/signal.h>.  */
993 #define SIGFPE  8
994
995         .code   32
996         FUNC_START div0
997
998         stmfd   sp!, {r1, lr}
999         mov     r0, #SIGFPE
1000         bl      SYM(raise) __PLT__
1001         RETLDM  r1
1002
1003         FUNC_END div0
1004         
1005 #endif /* L_dvmd_lnx */
1006 /* ------------------------------------------------------------------------ */
1007 /* Dword shift operations.  */
1008 /* All the following Dword shift variants rely on the fact that
1009         shft xxx, Reg
1010    is in fact done as
1011         shft xxx, (Reg & 255)
1012    so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1013    case of logical shifts) or the sign (for asr).  */
1014
1015 #ifdef __ARMEB__
1016 #define al      r1
1017 #define ah      r0
1018 #else
1019 #define al      r0
1020 #define ah      r1
1021 #endif
1022
1023 /* Prevent __aeabi double-word shifts from being produced on SymbianOS.  */
1024 #ifndef __symbian__
1025
1026 #ifdef L_lshrdi3
1027
1028         FUNC_START lshrdi3
1029         FUNC_ALIAS aeabi_llsr lshrdi3
1030         
1031 #ifdef __thumb__
1032         lsr     al, r2
1033         mov     r3, ah
1034         lsr     ah, r2
1035         mov     ip, r3
1036         sub     r2, #32
1037         lsr     r3, r2
1038         orr     al, r3
1039         neg     r2, r2
1040         mov     r3, ip
1041         lsl     r3, r2
1042         orr     al, r3
1043         RET
1044 #else
1045         subs    r3, r2, #32
1046         rsb     ip, r2, #32
1047         movmi   al, al, lsr r2
1048         movpl   al, ah, lsr r3
1049         orrmi   al, al, ah, lsl ip
1050         mov     ah, ah, lsr r2
1051         RET
1052 #endif
1053         FUNC_END aeabi_llsr
1054         FUNC_END lshrdi3
1055
1056 #endif
1057         
1058 #ifdef L_ashrdi3
1059         
1060         FUNC_START ashrdi3
1061         FUNC_ALIAS aeabi_lasr ashrdi3
1062         
1063 #ifdef __thumb__
1064         lsr     al, r2
1065         mov     r3, ah
1066         asr     ah, r2
1067         sub     r2, #32
1068         @ If r2 is negative at this point the following step would OR
1069         @ the sign bit into all of AL.  That's not what we want...
1070         bmi     1f
1071         mov     ip, r3
1072         asr     r3, r2
1073         orr     al, r3
1074         mov     r3, ip
1075 1:
1076         neg     r2, r2
1077         lsl     r3, r2
1078         orr     al, r3
1079         RET
1080 #else
1081         subs    r3, r2, #32
1082         rsb     ip, r2, #32
1083         movmi   al, al, lsr r2
1084         movpl   al, ah, asr r3
1085         orrmi   al, al, ah, lsl ip
1086         mov     ah, ah, asr r2
1087         RET
1088 #endif
1089
1090         FUNC_END aeabi_lasr
1091         FUNC_END ashrdi3
1092
1093 #endif
1094
1095 #ifdef L_ashldi3
1096
1097         FUNC_START ashldi3
1098         FUNC_ALIAS aeabi_llsl ashldi3
1099         
1100 #ifdef __thumb__
1101         lsl     ah, r2
1102         mov     r3, al
1103         lsl     al, r2
1104         mov     ip, r3
1105         sub     r2, #32
1106         lsl     r3, r2
1107         orr     ah, r3
1108         neg     r2, r2
1109         mov     r3, ip
1110         lsr     r3, r2
1111         orr     ah, r3
1112         RET
1113 #else
1114         subs    r3, r2, #32
1115         rsb     ip, r2, #32
1116         movmi   ah, ah, lsl r2
1117         movpl   ah, al, lsl r3
1118         orrmi   ah, ah, al, lsr ip
1119         mov     al, al, lsl r2
1120         RET
1121 #endif
1122         FUNC_END aeabi_llsl
1123         FUNC_END ashldi3
1124
1125 #endif
1126
1127 #endif /* __symbian__ */
1128
1129 /* ------------------------------------------------------------------------ */
1130 /* These next two sections are here despite the fact that they contain Thumb 
1131    assembler because their presence allows interworked code to be linked even
1132    when the GCC library is this one.  */
1133                 
1134 /* Do not build the interworking functions when the target architecture does 
1135    not support Thumb instructions.  (This can be a multilib option).  */
1136 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1137       || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1138       || __ARM_ARCH__ >= 6
1139
1140 #if defined L_call_via_rX
1141
1142 /* These labels & instructions are used by the Arm/Thumb interworking code. 
1143    The address of function to be called is loaded into a register and then 
1144    one of these labels is called via a BL instruction.  This puts the 
1145    return address into the link register with the bottom bit set, and the 
1146    code here switches to the correct mode before executing the function.  */
1147         
1148         .text
1149         .align 0
1150         .force_thumb
1151
1152 .macro call_via register
1153         THUMB_FUNC_START _call_via_\register
1154
1155         bx      \register
1156         nop
1157
1158         SIZE    (_call_via_\register)
1159 .endm
1160
1161         call_via r0
1162         call_via r1
1163         call_via r2
1164         call_via r3
1165         call_via r4
1166         call_via r5
1167         call_via r6
1168         call_via r7
1169         call_via r8
1170         call_via r9
1171         call_via sl
1172         call_via fp
1173         call_via ip
1174         call_via sp
1175         call_via lr
1176
1177 #endif /* L_call_via_rX */
1178
1179 #if defined L_interwork_call_via_rX
1180
1181 /* These labels & instructions are used by the Arm/Thumb interworking code,
1182    when the target address is in an unknown instruction set.  The address 
1183    of function to be called is loaded into a register and then one of these
1184    labels is called via a BL instruction.  This puts the return address 
1185    into the link register with the bottom bit set, and the code here 
1186    switches to the correct mode before executing the function.  Unfortunately
1187    the target code cannot be relied upon to return via a BX instruction, so
1188    instead we have to store the resturn address on the stack and allow the
1189    called function to return here instead.  Upon return we recover the real
1190    return address and use a BX to get back to Thumb mode.
1191
1192    There are three variations of this code.  The first,
1193    _interwork_call_via_rN(), will push the return address onto the
1194    stack and pop it in _arm_return().  It should only be used if all
1195    arguments are passed in registers.
1196
1197    The second, _interwork_r7_call_via_rN(), instead stores the return
1198    address at [r7, #-4].  It is the caller's responsibility to ensure
1199    that this address is valid and contains no useful data.
1200
1201    The third, _interwork_r11_call_via_rN(), works in the same way but
1202    uses r11 instead of r7.  It is useful if the caller does not really
1203    need a frame pointer.  */
1204         
1205         .text
1206         .align 0
1207
1208         .code   32
1209         .globl _arm_return
1210 LSYM(Lstart_arm_return):
1211         cfi_start       LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1212         cfi_push        0, 0xe, -0x8, 0x8
1213         nop     @ This nop is for the benefit of debuggers, so that
1214                 @ backtraces will use the correct unwind information.
1215 _arm_return:
1216         RETLDM  unwind=LSYM(Lstart_arm_return)
1217         cfi_end LSYM(Lend_arm_return)
1218
1219         .globl _arm_return_r7
1220 _arm_return_r7:
1221         ldr     lr, [r7, #-4]
1222         bx      lr
1223
1224         .globl _arm_return_r11
1225 _arm_return_r11:
1226         ldr     lr, [r11, #-4]
1227         bx      lr
1228
1229 .macro interwork_with_frame frame, register, name, return
1230         .code   16
1231
1232         THUMB_FUNC_START \name
1233
1234         bx      pc
1235         nop
1236
1237         .code   32
1238         tst     \register, #1
1239         streq   lr, [\frame, #-4]
1240         adreq   lr, _arm_return_\frame
1241         bx      \register
1242
1243         SIZE    (\name)
1244 .endm
1245
1246 .macro interwork register
1247         .code   16
1248
1249         THUMB_FUNC_START _interwork_call_via_\register
1250
1251         bx      pc
1252         nop
1253
1254         .code   32
1255         .globl LSYM(Lchange_\register)
1256 LSYM(Lchange_\register):
1257         tst     \register, #1
1258         streq   lr, [sp, #-8]!
1259         adreq   lr, _arm_return
1260         bx      \register
1261
1262         SIZE    (_interwork_call_via_\register)
1263
1264         interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1265         interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1266 .endm
1267         
1268         interwork r0
1269         interwork r1
1270         interwork r2
1271         interwork r3
1272         interwork r4
1273         interwork r5
1274         interwork r6
1275         interwork r7
1276         interwork r8
1277         interwork r9
1278         interwork sl
1279         interwork fp
1280         interwork ip
1281         interwork sp
1282         
1283         /* The LR case has to be handled a little differently...  */
1284         .code 16
1285
1286         THUMB_FUNC_START _interwork_call_via_lr
1287
1288         bx      pc
1289         nop
1290         
1291         .code 32
1292         .globl .Lchange_lr
1293 .Lchange_lr:
1294         tst     lr, #1
1295         stmeqdb r13!, {lr, pc}
1296         mov     ip, lr
1297         adreq   lr, _arm_return
1298         bx      ip
1299         
1300         SIZE    (_interwork_call_via_lr)
1301         
1302 #endif /* L_interwork_call_via_rX */
1303 #endif /* Arch supports thumb.  */
1304
1305 #ifndef __symbian__
1306 #include "ieee754-df.S"
1307 #include "ieee754-sf.S"
1308 #include "bpabi.S"
1309 #endif /* __symbian__ */