OSDN Git Service

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