1156cd587Sjoerg //===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===//
2156cd587Sjoerg //
3156cd587Sjoerg // The LLVM Compiler Infrastructure
4156cd587Sjoerg //
5156cd587Sjoerg // This file is dual licensed under the MIT and the University of Illinois Open
6156cd587Sjoerg // Source Licenses. See LICENSE.TXT for details.
7156cd587Sjoerg //
8156cd587Sjoerg //===----------------------------------------------------------------------===//
9156cd587Sjoerg //
10156cd587Sjoerg // // This file implements the following soft-float comparison routines:
11156cd587Sjoerg //
12156cd587Sjoerg // __eqdf2 __gedf2 __unorddf2
13156cd587Sjoerg // __ledf2 __gtdf2
14156cd587Sjoerg // __ltdf2
15156cd587Sjoerg // __nedf2
16156cd587Sjoerg //
17156cd587Sjoerg // The semantics of the routines grouped in each column are identical, so there
18156cd587Sjoerg // is a single implementation for each, and wrappers to provide the other names.
19156cd587Sjoerg //
20156cd587Sjoerg // The main routines behave as follows:
21156cd587Sjoerg //
22156cd587Sjoerg // __ledf2(a,b) returns -1 if a < b
23156cd587Sjoerg // 0 if a == b
24156cd587Sjoerg // 1 if a > b
25156cd587Sjoerg // 1 if either a or b is NaN
26156cd587Sjoerg //
27156cd587Sjoerg // __gedf2(a,b) returns -1 if a < b
28156cd587Sjoerg // 0 if a == b
29156cd587Sjoerg // 1 if a > b
30156cd587Sjoerg // -1 if either a or b is NaN
31156cd587Sjoerg //
32156cd587Sjoerg // __unorddf2(a,b) returns 0 if both a and b are numbers
33156cd587Sjoerg // 1 if either a or b is NaN
34156cd587Sjoerg //
35156cd587Sjoerg // Note that __ledf2( ) and __gedf2( ) are identical except in their handling of
36156cd587Sjoerg // NaN values.
37156cd587Sjoerg //
38156cd587Sjoerg //===----------------------------------------------------------------------===//
39156cd587Sjoerg
40156cd587Sjoerg #define DOUBLE_PRECISION
41156cd587Sjoerg #include "fp_lib.h"
42156cd587Sjoerg
43156cd587Sjoerg enum LE_RESULT {
44156cd587Sjoerg LE_LESS = -1,
45156cd587Sjoerg LE_EQUAL = 0,
46156cd587Sjoerg LE_GREATER = 1,
47156cd587Sjoerg LE_UNORDERED = 1
48156cd587Sjoerg };
49156cd587Sjoerg
50f7f78b33Sjoerg COMPILER_RT_ABI enum LE_RESULT
__ledf2(fp_t a,fp_t b)51f7f78b33Sjoerg __ledf2(fp_t a, fp_t b) {
52156cd587Sjoerg
53156cd587Sjoerg const srep_t aInt = toRep(a);
54156cd587Sjoerg const srep_t bInt = toRep(b);
55156cd587Sjoerg const rep_t aAbs = aInt & absMask;
56156cd587Sjoerg const rep_t bAbs = bInt & absMask;
57156cd587Sjoerg
58156cd587Sjoerg // If either a or b is NaN, they are unordered.
59156cd587Sjoerg if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
60156cd587Sjoerg
61156cd587Sjoerg // If a and b are both zeros, they are equal.
62156cd587Sjoerg if ((aAbs | bAbs) == 0) return LE_EQUAL;
63156cd587Sjoerg
64156cd587Sjoerg // If at least one of a and b is positive, we get the same result comparing
65156cd587Sjoerg // a and b as signed integers as we would with a floating-point compare.
66156cd587Sjoerg if ((aInt & bInt) >= 0) {
67156cd587Sjoerg if (aInt < bInt) return LE_LESS;
68156cd587Sjoerg else if (aInt == bInt) return LE_EQUAL;
69156cd587Sjoerg else return LE_GREATER;
70156cd587Sjoerg }
71156cd587Sjoerg
72156cd587Sjoerg // Otherwise, both are negative, so we need to flip the sense of the
73156cd587Sjoerg // comparison to get the correct result. (This assumes a twos- or ones-
74156cd587Sjoerg // complement integer representation; if integers are represented in a
75156cd587Sjoerg // sign-magnitude representation, then this flip is incorrect).
76156cd587Sjoerg else {
77156cd587Sjoerg if (aInt > bInt) return LE_LESS;
78156cd587Sjoerg else if (aInt == bInt) return LE_EQUAL;
79156cd587Sjoerg else return LE_GREATER;
80156cd587Sjoerg }
81156cd587Sjoerg }
82156cd587Sjoerg
83ef84fd3bSjoerg #if defined(__ELF__)
84ef84fd3bSjoerg // Alias for libgcc compatibility
85ef84fd3bSjoerg FNALIAS(__cmpdf2, __ledf2);
86ef84fd3bSjoerg #endif
87ef84fd3bSjoerg
88156cd587Sjoerg enum GE_RESULT {
89156cd587Sjoerg GE_LESS = -1,
90156cd587Sjoerg GE_EQUAL = 0,
91156cd587Sjoerg GE_GREATER = 1,
92156cd587Sjoerg GE_UNORDERED = -1 // Note: different from LE_UNORDERED
93156cd587Sjoerg };
94156cd587Sjoerg
95f7f78b33Sjoerg COMPILER_RT_ABI enum GE_RESULT
__gedf2(fp_t a,fp_t b)96f7f78b33Sjoerg __gedf2(fp_t a, fp_t b) {
97156cd587Sjoerg
98156cd587Sjoerg const srep_t aInt = toRep(a);
99156cd587Sjoerg const srep_t bInt = toRep(b);
100156cd587Sjoerg const rep_t aAbs = aInt & absMask;
101156cd587Sjoerg const rep_t bAbs = bInt & absMask;
102156cd587Sjoerg
103156cd587Sjoerg if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
104156cd587Sjoerg if ((aAbs | bAbs) == 0) return GE_EQUAL;
105156cd587Sjoerg if ((aInt & bInt) >= 0) {
106156cd587Sjoerg if (aInt < bInt) return GE_LESS;
107156cd587Sjoerg else if (aInt == bInt) return GE_EQUAL;
108156cd587Sjoerg else return GE_GREATER;
109156cd587Sjoerg } else {
110156cd587Sjoerg if (aInt > bInt) return GE_LESS;
111156cd587Sjoerg else if (aInt == bInt) return GE_EQUAL;
112156cd587Sjoerg else return GE_GREATER;
113156cd587Sjoerg }
114156cd587Sjoerg }
115156cd587Sjoerg
116f7f78b33Sjoerg COMPILER_RT_ABI int
__unorddf2(fp_t a,fp_t b)117f7f78b33Sjoerg __unorddf2(fp_t a, fp_t b) {
118156cd587Sjoerg const rep_t aAbs = toRep(a) & absMask;
119156cd587Sjoerg const rep_t bAbs = toRep(b) & absMask;
120156cd587Sjoerg return aAbs > infRep || bAbs > infRep;
121156cd587Sjoerg }
122156cd587Sjoerg
12330308f42Sjoerg // The following are alternative names for the preceding routines.
124156cd587Sjoerg
125f7f78b33Sjoerg COMPILER_RT_ABI enum LE_RESULT
__eqdf2(fp_t a,fp_t b)126f7f78b33Sjoerg __eqdf2(fp_t a, fp_t b) {
127156cd587Sjoerg return __ledf2(a, b);
128156cd587Sjoerg }
129156cd587Sjoerg
130f7f78b33Sjoerg COMPILER_RT_ABI enum LE_RESULT
__ltdf2(fp_t a,fp_t b)131f7f78b33Sjoerg __ltdf2(fp_t a, fp_t b) {
132156cd587Sjoerg return __ledf2(a, b);
133156cd587Sjoerg }
134156cd587Sjoerg
135f7f78b33Sjoerg COMPILER_RT_ABI enum LE_RESULT
__nedf2(fp_t a,fp_t b)136f7f78b33Sjoerg __nedf2(fp_t a, fp_t b) {
137156cd587Sjoerg return __ledf2(a, b);
138156cd587Sjoerg }
139156cd587Sjoerg
140f7f78b33Sjoerg COMPILER_RT_ABI enum GE_RESULT
__gtdf2(fp_t a,fp_t b)141f7f78b33Sjoerg __gtdf2(fp_t a, fp_t b) {
142156cd587Sjoerg return __gedf2(a, b);
143156cd587Sjoerg }
144156cd587Sjoerg
1453044ee7eSrin #if defined(__ARM_EABI__)
146*d3143459Srin #if defined(COMPILER_RT_ARMHF_TARGET)
__aeabi_dcmpun(fp_t a,fp_t b)1473044ee7eSrin AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) {
1483044ee7eSrin return __unorddf2(a, b);
1493044ee7eSrin }
150*d3143459Srin #else
151*d3143459Srin AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) COMPILER_RT_ALIAS(__unorddf2);
1523044ee7eSrin #endif
153*d3143459Srin #endif
154