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 push {r0-r3, lr}
26 bl __aeabi_cdcmpeq_check_nan
27 cmp r0, #1
28#if defined(USE_THUMB_1)
29 beq 1f
30 // NaN has been ruled out, so __aeabi_cdcmple can't trap
31 mov r0, sp
32 ldm r0, {r0-r3}
33 bl __aeabi_cdcmple
34 pop {r0-r3, pc}
351:
36 // Z = 0, C = 1
37 movs r0, #0xF
38 lsls r0, r0, #31
39 pop {r0-r3, pc}
40#else
41 pop {r0-r3, lr}
42
43 // NaN has been ruled out, so __aeabi_cdcmple can't trap
44 // Use "it ne" + unconditional branch to guarantee a supported relocation if
45 // __aeabi_cdcmple is in a different section for some builds.
46 IT(ne)
47 bne __aeabi_cdcmple
48
49#if defined(USE_THUMB_2)
50 mov ip, #APSR_C
51 msr APSR_nzcvq, ip
52#else
53 msr APSR_nzcvq, #APSR_C
54#endif
55 JMP(lr)
56#endif
57END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
58
59
60// void __aeabi_cdcmple(double a, double b) {
61// if (__aeabi_dcmplt(a, b)) {
62// Z = 0; C = 0;
63// } else if (__aeabi_dcmpeq(a, b)) {
64// Z = 1; C = 1;
65// } else {
66// Z = 0; C = 1;
67// }
68// }
69
70 .syntax unified
71 .p2align 2
72DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
73 // Per the RTABI, this function must preserve r0-r11.
74 // Save lr in the same instruction for compactness
75 push {r0-r3, lr}
76
77 bl __aeabi_dcmplt
78 cmp r0, #1
79#if defined(USE_THUMB_1)
80 bne 1f
81 // Z = 0, C = 0
82 movs r0, #1
83 lsls r0, r0, #1
84 pop {r0-r3, pc}
851:
86 mov r0, sp
87 ldm r0, {r0-r3}
88 bl __aeabi_dcmpeq
89 cmp r0, #1
90 bne 2f
91 // Z = 1, C = 1
92 movs r0, #2
93 lsls r0, r0, #31
94 pop {r0-r3, pc}
952:
96 // Z = 0, C = 1
97 movs r0, #0xF
98 lsls r0, r0, #31
99 pop {r0-r3, pc}
100#else
101 ITT(eq)
102 moveq ip, #0
103 beq 1f
104
105 ldm sp, {r0-r3}
106 bl __aeabi_dcmpeq
107 cmp r0, #1
108 ITE(eq)
109 moveq ip, #(APSR_C | APSR_Z)
110 movne ip, #(APSR_C)
111
1121:
113 msr APSR_nzcvq, ip
114 pop {r0-r3}
115 POP_PC()
116#endif
117END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
118
119// int __aeabi_cdrcmple(double a, double b) {
120// return __aeabi_cdcmple(b, a);
121// }
122
123 .syntax unified
124 .p2align 2
125DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
126 // Swap r0 and r2
127 mov ip, r0
128 mov r0, r2
129 mov r2, ip
130
131 // Swap r1 and r3
132 mov ip, r1
133 mov r1, r3
134 mov r3, ip
135
136 b __aeabi_cdcmple
137END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
138
139NO_EXEC_STACK_DIRECTIVE
140
141

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