]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/arm/aeabi_cfcmp.S
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, and update
[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 __ARM_ARCH_ISA_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         bne __aeabi_cfcmple
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_cfcmpeq)
60
61
62 // void __aeabi_cfcmple(float a, float b) {
63 //   if (__aeabi_fcmplt(a, b)) {
64 //     Z = 0; C = 0;
65 //   } else if (__aeabi_fcmpeq(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_cfcmple)
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_fcmplt
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_fcmpeq
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_fcmpeq
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_cfcmple)
124
125 // int __aeabi_cfrcmple(float a, float b) {
126 //   return __aeabi_cfcmple(b, a);
127 // }
128
129         .syntax unified
130         .p2align 2
131 DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
132         // Swap r0 and r1
133         mov ip, r0
134         mov r0, r1
135         mov r1, ip
136
137         b __aeabi_cfcmple
138 END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
139
140 NO_EXEC_STACK_DIRECTIVE
141