Print this page
5262 libm needs to be carefully unifdef'd
5268 libm doesn't need to hide symbols which are already local
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/m9x/nexttoward.c
+++ new/usr/src/lib/libm/common/m9x/nexttoward.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
20 20 */
21 21
22 22 /*
23 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25 /*
26 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 27 * Use is subject to license terms.
28 28 */
29 29
30 -#if defined(ELFOBJ)
31 30 #pragma weak nexttoward = __nexttoward
32 -#endif
33 31
34 32 /*
35 33 * nexttoward(x, y) delivers the next representable number after x
36 34 * in the direction of y. If x and y are both zero, the result is
37 35 * zero with the same sign as y. If either x or y is NaN, the result
38 36 * is NaN.
39 37 *
40 38 * If x != y and the result is infinite, overflow is raised; if
41 39 * x != y and the result is subnormal or zero, underflow is raised.
42 40 * (This is wrong, but it's what C99 apparently wants.)
43 41 */
44 42
45 43 #include "libm.h"
46 44
47 45 #if defined(__sparc)
48 46
49 47 static union {
50 48 unsigned i[2];
51 49 double d;
52 50 } C[] = {
53 51 0x00100000, 0,
54 52 0x7fe00000, 0,
55 53 0x7fffffff, 0xffffffff
56 54 };
57 55
58 56 #define tiny C[0].d
59 57 #define huge C[1].d
60 58 #define qnan C[2].d
61 59
62 60 enum fcc_type {
63 61 fcc_equal = 0,
64 62 fcc_less = 1,
65 63 fcc_greater = 2,
66 64 fcc_unordered = 3
67 65 };
68 66
69 67 #ifdef __sparcv9
70 68 #define _Q_cmp _Qp_cmp
71 69 #endif
72 70
73 71 extern enum fcc_type _Q_cmp(const long double *, const long double *);
74 72
75 73 double
76 74 __nexttoward(double x, long double y) {
77 75 union {
78 76 unsigned i[2];
79 77 double d;
80 78 } xx;
81 79 union {
82 80 unsigned i[4];
83 81 long double q;
84 82 } yy;
85 83 long double lx;
86 84 unsigned hx;
87 85 volatile double dummy;
88 86 enum fcc_type rel;
89 87
90 88 /*
91 89 * It would be somewhat more efficient to check for NaN and
92 90 * zero operands before converting x to long double and then
93 91 * to code the comparison in line rather than calling _Q_cmp.
94 92 * However, since this code probably won't get used much,
95 93 * I'm opting in favor of simplicity instead.
96 94 */
97 95 lx = xx.d = x;
98 96 hx = (xx.i[0] & ~0x80000000) | xx.i[1];
99 97
100 98 /* check for each of four possible orderings */
101 99 rel = _Q_cmp(&lx, &y);
102 100 if (rel == fcc_unordered)
103 101 return (qnan);
104 102
105 103 if (rel == fcc_equal) {
106 104 if (hx == 0) { /* x is zero; return zero with y's sign */
107 105 yy.q = y;
108 106 xx.i[0] = yy.i[0];
109 107 return (xx.d);
110 108 }
111 109 return (x);
112 110 }
113 111
114 112 if (rel == fcc_less) {
115 113 if (hx == 0) { /* x is zero */
116 114 xx.i[0] = 0;
117 115 xx.i[1] = 0x00000001;
118 116 } else if ((int)xx.i[0] >= 0) { /* x is positive */
119 117 if (++xx.i[1] == 0)
120 118 xx.i[0]++;
121 119 } else {
122 120 if (xx.i[1]-- == 0)
123 121 xx.i[0]--;
124 122 }
125 123 } else {
126 124 if (hx == 0) { /* x is zero */
127 125 xx.i[0] = 0x80000000;
128 126 xx.i[1] = 0x00000001;
129 127 } else if ((int)xx.i[0] >= 0) { /* x is positive */
130 128 if (xx.i[1]-- == 0)
131 129 xx.i[0]--;
132 130 } else {
133 131 if (++xx.i[1] == 0)
134 132 xx.i[0]++;
135 133 }
136 134 }
137 135
138 136 /* raise exceptions as needed */
139 137 hx = xx.i[0] & ~0x80000000;
140 138 if (hx == 0x7ff00000) {
141 139 dummy = huge;
142 140 dummy *= huge;
143 141 } else if (hx < 0x00100000) {
144 142 dummy = tiny;
145 143 dummy *= tiny;
146 144 }
147 145
148 146 return (xx.d);
149 147 }
150 148
151 149 #elif defined(__x86)
152 150
153 151 static union {
154 152 unsigned i[2];
155 153 double d;
156 154 } C[] = {
157 155 0, 0x00100000,
158 156 0, 0x7fe00000,
159 157 };
160 158
161 159 #define tiny C[0].d
162 160 #define huge C[1].d
163 161
164 162 double
165 163 __nexttoward(double x, long double y) {
166 164 union {
167 165 unsigned i[2];
168 166 double d;
169 167 } xx;
170 168 unsigned hx;
171 169 long double lx;
172 170 volatile double dummy;
173 171
174 172 lx = xx.d = x;
175 173 hx = (xx.i[1] & ~0x80000000) | xx.i[0];
176 174
177 175 /* check for each of four possible orderings */
178 176 if (isunordered(lx, y))
179 177 return ((double) (lx + y));
180 178
181 179 if (lx == y)
182 180 return ((double) y);
183 181
184 182 if (lx < y) {
185 183 if (hx == 0) { /* x is zero */
186 184 xx.i[0] = 0x00000001;
187 185 xx.i[1] = 0;
188 186 } else if ((int)xx.i[1] >= 0) { /* x is positive */
189 187 if (++xx.i[0] == 0)
190 188 xx.i[1]++;
191 189 } else {
192 190 if (xx.i[0]-- == 0)
193 191 xx.i[1]--;
194 192 }
195 193 } else {
196 194 if (hx == 0) { /* x is zero */
197 195 xx.i[0] = 0x00000001;
198 196 xx.i[1] = 0x80000000;
199 197 } else if ((int)xx.i[1] >= 0) { /* x is positive */
200 198 if (xx.i[0]-- == 0)
201 199 xx.i[1]--;
202 200 } else {
203 201 if (++xx.i[0] == 0)
204 202 xx.i[1]++;
205 203 }
206 204 }
207 205
208 206 /* raise exceptions as needed */
209 207 hx = xx.i[1] & ~0x80000000;
210 208 if (hx == 0x7ff00000) {
211 209 dummy = huge;
212 210 dummy *= huge;
213 211 } else if (hx < 0x00100000) {
214 212 dummy = tiny;
215 213 dummy *= tiny;
216 214 }
217 215
218 216 return (xx.d);
219 217 }
220 218
221 219 #else
222 220 #error Unknown architecture
223 221 #endif
↓ open down ↓ |
181 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX