OSDN Git Service

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