]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/arm/aeabi_cdcmp.S
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, and update
[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 __ARM_ARCH_ISA_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         bne __aeabi_cdcmple
50
51 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
52         mov ip, #APSR_C
53         msr APSR_nzcvq, ip
54 #else
55         msr CPSR_f, #APSR_C
56 #endif
57         JMP(lr)
58 #endif
59 END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
60
61
62 // void __aeabi_cdcmple(double a, double b) {
63 //   if (__aeabi_dcmplt(a, b)) {
64 //     Z = 0; C = 0;
65 //   } else if (__aeabi_dcmpeq(a, b)) {
66 //     Z = 1; C = 1;
67 //   } else {
68 //     Z = 0; C = 1;
69 //   }
70 // }
71
72         .syntax unified
73         .p2align 2
74 DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
75         // Per the RTABI, this function must preserve r0-r11.
76         // Save lr in the same instruction for compactness
77         push {r0-r3, lr}
78
79         bl __aeabi_dcmplt
80         cmp r0, #1
81 #if __ARM_ARCH_ISA_THUMB == 1
82         bne 1f
83         // Z = 0, C = 0
84         movs r0, #1
85         lsls r0, r0, #1
86         pop {r0-r3, pc}
87 1:
88         mov r0, sp
89         ldm r0, {r0-r3}
90         bl __aeabi_dcmpeq
91         cmp r0, #1
92         bne 2f
93         // Z = 1, C = 1
94         movs r0, #2
95         lsls r0, r0, #31
96         pop {r0-r3, pc}
97 2:
98         // Z = 0, C = 1
99         movs r0, #0xF
100         lsls r0, r0, #31
101         pop {r0-r3, pc}
102 #else
103         ITT(eq)
104         moveq ip, #0
105         beq 1f
106
107         ldm sp, {r0-r3}
108         bl __aeabi_dcmpeq
109         cmp r0, #1
110         ITE(eq)
111         moveq ip, #(APSR_C | APSR_Z)
112         movne ip, #(APSR_C)
113
114 1:
115 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
116         msr APSR_nzcvq, ip
117 #else
118         msr CPSR_f, ip
119 #endif
120         pop {r0-r3}
121         POP_PC()
122 #endif
123 END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
124
125 // int __aeabi_cdrcmple(double a, double b) {
126 //   return __aeabi_cdcmple(b, a);
127 // }
128
129         .syntax unified
130         .p2align 2
131 DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
132         // Swap r0 and r2
133         mov ip, r0
134         mov r0, r2
135         mov r2, ip
136
137         // Swap r1 and r3
138         mov ip, r1
139         mov r1, r3
140         mov r3, ip
141
142         b __aeabi_cdcmple
143 END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
144
145 NO_EXEC_STACK_DIRECTIVE
146