[Patch (preapproved)] Guard Copy Header pass on
[official-gcc.git] / libgcc / config / arm / bpabi-v6m.S
blobb1ef2fcc5e969893f7582bf1498496dda5ee21cc
1 /* Miscellaneous BPABI functions.  Thumb-1 implementation, suitable for ARMv4T,
2    ARMv6-M and ARMv8-M Baseline like ISA variants.
4    Copyright (C) 2006-2017 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         mov     r0, #1
43         neg     r0, r0
44         RET
46         mov     r0, #1
47         RET
49         sub     r0, xxl, yyl
50         beq     1f
51         bhi     2f
52         mov     r0, #1
53         neg     r0, r0
54         RET
56         mov     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         sub     r0, xxl, yyl
69         beq     2f
71         bcs     1f
72         mov     r0, #1
73         neg     r0, r0
74         RET
76         mov     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         mov     xxh, #0
95         mvn     xxh, xxh                @ 0xffffffff
96         mov     xxl, xxh
98         .else
99         blt     6f
100         bgt     4f
101         cmp     xxl, #0
102         beq     5f
103 4:      mov     xxl, #0
104         mvn     xxl, xxl                @ 0xffffffff
105         lsr     xxh, xxl, #1            @ 0x7fffffff
106         b       5f
107 6:      mov     xxh, #0x80
108         lsl     xxh, xxh, #24           @ 0x80000000
109         mov     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         add     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       mov       r4, #1
170       lsl       r4, #31
171       eor       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         mov     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         mov     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         neg     r0, r0
214         add     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         mov     r0, #0
227         pop     {r4, pc}
229         mov     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       mov       r4, #1
248       lsl       r4, #31
249       eor       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         mov     r0, r2
263         mov     r2, ip
264         mov     ip, r1
265         mov     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         mov     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         neg     r0, r0
295         add     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         mov     r0, #0
308         pop     {r4, pc}
310         mov     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 */