OSDN Git Service

2010-02-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
[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, 2008,
5    2009  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 3, or (at your option) any
10 later version.
11
12 This file is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25
26 /* An executable stack is *not* required for these functions.  */
27 #if defined(__ELF__) && defined(__linux__)
28 .section .note.GNU-stack,"",%progbits
29 .previous
30 #endif  /* __ELF__ and __linux__ */
31
32 #ifdef __ARM_EABI__
33 /* Some attributes that are common to all routines in this file.  */
34         /* Tag_ABI_align8_needed: This code does not require 8-byte
35            alignment from the caller.  */
36         /* .eabi_attribute 24, 0  -- default setting.  */
37         /* Tag_ABI_align8_preserved: This code preserves 8-byte 
38            alignment in any callee.  */
39         .eabi_attribute 25, 1
40 #endif /* __ARM_EABI__ */
41 /* ------------------------------------------------------------------------ */
42
43 /* We need to know what prefix to add to function names.  */
44
45 #ifndef __USER_LABEL_PREFIX__
46 #error  __USER_LABEL_PREFIX__ not defined
47 #endif
48
49 /* ANSI concatenation macros.  */
50
51 #define CONCAT1(a, b) CONCAT2(a, b)
52 #define CONCAT2(a, b) a ## b
53
54 /* Use the right prefix for global labels.  */
55
56 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
57
58 #ifdef __ELF__
59 #ifdef __thumb__
60 #define __PLT__  /* Not supported in Thumb assembler (for now).  */
61 #elif defined __vxworks && !defined __PIC__
62 #define __PLT__ /* Not supported by the kernel loader.  */
63 #else
64 #define __PLT__ (PLT)
65 #endif
66 #define TYPE(x) .type SYM(x),function
67 #define SIZE(x) .size SYM(x), . - SYM(x)
68 #define LSYM(x) .x
69 #else
70 #define __PLT__
71 #define TYPE(x)
72 #define SIZE(x)
73 #define LSYM(x) x
74 #endif
75
76 /* Function end macros.  Variants for interworking.  */
77
78 #if defined(__ARM_ARCH_2__)
79 # define __ARM_ARCH__ 2
80 #endif
81
82 #if defined(__ARM_ARCH_3__)
83 # define __ARM_ARCH__ 3
84 #endif
85
86 #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
87         || defined(__ARM_ARCH_4T__)
88 /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
89    long multiply instructions.  That includes v3M.  */
90 # define __ARM_ARCH__ 4
91 #endif
92         
93 #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
94         || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
95         || defined(__ARM_ARCH_5TEJ__)
96 # define __ARM_ARCH__ 5
97 #endif
98
99 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
100         || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
101         || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
102         || defined(__ARM_ARCH_6M__)
103 # define __ARM_ARCH__ 6
104 #endif
105
106 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
107         || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
108 # define __ARM_ARCH__ 7
109 #endif
110
111 #ifndef __ARM_ARCH__
112 #error Unable to determine architecture.
113 #endif
114
115 /* There are times when we might prefer Thumb1 code even if ARM code is
116    permitted, for example, the code might be smaller, or there might be
117    interworking problems with switching to ARM state if interworking is
118    disabled.  */
119 #if (defined(__thumb__)                 \
120      && !defined(__thumb2__)            \
121      && (!defined(__THUMB_INTERWORK__)  \
122          || defined (__OPTIMIZE_SIZE__) \
123          || defined(__ARM_ARCH_6M__)))
124 # define __prefer_thumb__
125 #endif
126
127 /* How to return from a function call depends on the architecture variant.  */
128
129 #if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
130
131 # define RET            bx      lr
132 # define RETc(x)        bx##x   lr
133
134 /* Special precautions for interworking on armv4t.  */
135 # if (__ARM_ARCH__ == 4)
136
137 /* Always use bx, not ldr pc.  */
138 #  if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
139 #    define __INTERWORKING__
140 #   endif /* __THUMB__ || __THUMB_INTERWORK__ */
141
142 /* Include thumb stub before arm mode code.  */
143 #  if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
144 #   define __INTERWORKING_STUBS__
145 #  endif /* __thumb__ && !__THUMB_INTERWORK__ */
146
147 #endif /* __ARM_ARCH == 4 */
148
149 #else
150
151 # define RET            mov     pc, lr
152 # define RETc(x)        mov##x  pc, lr
153
154 #endif
155
156 .macro  cfi_pop         advance, reg, cfa_offset
157 #ifdef __ELF__
158         .pushsection    .debug_frame
159         .byte   0x4             /* DW_CFA_advance_loc4 */
160         .4byte  \advance
161         .byte   (0xc0 | \reg)   /* DW_CFA_restore */
162         .byte   0xe             /* DW_CFA_def_cfa_offset */
163         .uleb128 \cfa_offset
164         .popsection
165 #endif
166 .endm
167 .macro  cfi_push        advance, reg, offset, cfa_offset
168 #ifdef __ELF__
169         .pushsection    .debug_frame
170         .byte   0x4             /* DW_CFA_advance_loc4 */
171         .4byte  \advance
172         .byte   (0x80 | \reg)   /* DW_CFA_offset */
173         .uleb128 (\offset / -4)
174         .byte   0xe             /* DW_CFA_def_cfa_offset */
175         .uleb128 \cfa_offset
176         .popsection
177 #endif
178 .endm
179 .macro cfi_start        start_label, end_label
180 #ifdef __ELF__
181         .pushsection    .debug_frame
182 LSYM(Lstart_frame):
183         .4byte  LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
184 LSYM(Lstart_cie):
185         .4byte  0xffffffff      @ CIE Identifier Tag
186         .byte   0x1     @ CIE Version
187         .ascii  "\0"    @ CIE Augmentation
188         .uleb128 0x1    @ CIE Code Alignment Factor
189         .sleb128 -4     @ CIE Data Alignment Factor
190         .byte   0xe     @ CIE RA Column
191         .byte   0xc     @ DW_CFA_def_cfa
192         .uleb128 0xd
193         .uleb128 0x0
194
195         .align 2
196 LSYM(Lend_cie):
197         .4byte  LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
198 LSYM(Lstart_fde):
199         .4byte  LSYM(Lstart_frame)      @ FDE CIE offset
200         .4byte  \start_label    @ FDE initial location
201         .4byte  \end_label-\start_label @ FDE address range
202         .popsection
203 #endif
204 .endm
205 .macro cfi_end  end_label
206 #ifdef __ELF__
207         .pushsection    .debug_frame
208         .align  2
209 LSYM(Lend_fde):
210         .popsection
211 \end_label:
212 #endif
213 .endm
214
215 /* Don't pass dirn, it's there just to get token pasting right.  */
216
217 .macro  RETLDM  regs=, cond=, unwind=, dirn=ia
218 #if defined (__INTERWORKING__)
219         .ifc "\regs",""
220         ldr\cond        lr, [sp], #8
221         .else
222 # if defined(__thumb2__)
223         pop\cond        {\regs, lr}
224 # else
225         ldm\cond\dirn   sp!, {\regs, lr}
226 # endif
227         .endif
228         .ifnc "\unwind", ""
229         /* Mark LR as restored.  */
230 97:     cfi_pop 97b - \unwind, 0xe, 0x0
231         .endif
232         bx\cond lr
233 #else
234         /* Caller is responsible for providing IT instruction.  */
235         .ifc "\regs",""
236         ldr\cond        pc, [sp], #8
237         .else
238 # if defined(__thumb2__)
239         pop\cond        {\regs, pc}
240 # else
241         ldm\cond\dirn   sp!, {\regs, pc}
242 # endif
243         .endif
244 #endif
245 .endm
246
247 /* The Unified assembly syntax allows the same code to be assembled for both
248    ARM and Thumb-2.  However this is only supported by recent gas, so define
249    a set of macros to allow ARM code on older assemblers.  */
250 #if defined(__thumb2__)
251 .macro do_it cond, suffix=""
252         it\suffix       \cond
253 .endm
254 .macro shift1 op, arg0, arg1, arg2
255         \op     \arg0, \arg1, \arg2
256 .endm
257 #define do_push push
258 #define do_pop  pop
259 #define COND(op1, op2, cond) op1 ## op2 ## cond
260 /* Perform an arithmetic operation with a variable shift operand.  This
261    requires two instructions and a scratch register on Thumb-2.  */
262 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
263         \shiftop \tmp, \src2, \shiftreg
264         \name \dest, \src1, \tmp
265 .endm
266 #else
267 .macro do_it cond, suffix=""
268 .endm
269 .macro shift1 op, arg0, arg1, arg2
270         mov     \arg0, \arg1, \op \arg2
271 .endm
272 #define do_push stmfd sp!,
273 #define do_pop  ldmfd sp!,
274 #define COND(op1, op2, cond) op1 ## cond ## op2
275 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
276         \name \dest, \src1, \src2, \shiftop \shiftreg
277 .endm
278 #endif
279
280 #ifdef __ARM_EABI__
281 .macro ARM_LDIV0 name signed
282         cmp     r0, #0
283         .ifc    \signed, unsigned
284         movne   r0, #0xffffffff
285         .else
286         movgt   r0, #0x7fffffff
287         movlt   r0, #0x80000000
288         .endif
289         b       SYM (__aeabi_idiv0) __PLT__
290 .endm
291 #else
292 .macro ARM_LDIV0 name signed
293         str     lr, [sp, #-8]!
294 98:     cfi_push 98b - __\name, 0xe, -0x8, 0x8
295         bl      SYM (__div0) __PLT__
296         mov     r0, #0                  @ About as wrong as it could be.
297         RETLDM  unwind=98b
298 .endm
299 #endif
300
301
302 #ifdef __ARM_EABI__
303 .macro THUMB_LDIV0 name signed
304 #if defined(__ARM_ARCH_6M__)
305         .ifc \signed, unsigned
306         cmp     r0, #0
307         beq     1f
308         mov     r0, #0
309         mvn     r0, r0          @ 0xffffffff
310 1:
311         .else
312         cmp     r0, #0
313         beq     2f
314         blt     3f
315         mov     r0, #0
316         mvn     r0, r0
317         lsr     r0, r0, #1      @ 0x7fffffff
318         b       2f
319 3:      mov     r0, #0x80
320         lsl     r0, r0, #24     @ 0x80000000
321 2:
322         .endif
323         push    {r0, r1, r2}
324         ldr     r0, 4f
325         adr     r1, 4f
326         add     r0, r1
327         str     r0, [sp, #8]
328         @ We know we are not on armv4t, so pop pc is safe.
329         pop     {r0, r1, pc}
330         .align  2
331 4:
332         .word   __aeabi_idiv0 - 4b
333 #elif defined(__thumb2__)
334         .syntax unified
335         .ifc \signed, unsigned
336         cbz     r0, 1f
337         mov     r0, #0xffffffff
338 1:
339         .else
340         cmp     r0, #0
341         do_it   gt
342         movgt   r0, #0x7fffffff
343         do_it   lt
344         movlt   r0, #0x80000000
345         .endif
346         b.w     SYM(__aeabi_idiv0) __PLT__
347 #else
348         .align  2
349         bx      pc
350         nop
351         .arm
352         cmp     r0, #0
353         .ifc    \signed, unsigned
354         movne   r0, #0xffffffff
355         .else
356         movgt   r0, #0x7fffffff
357         movlt   r0, #0x80000000
358         .endif
359         b       SYM(__aeabi_idiv0) __PLT__
360         .thumb
361 #endif
362 .endm
363 #else
364 .macro THUMB_LDIV0 name signed
365         push    { r1, lr }
366 98:     cfi_push 98b - __\name, 0xe, -0x4, 0x8
367         bl      SYM (__div0)
368         mov     r0, #0                  @ About as wrong as it could be.
369 #if defined (__INTERWORKING__)
370         pop     { r1, r2 }
371         bx      r2
372 #else
373         pop     { r1, pc }
374 #endif
375 .endm
376 #endif
377
378 .macro FUNC_END name
379         SIZE (__\name)
380 .endm
381
382 .macro DIV_FUNC_END name signed
383         cfi_start       __\name, LSYM(Lend_div0)
384 LSYM(Ldiv0):
385 #ifdef __thumb__
386         THUMB_LDIV0 \name \signed
387 #else
388         ARM_LDIV0 \name \signed
389 #endif
390         cfi_end LSYM(Lend_div0)
391         FUNC_END \name
392 .endm
393
394 .macro THUMB_FUNC_START name
395         .globl  SYM (\name)
396         TYPE    (\name)
397         .thumb_func
398 SYM (\name):
399 .endm
400
401 /* Function start macros.  Variants for ARM and Thumb.  */
402
403 #ifdef __thumb__
404 #define THUMB_FUNC .thumb_func
405 #define THUMB_CODE .force_thumb
406 # if defined(__thumb2__)
407 #define THUMB_SYNTAX .syntax divided
408 # else
409 #define THUMB_SYNTAX
410 # endif
411 #else
412 #define THUMB_FUNC
413 #define THUMB_CODE
414 #define THUMB_SYNTAX
415 #endif
416
417 .macro FUNC_START name
418         .text
419         .globl SYM (__\name)
420         TYPE (__\name)
421         .align 0
422         THUMB_CODE
423         THUMB_FUNC
424         THUMB_SYNTAX
425 SYM (__\name):
426 .endm
427
428 /* Special function that will always be coded in ARM assembly, even if
429    in Thumb-only compilation.  */
430
431 #if defined(__thumb2__)
432
433 /* For Thumb-2 we build everything in thumb mode.  */
434 .macro ARM_FUNC_START name
435        FUNC_START \name
436        .syntax unified
437 .endm
438 #define EQUIV .thumb_set
439 .macro  ARM_CALL name
440         bl      __\name
441 .endm
442
443 #elif defined(__INTERWORKING_STUBS__)
444
445 .macro  ARM_FUNC_START name
446         FUNC_START \name
447         bx      pc
448         nop
449         .arm
450 /* A hook to tell gdb that we've switched to ARM mode.  Also used to call
451    directly from other local arm routines.  */
452 _L__\name:              
453 .endm
454 #define EQUIV .thumb_set
455 /* Branch directly to a function declared with ARM_FUNC_START.
456    Must be called in arm mode.  */
457 .macro  ARM_CALL name
458         bl      _L__\name
459 .endm
460
461 #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
462
463 #ifdef __ARM_ARCH_6M__
464 #define EQUIV .thumb_set
465 #else
466 .macro  ARM_FUNC_START name
467         .text
468         .globl SYM (__\name)
469         TYPE (__\name)
470         .align 0
471         .arm
472 SYM (__\name):
473 .endm
474 #define EQUIV .set
475 .macro  ARM_CALL name
476         bl      __\name
477 .endm
478 #endif
479
480 #endif
481
482 .macro  FUNC_ALIAS new old
483         .globl  SYM (__\new)
484 #if defined (__thumb__)
485         .thumb_set      SYM (__\new), SYM (__\old)
486 #else
487         .set    SYM (__\new), SYM (__\old)
488 #endif
489 .endm
490
491 #ifndef __ARM_ARCH_6M__
492 .macro  ARM_FUNC_ALIAS new old
493         .globl  SYM (__\new)
494         EQUIV   SYM (__\new), SYM (__\old)
495 #if defined(__INTERWORKING_STUBS__)
496         .set    SYM (_L__\new), SYM (_L__\old)
497 #endif
498 .endm
499 #endif
500
501 #ifdef __ARMEB__
502 #define xxh r0
503 #define xxl r1
504 #define yyh r2
505 #define yyl r3
506 #else
507 #define xxh r1
508 #define xxl r0
509 #define yyh r3
510 #define yyl r2
511 #endif  
512
513 #ifdef __ARM_EABI__
514 .macro  WEAK name
515         .weak SYM (__\name)
516 .endm
517 #endif
518
519 #ifdef __thumb__
520 /* Register aliases.  */
521
522 work            .req    r4      @ XXXX is this safe ?
523 dividend        .req    r0
524 divisor         .req    r1
525 overdone        .req    r2
526 result          .req    r2
527 curbit          .req    r3
528 #endif
529 #if 0
530 ip              .req    r12
531 sp              .req    r13
532 lr              .req    r14
533 pc              .req    r15
534 #endif
535
536 /* ------------------------------------------------------------------------ */
537 /*              Bodies of the division and modulo routines.                 */
538 /* ------------------------------------------------------------------------ */  
539 .macro ARM_DIV_BODY dividend, divisor, result, curbit
540
541 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
542
543 #if defined (__thumb2__)
544         clz     \curbit, \dividend
545         clz     \result, \divisor
546         sub     \curbit, \result, \curbit
547         rsb     \curbit, \curbit, #31
548         adr     \result, 1f
549         add     \curbit, \result, \curbit, lsl #4
550         mov     \result, #0
551         mov     pc, \curbit
552 .p2align 3
553 1:
554         .set    shift, 32
555         .rept   32
556         .set    shift, shift - 1
557         cmp.w   \dividend, \divisor, lsl #shift
558         nop.n
559         adc.w   \result, \result, \result
560         it      cs
561         subcs.w \dividend, \dividend, \divisor, lsl #shift
562         .endr
563 #else
564         clz     \curbit, \dividend
565         clz     \result, \divisor
566         sub     \curbit, \result, \curbit
567         rsbs    \curbit, \curbit, #31
568         addne   \curbit, \curbit, \curbit, lsl #1
569         mov     \result, #0
570         addne   pc, pc, \curbit, lsl #2
571         nop
572         .set    shift, 32
573         .rept   32
574         .set    shift, shift - 1
575         cmp     \dividend, \divisor, lsl #shift
576         adc     \result, \result, \result
577         subcs   \dividend, \dividend, \divisor, lsl #shift
578         .endr
579 #endif
580
581 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
582 #if __ARM_ARCH__ >= 5
583
584         clz     \curbit, \divisor
585         clz     \result, \dividend
586         sub     \result, \curbit, \result
587         mov     \curbit, #1
588         mov     \divisor, \divisor, lsl \result
589         mov     \curbit, \curbit, lsl \result
590         mov     \result, #0
591         
592 #else /* __ARM_ARCH__ < 5 */
593
594         @ Initially shift the divisor left 3 bits if possible,
595         @ set curbit accordingly.  This allows for curbit to be located
596         @ at the left end of each 4-bit nibbles in the division loop
597         @ to save one loop in most cases.
598         tst     \divisor, #0xe0000000
599         moveq   \divisor, \divisor, lsl #3
600         moveq   \curbit, #8
601         movne   \curbit, #1
602
603         @ Unless the divisor is very big, shift it up in multiples of
604         @ four bits, since this is the amount of unwinding in the main
605         @ division loop.  Continue shifting until the divisor is 
606         @ larger than the dividend.
607 1:      cmp     \divisor, #0x10000000
608         cmplo   \divisor, \dividend
609         movlo   \divisor, \divisor, lsl #4
610         movlo   \curbit, \curbit, lsl #4
611         blo     1b
612
613         @ For very big divisors, we must shift it a bit at a time, or
614         @ we will be in danger of overflowing.
615 1:      cmp     \divisor, #0x80000000
616         cmplo   \divisor, \dividend
617         movlo   \divisor, \divisor, lsl #1
618         movlo   \curbit, \curbit, lsl #1
619         blo     1b
620
621         mov     \result, #0
622
623 #endif /* __ARM_ARCH__ < 5 */
624
625         @ Division loop
626 1:      cmp     \dividend, \divisor
627         do_it   hs, t
628         subhs   \dividend, \dividend, \divisor
629         orrhs   \result,   \result,   \curbit
630         cmp     \dividend, \divisor,  lsr #1
631         do_it   hs, t
632         subhs   \dividend, \dividend, \divisor, lsr #1
633         orrhs   \result,   \result,   \curbit,  lsr #1
634         cmp     \dividend, \divisor,  lsr #2
635         do_it   hs, t
636         subhs   \dividend, \dividend, \divisor, lsr #2
637         orrhs   \result,   \result,   \curbit,  lsr #2
638         cmp     \dividend, \divisor,  lsr #3
639         do_it   hs, t
640         subhs   \dividend, \dividend, \divisor, lsr #3
641         orrhs   \result,   \result,   \curbit,  lsr #3
642         cmp     \dividend, #0                   @ Early termination?
643         do_it   hs, t
644         movnes  \curbit,   \curbit,  lsr #4     @ No, any more bits to do?
645         movne   \divisor,  \divisor, lsr #4
646         bne     1b
647
648 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
649
650 .endm
651 /* ------------------------------------------------------------------------ */  
652 .macro ARM_DIV2_ORDER divisor, order
653
654 #if __ARM_ARCH__ >= 5
655
656         clz     \order, \divisor
657         rsb     \order, \order, #31
658
659 #else
660
661         cmp     \divisor, #(1 << 16)
662         movhs   \divisor, \divisor, lsr #16
663         movhs   \order, #16
664         movlo   \order, #0
665
666         cmp     \divisor, #(1 << 8)
667         movhs   \divisor, \divisor, lsr #8
668         addhs   \order, \order, #8
669
670         cmp     \divisor, #(1 << 4)
671         movhs   \divisor, \divisor, lsr #4
672         addhs   \order, \order, #4
673
674         cmp     \divisor, #(1 << 2)
675         addhi   \order, \order, #3
676         addls   \order, \order, \divisor, lsr #1
677
678 #endif
679
680 .endm
681 /* ------------------------------------------------------------------------ */
682 .macro ARM_MOD_BODY dividend, divisor, order, spare
683
684 #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
685
686         clz     \order, \divisor
687         clz     \spare, \dividend
688         sub     \order, \order, \spare
689         rsbs    \order, \order, #31
690         addne   pc, pc, \order, lsl #3
691         nop
692         .set    shift, 32
693         .rept   32
694         .set    shift, shift - 1
695         cmp     \dividend, \divisor, lsl #shift
696         subcs   \dividend, \dividend, \divisor, lsl #shift
697         .endr
698
699 #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
700 #if __ARM_ARCH__ >= 5
701
702         clz     \order, \divisor
703         clz     \spare, \dividend
704         sub     \order, \order, \spare
705         mov     \divisor, \divisor, lsl \order
706         
707 #else /* __ARM_ARCH__ < 5 */
708
709         mov     \order, #0
710
711         @ Unless the divisor is very big, shift it up in multiples of
712         @ four bits, since this is the amount of unwinding in the main
713         @ division loop.  Continue shifting until the divisor is 
714         @ larger than the dividend.
715 1:      cmp     \divisor, #0x10000000
716         cmplo   \divisor, \dividend
717         movlo   \divisor, \divisor, lsl #4
718         addlo   \order, \order, #4
719         blo     1b
720
721         @ For very big divisors, we must shift it a bit at a time, or
722         @ we will be in danger of overflowing.
723 1:      cmp     \divisor, #0x80000000
724         cmplo   \divisor, \dividend
725         movlo   \divisor, \divisor, lsl #1
726         addlo   \order, \order, #1
727         blo     1b
728
729 #endif /* __ARM_ARCH__ < 5 */
730
731         @ Perform all needed substractions to keep only the reminder.
732         @ Do comparisons in batch of 4 first.
733         subs    \order, \order, #3              @ yes, 3 is intended here
734         blt     2f
735
736 1:      cmp     \dividend, \divisor
737         subhs   \dividend, \dividend, \divisor
738         cmp     \dividend, \divisor,  lsr #1
739         subhs   \dividend, \dividend, \divisor, lsr #1
740         cmp     \dividend, \divisor,  lsr #2
741         subhs   \dividend, \dividend, \divisor, lsr #2
742         cmp     \dividend, \divisor,  lsr #3
743         subhs   \dividend, \dividend, \divisor, lsr #3
744         cmp     \dividend, #1
745         mov     \divisor, \divisor, lsr #4
746         subges  \order, \order, #4
747         bge     1b
748
749         tst     \order, #3
750         teqne   \dividend, #0
751         beq     5f
752
753         @ Either 1, 2 or 3 comparison/substractions are left.
754 2:      cmn     \order, #2
755         blt     4f
756         beq     3f
757         cmp     \dividend, \divisor
758         subhs   \dividend, \dividend, \divisor
759         mov     \divisor,  \divisor,  lsr #1
760 3:      cmp     \dividend, \divisor
761         subhs   \dividend, \dividend, \divisor
762         mov     \divisor,  \divisor,  lsr #1
763 4:      cmp     \dividend, \divisor
764         subhs   \dividend, \dividend, \divisor
765 5:
766
767 #endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
768
769 .endm
770 /* ------------------------------------------------------------------------ */
771 .macro THUMB_DIV_MOD_BODY modulo
772         @ Load the constant 0x10000000 into our work register.
773         mov     work, #1
774         lsl     work, #28
775 LSYM(Loop1):
776         @ Unless the divisor is very big, shift it up in multiples of
777         @ four bits, since this is the amount of unwinding in the main
778         @ division loop.  Continue shifting until the divisor is 
779         @ larger than the dividend.
780         cmp     divisor, work
781         bhs     LSYM(Lbignum)
782         cmp     divisor, dividend
783         bhs     LSYM(Lbignum)
784         lsl     divisor, #4
785         lsl     curbit,  #4
786         b       LSYM(Loop1)
787 LSYM(Lbignum):
788         @ Set work to 0x80000000
789         lsl     work, #3
790 LSYM(Loop2):
791         @ For very big divisors, we must shift it a bit at a time, or
792         @ we will be in danger of overflowing.
793         cmp     divisor, work
794         bhs     LSYM(Loop3)
795         cmp     divisor, dividend
796         bhs     LSYM(Loop3)
797         lsl     divisor, #1
798         lsl     curbit,  #1
799         b       LSYM(Loop2)
800 LSYM(Loop3):
801         @ Test for possible subtractions ...
802   .if \modulo
803         @ ... On the final pass, this may subtract too much from the dividend, 
804         @ so keep track of which subtractions are done, we can fix them up 
805         @ afterwards.
806         mov     overdone, #0
807         cmp     dividend, divisor
808         blo     LSYM(Lover1)
809         sub     dividend, dividend, divisor
810 LSYM(Lover1):
811         lsr     work, divisor, #1
812         cmp     dividend, work
813         blo     LSYM(Lover2)
814         sub     dividend, dividend, work
815         mov     ip, curbit
816         mov     work, #1
817         ror     curbit, work
818         orr     overdone, curbit
819         mov     curbit, ip
820 LSYM(Lover2):
821         lsr     work, divisor, #2
822         cmp     dividend, work
823         blo     LSYM(Lover3)
824         sub     dividend, dividend, work
825         mov     ip, curbit
826         mov     work, #2
827         ror     curbit, work
828         orr     overdone, curbit
829         mov     curbit, ip
830 LSYM(Lover3):
831         lsr     work, divisor, #3
832         cmp     dividend, work
833         blo     LSYM(Lover4)
834         sub     dividend, dividend, work
835         mov     ip, curbit
836         mov     work, #3
837         ror     curbit, work
838         orr     overdone, curbit
839         mov     curbit, ip
840 LSYM(Lover4):
841         mov     ip, curbit
842   .else
843         @ ... and note which bits are done in the result.  On the final pass,
844         @ this may subtract too much from the dividend, but the result will be ok,
845         @ since the "bit" will have been shifted out at the bottom.
846         cmp     dividend, divisor
847         blo     LSYM(Lover1)
848         sub     dividend, dividend, divisor
849         orr     result, result, curbit
850 LSYM(Lover1):
851         lsr     work, divisor, #1
852         cmp     dividend, work
853         blo     LSYM(Lover2)
854         sub     dividend, dividend, work
855         lsr     work, curbit, #1
856         orr     result, work
857 LSYM(Lover2):
858         lsr     work, divisor, #2
859         cmp     dividend, work
860         blo     LSYM(Lover3)
861         sub     dividend, dividend, work
862         lsr     work, curbit, #2
863         orr     result, work
864 LSYM(Lover3):
865         lsr     work, divisor, #3
866         cmp     dividend, work
867         blo     LSYM(Lover4)
868         sub     dividend, dividend, work
869         lsr     work, curbit, #3
870         orr     result, work
871 LSYM(Lover4):
872   .endif
873         
874         cmp     dividend, #0                    @ Early termination?
875         beq     LSYM(Lover5)
876         lsr     curbit,  #4                     @ No, any more bits to do?
877         beq     LSYM(Lover5)
878         lsr     divisor, #4
879         b       LSYM(Loop3)
880 LSYM(Lover5):
881   .if \modulo
882         @ Any subtractions that we should not have done will be recorded in
883         @ the top three bits of "overdone".  Exactly which were not needed
884         @ are governed by the position of the bit, stored in ip.
885         mov     work, #0xe
886         lsl     work, #28
887         and     overdone, work
888         beq     LSYM(Lgot_result)
889         
890         @ If we terminated early, because dividend became zero, then the 
891         @ bit in ip will not be in the bottom nibble, and we should not
892         @ perform the additions below.  We must test for this though
893         @ (rather relying upon the TSTs to prevent the additions) since
894         @ the bit in ip could be in the top two bits which might then match
895         @ with one of the smaller RORs.
896         mov     curbit, ip
897         mov     work, #0x7
898         tst     curbit, work
899         beq     LSYM(Lgot_result)
900         
901         mov     curbit, ip
902         mov     work, #3
903         ror     curbit, work
904         tst     overdone, curbit
905         beq     LSYM(Lover6)
906         lsr     work, divisor, #3
907         add     dividend, work
908 LSYM(Lover6):
909         mov     curbit, ip
910         mov     work, #2
911         ror     curbit, work
912         tst     overdone, curbit
913         beq     LSYM(Lover7)
914         lsr     work, divisor, #2
915         add     dividend, work
916 LSYM(Lover7):
917         mov     curbit, ip
918         mov     work, #1
919         ror     curbit, work
920         tst     overdone, curbit
921         beq     LSYM(Lgot_result)
922         lsr     work, divisor, #1
923         add     dividend, work
924   .endif
925 LSYM(Lgot_result):
926 .endm   
927 /* ------------------------------------------------------------------------ */
928 /*              Start of the Real Functions                                 */
929 /* ------------------------------------------------------------------------ */
930 #ifdef L_udivsi3
931
932 #if defined(__prefer_thumb__)
933
934         FUNC_START udivsi3
935         FUNC_ALIAS aeabi_uidiv udivsi3
936
937         cmp     divisor, #0
938         beq     LSYM(Ldiv0)
939 LSYM(udivsi3_skip_div0_test):
940         mov     curbit, #1
941         mov     result, #0
942         
943         push    { work }
944         cmp     dividend, divisor
945         blo     LSYM(Lgot_result)
946
947         THUMB_DIV_MOD_BODY 0
948         
949         mov     r0, result
950         pop     { work }
951         RET
952
953 #else /* ARM version/Thumb-2.  */
954
955         ARM_FUNC_START udivsi3
956         ARM_FUNC_ALIAS aeabi_uidiv udivsi3
957
958         /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
959            check for division-by-zero a second time.  */
960 LSYM(udivsi3_skip_div0_test):
961         subs    r2, r1, #1
962         do_it   eq
963         RETc(eq)
964         bcc     LSYM(Ldiv0)
965         cmp     r0, r1
966         bls     11f
967         tst     r1, r2
968         beq     12f
969         
970         ARM_DIV_BODY r0, r1, r2, r3
971         
972         mov     r0, r2
973         RET     
974
975 11:     do_it   eq, e
976         moveq   r0, #1
977         movne   r0, #0
978         RET
979
980 12:     ARM_DIV2_ORDER r1, r2
981
982         mov     r0, r0, lsr r2
983         RET
984
985 #endif /* ARM version */
986
987         DIV_FUNC_END udivsi3 unsigned
988
989 #if defined(__prefer_thumb__)
990 FUNC_START aeabi_uidivmod
991         cmp     r1, #0
992         beq     LSYM(Ldiv0)
993         push    {r0, r1, lr}
994         bl      LSYM(udivsi3_skip_div0_test)
995         POP     {r1, r2, r3}
996         mul     r2, r0
997         sub     r1, r1, r2
998         bx      r3
999 #else
1000 ARM_FUNC_START aeabi_uidivmod
1001         cmp     r1, #0
1002         beq     LSYM(Ldiv0)
1003         stmfd   sp!, { r0, r1, lr }
1004         bl      LSYM(udivsi3_skip_div0_test)
1005         ldmfd   sp!, { r1, r2, lr }
1006         mul     r3, r2, r0
1007         sub     r1, r1, r3
1008         RET
1009 #endif
1010         FUNC_END aeabi_uidivmod
1011         
1012 #endif /* L_udivsi3 */
1013 /* ------------------------------------------------------------------------ */
1014 #ifdef L_umodsi3
1015
1016         FUNC_START umodsi3
1017
1018 #ifdef __thumb__
1019
1020         cmp     divisor, #0
1021         beq     LSYM(Ldiv0)
1022         mov     curbit, #1
1023         cmp     dividend, divisor
1024         bhs     LSYM(Lover10)
1025         RET     
1026
1027 LSYM(Lover10):
1028         push    { work }
1029
1030         THUMB_DIV_MOD_BODY 1
1031         
1032         pop     { work }
1033         RET
1034         
1035 #else  /* ARM version.  */
1036         
1037         subs    r2, r1, #1                      @ compare divisor with 1
1038         bcc     LSYM(Ldiv0)
1039         cmpne   r0, r1                          @ compare dividend with divisor
1040         moveq   r0, #0
1041         tsthi   r1, r2                          @ see if divisor is power of 2
1042         andeq   r0, r0, r2
1043         RETc(ls)
1044
1045         ARM_MOD_BODY r0, r1, r2, r3
1046         
1047         RET     
1048
1049 #endif /* ARM version.  */
1050         
1051         DIV_FUNC_END umodsi3 unsigned
1052
1053 #endif /* L_umodsi3 */
1054 /* ------------------------------------------------------------------------ */
1055 #ifdef L_divsi3
1056
1057 #if defined(__prefer_thumb__)
1058
1059         FUNC_START divsi3       
1060         FUNC_ALIAS aeabi_idiv divsi3
1061
1062         cmp     divisor, #0
1063         beq     LSYM(Ldiv0)
1064 LSYM(divsi3_skip_div0_test):
1065         push    { work }
1066         mov     work, dividend
1067         eor     work, divisor           @ Save the sign of the result.
1068         mov     ip, work
1069         mov     curbit, #1
1070         mov     result, #0
1071         cmp     divisor, #0
1072         bpl     LSYM(Lover10)
1073         neg     divisor, divisor        @ Loops below use unsigned.
1074 LSYM(Lover10):
1075         cmp     dividend, #0
1076         bpl     LSYM(Lover11)
1077         neg     dividend, dividend
1078 LSYM(Lover11):
1079         cmp     dividend, divisor
1080         blo     LSYM(Lgot_result)
1081
1082         THUMB_DIV_MOD_BODY 0
1083         
1084         mov     r0, result
1085         mov     work, ip
1086         cmp     work, #0
1087         bpl     LSYM(Lover12)
1088         neg     r0, r0
1089 LSYM(Lover12):
1090         pop     { work }
1091         RET
1092
1093 #else /* ARM/Thumb-2 version.  */
1094         
1095         ARM_FUNC_START divsi3   
1096         ARM_FUNC_ALIAS aeabi_idiv divsi3
1097
1098         cmp     r1, #0
1099         beq     LSYM(Ldiv0)
1100 LSYM(divsi3_skip_div0_test):
1101         eor     ip, r0, r1                      @ save the sign of the result.
1102         do_it   mi
1103         rsbmi   r1, r1, #0                      @ loops below use unsigned.
1104         subs    r2, r1, #1                      @ division by 1 or -1 ?
1105         beq     10f
1106         movs    r3, r0
1107         do_it   mi
1108         rsbmi   r3, r0, #0                      @ positive dividend value
1109         cmp     r3, r1
1110         bls     11f
1111         tst     r1, r2                          @ divisor is power of 2 ?
1112         beq     12f
1113
1114         ARM_DIV_BODY r3, r1, r0, r2
1115         
1116         cmp     ip, #0
1117         do_it   mi
1118         rsbmi   r0, r0, #0
1119         RET     
1120
1121 10:     teq     ip, r0                          @ same sign ?
1122         do_it   mi
1123         rsbmi   r0, r0, #0
1124         RET     
1125
1126 11:     do_it   lo
1127         movlo   r0, #0
1128         do_it   eq,t
1129         moveq   r0, ip, asr #31
1130         orreq   r0, r0, #1
1131         RET
1132
1133 12:     ARM_DIV2_ORDER r1, r2
1134
1135         cmp     ip, #0
1136         mov     r0, r3, lsr r2
1137         do_it   mi
1138         rsbmi   r0, r0, #0
1139         RET
1140
1141 #endif /* ARM version */
1142         
1143         DIV_FUNC_END divsi3 signed
1144
1145 #if defined(__prefer_thumb__)
1146 FUNC_START aeabi_idivmod
1147         cmp     r1, #0
1148         beq     LSYM(Ldiv0)
1149         push    {r0, r1, lr}
1150         bl      LSYM(divsi3_skip_div0_test)
1151         POP     {r1, r2, r3}
1152         mul     r2, r0
1153         sub     r1, r1, r2
1154         bx      r3
1155 #else
1156 ARM_FUNC_START aeabi_idivmod
1157         cmp     r1, #0
1158         beq     LSYM(Ldiv0)
1159         stmfd   sp!, { r0, r1, lr }
1160         bl      LSYM(divsi3_skip_div0_test)
1161         ldmfd   sp!, { r1, r2, lr }
1162         mul     r3, r2, r0
1163         sub     r1, r1, r3
1164         RET
1165 #endif
1166         FUNC_END aeabi_idivmod
1167         
1168 #endif /* L_divsi3 */
1169 /* ------------------------------------------------------------------------ */
1170 #ifdef L_modsi3
1171
1172         FUNC_START modsi3
1173
1174 #ifdef __thumb__
1175
1176         mov     curbit, #1
1177         cmp     divisor, #0
1178         beq     LSYM(Ldiv0)
1179         bpl     LSYM(Lover10)
1180         neg     divisor, divisor                @ Loops below use unsigned.
1181 LSYM(Lover10):
1182         push    { work }
1183         @ Need to save the sign of the dividend, unfortunately, we need
1184         @ work later on.  Must do this after saving the original value of
1185         @ the work register, because we will pop this value off first.
1186         push    { dividend }
1187         cmp     dividend, #0
1188         bpl     LSYM(Lover11)
1189         neg     dividend, dividend
1190 LSYM(Lover11):
1191         cmp     dividend, divisor
1192         blo     LSYM(Lgot_result)
1193
1194         THUMB_DIV_MOD_BODY 1
1195                 
1196         pop     { work }
1197         cmp     work, #0
1198         bpl     LSYM(Lover12)
1199         neg     dividend, dividend
1200 LSYM(Lover12):
1201         pop     { work }
1202         RET     
1203
1204 #else /* ARM version.  */
1205         
1206         cmp     r1, #0
1207         beq     LSYM(Ldiv0)
1208         rsbmi   r1, r1, #0                      @ loops below use unsigned.
1209         movs    ip, r0                          @ preserve sign of dividend
1210         rsbmi   r0, r0, #0                      @ if negative make positive
1211         subs    r2, r1, #1                      @ compare divisor with 1
1212         cmpne   r0, r1                          @ compare dividend with divisor
1213         moveq   r0, #0
1214         tsthi   r1, r2                          @ see if divisor is power of 2
1215         andeq   r0, r0, r2
1216         bls     10f
1217
1218         ARM_MOD_BODY r0, r1, r2, r3
1219
1220 10:     cmp     ip, #0
1221         rsbmi   r0, r0, #0
1222         RET     
1223
1224 #endif /* ARM version */
1225         
1226         DIV_FUNC_END modsi3 signed
1227
1228 #endif /* L_modsi3 */
1229 /* ------------------------------------------------------------------------ */
1230 #ifdef L_dvmd_tls
1231
1232 #ifdef __ARM_EABI__
1233         WEAK aeabi_idiv0
1234         WEAK aeabi_ldiv0
1235         FUNC_START aeabi_idiv0
1236         FUNC_START aeabi_ldiv0
1237         RET
1238         FUNC_END aeabi_ldiv0
1239         FUNC_END aeabi_idiv0
1240 #else
1241         FUNC_START div0
1242         RET
1243         FUNC_END div0
1244 #endif
1245         
1246 #endif /* L_divmodsi_tools */
1247 /* ------------------------------------------------------------------------ */
1248 #ifdef L_dvmd_lnx
1249 @ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
1250
1251 /* Constant taken from <asm/signal.h>.  */
1252 #define SIGFPE  8
1253
1254 #ifdef __ARM_EABI__
1255         WEAK aeabi_idiv0
1256         WEAK aeabi_ldiv0
1257         ARM_FUNC_START aeabi_idiv0
1258         ARM_FUNC_START aeabi_ldiv0
1259 #else
1260         ARM_FUNC_START div0
1261 #endif
1262
1263         do_push {r1, lr}
1264         mov     r0, #SIGFPE
1265         bl      SYM(raise) __PLT__
1266         RETLDM  r1
1267
1268 #ifdef __ARM_EABI__
1269         FUNC_END aeabi_ldiv0
1270         FUNC_END aeabi_idiv0
1271 #else
1272         FUNC_END div0
1273 #endif
1274         
1275 #endif /* L_dvmd_lnx */
1276 #ifdef L_clear_cache
1277 #if defined __ARM_EABI__ && defined __linux__
1278 @ EABI GNU/Linux call to cacheflush syscall.
1279         ARM_FUNC_START clear_cache
1280         do_push {r7}
1281 #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1282         movw    r7, #2
1283         movt    r7, #0xf
1284 #else
1285         mov     r7, #0xf0000
1286         add     r7, r7, #2
1287 #endif
1288         mov     r2, #0
1289         swi     0
1290         do_pop  {r7}
1291         RET
1292         FUNC_END clear_cache
1293 #else
1294 #error "This is only for ARM EABI GNU/Linux"
1295 #endif
1296 #endif /* L_clear_cache */
1297 /* ------------------------------------------------------------------------ */
1298 /* Dword shift operations.  */
1299 /* All the following Dword shift variants rely on the fact that
1300         shft xxx, Reg
1301    is in fact done as
1302         shft xxx, (Reg & 255)
1303    so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1304    case of logical shifts) or the sign (for asr).  */
1305
1306 #ifdef __ARMEB__
1307 #define al      r1
1308 #define ah      r0
1309 #else
1310 #define al      r0
1311 #define ah      r1
1312 #endif
1313
1314 /* Prevent __aeabi double-word shifts from being produced on SymbianOS.  */
1315 #ifndef __symbian__
1316
1317 #ifdef L_lshrdi3
1318
1319         FUNC_START lshrdi3
1320         FUNC_ALIAS aeabi_llsr lshrdi3
1321         
1322 #ifdef __thumb__
1323         lsr     al, r2
1324         mov     r3, ah
1325         lsr     ah, r2
1326         mov     ip, r3
1327         sub     r2, #32
1328         lsr     r3, r2
1329         orr     al, r3
1330         neg     r2, r2
1331         mov     r3, ip
1332         lsl     r3, r2
1333         orr     al, r3
1334         RET
1335 #else
1336         subs    r3, r2, #32
1337         rsb     ip, r2, #32
1338         movmi   al, al, lsr r2
1339         movpl   al, ah, lsr r3
1340         orrmi   al, al, ah, lsl ip
1341         mov     ah, ah, lsr r2
1342         RET
1343 #endif
1344         FUNC_END aeabi_llsr
1345         FUNC_END lshrdi3
1346
1347 #endif
1348         
1349 #ifdef L_ashrdi3
1350         
1351         FUNC_START ashrdi3
1352         FUNC_ALIAS aeabi_lasr ashrdi3
1353         
1354 #ifdef __thumb__
1355         lsr     al, r2
1356         mov     r3, ah
1357         asr     ah, r2
1358         sub     r2, #32
1359         @ If r2 is negative at this point the following step would OR
1360         @ the sign bit into all of AL.  That's not what we want...
1361         bmi     1f
1362         mov     ip, r3
1363         asr     r3, r2
1364         orr     al, r3
1365         mov     r3, ip
1366 1:
1367         neg     r2, r2
1368         lsl     r3, r2
1369         orr     al, r3
1370         RET
1371 #else
1372         subs    r3, r2, #32
1373         rsb     ip, r2, #32
1374         movmi   al, al, lsr r2
1375         movpl   al, ah, asr r3
1376         orrmi   al, al, ah, lsl ip
1377         mov     ah, ah, asr r2
1378         RET
1379 #endif
1380
1381         FUNC_END aeabi_lasr
1382         FUNC_END ashrdi3
1383
1384 #endif
1385
1386 #ifdef L_ashldi3
1387
1388         FUNC_START ashldi3
1389         FUNC_ALIAS aeabi_llsl ashldi3
1390         
1391 #ifdef __thumb__
1392         lsl     ah, r2
1393         mov     r3, al
1394         lsl     al, r2
1395         mov     ip, r3
1396         sub     r2, #32
1397         lsl     r3, r2
1398         orr     ah, r3
1399         neg     r2, r2
1400         mov     r3, ip
1401         lsr     r3, r2
1402         orr     ah, r3
1403         RET
1404 #else
1405         subs    r3, r2, #32
1406         rsb     ip, r2, #32
1407         movmi   ah, ah, lsl r2
1408         movpl   ah, al, lsl r3
1409         orrmi   ah, ah, al, lsr ip
1410         mov     al, al, lsl r2
1411         RET
1412 #endif
1413         FUNC_END aeabi_llsl
1414         FUNC_END ashldi3
1415
1416 #endif
1417
1418 #endif /* __symbian__ */
1419
1420 #if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1421     || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1422     || defined(__ARM_ARCH_5TEJ__)
1423 #define HAVE_ARM_CLZ 1
1424 #endif
1425
1426 #ifdef L_clzsi2
1427 #if defined(__ARM_ARCH_6M__)
1428 FUNC_START clzsi2
1429         mov     r1, #28
1430         mov     r3, #1
1431         lsl     r3, r3, #16
1432         cmp     r0, r3 /* 0x10000 */
1433         bcc     2f
1434         lsr     r0, r0, #16
1435         sub     r1, r1, #16
1436 2:      lsr     r3, r3, #8
1437         cmp     r0, r3 /* #0x100 */
1438         bcc     2f
1439         lsr     r0, r0, #8
1440         sub     r1, r1, #8
1441 2:      lsr     r3, r3, #4
1442         cmp     r0, r3 /* #0x10 */
1443         bcc     2f
1444         lsr     r0, r0, #4
1445         sub     r1, r1, #4
1446 2:      adr     r2, 1f
1447         ldrb    r0, [r2, r0]
1448         add     r0, r0, r1
1449         bx lr
1450 .align 2
1451 1:
1452 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1453         FUNC_END clzsi2
1454 #else
1455 ARM_FUNC_START clzsi2
1456 # if defined(HAVE_ARM_CLZ)
1457         clz     r0, r0
1458         RET
1459 # else
1460         mov     r1, #28
1461         cmp     r0, #0x10000
1462         do_it   cs, t
1463         movcs   r0, r0, lsr #16
1464         subcs   r1, r1, #16
1465         cmp     r0, #0x100
1466         do_it   cs, t
1467         movcs   r0, r0, lsr #8
1468         subcs   r1, r1, #8
1469         cmp     r0, #0x10
1470         do_it   cs, t
1471         movcs   r0, r0, lsr #4
1472         subcs   r1, r1, #4
1473         adr     r2, 1f
1474         ldrb    r0, [r2, r0]
1475         add     r0, r0, r1
1476         RET
1477 .align 2
1478 1:
1479 .byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1480 # endif /* !HAVE_ARM_CLZ */
1481         FUNC_END clzsi2
1482 #endif
1483 #endif /* L_clzsi2 */
1484
1485 #ifdef L_clzdi2
1486 #if !defined(HAVE_ARM_CLZ)
1487
1488 # if defined(__ARM_ARCH_6M__)
1489 FUNC_START clzdi2
1490         push    {r4, lr}
1491 # else
1492 ARM_FUNC_START clzdi2
1493         do_push {r4, lr}
1494 # endif
1495         cmp     xxh, #0
1496         bne     1f
1497 # ifdef __ARMEB__
1498         mov     r0, xxl
1499         bl      __clzsi2
1500         add     r0, r0, #32
1501         b 2f
1502 1:
1503         bl      __clzsi2
1504 # else
1505         bl      __clzsi2
1506         add     r0, r0, #32
1507         b 2f
1508 1:
1509         mov     r0, xxh
1510         bl      __clzsi2
1511 # endif
1512 2:
1513 # if defined(__ARM_ARCH_6M__)
1514         pop     {r4, pc}
1515 # else
1516         RETLDM  r4
1517 # endif
1518         FUNC_END clzdi2
1519
1520 #else /* HAVE_ARM_CLZ */
1521
1522 ARM_FUNC_START clzdi2
1523         cmp     xxh, #0
1524         do_it   eq, et
1525         clzeq   r0, xxl
1526         clzne   r0, xxh
1527         addeq   r0, r0, #32
1528         RET
1529         FUNC_END clzdi2
1530
1531 #endif
1532 #endif /* L_clzdi2 */
1533
1534 /* ------------------------------------------------------------------------ */
1535 /* These next two sections are here despite the fact that they contain Thumb 
1536    assembler because their presence allows interworked code to be linked even
1537    when the GCC library is this one.  */
1538                 
1539 /* Do not build the interworking functions when the target architecture does 
1540    not support Thumb instructions.  (This can be a multilib option).  */
1541 #if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1542       || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1543       || __ARM_ARCH__ >= 6
1544
1545 #if defined L_call_via_rX
1546
1547 /* These labels & instructions are used by the Arm/Thumb interworking code. 
1548    The address of function to be called is loaded into a register and then 
1549    one of these labels is called via a BL instruction.  This puts the 
1550    return address into the link register with the bottom bit set, and the 
1551    code here switches to the correct mode before executing the function.  */
1552         
1553         .text
1554         .align 0
1555         .force_thumb
1556
1557 .macro call_via register
1558         THUMB_FUNC_START _call_via_\register
1559
1560         bx      \register
1561         nop
1562
1563         SIZE    (_call_via_\register)
1564 .endm
1565
1566         call_via r0
1567         call_via r1
1568         call_via r2
1569         call_via r3
1570         call_via r4
1571         call_via r5
1572         call_via r6
1573         call_via r7
1574         call_via r8
1575         call_via r9
1576         call_via sl
1577         call_via fp
1578         call_via ip
1579         call_via sp
1580         call_via lr
1581
1582 #endif /* L_call_via_rX */
1583
1584 /* Don't bother with the old interworking routines for Thumb-2.  */
1585 /* ??? Maybe only omit these on "m" variants.  */
1586 #if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1587
1588 #if defined L_interwork_call_via_rX
1589
1590 /* These labels & instructions are used by the Arm/Thumb interworking code,
1591    when the target address is in an unknown instruction set.  The address 
1592    of function to be called is loaded into a register and then one of these
1593    labels is called via a BL instruction.  This puts the return address 
1594    into the link register with the bottom bit set, and the code here 
1595    switches to the correct mode before executing the function.  Unfortunately
1596    the target code cannot be relied upon to return via a BX instruction, so
1597    instead we have to store the resturn address on the stack and allow the
1598    called function to return here instead.  Upon return we recover the real
1599    return address and use a BX to get back to Thumb mode.
1600
1601    There are three variations of this code.  The first,
1602    _interwork_call_via_rN(), will push the return address onto the
1603    stack and pop it in _arm_return().  It should only be used if all
1604    arguments are passed in registers.
1605
1606    The second, _interwork_r7_call_via_rN(), instead stores the return
1607    address at [r7, #-4].  It is the caller's responsibility to ensure
1608    that this address is valid and contains no useful data.
1609
1610    The third, _interwork_r11_call_via_rN(), works in the same way but
1611    uses r11 instead of r7.  It is useful if the caller does not really
1612    need a frame pointer.  */
1613         
1614         .text
1615         .align 0
1616
1617         .code   32
1618         .globl _arm_return
1619 LSYM(Lstart_arm_return):
1620         cfi_start       LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1621         cfi_push        0, 0xe, -0x8, 0x8
1622         nop     @ This nop is for the benefit of debuggers, so that
1623                 @ backtraces will use the correct unwind information.
1624 _arm_return:
1625         RETLDM  unwind=LSYM(Lstart_arm_return)
1626         cfi_end LSYM(Lend_arm_return)
1627
1628         .globl _arm_return_r7
1629 _arm_return_r7:
1630         ldr     lr, [r7, #-4]
1631         bx      lr
1632
1633         .globl _arm_return_r11
1634 _arm_return_r11:
1635         ldr     lr, [r11, #-4]
1636         bx      lr
1637
1638 .macro interwork_with_frame frame, register, name, return
1639         .code   16
1640
1641         THUMB_FUNC_START \name
1642
1643         bx      pc
1644         nop
1645
1646         .code   32
1647         tst     \register, #1
1648         streq   lr, [\frame, #-4]
1649         adreq   lr, _arm_return_\frame
1650         bx      \register
1651
1652         SIZE    (\name)
1653 .endm
1654
1655 .macro interwork register
1656         .code   16
1657
1658         THUMB_FUNC_START _interwork_call_via_\register
1659
1660         bx      pc
1661         nop
1662
1663         .code   32
1664         .globl LSYM(Lchange_\register)
1665 LSYM(Lchange_\register):
1666         tst     \register, #1
1667         streq   lr, [sp, #-8]!
1668         adreq   lr, _arm_return
1669         bx      \register
1670
1671         SIZE    (_interwork_call_via_\register)
1672
1673         interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1674         interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1675 .endm
1676         
1677         interwork r0
1678         interwork r1
1679         interwork r2
1680         interwork r3
1681         interwork r4
1682         interwork r5
1683         interwork r6
1684         interwork r7
1685         interwork r8
1686         interwork r9
1687         interwork sl
1688         interwork fp
1689         interwork ip
1690         interwork sp
1691         
1692         /* The LR case has to be handled a little differently...  */
1693         .code 16
1694
1695         THUMB_FUNC_START _interwork_call_via_lr
1696
1697         bx      pc
1698         nop
1699         
1700         .code 32
1701         .globl .Lchange_lr
1702 .Lchange_lr:
1703         tst     lr, #1
1704         stmeqdb r13!, {lr, pc}
1705         mov     ip, lr
1706         adreq   lr, _arm_return
1707         bx      ip
1708         
1709         SIZE    (_interwork_call_via_lr)
1710         
1711 #endif /* L_interwork_call_via_rX */
1712 #endif /* !__thumb2__ */
1713
1714 /* Functions to support compact pic switch tables in thumb1 state.
1715    All these routines take an index into the table in r0.  The
1716    table is at LR & ~1 (but this must be rounded up in the case
1717    of 32-bit entires).  They are only permitted to clobber r12
1718    and r14 and r0 must be preserved on exit.  */
1719 #ifdef L_thumb1_case_sqi
1720         
1721         .text
1722         .align 0
1723         .force_thumb
1724         .syntax unified
1725         THUMB_FUNC_START __gnu_thumb1_case_sqi
1726         push    {r1}
1727         mov     r1, lr
1728         lsrs    r1, r1, #1
1729         lsls    r1, r1, #1
1730         ldrsb   r1, [r1, r0]
1731         lsls    r1, r1, #1
1732         add     lr, lr, r1
1733         pop     {r1}
1734         bx      lr
1735         SIZE (__gnu_thumb1_case_sqi)
1736 #endif
1737
1738 #ifdef L_thumb1_case_uqi
1739         
1740         .text
1741         .align 0
1742         .force_thumb
1743         .syntax unified
1744         THUMB_FUNC_START __gnu_thumb1_case_uqi
1745         push    {r1}
1746         mov     r1, lr
1747         lsrs    r1, r1, #1
1748         lsls    r1, r1, #1
1749         ldrb    r1, [r1, r0]
1750         lsls    r1, r1, #1
1751         add     lr, lr, r1
1752         pop     {r1}
1753         bx      lr
1754         SIZE (__gnu_thumb1_case_uqi)
1755 #endif
1756
1757 #ifdef L_thumb1_case_shi
1758         
1759         .text
1760         .align 0
1761         .force_thumb
1762         .syntax unified
1763         THUMB_FUNC_START __gnu_thumb1_case_shi
1764         push    {r0, r1}
1765         mov     r1, lr
1766         lsrs    r1, r1, #1
1767         lsls    r0, r0, #1
1768         lsls    r1, r1, #1
1769         ldrsh   r1, [r1, r0]
1770         lsls    r1, r1, #1
1771         add     lr, lr, r1
1772         pop     {r0, r1}
1773         bx      lr
1774         SIZE (__gnu_thumb1_case_shi)
1775 #endif
1776
1777 #ifdef L_thumb1_case_uhi
1778         
1779         .text
1780         .align 0
1781         .force_thumb
1782         .syntax unified
1783         THUMB_FUNC_START __gnu_thumb1_case_uhi
1784         push    {r0, r1}
1785         mov     r1, lr
1786         lsrs    r1, r1, #1
1787         lsls    r0, r0, #1
1788         lsls    r1, r1, #1
1789         ldrh    r1, [r1, r0]
1790         lsls    r1, r1, #1
1791         add     lr, lr, r1
1792         pop     {r0, r1}
1793         bx      lr
1794         SIZE (__gnu_thumb1_case_uhi)
1795 #endif
1796
1797 #ifdef L_thumb1_case_si
1798         
1799         .text
1800         .align 0
1801         .force_thumb
1802         .syntax unified
1803         THUMB_FUNC_START __gnu_thumb1_case_si
1804         push    {r0, r1}
1805         mov     r1, lr
1806         adds.n  r1, r1, #2      /* Align to word.  */
1807         lsrs    r1, r1, #2
1808         lsls    r0, r0, #2
1809         lsls    r1, r1, #2
1810         ldr     r0, [r1, r0]
1811         adds    r0, r0, r1
1812         mov     lr, r0
1813         pop     {r0, r1}
1814         mov     pc, lr          /* We know we were called from thumb code.  */
1815         SIZE (__gnu_thumb1_case_si)
1816 #endif
1817
1818 #endif /* Arch supports thumb.  */
1819
1820 #ifndef __symbian__
1821 #ifndef __ARM_ARCH_6M__
1822 #include "ieee754-df.S"
1823 #include "ieee754-sf.S"
1824 #include "bpabi.S"
1825 #else /* __ARM_ARCH_6M__ */
1826 #include "bpabi-v6m.S"
1827 #endif /* __ARM_ARCH_6M__ */
1828 #endif /* !__symbian__ */