1/* Miscellaneous BPABI functions. ARMv6M implementation 2 3 Copyright (C) 2006-2013 Free Software Foundation, Inc. 4 Contributed by CodeSourcery. 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 8 Free Software Foundation; either version 3, or (at your option) any 9 later version. 10 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 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/>. */ 24 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 35#ifdef L_aeabi_lcmp 36 37FUNC_START aeabi_lcmp 38 cmp xxh, yyh 39 beq 1f 40 bgt 2f 41 mov r0, #1 42 neg r0, r0 43 RET 442: 45 mov r0, #1 46 RET 471: 48 sub r0, xxl, yyl 49 beq 1f 50 bhi 2f 51 mov r0, #1 52 neg r0, r0 53 RET 542: 55 mov r0, #1 561: 57 RET 58 FUNC_END aeabi_lcmp 59 60#endif /* L_aeabi_lcmp */ 61 62#ifdef L_aeabi_ulcmp 63 64FUNC_START aeabi_ulcmp 65 cmp xxh, yyh 66 bne 1f 67 sub r0, xxl, yyl 68 beq 2f 691: 70 bcs 1f 71 mov r0, #1 72 neg r0, r0 73 RET 741: 75 mov r0, #1 762: 77 RET 78 FUNC_END aeabi_ulcmp 79 80#endif /* L_aeabi_ulcmp */ 81 82.macro test_div_by_zero signed 83 cmp yyh, #0 84 bne 7f 85 cmp yyl, #0 86 bne 7f 87 cmp xxh, #0 88 .ifc \signed, unsigned 89 bne 2f 90 cmp xxl, #0 912: 92 beq 3f 93 mov xxh, #0 94 mvn xxh, xxh @ 0xffffffff 95 mov xxl, xxh 963: 97 .else 98 blt 6f 99 bgt 4f 100 cmp xxl, #0 101 beq 5f 1024: mov xxl, #0 103 mvn xxl, xxl @ 0xffffffff 104 lsr xxh, xxl, #1 @ 0x7fffffff 105 b 5f 1066: mov xxh, #0x80 107 lsl xxh, xxh, #24 @ 0x80000000 108 mov xxl, #0 1095: 110 .endif 111 @ tailcalls are tricky on v6-m. 112 push {r0, r1, r2} 113 ldr r0, 1f 114 adr r1, 1f 115 add r0, r1 116 str r0, [sp, #8] 117 @ We know we are not on armv4t, so pop pc is safe. 118 pop {r0, r1, pc} 119 .align 2 1201: 121 .word __aeabi_ldiv0 - 1b 1227: 123.endm 124 125#ifdef L_aeabi_ldivmod 126 127FUNC_START aeabi_ldivmod 128 test_div_by_zero signed 129 130 push {r0, r1} 131 mov r0, sp 132 push {r0, lr} 133 ldr r0, [sp, #8] 134 bl SYM(__gnu_ldivmod_helper) 135 ldr r3, [sp, #4] 136 mov lr, r3 137 add sp, sp, #8 138 pop {r2, r3} 139 RET 140 FUNC_END aeabi_ldivmod 141 142#endif /* L_aeabi_ldivmod */ 143 144#ifdef L_aeabi_uldivmod 145 146FUNC_START aeabi_uldivmod 147 test_div_by_zero unsigned 148 149 push {r0, r1} 150 mov r0, sp 151 push {r0, lr} 152 ldr r0, [sp, #8] 153 bl SYM(__gnu_uldivmod_helper) 154 ldr r3, [sp, #4] 155 mov lr, r3 156 add sp, sp, #8 157 pop {r2, r3} 158 RET 159 FUNC_END aeabi_uldivmod 160 161#endif /* L_aeabi_uldivmod */ 162 163#ifdef L_arm_addsubsf3 164 165FUNC_START aeabi_frsub 166 167 push {r4, lr} 168 mov r4, #1 169 lsl r4, #31 170 eor r0, r0, r4 171 bl __aeabi_fadd 172 pop {r4, pc} 173 174 FUNC_END aeabi_frsub 175 176#endif /* L_arm_addsubsf3 */ 177 178#ifdef L_arm_cmpsf2 179 180FUNC_START aeabi_cfrcmple 181 182 mov ip, r0 183 mov r0, r1 184 mov r1, ip 185 b 6f 186 187FUNC_START aeabi_cfcmpeq 188FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq 189 190 @ The status-returning routines are required to preserve all 191 @ registers except ip, lr, and cpsr. 1926: push {r0, r1, r2, r3, r4, lr} 193 bl __lesf2 194 @ Set the Z flag correctly, and the C flag unconditionally. 195 cmp r0, #0 196 @ Clear the C flag if the return value was -1, indicating 197 @ that the first operand was smaller than the second. 198 bmi 1f 199 mov r1, #0 200 cmn r0, r1 2011: 202 pop {r0, r1, r2, r3, r4, pc} 203 204 FUNC_END aeabi_cfcmple 205 FUNC_END aeabi_cfcmpeq 206 FUNC_END aeabi_cfrcmple 207 208FUNC_START aeabi_fcmpeq 209 210 push {r4, lr} 211 bl __eqsf2 212 neg r0, r0 213 add r0, r0, #1 214 pop {r4, pc} 215 216 FUNC_END aeabi_fcmpeq 217 218.macro COMPARISON cond, helper, mode=sf2 219FUNC_START aeabi_fcmp\cond 220 221 push {r4, lr} 222 bl __\helper\mode 223 cmp r0, #0 224 b\cond 1f 225 mov r0, #0 226 pop {r4, pc} 2271: 228 mov r0, #1 229 pop {r4, pc} 230 231 FUNC_END aeabi_fcmp\cond 232.endm 233 234COMPARISON lt, le 235COMPARISON le, le 236COMPARISON gt, ge 237COMPARISON ge, ge 238 239#endif /* L_arm_cmpsf2 */ 240 241#ifdef L_arm_addsubdf3 242 243FUNC_START aeabi_drsub 244 245 push {r4, lr} 246 mov r4, #1 247 lsl r4, #31 248 eor xxh, xxh, r4 249 bl __aeabi_dadd 250 pop {r4, pc} 251 252 FUNC_END aeabi_drsub 253 254#endif /* L_arm_addsubdf3 */ 255 256#ifdef L_arm_cmpdf2 257 258FUNC_START aeabi_cdrcmple 259 260 mov ip, r0 261 mov r0, r2 262 mov r2, ip 263 mov ip, r1 264 mov r1, r3 265 mov r3, ip 266 b 6f 267 268FUNC_START aeabi_cdcmpeq 269FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq 270 271 @ The status-returning routines are required to preserve all 272 @ registers except ip, lr, and cpsr. 2736: push {r0, r1, r2, r3, r4, lr} 274 bl __ledf2 275 @ Set the Z flag correctly, and the C flag unconditionally. 276 cmp r0, #0 277 @ Clear the C flag if the return value was -1, indicating 278 @ that the first operand was smaller than the second. 279 bmi 1f 280 mov r1, #0 281 cmn r0, r1 2821: 283 pop {r0, r1, r2, r3, r4, pc} 284 285 FUNC_END aeabi_cdcmple 286 FUNC_END aeabi_cdcmpeq 287 FUNC_END aeabi_cdrcmple 288 289FUNC_START aeabi_dcmpeq 290 291 push {r4, lr} 292 bl __eqdf2 293 neg r0, r0 294 add r0, r0, #1 295 pop {r4, pc} 296 297 FUNC_END aeabi_dcmpeq 298 299.macro COMPARISON cond, helper, mode=df2 300FUNC_START aeabi_dcmp\cond 301 302 push {r4, lr} 303 bl __\helper\mode 304 cmp r0, #0 305 b\cond 1f 306 mov r0, #0 307 pop {r4, pc} 3081: 309 mov r0, #1 310 pop {r4, pc} 311 312 FUNC_END aeabi_dcmp\cond 313.endm 314 315COMPARISON lt, le 316COMPARISON le, le 317COMPARISON gt, ge 318COMPARISON ge, ge 319 320#endif /* L_arm_cmpdf2 */ 321