]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/arm/aeabi_cfcmp.S
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / builtins / arm / aeabi_cfcmp.S
1 //===-- aeabi_cfcmp.S - EABI cfcmp* 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_cfcmpeq(float a, float b) {
20 //   if (isnan(a) || isnan(b)) {
21 //     Z = 0; C = 1;
22 //   } else {
23 //     __aeabi_cfcmple(a, b);
24 //   }
25 // }
26
27         .syntax unified
28         .p2align 2
29 DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
30         push {r0-r3, lr}
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         pop {r0-r3, lr}
47
48         // NaN has been ruled out, so __aeabi_cfcmple can't trap
49         // Use "it ne" + unconditional branch to guarantee a supported relocation if
50         // __aeabi_cfcmple is in a different section for some builds.
51         IT(ne)
52         bne __aeabi_cfcmple
53
54 #if defined(USE_THUMB_2)
55         mov ip, #APSR_C
56         msr APSR_nzcvq, ip
57 #else
58         msr APSR_nzcvq, #APSR_C
59 #endif
60         JMP(lr)
61 #endif
62 END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
63
64
65 // void __aeabi_cfcmple(float a, float b) {
66 //   if (__aeabi_fcmplt(a, b)) {
67 //     Z = 0; C = 0;
68 //   } else if (__aeabi_fcmpeq(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_cfcmple)
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_fcmplt
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_fcmpeq
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_fcmpeq
112         cmp r0, #1
113         ITE(eq)
114         moveq ip, #(APSR_C | APSR_Z)
115         movne ip, #(APSR_C)
116
117 1:
118         msr APSR_nzcvq, ip
119         pop {r0-r3}
120         POP_PC()
121 #endif
122 END_COMPILERRT_FUNCTION(__aeabi_cfcmple)
123
124 // int __aeabi_cfrcmple(float a, float b) {
125 //   return __aeabi_cfcmple(b, a);
126 // }
127
128         .syntax unified
129         .p2align 2
130 DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
131         // Swap r0 and r1
132         mov ip, r0
133         mov r0, r1
134         mov r1, ip
135
136         b __aeabi_cfcmple
137 END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
138
139 NO_EXEC_STACK_DIRECTIVE
140