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#define APSR_Z (1 << 30)
12#define APSR_C (1 << 29)
13
14// void __aeabi_cdcmpeq(double a, double b) {
15// if (isnan(a) || isnan(b)) {
16// Z = 0; C = 1;
17// } else {
18// __aeabi_cdcmple(a, b);
19// }
20// }
21
22 .syntax unified
23 .p2align 2
24DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
25 PACBTI_LANDING
26#if defined(__ARM_FEATURE_PAC_DEFAULT)
27 push {r0-r3, r12, lr}
28#else
29 push {r0-r3, lr}
30#endif
31 bl __aeabi_cdcmpeq_check_nan
32 cmp r0, #1
33#if defined(USE_THUMB_1)
34 beq 1f
35 // NaN has been ruled out, so __aeabi_cdcmple can't trap
36 mov r0, sp
37 ldm r0, {r0-r3}
38 bl __aeabi_cdcmple
39 pop {r0-r3, pc}
401:
41 // Z = 0, C = 1
42 movs r0, #0xF
43 lsls r0, r0, #31
44 pop {r0-r3, pc}
45#else
46#if defined(__ARM_FEATURE_PAC_DEFAULT)
47 pop {r0-r3, r12, lr}
48 aut r12, lr, sp
49#else
50 pop {r0-r3, lr}
51#endif
52
53 // NaN has been ruled out, so __aeabi_cdcmple can't trap
54 // Use "it ne" + unconditional branch to guarantee a supported relocation if
55 // __aeabi_cdcmple is in a different section for some builds.
56 IT(ne)
57 bne __aeabi_cdcmple
58
59#if defined(USE_THUMB_2)
60 mov r12, #APSR_C
61 msr APSR_nzcvq, r12
62#else
63 msr APSR_nzcvq, #APSR_C
64#endif
65 JMP(lr)
66#endif
67END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
68
69
70// void __aeabi_cdcmple(double a, double b) {
71// if (__aeabi_dcmplt(a, b)) {
72// Z = 0; C = 0;
73// } else if (__aeabi_dcmpeq(a, b)) {
74// Z = 1; C = 1;
75// } else {
76// Z = 0; C = 1;
77// }
78// }
79
80 .syntax unified
81 .p2align 2
82DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
83 PACBTI_LANDING
84 // Per the RTABI, this function must preserve r0-r11.
85 // Save lr in the same instruction for compactness
86#if defined(__ARM_FEATURE_PAC_DEFAULT)
87 push {r0-r3, r12, lr}
88#else
89 push {r0-r3, lr}
90#endif
91
92 bl __aeabi_dcmplt
93 cmp r0, #1
94#if defined(USE_THUMB_1)
95 bne 1f
96 // Z = 0, C = 0
97 movs r0, #1
98 lsls r0, r0, #1
99 pop {r0-r3, pc}
1001:
101 mov r0, sp
102 ldm r0, {r0-r3}
103 bl __aeabi_dcmpeq
104 cmp r0, #1
105 bne 2f
106 // Z = 1, C = 1
107 movs r0, #2
108 lsls r0, r0, #31
109 pop {r0-r3, pc}
1102:
111 // Z = 0, C = 1
112 movs r0, #0xF
113 lsls r0, r0, #31
114 pop {r0-r3, pc}
115#else
116 ITT(eq)
117 moveq ip, #0
118 beq 1f
119
120 ldm sp, {r0-r3}
121 bl __aeabi_dcmpeq
122 cmp r0, #1
123 ITE(eq)
124 moveq ip, #(APSR_C | APSR_Z)
125 movne ip, #(APSR_C)
126
1271:
128 msr APSR_nzcvq, ip
129#if defined(__ARM_FEATURE_PAC_DEFAULT)
130 pop {r0-r3, r12, lr}
131 bxaut r12, lr, sp
132#else
133 pop {r0-r3}
134 POP_PC()
135#endif
136#endif
137END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
138
139// int __aeabi_cdrcmple(double a, double b) {
140// return __aeabi_cdcmple(b, a);
141// }
142
143 .syntax unified
144 .p2align 2
145DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
146#if defined(__ARM_FEATURE_BTI_DEFAULT)
147 bti
148#endif
149 // Swap r0 and r2
150 mov ip, r0
151 mov r0, r2
152 mov r2, ip
153
154 // Swap r1 and r3
155 mov ip, r1
156 mov r1, r3
157 mov r3, ip
158
159 b __aeabi_cdcmple
160END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
161
162NO_EXEC_STACK_DIRECTIVE
163
164

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of compiler-rt/lib/builtins/arm/aeabi_cdcmp.S