]>
Commit | Line | Data |
---|---|---|
6f493951 TP |
1 | /* Miscellaneous BPABI functions. Thumb-1 implementation, suitable for ARMv4T, |
2 | ARMv6-M and ARMv8-M Baseline like ISA variants. | |
bf98ec6c | 3 | |
7adcbafe | 4 | Copyright (C) 2006-2022 Free Software Foundation, Inc. |
bf98ec6c PB |
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 | |
748086b7 | 9 | Free Software Foundation; either version 3, or (at your option) any |
bf98ec6c PB |
10 | later version. |
11 | ||
bf98ec6c PB |
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 | ||
748086b7 JJ |
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/>. */ | |
bf98ec6c | 25 | |
6f0668cf RE |
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 | ||
bf98ec6c PB |
36 | #ifdef L_aeabi_lcmp |
37 | ||
38 | FUNC_START aeabi_lcmp | |
39 | cmp xxh, yyh | |
40 | beq 1f | |
41 | bgt 2f | |
6b9ce2b4 RE |
42 | movs r0, #1 |
43 | negs r0, r0 | |
bf98ec6c PB |
44 | RET |
45 | 2: | |
6b9ce2b4 | 46 | movs r0, #1 |
bf98ec6c PB |
47 | RET |
48 | 1: | |
6b9ce2b4 | 49 | subs r0, xxl, yyl |
bf98ec6c PB |
50 | beq 1f |
51 | bhi 2f | |
6b9ce2b4 RE |
52 | movs r0, #1 |
53 | negs r0, r0 | |
bf98ec6c PB |
54 | RET |
55 | 2: | |
6b9ce2b4 | 56 | movs r0, #1 |
bf98ec6c PB |
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 | |
6b9ce2b4 | 68 | subs r0, xxl, yyl |
bf98ec6c PB |
69 | beq 2f |
70 | 1: | |
71 | bcs 1f | |
6b9ce2b4 RE |
72 | movs r0, #1 |
73 | negs r0, r0 | |
bf98ec6c PB |
74 | RET |
75 | 1: | |
6b9ce2b4 | 76 | movs r0, #1 |
bf98ec6c PB |
77 | 2: |
78 | RET | |
79 | FUNC_END aeabi_ulcmp | |
80 | ||
81 | #endif /* L_aeabi_ulcmp */ | |
82 | ||
0c23e1be JB |
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 | |
53cfb467 | 89 | .ifc \signed, unsigned |
0c23e1be JB |
90 | bne 2f |
91 | cmp xxl, #0 | |
92 | 2: | |
0c23e1be | 93 | beq 3f |
6b9ce2b4 RE |
94 | movs xxh, #0 |
95 | mvns xxh, xxh @ 0xffffffff | |
96 | movs xxl, xxh | |
0c23e1be JB |
97 | 3: |
98 | .else | |
0c23e1be | 99 | blt 6f |
53cfb467 SL |
100 | bgt 4f |
101 | cmp xxl, #0 | |
102 | beq 5f | |
6b9ce2b4 RE |
103 | 4: movs xxl, #0 |
104 | mvns xxl, xxl @ 0xffffffff | |
105 | lsrs xxh, xxl, #1 @ 0x7fffffff | |
0c23e1be | 106 | b 5f |
6b9ce2b4 RE |
107 | 6: movs xxh, #0x80 |
108 | lsls xxh, xxh, #24 @ 0x80000000 | |
109 | movs xxl, #0 | |
0c23e1be JB |
110 | 5: |
111 | .endif | |
112 | @ tailcalls are tricky on v6-m. | |
113 | push {r0, r1, r2} | |
114 | ldr r0, 1f | |
115 | adr r1, 1f | |
6b9ce2b4 | 116 | adds r0, r1 |
0c23e1be JB |
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 | ||
bf98ec6c PB |
126 | #ifdef L_aeabi_ldivmod |
127 | ||
128 | FUNC_START aeabi_ldivmod | |
0c23e1be JB |
129 | test_div_by_zero signed |
130 | ||
6b9ce2b4 RE |
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} | |
bf98ec6c PB |
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 | |
0c23e1be JB |
148 | test_div_by_zero unsigned |
149 | ||
6b9ce2b4 RE |
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} | |
bf98ec6c PB |
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} | |
6b9ce2b4 RE |
169 | movs r4, #1 |
170 | lsls r4, #31 | |
171 | eors r0, r0, r4 | |
bf98ec6c PB |
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 | |
6b9ce2b4 | 184 | movs r0, r1 |
bf98ec6c PB |
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. | |
6b9ce2b4 RE |
199 | bmi 1f |
200 | movs r1, #0 | |
bf98ec6c PB |
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 | |
6b9ce2b4 RE |
213 | negs r0, r0 |
214 | adds r0, r0, #1 | |
bf98ec6c PB |
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 | |
6b9ce2b4 | 226 | movs r0, #0 |
bf98ec6c PB |
227 | pop {r4, pc} |
228 | 1: | |
6b9ce2b4 | 229 | movs r0, #1 |
bf98ec6c PB |
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} | |
6b9ce2b4 RE |
247 | movs r4, #1 |
248 | lsls r4, #31 | |
249 | eors xxh, xxh, r4 | |
bf98ec6c PB |
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 | |
6b9ce2b4 | 262 | movs r0, r2 |
bf98ec6c PB |
263 | mov r2, ip |
264 | mov ip, r1 | |
6b9ce2b4 | 265 | movs r1, r3 |
bf98ec6c PB |
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. | |
6b9ce2b4 RE |
280 | bmi 1f |
281 | movs r1, #0 | |
bf98ec6c PB |
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 | |
6b9ce2b4 RE |
294 | negs r0, r0 |
295 | adds r0, r0, #1 | |
bf98ec6c PB |
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 | |
6b9ce2b4 | 307 | movs r0, #0 |
bf98ec6c PB |
308 | pop {r4, pc} |
309 | 1: | |
6b9ce2b4 | 310 | movs r0, #1 |
bf98ec6c PB |
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 */ |