Print this page
11210 libm should be cstyle(1ONBLD) clean
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/m9x/nearbyintf.c
+++ new/usr/src/lib/libm/common/m9x/nearbyintf.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.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
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
20 20 */
21 21
22 22 /*
23 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 +
25 26 /*
26 27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 28 * Use is subject to license terms.
28 29 */
29 30
30 31 #pragma weak nearbyintf = __nearbyintf
31 32
32 33 #include "libm.h"
33 34 #include <fenv.h>
34 35
35 36 float
36 -__nearbyintf(float x) {
37 +__nearbyintf(float x)
38 +{
37 39 union {
38 40 unsigned i;
39 41 float f;
40 42 } xx;
43 +
41 44 unsigned hx, sx, i, frac;
42 45 int rm;
43 46
44 47 xx.f = x;
45 48 sx = xx.i & 0x80000000;
46 49 hx = xx.i & ~0x80000000;
47 50
48 51 /* handle trivial cases */
49 - if (hx >= 0x4b000000) { /* x is nan, inf, or already integral */
52 + if (hx >= 0x4b000000) { /* x is nan, inf, or already integral */
50 53 if (hx > 0x7f800000) /* x is nan */
51 54 return (x * x); /* + -> * for Cheetah */
55 +
52 56 return (x);
53 - } else if (hx == 0) /* x is zero */
57 + } else if (hx == 0) { /* x is zero */
54 58 return (x);
59 + }
55 60
56 61 /* get the rounding mode */
57 62 rm = fegetround();
58 63
59 64 /* flip the sense of directed roundings if x is negative */
60 65 if (sx && (rm == FE_UPWARD || rm == FE_DOWNWARD))
61 66 rm = (FE_UPWARD + FE_DOWNWARD) - rm;
62 67
63 68 /* handle |x| < 1 */
64 69 if (hx < 0x3f800000) {
65 70 if (rm == FE_UPWARD || (rm == FE_TONEAREST && hx > 0x3f000000))
66 71 xx.i = sx | 0x3f800000;
67 72 else
68 73 xx.i = sx;
74 +
69 75 return (xx.f);
70 76 }
71 77
72 78 /* round x at the integer bit */
73 79 i = 1 << (0x96 - (hx >> 23));
74 80 frac = hx & (i - 1);
81 +
75 82 if (!frac)
76 83 return (x);
77 84
78 85 hx &= ~(i - 1);
86 +
79 87 if (rm == FE_UPWARD || (rm == FE_TONEAREST && (frac > (i >> 1) ||
80 - ((frac == (i >> 1)) && (hx & i)))))
88 + ((frac == (i >> 1)) && (hx & i)))))
81 89 xx.i = sx | (hx + i);
82 90 else
83 91 xx.i = sx | hx;
92 +
84 93 return (xx.f);
85 94 }
86 95
87 96 #if 0
88 -
89 97 /*
90 98 * Alternate implementations for SPARC, x86, using fp ops. These may
91 99 * be faster depending on how expensive saving and restoring the fp
92 100 * modes and status flags is.
93 101 */
94 102
95 103 #include "libm.h"
96 104 #include "fma.h"
97 105
98 106 #if defined(__sparc)
99 -
100 107 float
101 -__nearbyintf(float x) {
108 +__nearbyintf(float x)
109 +{
102 110 union {
103 111 unsigned i;
104 112 float f;
105 113 } xx, yy;
114 +
106 115 float z;
107 116 unsigned hx, sx, fsr, oldfsr;
108 117 int rm;
109 118
110 119 xx.f = x;
111 120 sx = xx.i & 0x80000000;
112 121 hx = xx.i & ~0x80000000;
113 122
114 123 /* handle trivial cases */
115 - if (hx >= 0x4b000000) /* x is nan, inf, or already integral */
124 + if (hx >= 0x4b000000) /* x is nan, inf, or already integral */
116 125 return (x + 0.0f);
117 - else if (hx == 0) /* x is zero */
126 + else if (hx == 0) /* x is zero */
118 127 return (x);
119 128
120 129 /* save the fsr */
121 130 __fenv_getfsr(&oldfsr);
122 131
123 132 /* handle |x| < 1 */
124 133 if (hx < 0x3f800000) {
125 134 /* flip the sense of directed roundings if x is negative */
126 135 rm = oldfsr >> 30;
136 +
127 137 if (sx)
128 138 rm ^= rm >> 1;
139 +
129 140 if (rm == FSR_RP || (rm == FSR_RN && hx > 0x3f000000))
130 141 xx.i = sx | 0x3f800000;
131 142 else
132 143 xx.i = sx;
144 +
133 145 return (xx.f);
134 146 }
135 147
136 148 /* clear the inexact trap */
137 149 fsr = oldfsr & ~FSR_NXM;
138 150 __fenv_setfsr(&fsr);
139 151
140 152 /* round x at the integer bit */
141 153 yy.i = sx | 0x4b000000;
142 154 z = (x + yy.f) - yy.f;
143 155
144 156 /* restore the old fsr */
145 157 __fenv_setfsr(&oldfsr);
146 158
147 159 return (z);
148 160 }
149 -
150 161 #elif defined(__x86)
151 -
152 162 /* inline template */
153 163 extern long double frndint(long double);
154 164
155 165 float
156 -__nearbyintf(float x) {
166 +__nearbyintf(float x)
167 +{
157 168 long double z;
158 169 unsigned oldcwsw, cwsw;
159 170
160 171 /* save the control and status words, mask the inexact exception */
161 172 __fenv_getcwsw(&oldcwsw);
162 173 cwsw = oldcwsw | 0x00200000;
163 174 __fenv_setcwsw(&cwsw);
164 175
165 - z = frndint((long double) x);
176 + z = frndint((long double)x);
166 177
167 178 /*
168 179 * restore the control and status words, preserving all but the
169 180 * inexact flag
170 181 */
171 182 __fenv_getcwsw(&cwsw);
172 183 oldcwsw |= (cwsw & 0x1f);
173 184 __fenv_setcwsw(&oldcwsw);
174 185
175 186 /* note: the value of z is representable in single precision */
176 187 return (z);
177 188 }
178 -
179 189 #else
180 190 #error Unknown architecture
181 191 #endif
182 -
183 192 #endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX