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