]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/arm/bpabi.S
bpabi.S (__aeabi_uldivmod): Optimise stack pointer manipulation.
[thirdparty/gcc.git] / libgcc / config / arm / bpabi.S
CommitLineData
b3f8d95d
MM
1/* Miscellaneous BPABI functions.
2
ac1dca3c 3 Copyright (C) 2003-2014 Free Software Foundation, Inc.
b3f8d95d
MM
4 Contributed by CodeSourcery, LLC.
5
6 This file is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
748086b7 8 Free Software Foundation; either version 3, or (at your option) any
b3f8d95d
MM
9 later version.
10
b3f8d95d
MM
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
748086b7
JJ
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
b3f8d95d 24
6f0668cf
RE
25#ifdef __ARM_EABI__
26/* Some attributes that are common to all routines in this file. */
27 /* Tag_ABI_align_needed: This code does not require 8-byte
28 alignment from the caller. */
29 /* .eabi_attribute 24, 0 -- default setting. */
30 /* Tag_ABI_align_preserved: This code preserves 8-byte
31 alignment in any callee. */
32 .eabi_attribute 25, 1
33#endif /* __ARM_EABI__ */
34
b3f8d95d
MM
35#ifdef L_aeabi_lcmp
36
37ARM_FUNC_START aeabi_lcmp
ad1ec76f
PB
38 cmp xxh, yyh
39 do_it lt
40 movlt r0, #-1
41 do_it gt
42 movgt r0, #1
43 do_it ne
44 RETc(ne)
45 subs r0, xxl, yyl
46 do_it lo
47 movlo r0, #-1
48 do_it hi
49 movhi r0, #1
b3f8d95d
MM
50 RET
51 FUNC_END aeabi_lcmp
52
53#endif /* L_aeabi_lcmp */
54
55#ifdef L_aeabi_ulcmp
56
57ARM_FUNC_START aeabi_ulcmp
58 cmp xxh, yyh
5b3e6663 59 do_it lo
b3f8d95d 60 movlo r0, #-1
5b3e6663 61 do_it hi
b3f8d95d 62 movhi r0, #1
5b3e6663 63 do_it ne
b3f8d95d
MM
64 RETc(ne)
65 cmp xxl, yyl
5b3e6663 66 do_it lo
b3f8d95d 67 movlo r0, #-1
5b3e6663 68 do_it hi
b3f8d95d 69 movhi r0, #1
5b3e6663 70 do_it eq
b3f8d95d
MM
71 moveq r0, #0
72 RET
73 FUNC_END aeabi_ulcmp
74
75#endif /* L_aeabi_ulcmp */
76
0c23e1be
JB
77.macro test_div_by_zero signed
78/* Tail-call to divide-by-zero handlers which may be overridden by the user,
79 so unwinding works properly. */
80#if defined(__thumb2__)
81 cbnz yyh, 1f
82 cbnz yyl, 1f
83 cmp xxh, #0
84 do_it eq
85 cmpeq xxl, #0
86 .ifc \signed, unsigned
87 beq 2f
88 mov xxh, #0xffffffff
89 mov xxl, xxh
902:
91 .else
92 do_it lt, t
93 movlt xxl, #0
94 movlt xxh, #0x80000000
95 do_it gt, t
96 movgt xxh, #0x7fffffff
97 movgt xxl, #0xffffffff
98 .endif
99 b SYM (__aeabi_ldiv0) __PLT__
1001:
101#else
102 /* Note: Thumb-1 code calls via an ARM shim on processors which
103 support ARM mode. */
104 cmp yyh, #0
105 cmpeq yyl, #0
106 bne 2f
107 cmp xxh, #0
108 cmpeq xxl, #0
109 .ifc \signed, unsigned
110 movne xxh, #0xffffffff
111 movne xxl, #0xffffffff
112 .else
113 movlt xxh, #0x80000000
114 movlt xxl, #0
115 movgt xxh, #0x7fffffff
116 movgt xxl, #0xffffffff
117 .endif
118 b SYM (__aeabi_ldiv0) __PLT__
1192:
120#endif
121.endm
122
c9dae335
CB
123/* we can use STRD/LDRD on v5TE and later, and any Thumb-2 architecture. */
124#if (defined(__ARM_EABI__) \
125 && (defined(__thumb2__) \
126 || (__ARM_ARCH >= 5 && defined(__TARGET_FEATURE_DSP))))
127#define CAN_USE_LDRD 1
128#else
129#define CAN_USE_LDRD 0
130#endif
131
132/* set up stack from for call to __udivmoddi4. At the end of the macro the
133 stack is arranged as follows:
134 sp+12 / space for remainder
135 sp+8 \ (written by __udivmoddi4)
136 sp+4 lr
137 sp+0 sp+8 [rp (remainder pointer) argument for __udivmoddi4]
138
139 */
140.macro push_for_divide fname
141#if defined(__thumb2__) && CAN_USE_LDRD
142 sub ip, sp, #8
143 strd ip, lr, [sp, #-16]!
144#else
145 sub sp, sp, #8
146 do_push {sp, lr}
147#endif
14898: cfi_push 98b - \fname, 0xe, -0xc, 0x10
149.endm
150
151/* restore stack */
152.macro pop_for_divide
153 ldr lr, [sp, #4]
154#if CAN_USE_LDRD
155 ldrd r2, r3, [sp, #8]
156 add sp, sp, #16
157#else
158 add sp, sp, #8
159 do_pop {r2, r3}
160#endif
161.endm
162
b3f8d95d
MM
163#ifdef L_aeabi_ldivmod
164
6857b807
CB
165/* Perform 64 bit signed division.
166 Inputs:
167 r0:r1 numerator
168 r2:r3 denominator
169 Outputs:
170 r0:r1 quotient
171 r2:r3 remainder
172 */
b3f8d95d 173ARM_FUNC_START aeabi_ldivmod
34652576 174 cfi_start __aeabi_ldivmod, LSYM(Lend_aeabi_ldivmod)
f21d8faa 175 test_div_by_zero signed
0c23e1be 176
f21d8faa 177 sub sp, sp, #8
5b3e6663 178#if defined(__thumb2__)
f21d8faa
CB
179 mov ip, sp
180 push {ip, lr}
5b3e6663 181#else
f21d8faa 182 do_push {sp, lr}
5b3e6663 183#endif
34652576 18498: cfi_push 98b - __aeabi_ldivmod, 0xe, -0xc, 0x10
f21d8faa
CB
185 bl SYM(__gnu_ldivmod_helper) __PLT__
186 ldr lr, [sp, #4]
187 add sp, sp, #8
188 do_pop {r2, r3}
b3f8d95d 189 RET
34652576 190 cfi_end LSYM(Lend_aeabi_ldivmod)
b3f8d95d
MM
191
192#endif /* L_aeabi_ldivmod */
193
194#ifdef L_aeabi_uldivmod
195
6857b807
CB
196/* Perform 64 bit signed division.
197 Inputs:
198 r0:r1 numerator
199 r2:r3 denominator
200 Outputs:
201 r0:r1 quotient
202 r2:r3 remainder
203 */
b3f8d95d 204ARM_FUNC_START aeabi_uldivmod
34652576 205 cfi_start __aeabi_uldivmod, LSYM(Lend_aeabi_uldivmod)
f21d8faa 206 test_div_by_zero unsigned
0c23e1be 207
c9dae335
CB
208 push_for_divide __aeabi_uldivmod
209 /* arguments in (r0:r1), (r2:r3) and *sp */
f21d8faa 210 bl SYM(__gnu_uldivmod_helper) __PLT__
c9dae335 211 pop_for_divide
b3f8d95d 212 RET
34652576
MI
213 cfi_end LSYM(Lend_aeabi_uldivmod)
214
b3f8d95d
MM
215#endif /* L_aeabi_divmod */
216