]> git.proxmox.com Git - rustc.git/blob - vendor/compiler_builtins/compiler-rt/lib/builtins/arm/aeabi_cdcmp.S
New upstream version 1.36.0+dfsg1
[rustc.git] / vendor / compiler_builtins / 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 APSR_nzcvq, #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 msr APSR_nzcvq, ip
119 pop {r0-r3}
120 POP_PC()
121 #endif
122 END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
123
124 // int __aeabi_cdrcmple(double a, double b) {
125 // return __aeabi_cdcmple(b, a);
126 // }
127
128 .syntax unified
129 .p2align 2
130 DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
131 // Swap r0 and r2
132 mov ip, r0
133 mov r0, r2
134 mov r2, ip
135
136 // Swap r1 and r3
137 mov ip, r1
138 mov r1, r3
139 mov r3, ip
140
141 b __aeabi_cdcmple
142 END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
143
144 NO_EXEC_STACK_DIRECTIVE
145