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