ada: Recognize iterated_component_association as potentially unevaluated
[official-gcc.git] / libgcc / config / arm / bpabi-v6m.S
blob713167e483a86f9acf58e1d989fd5aea87518df8
1 /* Miscellaneous BPABI functions.  Thumb-1 implementation, suitable for ARMv4T,
2    ARMv6-M and ARMv8-M Baseline like ISA variants.
4    Copyright (C) 2006-2023 Free Software Foundation, Inc.
5    Contributed by CodeSourcery.
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.
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.
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.
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/>.  */
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__ */
36 #ifdef L_aeabi_lcmp
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
46         movs    r0, #1
47         RET
49         subs    r0, xxl, yyl
50         beq     1f
51         bhi     2f
52         movs    r0, #1
53         negs    r0, r0
54         RET
56         movs    r0, #1
58         RET
59         FUNC_END aeabi_lcmp
61 #endif /* L_aeabi_lcmp */
62         
63 #ifdef L_aeabi_ulcmp
65 FUNC_START aeabi_ulcmp
66         cmp     xxh, yyh
67         bne     1f
68         subs    r0, xxl, yyl
69         beq     2f
71         bcs     1f
72         movs    r0, #1
73         negs    r0, r0
74         RET
76         movs    r0, #1
78         RET
79         FUNC_END aeabi_ulcmp
81 #endif /* L_aeabi_ulcmp */
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
93         beq     3f
94         movs    xxh, #0
95         mvns    xxh, xxh                @ 0xffffffff
96         movs    xxl, xxh
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
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
122         .word   __aeabi_ldiv0 - 1b
124 .endm
126 #ifdef L_aeabi_ldivmod
128 FUNC_START aeabi_ldivmod
129         test_div_by_zero signed
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
143 #endif /* L_aeabi_ldivmod */
145 #ifdef L_aeabi_uldivmod
147 FUNC_START aeabi_uldivmod
148         test_div_by_zero unsigned
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 */
164 #ifdef L_arm_addsubsf3
166 FUNC_START aeabi_frsub
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}
175       FUNC_END aeabi_frsub
177 #endif /* L_arm_addsubsf3 */
179 #ifdef L_arm_cmpsf2
181 FUNC_START aeabi_cfrcmple
183         mov     ip, r0
184         movs    r0, r1
185         mov     r1, ip
186         b       6f
188 FUNC_START aeabi_cfcmpeq
189 FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
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
203         pop     {r0, r1, r2, r3, r4, pc}
205         FUNC_END aeabi_cfcmple
206         FUNC_END aeabi_cfcmpeq
207         FUNC_END aeabi_cfrcmple
209 FUNC_START      aeabi_fcmpeq
211         push    {r4, lr}
212         bl      __eqsf2
213         negs    r0, r0
214         adds    r0, r0, #1
215         pop     {r4, pc}
217         FUNC_END aeabi_fcmpeq
219 .macro COMPARISON cond, helper, mode=sf2
220 FUNC_START      aeabi_fcmp\cond
222         push    {r4, lr}
223         bl      __\helper\mode
224         cmp     r0, #0
225         b\cond  1f
226         movs    r0, #0
227         pop     {r4, pc}
229         movs    r0, #1
230         pop     {r4, pc}
232         FUNC_END aeabi_fcmp\cond
233 .endm
235 COMPARISON lt, le
236 COMPARISON le, le
237 COMPARISON gt, ge
238 COMPARISON ge, ge
240 #endif /* L_arm_cmpsf2 */
242 #ifdef L_arm_addsubdf3
244 FUNC_START aeabi_drsub
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}
253       FUNC_END aeabi_drsub
255 #endif /* L_arm_addsubdf3 */
257 #ifdef L_arm_cmpdf2
259 FUNC_START aeabi_cdrcmple
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
269 FUNC_START aeabi_cdcmpeq
270 FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
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
284         pop     {r0, r1, r2, r3, r4, pc}
286         FUNC_END aeabi_cdcmple
287         FUNC_END aeabi_cdcmpeq
288         FUNC_END aeabi_cdrcmple
290 FUNC_START      aeabi_dcmpeq
292         push    {r4, lr}
293         bl      __eqdf2
294         negs    r0, r0
295         adds    r0, r0, #1
296         pop     {r4, pc}
298         FUNC_END aeabi_dcmpeq
300 .macro COMPARISON cond, helper, mode=df2
301 FUNC_START      aeabi_dcmp\cond
303         push    {r4, lr}
304         bl      __\helper\mode
305         cmp     r0, #0
306         b\cond  1f
307         movs    r0, #0
308         pop     {r4, pc}
310         movs    r0, #1
311         pop     {r4, pc}
313         FUNC_END aeabi_dcmp\cond
314 .endm
316 COMPARISON lt, le
317 COMPARISON le, le
318 COMPARISON gt, ge
319 COMPARISON ge, ge
321 #endif /* L_arm_cmpdf2 */