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-2018 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 38FUNC_START aeabi_lcmp 39 cmp xxh, yyh 40 beq 1f 41 bgt 2f 42 mov r0, #1 43 neg r0, r0 44 RET 452: 46 mov r0, #1 47 RET 481: 49 sub r0, xxl, yyl 50 beq 1f 51 bhi 2f 52 mov r0, #1 53 neg r0, r0 54 RET 552: 56 mov r0, #1 571: 58 RET 59 FUNC_END aeabi_lcmp 60 61#endif /* L_aeabi_lcmp */ 62 63#ifdef L_aeabi_ulcmp 64 65FUNC_START aeabi_ulcmp 66 cmp xxh, yyh 67 bne 1f 68 sub r0, xxl, yyl 69 beq 2f 701: 71 bcs 1f 72 mov r0, #1 73 neg r0, r0 74 RET 751: 76 mov r0, #1 772: 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 922: 93 beq 3f 94 mov xxh, #0 95 mvn xxh, xxh @ 0xffffffff 96 mov xxl, xxh 973: 98 .else 99 blt 6f 100 bgt 4f 101 cmp xxl, #0 102 beq 5f 1034: mov xxl, #0 104 mvn xxl, xxl @ 0xffffffff 105 lsr xxh, xxl, #1 @ 0x7fffffff 106 b 5f 1076: mov xxh, #0x80 108 lsl xxh, xxh, #24 @ 0x80000000 109 mov xxl, #0 1105: 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 1211: 122 .word __aeabi_ldiv0 - 1b 1237: 124.endm 125 126#ifdef L_aeabi_ldivmod 127 128FUNC_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 147FUNC_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 166FUNC_START aeabi_frsub 167 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} 174 175 FUNC_END aeabi_frsub 176 177#endif /* L_arm_addsubsf3 */ 178 179#ifdef L_arm_cmpsf2 180 181FUNC_START aeabi_cfrcmple 182 183 mov ip, r0 184 mov r0, r1 185 mov r1, ip 186 b 6f 187 188FUNC_START aeabi_cfcmpeq 189FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq 190 191 @ The status-returning routines are required to preserve all 192 @ registers except ip, lr, and cpsr. 1936: 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 2021: 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 209FUNC_START aeabi_fcmpeq 210 211 push {r4, lr} 212 bl __eqsf2 213 neg r0, r0 214 add r0, r0, #1 215 pop {r4, pc} 216 217 FUNC_END aeabi_fcmpeq 218 219.macro COMPARISON cond, helper, mode=sf2 220FUNC_START aeabi_fcmp\cond 221 222 push {r4, lr} 223 bl __\helper\mode 224 cmp r0, #0 225 b\cond 1f 226 mov r0, #0 227 pop {r4, pc} 2281: 229 mov r0, #1 230 pop {r4, pc} 231 232 FUNC_END aeabi_fcmp\cond 233.endm 234 235COMPARISON lt, le 236COMPARISON le, le 237COMPARISON gt, ge 238COMPARISON ge, ge 239 240#endif /* L_arm_cmpsf2 */ 241 242#ifdef L_arm_addsubdf3 243 244FUNC_START aeabi_drsub 245 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} 252 253 FUNC_END aeabi_drsub 254 255#endif /* L_arm_addsubdf3 */ 256 257#ifdef L_arm_cmpdf2 258 259FUNC_START aeabi_cdrcmple 260 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 268 269FUNC_START aeabi_cdcmpeq 270FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq 271 272 @ The status-returning routines are required to preserve all 273 @ registers except ip, lr, and cpsr. 2746: 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 2831: 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 290FUNC_START aeabi_dcmpeq 291 292 push {r4, lr} 293 bl __eqdf2 294 neg r0, r0 295 add r0, r0, #1 296 pop {r4, pc} 297 298 FUNC_END aeabi_dcmpeq 299 300.macro COMPARISON cond, helper, mode=df2 301FUNC_START aeabi_dcmp\cond 302 303 push {r4, lr} 304 bl __\helper\mode 305 cmp r0, #0 306 b\cond 1f 307 mov r0, #0 308 pop {r4, pc} 3091: 310 mov r0, #1 311 pop {r4, pc} 312 313 FUNC_END aeabi_dcmp\cond 314.endm 315 316COMPARISON lt, le 317COMPARISON le, le 318COMPARISON gt, ge 319COMPARISON ge, ge 320 321#endif /* L_arm_cmpdf2 */ 322