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/nexttowardf.c
+++ new/usr/src/lib/libm/common/m9x/nexttowardf.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 nexttowardf = __nexttowardf
32 -#endif
33 31
34 32 #include "libm.h"
35 33
36 34 static union {
37 35 unsigned i;
38 36 float f;
39 37 } C[] = {
40 38 0x00800000,
41 39 0x7f000000,
42 40 0x7fffffff
43 41 };
44 42
45 43 #define tiny C[0].f
46 44 #define huge C[1].f
47 45 #define qnan C[2].f
48 46
49 47 #if defined(__sparc)
50 48
51 49 enum fcc_type {
52 50 fcc_equal = 0,
53 51 fcc_less = 1,
54 52 fcc_greater = 2,
55 53 fcc_unordered = 3
56 54 };
57 55
58 56 #ifdef __sparcv9
59 57 #define _Q_cmp _Qp_cmp
60 58 #endif
61 59
62 60 extern enum fcc_type _Q_cmp(const long double *, const long double *);
63 61
64 62 float
65 63 __nexttowardf(float x, long double y) {
66 64 union {
67 65 unsigned i;
68 66 float f;
69 67 } xx;
70 68 union {
71 69 unsigned i[4];
72 70 long double q;
73 71 } yy;
74 72 long double lx;
75 73 unsigned hx;
76 74 volatile float dummy;
77 75 enum fcc_type rel;
78 76
79 77 /*
80 78 * It would be somewhat more efficient to check for NaN and
81 79 * zero operands before converting x to long double and then
82 80 * to code the comparison in line rather than calling _Q_cmp.
83 81 * However, since this code probably won't get used much,
84 82 * I'm opting in favor of simplicity instead.
85 83 */
86 84 lx = xx.f = x;
87 85 hx = xx.i & ~0x80000000;
88 86
89 87 /* check for each of four possible orderings */
90 88 rel = _Q_cmp(&lx, &y);
91 89 if (rel == fcc_unordered)
92 90 return (qnan);
93 91
94 92 if (rel == fcc_equal) {
95 93 if (hx == 0) { /* x is zero; return zero with y's sign */
96 94 yy.q = y;
97 95 xx.i = yy.i[0];
98 96 return (xx.f);
99 97 }
100 98 return (x);
101 99 }
102 100
103 101 if (rel == fcc_less) {
104 102 if (hx == 0) /* x is zero */
105 103 xx.i = 0x00000001;
106 104 else if ((int) xx.i >= 0) /* x is positive */
107 105 xx.i++;
108 106 else
109 107 xx.i--;
110 108 } else {
111 109 if (hx == 0) /* x is zero */
112 110 xx.i = 0x80000001;
113 111 else if ((int) xx.i >= 0) /* x is positive */
114 112 xx.i--;
115 113 else
116 114 xx.i++;
117 115 }
118 116
119 117 /* raise exceptions as needed */
120 118 hx = xx.i & ~0x80000000;
121 119 if (hx == 0x7f800000) {
122 120 dummy = huge;
123 121 dummy *= huge;
124 122 } else if (hx < 0x00800000) {
125 123 dummy = tiny;
126 124 dummy *= tiny;
127 125 }
128 126
129 127 return (xx.f);
130 128 }
131 129
132 130 #elif defined(__x86)
133 131
134 132 float
135 133 __nexttowardf(float x, long double y) {
136 134 union {
137 135 unsigned i;
138 136 float f;
139 137 } xx;
140 138 unsigned hx;
141 139 long double lx;
142 140 volatile float dummy;
143 141
144 142 lx = xx.f = x;
145 143 hx = xx.i & ~0x80000000;
146 144
147 145 /* check for each of four possible orderings */
148 146 if (isunordered(lx, y))
149 147 return ((float) (lx + y));
150 148
151 149 if (lx == y)
152 150 return ((float) y);
153 151
154 152 if (lx < y) {
155 153 if (hx == 0) /* x is zero */
156 154 xx.i = 0x00000001;
157 155 else if ((int) xx.i >= 0) /* x is positive */
158 156 xx.i++;
159 157 else
160 158 xx.i--;
161 159 } else {
162 160 if (hx == 0) /* x is zero */
163 161 xx.i = 0x80000001;
164 162 else if ((int) xx.i >= 0) /* x is positive */
165 163 xx.i--;
166 164 else
167 165 xx.i++;
168 166 }
169 167
170 168 /* raise exceptions as needed */
171 169 hx = xx.i & ~0x80000000;
172 170 if (hx == 0x7f800000) {
173 171 dummy = huge;
174 172 dummy *= huge;
175 173 } else if (hx < 0x00800000) {
176 174 dummy = tiny;
177 175 dummy *= tiny;
178 176 }
179 177
180 178 return (xx.f);
181 179 }
182 180
183 181 #else
184 182 #error Unknown architecture
185 183 #endif
↓ open down ↓ |
143 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX