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-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_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 unified |
23 | .p2align 2 |
24 | DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq) |
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_cfcmpeq_check_nan |
32 | cmp r0, #1 |
33 | #if defined(USE_THUMB_1) |
34 | beq 1f |
35 | // NaN has been ruled out, so __aeabi_cfcmple can't trap |
36 | mov r0, sp |
37 | ldm r0, {r0-r3} |
38 | bl __aeabi_cfcmple |
39 | pop {r0-r3, pc} |
40 | 1: |
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_cfcmple can't trap |
54 | // Use "it ne" + unconditional branch to guarantee a supported relocation if |
55 | // __aeabi_cfcmple is in a different section for some builds. |
56 | IT(ne) |
57 | bne __aeabi_cfcmple |
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 |
67 | END_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 unified |
81 | .p2align 2 |
82 | DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple) |
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_fcmplt |
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} |
100 | 1: |
101 | mov r0, sp |
102 | ldm r0, {r0-r3} |
103 | bl __aeabi_fcmpeq |
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} |
110 | 2: |
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_fcmpeq |
122 | cmp r0, #1 |
123 | ITE(eq) |
124 | moveq ip, #(APSR_C | APSR_Z) |
125 | movne ip, #(APSR_C) |
126 | |
127 | 1: |
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 |
137 | END_COMPILERRT_FUNCTION(__aeabi_cfcmple) |
138 | |
139 | // int __aeabi_cfrcmple(float a, float b) { |
140 | // return __aeabi_cfcmple(b, a); |
141 | // } |
142 | |
143 | .syntax unified |
144 | .p2align 2 |
145 | DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple) |
146 | #if defined(__ARM_FEATURE_BTI_DEFAULT) |
147 | bti |
148 | #endif |
149 | // Swap r0 and r1 |
150 | mov ip, r0 |
151 | mov r0, r1 |
152 | mov r1, ip |
153 | |
154 | b __aeabi_cfcmple |
155 | END_COMPILERRT_FUNCTION(__aeabi_cfrcmple) |
156 | |
157 | NO_EXEC_STACK_DIRECTIVE |
158 | |
159 | |