xref: /aosp_15_r20/external/compiler-rt/lib/builtins/comparetf2.c (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot //===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot //                     The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is dual licensed under the MIT and the University of Illinois Open
6*7c3d14c8STreehugger Robot // Source Licenses. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // // This file implements the following soft-float comparison routines:
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot //   __eqtf2   __getf2   __unordtf2
13*7c3d14c8STreehugger Robot //   __letf2   __gttf2
14*7c3d14c8STreehugger Robot //   __lttf2
15*7c3d14c8STreehugger Robot //   __netf2
16*7c3d14c8STreehugger Robot //
17*7c3d14c8STreehugger Robot // The semantics of the routines grouped in each column are identical, so there
18*7c3d14c8STreehugger Robot // is a single implementation for each, and wrappers to provide the other names.
19*7c3d14c8STreehugger Robot //
20*7c3d14c8STreehugger Robot // The main routines behave as follows:
21*7c3d14c8STreehugger Robot //
22*7c3d14c8STreehugger Robot //   __letf2(a,b) returns -1 if a < b
23*7c3d14c8STreehugger Robot //                         0 if a == b
24*7c3d14c8STreehugger Robot //                         1 if a > b
25*7c3d14c8STreehugger Robot //                         1 if either a or b is NaN
26*7c3d14c8STreehugger Robot //
27*7c3d14c8STreehugger Robot //   __getf2(a,b) returns -1 if a < b
28*7c3d14c8STreehugger Robot //                         0 if a == b
29*7c3d14c8STreehugger Robot //                         1 if a > b
30*7c3d14c8STreehugger Robot //                        -1 if either a or b is NaN
31*7c3d14c8STreehugger Robot //
32*7c3d14c8STreehugger Robot //   __unordtf2(a,b) returns 0 if both a and b are numbers
33*7c3d14c8STreehugger Robot //                           1 if either a or b is NaN
34*7c3d14c8STreehugger Robot //
35*7c3d14c8STreehugger Robot // Note that __letf2( ) and __getf2( ) are identical except in their handling of
36*7c3d14c8STreehugger Robot // NaN values.
37*7c3d14c8STreehugger Robot //
38*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
39*7c3d14c8STreehugger Robot 
40*7c3d14c8STreehugger Robot #define QUAD_PRECISION
41*7c3d14c8STreehugger Robot #include "fp_lib.h"
42*7c3d14c8STreehugger Robot 
43*7c3d14c8STreehugger Robot #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
44*7c3d14c8STreehugger Robot enum LE_RESULT {
45*7c3d14c8STreehugger Robot     LE_LESS      = -1,
46*7c3d14c8STreehugger Robot     LE_EQUAL     =  0,
47*7c3d14c8STreehugger Robot     LE_GREATER   =  1,
48*7c3d14c8STreehugger Robot     LE_UNORDERED =  1
49*7c3d14c8STreehugger Robot };
50*7c3d14c8STreehugger Robot 
__letf2(fp_t a,fp_t b)51*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {
52*7c3d14c8STreehugger Robot 
53*7c3d14c8STreehugger Robot     const srep_t aInt = toRep(a);
54*7c3d14c8STreehugger Robot     const srep_t bInt = toRep(b);
55*7c3d14c8STreehugger Robot     const rep_t aAbs = aInt & absMask;
56*7c3d14c8STreehugger Robot     const rep_t bAbs = bInt & absMask;
57*7c3d14c8STreehugger Robot 
58*7c3d14c8STreehugger Robot     // If either a or b is NaN, they are unordered.
59*7c3d14c8STreehugger Robot     if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
60*7c3d14c8STreehugger Robot 
61*7c3d14c8STreehugger Robot     // If a and b are both zeros, they are equal.
62*7c3d14c8STreehugger Robot     if ((aAbs | bAbs) == 0) return LE_EQUAL;
63*7c3d14c8STreehugger Robot 
64*7c3d14c8STreehugger Robot     // If at least one of a and b is positive, we get the same result comparing
65*7c3d14c8STreehugger Robot     // a and b as signed integers as we would with a floating-point compare.
66*7c3d14c8STreehugger Robot     if ((aInt & bInt) >= 0) {
67*7c3d14c8STreehugger Robot         if (aInt < bInt) return LE_LESS;
68*7c3d14c8STreehugger Robot         else if (aInt == bInt) return LE_EQUAL;
69*7c3d14c8STreehugger Robot         else return LE_GREATER;
70*7c3d14c8STreehugger Robot     }
71*7c3d14c8STreehugger Robot     else {
72*7c3d14c8STreehugger Robot         // Otherwise, both are negative, so we need to flip the sense of the
73*7c3d14c8STreehugger Robot         // comparison to get the correct result.  (This assumes a twos- or ones-
74*7c3d14c8STreehugger Robot         // complement integer representation; if integers are represented in a
75*7c3d14c8STreehugger Robot         // sign-magnitude representation, then this flip is incorrect).
76*7c3d14c8STreehugger Robot         if (aInt > bInt) return LE_LESS;
77*7c3d14c8STreehugger Robot         else if (aInt == bInt) return LE_EQUAL;
78*7c3d14c8STreehugger Robot         else return LE_GREATER;
79*7c3d14c8STreehugger Robot     }
80*7c3d14c8STreehugger Robot }
81*7c3d14c8STreehugger Robot 
82*7c3d14c8STreehugger Robot #if defined(__ELF__)
83*7c3d14c8STreehugger Robot // Alias for libgcc compatibility
84*7c3d14c8STreehugger Robot FNALIAS(__cmptf2, __letf2);
85*7c3d14c8STreehugger Robot #endif
86*7c3d14c8STreehugger Robot 
87*7c3d14c8STreehugger Robot enum GE_RESULT {
88*7c3d14c8STreehugger Robot     GE_LESS      = -1,
89*7c3d14c8STreehugger Robot     GE_EQUAL     =  0,
90*7c3d14c8STreehugger Robot     GE_GREATER   =  1,
91*7c3d14c8STreehugger Robot     GE_UNORDERED = -1   // Note: different from LE_UNORDERED
92*7c3d14c8STreehugger Robot };
93*7c3d14c8STreehugger Robot 
__getf2(fp_t a,fp_t b)94*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum GE_RESULT __getf2(fp_t a, fp_t b) {
95*7c3d14c8STreehugger Robot 
96*7c3d14c8STreehugger Robot     const srep_t aInt = toRep(a);
97*7c3d14c8STreehugger Robot     const srep_t bInt = toRep(b);
98*7c3d14c8STreehugger Robot     const rep_t aAbs = aInt & absMask;
99*7c3d14c8STreehugger Robot     const rep_t bAbs = bInt & absMask;
100*7c3d14c8STreehugger Robot 
101*7c3d14c8STreehugger Robot     if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
102*7c3d14c8STreehugger Robot     if ((aAbs | bAbs) == 0) return GE_EQUAL;
103*7c3d14c8STreehugger Robot     if ((aInt & bInt) >= 0) {
104*7c3d14c8STreehugger Robot         if (aInt < bInt) return GE_LESS;
105*7c3d14c8STreehugger Robot         else if (aInt == bInt) return GE_EQUAL;
106*7c3d14c8STreehugger Robot         else return GE_GREATER;
107*7c3d14c8STreehugger Robot     } else {
108*7c3d14c8STreehugger Robot         if (aInt > bInt) return GE_LESS;
109*7c3d14c8STreehugger Robot         else if (aInt == bInt) return GE_EQUAL;
110*7c3d14c8STreehugger Robot         else return GE_GREATER;
111*7c3d14c8STreehugger Robot     }
112*7c3d14c8STreehugger Robot }
113*7c3d14c8STreehugger Robot 
__unordtf2(fp_t a,fp_t b)114*7c3d14c8STreehugger Robot COMPILER_RT_ABI int __unordtf2(fp_t a, fp_t b) {
115*7c3d14c8STreehugger Robot     const rep_t aAbs = toRep(a) & absMask;
116*7c3d14c8STreehugger Robot     const rep_t bAbs = toRep(b) & absMask;
117*7c3d14c8STreehugger Robot     return aAbs > infRep || bAbs > infRep;
118*7c3d14c8STreehugger Robot }
119*7c3d14c8STreehugger Robot 
120*7c3d14c8STreehugger Robot // The following are alternative names for the preceding routines.
121*7c3d14c8STreehugger Robot 
__eqtf2(fp_t a,fp_t b)122*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT __eqtf2(fp_t a, fp_t b) {
123*7c3d14c8STreehugger Robot     return __letf2(a, b);
124*7c3d14c8STreehugger Robot }
125*7c3d14c8STreehugger Robot 
__lttf2(fp_t a,fp_t b)126*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT __lttf2(fp_t a, fp_t b) {
127*7c3d14c8STreehugger Robot     return __letf2(a, b);
128*7c3d14c8STreehugger Robot }
129*7c3d14c8STreehugger Robot 
__netf2(fp_t a,fp_t b)130*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT __netf2(fp_t a, fp_t b) {
131*7c3d14c8STreehugger Robot     return __letf2(a, b);
132*7c3d14c8STreehugger Robot }
133*7c3d14c8STreehugger Robot 
__gttf2(fp_t a,fp_t b)134*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum GE_RESULT __gttf2(fp_t a, fp_t b) {
135*7c3d14c8STreehugger Robot     return __getf2(a, b);
136*7c3d14c8STreehugger Robot }
137*7c3d14c8STreehugger Robot 
138*7c3d14c8STreehugger Robot #endif
139