blob: de700808a9259185280138cea289ce3f210b5d9d [file] [log] [blame]
Stephen Canonb1fdde12010-07-01 15:52:42 +00001/*
2 * The LLVM Compiler Infrastructure
3 *
4 * This file is distributed under the University of Illinois Open Source
5 * License. See LICENSE.TXT for details.
6 */
7
8#define DOUBLE_PRECISION
9#include "fp_lib.h"
10
11// This file implements the following soft-float comparison routines:
12//
13// __eqdf2 __gedf2 __nedf2
14// __ledf2 __gtdf2
15// __ltdf2
16// __nedf2
17//
18// The semantics of the routines grouped in each column are identical, so there
19// is a single implementation for each, and wrappers to provide the other names.
20//
21// The main routines behave as follows:
22//
23// __ledf2(a,b) returns -1 if a < b
24// 0 if a == b
25// 1 if a > b
26// 1 if either a or b is NaN
27//
28// __gedf2(a,b) returns -1 if a < b
29// 0 if a == b
30// 1 if a > b
31// -1 if either a or b is NaN
32//
33// __unorddf2(a,b) returns 0 if both a and b are numbers
34// 1 if either a or b is NaN
35//
36// Note that __ledf2( ) and __gedf2( ) are identical except in their handling of
37// NaN values.
38
39enum LE_RESULT {
40 LE_LESS = -1,
41 LE_EQUAL = 0,
42 LE_GREATER = 1,
43 LE_UNORDERED = 1
44};
45
46enum LE_RESULT __ledf2(fp_t a, fp_t b) {
47
48 const srep_t aInt = toRep(a);
49 const srep_t bInt = toRep(b);
50 const rep_t aAbs = aInt & absMask;
51 const rep_t bAbs = bInt & absMask;
52
53 // If either a or b is NaN, they are unordered.
54 if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
55
56 // If a and b are both zeros, they are equal.
57 if ((aAbs | bAbs) == 0) return LE_EQUAL;
58
59 // If at least one of a and b is positive, we get the same result comparing
60 // a and b as signed integers as we would with a floating-point compare.
61 if ((aInt & bInt) >= 0) {
62 if (aInt < bInt) return LE_LESS;
63 else if (aInt == bInt) return LE_EQUAL;
64 else return LE_GREATER;
65 }
66
67 // Otherwise, both are negative, so we need to flip the sense of the
68 // comparison to get the correct result. (This assumes a twos- or ones-
69 // complement integer representation; if integers are represented in a
70 // sign-magnitude representation, then this flip is incorrect).
71 else {
72 if (aInt > bInt) return LE_LESS;
73 else if (aInt == bInt) return LE_EQUAL;
74 else return LE_GREATER;
75 }
76}
77
78
79enum GE_RESULT {
80 GE_LESS = -1,
81 GE_EQUAL = 0,
82 GE_GREATER = 1,
83 GE_UNORDERED = -1 // Note: different from LE_UNORDERED
84};
85
86enum GE_RESULT __gedf2(fp_t a, fp_t b) {
87
88 const srep_t aInt = toRep(a);
89 const srep_t bInt = toRep(b);
90 const rep_t aAbs = aInt & absMask;
91 const rep_t bAbs = bInt & absMask;
92
93 if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
94 if ((aAbs | bAbs) == 0) return GE_EQUAL;
95 if ((aInt & bInt) >= 0) {
96 if (aInt < bInt) return GE_LESS;
97 else if (aInt == bInt) return GE_EQUAL;
98 else return GE_GREATER;
99 } else {
100 if (aInt > bInt) return GE_LESS;
101 else if (aInt == bInt) return GE_EQUAL;
102 else return GE_GREATER;
103 }
104}
105
106int __unorddf2(fp_t a, fp_t b) {
107 const rep_t aAbs = toRep(a) & absMask;
108 const rep_t bAbs = toRep(b) & absMask;
109 return aAbs > infRep || bAbs > infRep;
110}
111
112enum LE_RESULT __eqdf2(fp_t a, fp_t b) {
113 return __ledf2(a, b);
114}
115
116enum LE_RESULT __ltdf2(fp_t a, fp_t b) {
117 return __ledf2(a, b);
118}
119
120enum LE_RESULT __nedf2(fp_t a, fp_t b) {
121 return __ledf2(a, b);
122}
123
124enum GE_RESULT __gtdf2(fp_t a, fp_t b) {
125 return __gedf2(a, b);
126}
127