1214152Sed//===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===// 2214152Sed// 3214152Sed// The LLVM Compiler Infrastructure 4214152Sed// 5222656Sed// This file is dual licensed under the MIT and the University of Illinois Open 6222656Sed// Source Licenses. See LICENSE.TXT for details. 7214152Sed// 8214152Sed//===----------------------------------------------------------------------===// 9214152Sed// 10214152Sed// This file implements the following soft-fp_t comparison routines: 11214152Sed// 12214152Sed// __eqsf2 __gesf2 __unordsf2 13214152Sed// __lesf2 __gtsf2 14214152Sed// __ltsf2 15214152Sed// __nesf2 16214152Sed// 17214152Sed// The semantics of the routines grouped in each column are identical, so there 18214152Sed// is a single implementation for each, and wrappers to provide the other names. 19214152Sed// 20214152Sed// The main routines behave as follows: 21214152Sed// 22214152Sed// __lesf2(a,b) returns -1 if a < b 23214152Sed// 0 if a == b 24214152Sed// 1 if a > b 25214152Sed// 1 if either a or b is NaN 26214152Sed// 27214152Sed// __gesf2(a,b) returns -1 if a < b 28214152Sed// 0 if a == b 29214152Sed// 1 if a > b 30214152Sed// -1 if either a or b is NaN 31214152Sed// 32214152Sed// __unordsf2(a,b) returns 0 if both a and b are numbers 33214152Sed// 1 if either a or b is NaN 34214152Sed// 35214152Sed// Note that __lesf2( ) and __gesf2( ) are identical except in their handling of 36214152Sed// NaN values. 37214152Sed// 38214152Sed//===----------------------------------------------------------------------===// 39214152Sed 40214152Sed#define SINGLE_PRECISION 41214152Sed#include "fp_lib.h" 42214152Sed 43214152Sedenum LE_RESULT { 44214152Sed LE_LESS = -1, 45214152Sed LE_EQUAL = 0, 46214152Sed LE_GREATER = 1, 47214152Sed LE_UNORDERED = 1 48214152Sed}; 49214152Sed 50214152Sedenum LE_RESULT __lesf2(fp_t a, fp_t b) { 51214152Sed 52214152Sed const srep_t aInt = toRep(a); 53214152Sed const srep_t bInt = toRep(b); 54214152Sed const rep_t aAbs = aInt & absMask; 55214152Sed const rep_t bAbs = bInt & absMask; 56214152Sed 57214152Sed // If either a or b is NaN, they are unordered. 58214152Sed if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; 59214152Sed 60214152Sed // If a and b are both zeros, they are equal. 61214152Sed if ((aAbs | bAbs) == 0) return LE_EQUAL; 62214152Sed 63214152Sed // If at least one of a and b is positive, we get the same result comparing 64214152Sed // a and b as signed integers as we would with a fp_ting-point compare. 65214152Sed if ((aInt & bInt) >= 0) { 66214152Sed if (aInt < bInt) return LE_LESS; 67214152Sed else if (aInt == bInt) return LE_EQUAL; 68214152Sed else return LE_GREATER; 69214152Sed } 70214152Sed 71214152Sed // Otherwise, both are negative, so we need to flip the sense of the 72214152Sed // comparison to get the correct result. (This assumes a twos- or ones- 73214152Sed // complement integer representation; if integers are represented in a 74214152Sed // sign-magnitude representation, then this flip is incorrect). 75214152Sed else { 76214152Sed if (aInt > bInt) return LE_LESS; 77214152Sed else if (aInt == bInt) return LE_EQUAL; 78214152Sed else return LE_GREATER; 79214152Sed } 80214152Sed} 81214152Sed 82214152Sedenum GE_RESULT { 83214152Sed GE_LESS = -1, 84214152Sed GE_EQUAL = 0, 85214152Sed GE_GREATER = 1, 86214152Sed GE_UNORDERED = -1 // Note: different from LE_UNORDERED 87214152Sed}; 88214152Sed 89214152Sedenum GE_RESULT __gesf2(fp_t a, fp_t b) { 90214152Sed 91214152Sed const srep_t aInt = toRep(a); 92214152Sed const srep_t bInt = toRep(b); 93214152Sed const rep_t aAbs = aInt & absMask; 94214152Sed const rep_t bAbs = bInt & absMask; 95214152Sed 96214152Sed if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; 97214152Sed if ((aAbs | bAbs) == 0) return GE_EQUAL; 98214152Sed if ((aInt & bInt) >= 0) { 99214152Sed if (aInt < bInt) return GE_LESS; 100214152Sed else if (aInt == bInt) return GE_EQUAL; 101214152Sed else return GE_GREATER; 102214152Sed } else { 103214152Sed if (aInt > bInt) return GE_LESS; 104214152Sed else if (aInt == bInt) return GE_EQUAL; 105214152Sed else return GE_GREATER; 106214152Sed } 107214152Sed} 108214152Sed 109214152Sedint __unordsf2(fp_t a, fp_t b) { 110214152Sed const rep_t aAbs = toRep(a) & absMask; 111214152Sed const rep_t bAbs = toRep(b) & absMask; 112214152Sed return aAbs > infRep || bAbs > infRep; 113214152Sed} 114214152Sed 115214152Sed// The following are alternative names for the preceeding routines. 116214152Sed 117214152Sedenum LE_RESULT __eqsf2(fp_t a, fp_t b) { 118214152Sed return __lesf2(a, b); 119214152Sed} 120214152Sed 121214152Sedenum LE_RESULT __ltsf2(fp_t a, fp_t b) { 122214152Sed return __lesf2(a, b); 123214152Sed} 124214152Sed 125214152Sedenum LE_RESULT __nesf2(fp_t a, fp_t b) { 126214152Sed return __lesf2(a, b); 127214152Sed} 128214152Sed 129214152Sedenum GE_RESULT __gtsf2(fp_t a, fp_t b) { 130214152Sed return __gesf2(a, b); 131214152Sed} 132