Print this page
5262 libm needs to be carefully unifdef'd
5268 libm doesn't need to hide symbols which are already local
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Reviewed by: Gordon Ross <gwr@nexenta.com>
Approved by: Gordon Ross <gwr@nexenta.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/m9x/nearbyintl.c
+++ new/usr/src/lib/libm/common/m9x/nearbyintl.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 nearbyintl = __nearbyintl
32 -#endif
33 31
34 32 #include "libm.h"
35 33 #include "fma.h"
36 34 #include "fenv_inlines.h"
37 35
38 36 #if defined(__sparc)
39 37
40 38 static union {
41 39 unsigned i;
42 40 float f;
43 41 } snan = { 0x7f800001 };
44 42
45 43 long double
46 44 __nearbyintl(long double x) {
47 45 union {
48 46 unsigned i[4];
49 47 long double q;
50 48 } xx;
51 49 unsigned hx, sx, i, frac;
52 50 unsigned int fsr;
53 51 int rm, j;
54 52 volatile float dummy;
55 53
56 54 xx.q = x;
57 55 sx = xx.i[0] & 0x80000000;
58 56 hx = xx.i[0] & ~0x80000000;
59 57
60 58 /* handle trivial cases */
61 59 if (hx >= 0x406f0000) { /* x is nan, inf, or already integral */
62 60 /* check for signaling nan */
63 61 if ((hx > 0x7fff0000 || (hx == 0x7fff0000 &&
64 62 (xx.i[1] | xx.i[2] | xx.i[3]))) && !(hx & 0x8000)) {
65 63 dummy = snan.f;
66 64 dummy += snan.f;
67 65 xx.i[0] = sx | hx | 0x8000;
68 66 }
69 67 return (xx.q);
70 68 } else if ((hx | xx.i[1] | xx.i[2] | xx.i[3]) == 0) /* x is zero */
71 69 return (x);
72 70
73 71 /* get the rounding mode */
74 72 __fenv_getfsr32(&fsr);
75 73 rm = fsr >> 30;
76 74
77 75 /* flip the sense of directed roundings if x is negative */
78 76 if (sx)
79 77 rm ^= rm >> 1;
80 78
81 79 /* handle |x| < 1 */
82 80 if (hx < 0x3fff0000) {
83 81 if (rm == FSR_RP || (rm == FSR_RN && (hx >= 0x3ffe0000 &&
84 82 ((hx & 0xffff) | xx.i[1] | xx.i[2] | xx.i[3]))))
85 83 xx.i[0] = sx | 0x3fff0000;
86 84 else
87 85 xx.i[0] = sx;
88 86 xx.i[1] = xx.i[2] = xx.i[3] = 0;
89 87 return (xx.q);
90 88 }
91 89
92 90 /* round x at the integer bit */
93 91 j = 0x406f - (hx >> 16);
94 92 if (j >= 96) {
95 93 i = 1 << (j - 96);
96 94 frac = ((xx.i[0] << 1) << (127 - j)) | (xx.i[1] >> (j - 96));
97 95 if ((xx.i[1] & (i - 1)) | xx.i[2] | xx.i[3])
98 96 frac |= 1;
99 97 if (!frac)
100 98 return (x);
101 99 xx.i[1] = xx.i[2] = xx.i[3] = 0;
102 100 xx.i[0] &= ~(i - 1);
103 101 if (rm == FSR_RP || (rm == FSR_RN && (frac > 0x80000000u ||
104 102 (frac == 0x80000000 && (xx.i[0] & i)))))
105 103 xx.i[0] += i;
106 104 } else if (j >= 64) {
107 105 i = 1 << (j - 64);
108 106 frac = ((xx.i[1] << 1) << (95 - j)) | (xx.i[2] >> (j - 64));
109 107 if ((xx.i[2] & (i - 1)) | xx.i[3])
110 108 frac |= 1;
111 109 if (!frac)
112 110 return (x);
113 111 xx.i[2] = xx.i[3] = 0;
114 112 xx.i[1] &= ~(i - 1);
115 113 if (rm == FSR_RP || (rm == FSR_RN && (frac > 0x80000000u ||
116 114 (frac == 0x80000000 && (xx.i[1] & i))))) {
117 115 xx.i[1] += i;
118 116 if (xx.i[1] == 0)
119 117 xx.i[0]++;
120 118 }
121 119 } else if (j >= 32) {
122 120 i = 1 << (j - 32);
123 121 frac = ((xx.i[2] << 1) << (63 - j)) | (xx.i[3] >> (j - 32));
124 122 if (xx.i[3] & (i - 1))
125 123 frac |= 1;
126 124 if (!frac)
127 125 return (x);
128 126 xx.i[3] = 0;
129 127 xx.i[2] &= ~(i - 1);
130 128 if (rm == FSR_RP || (rm == FSR_RN && (frac > 0x80000000u ||
131 129 (frac == 0x80000000 && (xx.i[2] & i))))) {
132 130 xx.i[2] += i;
133 131 if (xx.i[2] == 0)
134 132 if (++xx.i[1] == 0)
135 133 xx.i[0]++;
136 134 }
137 135 } else {
138 136 i = 1 << j;
139 137 frac = (xx.i[3] << 1) << (31 - j);
140 138 if (!frac)
141 139 return (x);
142 140 xx.i[3] &= ~(i - 1);
143 141 if (rm == FSR_RP || (rm == FSR_RN && (frac > 0x80000000u ||
144 142 (frac == 0x80000000 && (xx.i[3] & i))))) {
145 143 xx.i[3] += i;
146 144 if (xx.i[3] == 0)
147 145 if (++xx.i[2] == 0)
148 146 if (++xx.i[1] == 0)
149 147 xx.i[0]++;
150 148 }
151 149 }
152 150
153 151 return (xx.q);
154 152 }
155 153
156 154 #elif defined(__x86)
157 155
158 156 /* inline template */
159 157 extern long double frndint(long double);
160 158
161 159 long double
162 160 __nearbyintl(long double x) {
163 161 long double z;
164 162 unsigned oldcwsw, cwsw;
165 163
166 164 /* save the control and status words, mask the inexact exception */
167 165 __fenv_getcwsw(&oldcwsw);
168 166 cwsw = oldcwsw | 0x00200000;
169 167 __fenv_setcwsw(&cwsw);
170 168
171 169 z = frndint(x);
172 170
173 171 /*
174 172 * restore the control and status words, preserving all but the
175 173 * inexact flag
176 174 */
177 175 __fenv_getcwsw(&cwsw);
178 176 oldcwsw |= (cwsw & 0x1f);
179 177 __fenv_setcwsw(&oldcwsw);
180 178
181 179 return (z);
182 180 }
183 181
184 182 #else
185 183 #error Unknown architecture
186 184 #endif
↓ open down ↓ |
144 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX