4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 * Portions of this source code were derived from Berkeley
31 * 4.3 BSD under license from the Regents of the University of
35 * Copyright 2011 Jason King. All rights reserved
39 * Generic XDR routines impelmentation.
41 * These are the "floating point" xdr routines used to (de)serialize
42 * most common data items. See xdr.h for more info on the interface to
47 #include <sys/types.h>
50 #include <rpc/types.h>
52 #include <sys/byteorder.h>
57 * The OTW format is IEEE 754 with big endian ordering.
60 xdr_float(XDR
*xdrs
, float *fp
)
65 return (XDR_PUTINT32(xdrs
, (int *)fp
));
68 return (XDR_GETINT32(xdrs
, (int *)fp
));
77 xdr_double(XDR
*xdrs
, double *dp
)
79 int64_t *i64p
= (int64_t *)dp
;
87 return (XDR_PUTBYTES(xdrs
, (char *)&val
, sizeof (val
)));
90 ret
= XDR_GETBYTES(xdrs
, (char *)dp
, sizeof (double));
104 xdr_quadruple(XDR
*xdrs
, long double *fp
)
107 * The Sparc uses IEEE FP encoding, so just do a byte copy
113 switch (xdrs
->x_op
) {
115 return (XDR_PUTBYTES(xdrs
, (char *)fp
, sizeof (long double)));
117 return (XDR_GETBYTES(xdrs
, (char *)fp
, sizeof (long double)));
127 #warn No platform specific implementation defined for floats
130 xdr_float(XDR
*xdrs
, float *fp
)
133 * Every machine can do this, its just not very efficient.
134 * In addtion, some rounding errors may occur do to the
135 * calculations involved.
142 switch (xdrs
->x_op
) {
147 return (XDR_PUTINT32(xdrs
, &val
));
161 if ((exp
> 128) || (exp
< -127)) {
162 /* over or under flowing ieee exponent */
166 val
= val
<< 8; /* for the exponent */
167 val
+= 127 + exp
; /* 127 is the bias */
168 val
= val
<< 23; /* for the mantissa */
169 val
+= (int32_t)((f
- 1) * 8388608); /* 2 ^ 23 */
170 return (XDR_PUTINT32(xdrs
, &val
));
174 * It assumes that the decoding machine's float can represent
175 * any value in the range of
176 * ieee largest float = (2 ^ 128) * 0x1.fffff
178 * ieee smallest float = (2 ^ -127) * 0x1.00000
179 * In addtion, some rounding errors may occur do to the
180 * calculations involved.
183 if (!XDR_GETINT32(xdrs
, (int32_t *)&val
))
185 neg
= val
& 0x80000000;
186 exp
= (val
& 0x7f800000) >> 23;
187 exp
-= 127; /* subtract exponent base */
188 f
= (val
& 0x007fffff) * 0.00000011920928955078125;
216 xdr_double(XDR
*xdrs
, double *dp
)
219 * Every machine can do this, its just not very efficient.
220 * In addtion, some rounding errors may occur do to the
221 * calculations involved.
230 switch (xdrs
->x_op
) {
237 return (XDR_PUTINT32(xdrs
, lp
++) &&
238 XDR_PUTINT32(xdrs
, lp
));
252 if ((exp
> 1024) || (exp
< -1023)) {
253 /* over or under flowing ieee exponent */
256 val
[0] = (neg
<< 11); /* for the exponent */
257 val
[0] += 1023 + exp
; /* 1023 is the bias */
258 val
[0] = val
[0] << 20; /* for the mantissa */
259 val
[0] += (int32_t)((d
- 1) * 1048576); /* 2 ^ 20 */
260 val
[1] += (uint32_t)((((d
- 1) * 1048576) - val
[0]) *
261 4294967296); /* 2 ^ 32 */
264 return (XDR_PUTINT32(xdrs
, lp
++) && XDR_PUTINT32(xdrs
, lp
));
268 * It assumes that the decoding machine's
269 * double can represent any value in the range of
270 * ieee largest double = (2 ^ 1024) * 0x1.fffffffffffff
272 * ieee smallest double = (2 ^ -1023) * 0x1.0000000000000
273 * In addtion, some rounding errors may occur do to the
274 * calculations involved.
278 if (!XDR_GETINT32(xdrs
, lp
++) || !XDR_GETINT32(xdrs
, lp
))
280 neg
= val
[0] & 0x80000000;
281 exp
= (val
[0] & 0x7ff00000) >> 20;
282 exp
-= 1023; /* subtract exponent base */
283 d
= (val
[0] & 0x000fffff) * 0.00000095367431640625;
285 d
+= (val
[1] * 0.0000000000000002220446049250313);
311 xdr_quadruple(XDR
*xdrs
, long double *fp
)
316 #endif /* _IEEE_754 */