1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
//===-- aeabi_cdcmp.S - EABI cdcmp* implementation ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
#error big endian support not implemented
#endif
#define APSR_Z (1 << 30)
#define APSR_C (1 << 29)
// void __aeabi_cdcmpeq(double a, double b) {
// if (isnan(a) || isnan(b)) {
// Z = 0; C = 1;
// } else {
// __aeabi_cdcmple(a, b);
// }
// }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
push {r0-r3, lr}
bl __aeabi_cdcmpeq_check_nan
cmp r0, #1
#if __ARM_ARCH_ISA_THUMB == 1
beq 1f
// NaN has been ruled out, so __aeabi_cdcmple can't trap
mov r0, sp
ldm r0, {r0-r3}
bl __aeabi_cdcmple
pop {r0-r3, pc}
1:
// Z = 0, C = 1
movs r0, #0xF
lsls r0, r0, #31
pop {r0-r3, pc}
#else
pop {r0-r3, lr}
// NaN has been ruled out, so __aeabi_cdcmple can't trap
bne __aeabi_cdcmple
msr CPSR_f, #APSR_C
JMP(lr)
#endif
END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
// void __aeabi_cdcmple(double a, double b) {
// if (__aeabi_dcmplt(a, b)) {
// Z = 0; C = 0;
// } else if (__aeabi_dcmpeq(a, b)) {
// Z = 1; C = 1;
// } else {
// Z = 0; C = 1;
// }
// }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
// Per the RTABI, this function must preserve r0-r11.
// Save lr in the same instruction for compactness
push {r0-r3, lr}
bl __aeabi_dcmplt
cmp r0, #1
#if __ARM_ARCH_ISA_THUMB == 1
bne 1f
// Z = 0, C = 0
movs r0, #1
lsls r0, r0, #1
pop {r0-r3, pc}
1:
mov r0, sp
ldm r0, {r0-r3}
bl __aeabi_dcmpeq
cmp r0, #1
bne 2f
// Z = 1, C = 1
movs r0, #2
lsls r0, r0, #31
pop {r0-r3, pc}
2:
// Z = 0, C = 1
movs r0, #0xF
lsls r0, r0, #31
pop {r0-r3, pc}
#else
moveq ip, #0
beq 1f
ldm sp, {r0-r3}
bl __aeabi_dcmpeq
cmp r0, #1
moveq ip, #(APSR_C | APSR_Z)
movne ip, #(APSR_C)
1:
msr CPSR_f, ip
pop {r0-r3}
POP_PC()
#endif
END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
// int __aeabi_cdrcmple(double a, double b) {
// return __aeabi_cdcmple(b, a);
// }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
// Swap r0 and r2
mov ip, r0
mov r0, r2
mov r2, ip
// Swap r1 and r3
mov ip, r1
mov r1, r3
mov r3, ip
b __aeabi_cdcmple
END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
NO_EXEC_STACK_DIRECTIVE
|