OSDN Git Service

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