xref: /aosp_15_r20/external/compiler-rt/lib/builtins/comparesf2.c (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot //===-- lib/comparesf2.c - Single-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-fp_t comparison routines:
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot //   __eqsf2   __gesf2   __unordsf2
13*7c3d14c8STreehugger Robot //   __lesf2   __gtsf2
14*7c3d14c8STreehugger Robot //   __ltsf2
15*7c3d14c8STreehugger Robot //   __nesf2
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 //   __lesf2(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 //   __gesf2(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 //   __unordsf2(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 __lesf2( ) and __gesf2( ) 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 SINGLE_PRECISION
41*7c3d14c8STreehugger Robot #include "fp_lib.h"
42*7c3d14c8STreehugger Robot 
43*7c3d14c8STreehugger Robot enum LE_RESULT {
44*7c3d14c8STreehugger Robot     LE_LESS      = -1,
45*7c3d14c8STreehugger Robot     LE_EQUAL     =  0,
46*7c3d14c8STreehugger Robot     LE_GREATER   =  1,
47*7c3d14c8STreehugger Robot     LE_UNORDERED =  1
48*7c3d14c8STreehugger Robot };
49*7c3d14c8STreehugger Robot 
50*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT
__lesf2(fp_t a,fp_t b)51*7c3d14c8STreehugger Robot __lesf2(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 fp_ting-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 
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     else {
77*7c3d14c8STreehugger Robot         if (aInt > bInt) return LE_LESS;
78*7c3d14c8STreehugger Robot         else if (aInt == bInt) return LE_EQUAL;
79*7c3d14c8STreehugger Robot         else return LE_GREATER;
80*7c3d14c8STreehugger Robot     }
81*7c3d14c8STreehugger Robot }
82*7c3d14c8STreehugger Robot 
83*7c3d14c8STreehugger Robot #if defined(__ELF__)
84*7c3d14c8STreehugger Robot // Alias for libgcc compatibility
85*7c3d14c8STreehugger Robot FNALIAS(__cmpsf2, __lesf2);
86*7c3d14c8STreehugger Robot #endif
87*7c3d14c8STreehugger Robot 
88*7c3d14c8STreehugger Robot enum GE_RESULT {
89*7c3d14c8STreehugger Robot     GE_LESS      = -1,
90*7c3d14c8STreehugger Robot     GE_EQUAL     =  0,
91*7c3d14c8STreehugger Robot     GE_GREATER   =  1,
92*7c3d14c8STreehugger Robot     GE_UNORDERED = -1   // Note: different from LE_UNORDERED
93*7c3d14c8STreehugger Robot };
94*7c3d14c8STreehugger Robot 
95*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum GE_RESULT
__gesf2(fp_t a,fp_t b)96*7c3d14c8STreehugger Robot __gesf2(fp_t a, fp_t b) {
97*7c3d14c8STreehugger Robot 
98*7c3d14c8STreehugger Robot     const srep_t aInt = toRep(a);
99*7c3d14c8STreehugger Robot     const srep_t bInt = toRep(b);
100*7c3d14c8STreehugger Robot     const rep_t aAbs = aInt & absMask;
101*7c3d14c8STreehugger Robot     const rep_t bAbs = bInt & absMask;
102*7c3d14c8STreehugger Robot 
103*7c3d14c8STreehugger Robot     if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
104*7c3d14c8STreehugger Robot     if ((aAbs | bAbs) == 0) return GE_EQUAL;
105*7c3d14c8STreehugger Robot     if ((aInt & bInt) >= 0) {
106*7c3d14c8STreehugger Robot         if (aInt < bInt) return GE_LESS;
107*7c3d14c8STreehugger Robot         else if (aInt == bInt) return GE_EQUAL;
108*7c3d14c8STreehugger Robot         else return GE_GREATER;
109*7c3d14c8STreehugger Robot     } else {
110*7c3d14c8STreehugger Robot         if (aInt > bInt) return GE_LESS;
111*7c3d14c8STreehugger Robot         else if (aInt == bInt) return GE_EQUAL;
112*7c3d14c8STreehugger Robot         else return GE_GREATER;
113*7c3d14c8STreehugger Robot     }
114*7c3d14c8STreehugger Robot }
115*7c3d14c8STreehugger Robot 
ARM_EABI_FNALIAS(fcmpun,unordsf2)116*7c3d14c8STreehugger Robot ARM_EABI_FNALIAS(fcmpun, unordsf2)
117*7c3d14c8STreehugger Robot 
118*7c3d14c8STreehugger Robot COMPILER_RT_ABI int
119*7c3d14c8STreehugger Robot __unordsf2(fp_t a, fp_t b) {
120*7c3d14c8STreehugger Robot     const rep_t aAbs = toRep(a) & absMask;
121*7c3d14c8STreehugger Robot     const rep_t bAbs = toRep(b) & absMask;
122*7c3d14c8STreehugger Robot     return aAbs > infRep || bAbs > infRep;
123*7c3d14c8STreehugger Robot }
124*7c3d14c8STreehugger Robot 
125*7c3d14c8STreehugger Robot // The following are alternative names for the preceding routines.
126*7c3d14c8STreehugger Robot 
127*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT
__eqsf2(fp_t a,fp_t b)128*7c3d14c8STreehugger Robot __eqsf2(fp_t a, fp_t b) {
129*7c3d14c8STreehugger Robot     return __lesf2(a, b);
130*7c3d14c8STreehugger Robot }
131*7c3d14c8STreehugger Robot 
132*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT
__ltsf2(fp_t a,fp_t b)133*7c3d14c8STreehugger Robot __ltsf2(fp_t a, fp_t b) {
134*7c3d14c8STreehugger Robot     return __lesf2(a, b);
135*7c3d14c8STreehugger Robot }
136*7c3d14c8STreehugger Robot 
137*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum LE_RESULT
__nesf2(fp_t a,fp_t b)138*7c3d14c8STreehugger Robot __nesf2(fp_t a, fp_t b) {
139*7c3d14c8STreehugger Robot     return __lesf2(a, b);
140*7c3d14c8STreehugger Robot }
141*7c3d14c8STreehugger Robot 
142*7c3d14c8STreehugger Robot COMPILER_RT_ABI enum GE_RESULT
__gtsf2(fp_t a,fp_t b)143*7c3d14c8STreehugger Robot __gtsf2(fp_t a, fp_t b) {
144*7c3d14c8STreehugger Robot     return __gesf2(a, b);
145*7c3d14c8STreehugger Robot }
146