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