]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/arm/bpabi-v6m.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / arm / bpabi-v6m.S
1 /* Miscellaneous BPABI functions. Thumb-1 implementation, suitable for ARMv4T,
2 ARMv6-M and ARMv8-M Baseline like ISA variants.
3
4 Copyright (C) 2006-2024 Free Software Foundation, Inc.
5 Contributed by CodeSourcery.
6
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
10 later version.
11
12 This file is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #ifdef __ARM_EABI__
27 /* Some attributes that are common to all routines in this file. */
28 /* Tag_ABI_align_needed: This code does not require 8-byte
29 alignment from the caller. */
30 /* .eabi_attribute 24, 0 -- default setting. */
31 /* Tag_ABI_align_preserved: This code preserves 8-byte
32 alignment in any callee. */
33 .eabi_attribute 25, 1
34 #endif /* __ARM_EABI__ */
35
36 #ifdef L_aeabi_lcmp
37
38 FUNC_START aeabi_lcmp
39 cmp xxh, yyh
40 beq 1f
41 bgt 2f
42 movs r0, #1
43 negs r0, r0
44 RET
45 2:
46 movs r0, #1
47 RET
48 1:
49 subs r0, xxl, yyl
50 beq 1f
51 bhi 2f
52 movs r0, #1
53 negs r0, r0
54 RET
55 2:
56 movs r0, #1
57 1:
58 RET
59 FUNC_END aeabi_lcmp
60
61 #endif /* L_aeabi_lcmp */
62
63 #ifdef L_aeabi_ulcmp
64
65 FUNC_START aeabi_ulcmp
66 cmp xxh, yyh
67 bne 1f
68 subs r0, xxl, yyl
69 beq 2f
70 1:
71 bcs 1f
72 movs r0, #1
73 negs r0, r0
74 RET
75 1:
76 movs r0, #1
77 2:
78 RET
79 FUNC_END aeabi_ulcmp
80
81 #endif /* L_aeabi_ulcmp */
82
83 .macro test_div_by_zero signed
84 cmp yyh, #0
85 bne 7f
86 cmp yyl, #0
87 bne 7f
88 cmp xxh, #0
89 .ifc \signed, unsigned
90 bne 2f
91 cmp xxl, #0
92 2:
93 beq 3f
94 movs xxh, #0
95 mvns xxh, xxh @ 0xffffffff
96 movs xxl, xxh
97 3:
98 .else
99 blt 6f
100 bgt 4f
101 cmp xxl, #0
102 beq 5f
103 4: movs xxl, #0
104 mvns xxl, xxl @ 0xffffffff
105 lsrs xxh, xxl, #1 @ 0x7fffffff
106 b 5f
107 6: movs xxh, #0x80
108 lsls xxh, xxh, #24 @ 0x80000000
109 movs xxl, #0
110 5:
111 .endif
112 @ tailcalls are tricky on v6-m.
113 push {r0, r1, r2}
114 ldr r0, 1f
115 adr r1, 1f
116 adds r0, r1
117 str r0, [sp, #8]
118 @ We know we are not on armv4t, so pop pc is safe.
119 pop {r0, r1, pc}
120 .align 2
121 1:
122 .word __aeabi_ldiv0 - 1b
123 7:
124 .endm
125
126 #ifdef L_aeabi_ldivmod
127
128 FUNC_START aeabi_ldivmod
129 test_div_by_zero signed
130
131 push {r0, r1}
132 mov r0, sp
133 push {r0, lr}
134 ldr r0, [sp, #8]
135 bl SYM(__gnu_ldivmod_helper)
136 ldr r3, [sp, #4]
137 mov lr, r3
138 add sp, sp, #8
139 pop {r2, r3}
140 RET
141 FUNC_END aeabi_ldivmod
142
143 #endif /* L_aeabi_ldivmod */
144
145 #ifdef L_aeabi_uldivmod
146
147 FUNC_START aeabi_uldivmod
148 test_div_by_zero unsigned
149
150 push {r0, r1}
151 mov r0, sp
152 push {r0, lr}
153 ldr r0, [sp, #8]
154 bl SYM(__udivmoddi4)
155 ldr r3, [sp, #4]
156 mov lr, r3
157 add sp, sp, #8
158 pop {r2, r3}
159 RET
160 FUNC_END aeabi_uldivmod
161
162 #endif /* L_aeabi_uldivmod */
163
164 #ifdef L_arm_addsubsf3
165
166 FUNC_START aeabi_frsub
167
168 push {r4, lr}
169 movs r4, #1
170 lsls r4, #31
171 eors r0, r0, r4
172 bl __aeabi_fadd
173 pop {r4, pc}
174
175 FUNC_END aeabi_frsub
176
177 #endif /* L_arm_addsubsf3 */
178
179 #ifdef L_arm_cmpsf2
180
181 FUNC_START aeabi_cfrcmple
182
183 mov ip, r0
184 movs r0, r1
185 mov r1, ip
186 b 6f
187
188 FUNC_START aeabi_cfcmpeq
189 FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
190
191 @ The status-returning routines are required to preserve all
192 @ registers except ip, lr, and cpsr.
193 6: push {r0, r1, r2, r3, r4, lr}
194 bl __lesf2
195 @ Set the Z flag correctly, and the C flag unconditionally.
196 cmp r0, #0
197 @ Clear the C flag if the return value was -1, indicating
198 @ that the first operand was smaller than the second.
199 bmi 1f
200 movs r1, #0
201 cmn r0, r1
202 1:
203 pop {r0, r1, r2, r3, r4, pc}
204
205 FUNC_END aeabi_cfcmple
206 FUNC_END aeabi_cfcmpeq
207 FUNC_END aeabi_cfrcmple
208
209 FUNC_START aeabi_fcmpeq
210
211 push {r4, lr}
212 bl __eqsf2
213 negs r0, r0
214 adds r0, r0, #1
215 pop {r4, pc}
216
217 FUNC_END aeabi_fcmpeq
218
219 .macro COMPARISON cond, helper, mode=sf2
220 FUNC_START aeabi_fcmp\cond
221
222 push {r4, lr}
223 bl __\helper\mode
224 cmp r0, #0
225 b\cond 1f
226 movs r0, #0
227 pop {r4, pc}
228 1:
229 movs r0, #1
230 pop {r4, pc}
231
232 FUNC_END aeabi_fcmp\cond
233 .endm
234
235 COMPARISON lt, le
236 COMPARISON le, le
237 COMPARISON gt, ge
238 COMPARISON ge, ge
239
240 #endif /* L_arm_cmpsf2 */
241
242 #ifdef L_arm_addsubdf3
243
244 FUNC_START aeabi_drsub
245
246 push {r4, lr}
247 movs r4, #1
248 lsls r4, #31
249 eors xxh, xxh, r4
250 bl __aeabi_dadd
251 pop {r4, pc}
252
253 FUNC_END aeabi_drsub
254
255 #endif /* L_arm_addsubdf3 */
256
257 #ifdef L_arm_cmpdf2
258
259 FUNC_START aeabi_cdrcmple
260
261 mov ip, r0
262 movs r0, r2
263 mov r2, ip
264 mov ip, r1
265 movs r1, r3
266 mov r3, ip
267 b 6f
268
269 FUNC_START aeabi_cdcmpeq
270 FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
271
272 @ The status-returning routines are required to preserve all
273 @ registers except ip, lr, and cpsr.
274 6: push {r0, r1, r2, r3, r4, lr}
275 bl __ledf2
276 @ Set the Z flag correctly, and the C flag unconditionally.
277 cmp r0, #0
278 @ Clear the C flag if the return value was -1, indicating
279 @ that the first operand was smaller than the second.
280 bmi 1f
281 movs r1, #0
282 cmn r0, r1
283 1:
284 pop {r0, r1, r2, r3, r4, pc}
285
286 FUNC_END aeabi_cdcmple
287 FUNC_END aeabi_cdcmpeq
288 FUNC_END aeabi_cdrcmple
289
290 FUNC_START aeabi_dcmpeq
291
292 push {r4, lr}
293 bl __eqdf2
294 negs r0, r0
295 adds r0, r0, #1
296 pop {r4, pc}
297
298 FUNC_END aeabi_dcmpeq
299
300 .macro COMPARISON cond, helper, mode=df2
301 FUNC_START aeabi_dcmp\cond
302
303 push {r4, lr}
304 bl __\helper\mode
305 cmp r0, #0
306 b\cond 1f
307 movs r0, #0
308 pop {r4, pc}
309 1:
310 movs r0, #1
311 pop {r4, pc}
312
313 FUNC_END aeabi_dcmp\cond
314 .endm
315
316 COMPARISON lt, le
317 COMPARISON le, le
318 COMPARISON gt, ge
319 COMPARISON ge, ge
320
321 #endif /* L_arm_cmpdf2 */