159 lines · plain
1//===-- aeabi_cfcmp.S - EABI cfcmp* implementation ------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../assembly.h"10 11#define APSR_Z (1 << 30)12#define APSR_C (1 << 29)13 14// void __aeabi_cfcmpeq(float a, float b) {15// if (isnan(a) || isnan(b)) {16// Z = 0; C = 1;17// } else {18// __aeabi_cfcmple(a, b);19// }20// }21 22 .syntax unified23 .p2align 224DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)25 PACBTI_LANDING26#if defined(__ARM_FEATURE_PAC_DEFAULT)27 push {r0-r3, r12, lr}28#else29 push {r0-r3, lr}30#endif31 bl __aeabi_cfcmpeq_check_nan32 cmp r0, #133#if defined(USE_THUMB_1)34 beq 1f35 // NaN has been ruled out, so __aeabi_cfcmple can't trap36 mov r0, sp37 ldm r0, {r0-r3}38 bl __aeabi_cfcmple39 pop {r0-r3, pc}401:41 // Z = 0, C = 142 movs r0, #0xF43 lsls r0, r0, #3144 pop {r0-r3, pc}45#else46#if defined(__ARM_FEATURE_PAC_DEFAULT)47 pop {r0-r3, r12, lr}48 aut r12, lr, sp49#else50 pop {r0-r3, lr}51#endif52 53 // NaN has been ruled out, so __aeabi_cfcmple can't trap54 // Use "it ne" + unconditional branch to guarantee a supported relocation if55 // __aeabi_cfcmple is in a different section for some builds.56 IT(ne)57 bne __aeabi_cfcmple58 59#if defined(USE_THUMB_2)60 mov r12, #APSR_C61 msr APSR_nzcvq, r1262#else63 msr APSR_nzcvq, #APSR_C64#endif65 JMP(lr)66#endif67END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)68 69 70// void __aeabi_cfcmple(float a, float b) {71// if (__aeabi_fcmplt(a, b)) {72// Z = 0; C = 0;73// } else if (__aeabi_fcmpeq(a, b)) {74// Z = 1; C = 1;75// } else {76// Z = 0; C = 1;77// }78// }79 80 .syntax unified81 .p2align 282DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)83 PACBTI_LANDING84 // Per the RTABI, this function must preserve r0-r11.85 // Save lr in the same instruction for compactness86#if defined(__ARM_FEATURE_PAC_DEFAULT)87 push {r0-r3, r12, lr}88#else89 push {r0-r3, lr}90#endif91 92 bl __aeabi_fcmplt93 cmp r0, #194#if defined(USE_THUMB_1)95 bne 1f96 // Z = 0, C = 097 movs r0, #198 lsls r0, r0, #199 pop {r0-r3, pc}1001:101 mov r0, sp102 ldm r0, {r0-r3}103 bl __aeabi_fcmpeq104 cmp r0, #1105 bne 2f106 // Z = 1, C = 1107 movs r0, #2108 lsls r0, r0, #31109 pop {r0-r3, pc}1102:111 // Z = 0, C = 1112 movs r0, #0xF113 lsls r0, r0, #31114 pop {r0-r3, pc}115#else116 ITT(eq)117 moveq ip, #0118 beq 1f119 120 ldm sp, {r0-r3}121 bl __aeabi_fcmpeq122 cmp r0, #1123 ITE(eq)124 moveq ip, #(APSR_C | APSR_Z)125 movne ip, #(APSR_C)126 1271:128 msr APSR_nzcvq, ip129#if defined(__ARM_FEATURE_PAC_DEFAULT)130 pop {r0-r3, r12, lr}131 PAC_RETURN132#else133 pop {r0-r3}134 POP_PC()135#endif136#endif137END_COMPILERRT_FUNCTION(__aeabi_cfcmple)138 139// int __aeabi_cfrcmple(float a, float b) {140// return __aeabi_cfcmple(b, a);141// }142 143 .syntax unified144 .p2align 2145DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)146#if defined(__ARM_FEATURE_BTI_DEFAULT)147 bti148#endif149 // Swap r0 and r1150 mov ip, r0151 mov r0, r1152 mov r1, ip153 154 b __aeabi_cfcmple155END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)156 157NO_EXEC_STACK_DIRECTIVE158 159