1 //===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // // This file implements the following soft-float comparison routines:
11 // __eqtf2 __getf2 __unordtf2
16 // The semantics of the routines grouped in each column are identical, so there
17 // is a single implementation for each, and wrappers to provide the other names.
19 // The main routines behave as follows:
21 // __letf2(a,b) returns -1 if a < b
24 // 1 if either a or b is NaN
26 // __getf2(a,b) returns -1 if a < b
29 // -1 if either a or b is NaN
31 // __unordtf2(a,b) returns 0 if both a and b are numbers
32 // 1 if either a or b is NaN
34 // Note that __letf2( ) and __getf2( ) are identical except in their handling of
37 //===----------------------------------------------------------------------===//
39 #define QUAD_PRECISION
42 #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
43 enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 };
45 COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {
47 const srep_t aInt = toRep(a);
48 const srep_t bInt = toRep(b);
49 const rep_t aAbs = aInt & absMask;
50 const rep_t bAbs = bInt & absMask;
52 // If either a or b is NaN, they are unordered.
53 if (aAbs > infRep || bAbs > infRep)
56 // If a and b are both zeros, they are equal.
57 if ((aAbs | bAbs) == 0)
60 // If at least one of a and b is positive, we get the same result comparing
61 // a and b as signed integers as we would with a floating-point compare.
62 if ((aInt & bInt) >= 0) {
65 else if (aInt == bInt)
70 // Otherwise, both are negative, so we need to flip the sense of the
71 // comparison to get the correct result. (This assumes a twos- or ones-
72 // complement integer representation; if integers are represented in a
73 // sign-magnitude representation, then this flip is incorrect).
76 else if (aInt == bInt)
84 // Alias for libgcc compatibility
85 COMPILER_RT_ALIAS(__letf2, __cmptf2)
87 COMPILER_RT_ALIAS(__letf2, __eqtf2)
88 COMPILER_RT_ALIAS(__letf2, __lttf2)
89 COMPILER_RT_ALIAS(__letf2, __netf2)
95 GE_UNORDERED = -1 // Note: different from LE_UNORDERED
98 COMPILER_RT_ABI enum GE_RESULT __getf2(fp_t a, fp_t b) {
100 const srep_t aInt = toRep(a);
101 const srep_t bInt = toRep(b);
102 const rep_t aAbs = aInt & absMask;
103 const rep_t bAbs = bInt & absMask;
105 if (aAbs > infRep || bAbs > infRep)
107 if ((aAbs | bAbs) == 0)
109 if ((aInt & bInt) >= 0) {
112 else if (aInt == bInt)
119 else if (aInt == bInt)
126 COMPILER_RT_ALIAS(__getf2, __gttf2)
128 COMPILER_RT_ABI int __unordtf2(fp_t a, fp_t b) {
129 const rep_t aAbs = toRep(a) & absMask;
130 const rep_t bAbs = toRep(b) & absMask;
131 return aAbs > infRep || bAbs > infRep;