comparedf2.c revision 276851
1214571Sdim//===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===// 2214571Sdim// 3214571Sdim// The LLVM Compiler Infrastructure 4214571Sdim// 5214571Sdim// This file is dual licensed under the MIT and the University of Illinois Open 6214571Sdim// Source Licenses. See LICENSE.TXT for details. 7214571Sdim// 8214571Sdim//===----------------------------------------------------------------------===// 9214571Sdim// 10214571Sdim// // This file implements the following soft-float comparison routines: 11214571Sdim// 12214571Sdim// __eqdf2 __gedf2 __unorddf2 13214571Sdim// __ledf2 __gtdf2 14214571Sdim// __ltdf2 15214571Sdim// __nedf2 16214571Sdim// 17214571Sdim// The semantics of the routines grouped in each column are identical, so there 18214571Sdim// is a single implementation for each, and wrappers to provide the other names. 19214571Sdim// 20214571Sdim// The main routines behave as follows: 21214571Sdim// 22214571Sdim// __ledf2(a,b) returns -1 if a < b 23214571Sdim// 0 if a == b 24214571Sdim// 1 if a > b 25214571Sdim// 1 if either a or b is NaN 26214571Sdim// 27214571Sdim// __gedf2(a,b) returns -1 if a < b 28214571Sdim// 0 if a == b 29214571Sdim// 1 if a > b 30214571Sdim// -1 if either a or b is NaN 31214571Sdim// 32214571Sdim// __unorddf2(a,b) returns 0 if both a and b are numbers 33214571Sdim// 1 if either a or b is NaN 34214571Sdim// 35214571Sdim// Note that __ledf2( ) and __gedf2( ) are identical except in their handling of 36214571Sdim// NaN values. 37214571Sdim// 38214571Sdim//===----------------------------------------------------------------------===// 39214571Sdim 40214571Sdim#define DOUBLE_PRECISION 41214571Sdim#include "fp_lib.h" 42214571Sdim 43214571Sdimenum LE_RESULT { 44214571Sdim LE_LESS = -1, 45214571Sdim LE_EQUAL = 0, 46214571Sdim LE_GREATER = 1, 47214571Sdim LE_UNORDERED = 1 48214571Sdim}; 49214571Sdim 50214571SdimCOMPILER_RT_ABI enum LE_RESULT 51214571Sdim__ledf2(fp_t a, fp_t b) { 52214571Sdim 53214571Sdim const srep_t aInt = toRep(a); 54214571Sdim const srep_t bInt = toRep(b); 55214571Sdim const rep_t aAbs = aInt & absMask; 56214571Sdim const rep_t bAbs = bInt & absMask; 57214571Sdim 58214571Sdim // If either a or b is NaN, they are unordered. 59214571Sdim if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; 60214571Sdim 61214571Sdim // If a and b are both zeros, they are equal. 62214571Sdim if ((aAbs | bAbs) == 0) return LE_EQUAL; 63214571Sdim 64214571Sdim // If at least one of a and b is positive, we get the same result comparing 65214571Sdim // a and b as signed integers as we would with a floating-point compare. 66214571Sdim if ((aInt & bInt) >= 0) { 67214571Sdim if (aInt < bInt) return LE_LESS; 68214571Sdim else if (aInt == bInt) return LE_EQUAL; 69214571Sdim else return LE_GREATER; 70214571Sdim } 71214571Sdim 72214571Sdim // Otherwise, both are negative, so we need to flip the sense of the 73214571Sdim // comparison to get the correct result. (This assumes a twos- or ones- 74214571Sdim // complement integer representation; if integers are represented in a 75214571Sdim // sign-magnitude representation, then this flip is incorrect). 76214571Sdim else { 77214571Sdim if (aInt > bInt) return LE_LESS; 78214571Sdim else if (aInt == bInt) return LE_EQUAL; 79214571Sdim else return LE_GREATER; 80214571Sdim } 81214571Sdim} 82 83enum GE_RESULT { 84 GE_LESS = -1, 85 GE_EQUAL = 0, 86 GE_GREATER = 1, 87 GE_UNORDERED = -1 // Note: different from LE_UNORDERED 88}; 89 90COMPILER_RT_ABI enum GE_RESULT 91__gedf2(fp_t a, fp_t b) { 92 93 const srep_t aInt = toRep(a); 94 const srep_t bInt = toRep(b); 95 const rep_t aAbs = aInt & absMask; 96 const rep_t bAbs = bInt & absMask; 97 98 if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; 99 if ((aAbs | bAbs) == 0) return GE_EQUAL; 100 if ((aInt & bInt) >= 0) { 101 if (aInt < bInt) return GE_LESS; 102 else if (aInt == bInt) return GE_EQUAL; 103 else return GE_GREATER; 104 } else { 105 if (aInt > bInt) return GE_LESS; 106 else if (aInt == bInt) return GE_EQUAL; 107 else return GE_GREATER; 108 } 109} 110 111ARM_EABI_FNALIAS(dcmpun, unorddf2) 112 113COMPILER_RT_ABI int 114__unorddf2(fp_t a, fp_t b) { 115 const rep_t aAbs = toRep(a) & absMask; 116 const rep_t bAbs = toRep(b) & absMask; 117 return aAbs > infRep || bAbs > infRep; 118} 119 120// The following are alternative names for the preceding routines. 121 122COMPILER_RT_ABI enum LE_RESULT 123__eqdf2(fp_t a, fp_t b) { 124 return __ledf2(a, b); 125} 126 127COMPILER_RT_ABI enum LE_RESULT 128__ltdf2(fp_t a, fp_t b) { 129 return __ledf2(a, b); 130} 131 132COMPILER_RT_ABI enum LE_RESULT 133__nedf2(fp_t a, fp_t b) { 134 return __ledf2(a, b); 135} 136 137COMPILER_RT_ABI enum GE_RESULT 138__gtdf2(fp_t a, fp_t b) { 139 return __gedf2(a, b); 140} 141 142