1//===-- aeabi_cdcmp.S - EABI cdcmp* 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-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "../assembly.h" 10 11#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ 12#error big endian support not implemented 13#endif 14 15#define APSR_Z (1 << 30) 16#define APSR_C (1 << 29) 17 18// void __aeabi_cdcmpeq(double a, double b) { 19// if (isnan(a) || isnan(b)) { 20// Z = 0; C = 1; 21// } else { 22// __aeabi_cdcmple(a, b); 23// } 24// } 25 26 .syntax unified 27 .p2align 2 28DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq) 29 push {r0-r3, lr} 30 bl __aeabi_cdcmpeq_check_nan 31 cmp r0, #1 32#if defined(USE_THUMB_1) 33 beq 1f 34 // NaN has been ruled out, so __aeabi_cdcmple can't trap 35 mov r0, sp 36 ldm r0, {r0-r3} 37 bl __aeabi_cdcmple 38 pop {r0-r3, pc} 391: 40 // Z = 0, C = 1 41 movs r0, #0xF 42 lsls r0, r0, #31 43 pop {r0-r3, pc} 44#else 45 pop {r0-r3, lr} 46 47 // NaN has been ruled out, so __aeabi_cdcmple can't trap 48 // Use "it ne" + unconditional branch to guarantee a supported relocation if 49 // __aeabi_cdcmple is in a different section for some builds. 50 IT(ne) 51 bne __aeabi_cdcmple 52 53#if defined(USE_THUMB_2) 54 mov ip, #APSR_C 55 msr APSR_nzcvq, ip 56#else 57 msr APSR_nzcvq, #APSR_C 58#endif 59 JMP(lr) 60#endif 61END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq) 62 63 64// void __aeabi_cdcmple(double a, double b) { 65// if (__aeabi_dcmplt(a, b)) { 66// Z = 0; C = 0; 67// } else if (__aeabi_dcmpeq(a, b)) { 68// Z = 1; C = 1; 69// } else { 70// Z = 0; C = 1; 71// } 72// } 73 74 .syntax unified 75 .p2align 2 76DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple) 77 // Per the RTABI, this function must preserve r0-r11. 78 // Save lr in the same instruction for compactness 79 push {r0-r3, lr} 80 81 bl __aeabi_dcmplt 82 cmp r0, #1 83#if defined(USE_THUMB_1) 84 bne 1f 85 // Z = 0, C = 0 86 movs r0, #1 87 lsls r0, r0, #1 88 pop {r0-r3, pc} 891: 90 mov r0, sp 91 ldm r0, {r0-r3} 92 bl __aeabi_dcmpeq 93 cmp r0, #1 94 bne 2f 95 // Z = 1, C = 1 96 movs r0, #2 97 lsls r0, r0, #31 98 pop {r0-r3, pc} 992: 100 // Z = 0, C = 1 101 movs r0, #0xF 102 lsls r0, r0, #31 103 pop {r0-r3, pc} 104#else 105 ITT(eq) 106 moveq ip, #0 107 beq 1f 108 109 ldm sp, {r0-r3} 110 bl __aeabi_dcmpeq 111 cmp r0, #1 112 ITE(eq) 113 moveq ip, #(APSR_C | APSR_Z) 114 movne ip, #(APSR_C) 115 1161: 117 msr APSR_nzcvq, ip 118 pop {r0-r3} 119 POP_PC() 120#endif 121END_COMPILERRT_FUNCTION(__aeabi_cdcmple) 122 123// int __aeabi_cdrcmple(double a, double b) { 124// return __aeabi_cdcmple(b, a); 125// } 126 127 .syntax unified 128 .p2align 2 129DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple) 130 // Swap r0 and r2 131 mov ip, r0 132 mov r0, r2 133 mov r2, ip 134 135 // Swap r1 and r3 136 mov ip, r1 137 mov r1, r3 138 mov r3, ip 139 140 b __aeabi_cdcmple 141END_COMPILERRT_FUNCTION(__aeabi_cdrcmple) 142 143NO_EXEC_STACK_DIRECTIVE 144 145