18360efbdSAlfred Perlstein /* $NetBSD: xdr_float.c,v 1.23 2000/07/17 04:59:51 matt Exp $ */
28360efbdSAlfred Perlstein
3a204967aSHiroki Sato /*-
4*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
5*8a16b7a1SPedro F. Giffuni *
6a204967aSHiroki Sato * Copyright (c) 2010, Oracle America, Inc.
7eae561b3SGarrett Wollman *
8a204967aSHiroki Sato * Redistribution and use in source and binary forms, with or without
9a204967aSHiroki Sato * modification, are permitted provided that the following conditions are
10a204967aSHiroki Sato * met:
11eae561b3SGarrett Wollman *
12a204967aSHiroki Sato * * Redistributions of source code must retain the above copyright
13a204967aSHiroki Sato * notice, this list of conditions and the following disclaimer.
14a204967aSHiroki Sato * * Redistributions in binary form must reproduce the above
15a204967aSHiroki Sato * copyright notice, this list of conditions and the following
16a204967aSHiroki Sato * disclaimer in the documentation and/or other materials
17a204967aSHiroki Sato * provided with the distribution.
18a204967aSHiroki Sato * * Neither the name of the "Oracle America, Inc." nor the names of its
19a204967aSHiroki Sato * contributors may be used to endorse or promote products derived
20a204967aSHiroki Sato * from this software without specific prior written permission.
21eae561b3SGarrett Wollman *
22a204967aSHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23a204967aSHiroki Sato * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24a204967aSHiroki Sato * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25a204967aSHiroki Sato * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26a204967aSHiroki Sato * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27a204967aSHiroki Sato * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28a204967aSHiroki Sato * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29a204967aSHiroki Sato * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30a204967aSHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31a204967aSHiroki Sato * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32a204967aSHiroki Sato * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33a204967aSHiroki Sato * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34eae561b3SGarrett Wollman */
35eae561b3SGarrett Wollman
36eae561b3SGarrett Wollman /*
378360efbdSAlfred Perlstein * xdr_float.c, Generic XDR routines implementation.
38eae561b3SGarrett Wollman *
39eae561b3SGarrett Wollman * These are the "floating point" xdr routines used to (de)serialize
40eae561b3SGarrett Wollman * most common data items. See xdr.h for more info on the interface to
41eae561b3SGarrett Wollman * xdr.
42eae561b3SGarrett Wollman */
43eae561b3SGarrett Wollman
448360efbdSAlfred Perlstein #include "namespace.h"
45eae561b3SGarrett Wollman #include <sys/param.h>
468360efbdSAlfred Perlstein
478360efbdSAlfred Perlstein #include <stdio.h>
488360efbdSAlfred Perlstein
49eae561b3SGarrett Wollman #include <rpc/types.h>
50eae561b3SGarrett Wollman #include <rpc/xdr.h>
518360efbdSAlfred Perlstein #include "un-namespace.h"
52eae561b3SGarrett Wollman
53eae561b3SGarrett Wollman /*
54eae561b3SGarrett Wollman * NB: Not portable.
551ad08a09SPeter Wemm * This routine works on machines with IEEE754 FP and Vaxen.
56eae561b3SGarrett Wollman */
57eae561b3SGarrett Wollman
581ad08a09SPeter Wemm #include <machine/endian.h>
59eae561b3SGarrett Wollman #define IEEEFP
60eae561b3SGarrett Wollman
618360efbdSAlfred Perlstein #if defined(__vax__)
62eae561b3SGarrett Wollman
63eae561b3SGarrett Wollman /* What IEEE single precision floating point looks like on a Vax */
64eae561b3SGarrett Wollman struct ieee_single {
65eae561b3SGarrett Wollman unsigned int mantissa: 23;
66eae561b3SGarrett Wollman unsigned int exp : 8;
67eae561b3SGarrett Wollman unsigned int sign : 1;
68eae561b3SGarrett Wollman };
69eae561b3SGarrett Wollman
70eae561b3SGarrett Wollman /* Vax single precision floating point */
71eae561b3SGarrett Wollman struct vax_single {
72eae561b3SGarrett Wollman unsigned int mantissa1 : 7;
73eae561b3SGarrett Wollman unsigned int exp : 8;
74eae561b3SGarrett Wollman unsigned int sign : 1;
75eae561b3SGarrett Wollman unsigned int mantissa2 : 16;
76eae561b3SGarrett Wollman };
77eae561b3SGarrett Wollman
78eae561b3SGarrett Wollman #define VAX_SNG_BIAS 0x81
79eae561b3SGarrett Wollman #define IEEE_SNG_BIAS 0x7f
80eae561b3SGarrett Wollman
81eae561b3SGarrett Wollman static struct sgl_limits {
82eae561b3SGarrett Wollman struct vax_single s;
83eae561b3SGarrett Wollman struct ieee_single ieee;
84eae561b3SGarrett Wollman } sgl_limits[2] = {
85eae561b3SGarrett Wollman {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
86eae561b3SGarrett Wollman { 0x0, 0xff, 0x0 }}, /* Max IEEE */
87eae561b3SGarrett Wollman {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
88eae561b3SGarrett Wollman { 0x0, 0x0, 0x0 }} /* Min IEEE */
89eae561b3SGarrett Wollman };
90eae561b3SGarrett Wollman #endif /* vax */
91eae561b3SGarrett Wollman
92eae561b3SGarrett Wollman bool_t
xdr_float(XDR * xdrs,float * fp)93107909b8SCraig Rodrigues xdr_float(XDR *xdrs, float *fp)
94eae561b3SGarrett Wollman {
958360efbdSAlfred Perlstein #ifndef IEEEFP
96eae561b3SGarrett Wollman struct ieee_single is;
97eae561b3SGarrett Wollman struct vax_single vs, *vsp;
98eae561b3SGarrett Wollman struct sgl_limits *lim;
9989017bc2SPedro F. Giffuni u_int i;
100eae561b3SGarrett Wollman #endif
101eae561b3SGarrett Wollman switch (xdrs->x_op) {
102eae561b3SGarrett Wollman
103eae561b3SGarrett Wollman case XDR_ENCODE:
104eae561b3SGarrett Wollman #ifdef IEEEFP
1058360efbdSAlfred Perlstein return (XDR_PUTINT32(xdrs, (int32_t *)fp));
106eae561b3SGarrett Wollman #else
107eae561b3SGarrett Wollman vs = *((struct vax_single *)fp);
108bf51882aSPedro F. Giffuni for (i = 0, lim = sgl_limits; i < nitems(sgl_limits);
109eae561b3SGarrett Wollman i++, lim++) {
110eae561b3SGarrett Wollman if ((vs.mantissa2 == lim->s.mantissa2) &&
111eae561b3SGarrett Wollman (vs.exp == lim->s.exp) &&
112eae561b3SGarrett Wollman (vs.mantissa1 == lim->s.mantissa1)) {
113eae561b3SGarrett Wollman is = lim->ieee;
114eae561b3SGarrett Wollman goto shipit;
115eae561b3SGarrett Wollman }
116eae561b3SGarrett Wollman }
117eae561b3SGarrett Wollman is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
118eae561b3SGarrett Wollman is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
119eae561b3SGarrett Wollman shipit:
120eae561b3SGarrett Wollman is.sign = vs.sign;
1218360efbdSAlfred Perlstein return (XDR_PUTINT32(xdrs, (int32_t *)&is));
122eae561b3SGarrett Wollman #endif
123eae561b3SGarrett Wollman
124eae561b3SGarrett Wollman case XDR_DECODE:
125eae561b3SGarrett Wollman #ifdef IEEEFP
1268360efbdSAlfred Perlstein return (XDR_GETINT32(xdrs, (int32_t *)fp));
127eae561b3SGarrett Wollman #else
128eae561b3SGarrett Wollman vsp = (struct vax_single *)fp;
1298360efbdSAlfred Perlstein if (!XDR_GETINT32(xdrs, (int32_t *)&is))
130eae561b3SGarrett Wollman return (FALSE);
131bf51882aSPedro F. Giffuni for (i = 0, lim = sgl_limits; i < nitems(sgl_limits);
132eae561b3SGarrett Wollman i++, lim++) {
133eae561b3SGarrett Wollman if ((is.exp == lim->ieee.exp) &&
134eae561b3SGarrett Wollman (is.mantissa == lim->ieee.mantissa)) {
135eae561b3SGarrett Wollman *vsp = lim->s;
136eae561b3SGarrett Wollman goto doneit;
137eae561b3SGarrett Wollman }
138eae561b3SGarrett Wollman }
139eae561b3SGarrett Wollman vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
140eae561b3SGarrett Wollman vsp->mantissa2 = is.mantissa;
141eae561b3SGarrett Wollman vsp->mantissa1 = (is.mantissa >> 16);
142eae561b3SGarrett Wollman doneit:
143eae561b3SGarrett Wollman vsp->sign = is.sign;
144eae561b3SGarrett Wollman return (TRUE);
145eae561b3SGarrett Wollman #endif
146eae561b3SGarrett Wollman
147eae561b3SGarrett Wollman case XDR_FREE:
148eae561b3SGarrett Wollman return (TRUE);
149eae561b3SGarrett Wollman }
1508360efbdSAlfred Perlstein /* NOTREACHED */
151eae561b3SGarrett Wollman return (FALSE);
152eae561b3SGarrett Wollman }
153eae561b3SGarrett Wollman
1548360efbdSAlfred Perlstein #if defined(__vax__)
155eae561b3SGarrett Wollman /* What IEEE double precision floating point looks like on a Vax */
156eae561b3SGarrett Wollman struct ieee_double {
157eae561b3SGarrett Wollman unsigned int mantissa1 : 20;
158eae561b3SGarrett Wollman unsigned int exp : 11;
159eae561b3SGarrett Wollman unsigned int sign : 1;
160eae561b3SGarrett Wollman unsigned int mantissa2 : 32;
161eae561b3SGarrett Wollman };
162eae561b3SGarrett Wollman
163eae561b3SGarrett Wollman /* Vax double precision floating point */
164eae561b3SGarrett Wollman struct vax_double {
165eae561b3SGarrett Wollman unsigned int mantissa1 : 7;
166eae561b3SGarrett Wollman unsigned int exp : 8;
167eae561b3SGarrett Wollman unsigned int sign : 1;
168eae561b3SGarrett Wollman unsigned int mantissa2 : 16;
169eae561b3SGarrett Wollman unsigned int mantissa3 : 16;
170eae561b3SGarrett Wollman unsigned int mantissa4 : 16;
171eae561b3SGarrett Wollman };
172eae561b3SGarrett Wollman
173eae561b3SGarrett Wollman #define VAX_DBL_BIAS 0x81
174eae561b3SGarrett Wollman #define IEEE_DBL_BIAS 0x3ff
175eae561b3SGarrett Wollman #define MASK(nbits) ((1 << nbits) - 1)
176eae561b3SGarrett Wollman
177eae561b3SGarrett Wollman static struct dbl_limits {
178eae561b3SGarrett Wollman struct vax_double d;
179eae561b3SGarrett Wollman struct ieee_double ieee;
180eae561b3SGarrett Wollman } dbl_limits[2] = {
181eae561b3SGarrett Wollman {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
182eae561b3SGarrett Wollman { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
183eae561b3SGarrett Wollman {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
184eae561b3SGarrett Wollman { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
185eae561b3SGarrett Wollman };
186eae561b3SGarrett Wollman
187eae561b3SGarrett Wollman #endif /* vax */
188eae561b3SGarrett Wollman
189eae561b3SGarrett Wollman
190eae561b3SGarrett Wollman bool_t
xdr_double(XDR * xdrs,double * dp)191d660d38dSCraig Rodrigues xdr_double(XDR *xdrs, double *dp)
192eae561b3SGarrett Wollman {
1931ad08a09SPeter Wemm #ifdef IEEEFP
1948360efbdSAlfred Perlstein int32_t *i32p;
1951ad08a09SPeter Wemm bool_t rv;
1961ad08a09SPeter Wemm #else
1978360efbdSAlfred Perlstein int32_t *lp;
198eae561b3SGarrett Wollman struct ieee_double id;
199eae561b3SGarrett Wollman struct vax_double vd;
2008360efbdSAlfred Perlstein struct dbl_limits *lim;
20189017bc2SPedro F. Giffuni u_int i;
202eae561b3SGarrett Wollman #endif
203eae561b3SGarrett Wollman
204eae561b3SGarrett Wollman switch (xdrs->x_op) {
205eae561b3SGarrett Wollman
206eae561b3SGarrett Wollman case XDR_ENCODE:
207eae561b3SGarrett Wollman #ifdef IEEEFP
2088360efbdSAlfred Perlstein i32p = (int32_t *)(void *)dp;
209eae561b3SGarrett Wollman #if BYTE_ORDER == BIG_ENDIAN
2108360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p);
2111ad08a09SPeter Wemm if (!rv)
2121ad08a09SPeter Wemm return (rv);
2138360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p+1);
214eae561b3SGarrett Wollman #else
2158360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p+1);
2161ad08a09SPeter Wemm if (!rv)
2171ad08a09SPeter Wemm return (rv);
2188360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p);
219eae561b3SGarrett Wollman #endif
2201ad08a09SPeter Wemm return (rv);
221eae561b3SGarrett Wollman #else
222eae561b3SGarrett Wollman vd = *((struct vax_double *)dp);
223bf51882aSPedro F. Giffuni for (i = 0, lim = dbl_limits; i < nitems(dbl_limits);
224eae561b3SGarrett Wollman i++, lim++) {
225eae561b3SGarrett Wollman if ((vd.mantissa4 == lim->d.mantissa4) &&
226eae561b3SGarrett Wollman (vd.mantissa3 == lim->d.mantissa3) &&
227eae561b3SGarrett Wollman (vd.mantissa2 == lim->d.mantissa2) &&
228eae561b3SGarrett Wollman (vd.mantissa1 == lim->d.mantissa1) &&
229eae561b3SGarrett Wollman (vd.exp == lim->d.exp)) {
230eae561b3SGarrett Wollman id = lim->ieee;
231eae561b3SGarrett Wollman goto shipit;
232eae561b3SGarrett Wollman }
233eae561b3SGarrett Wollman }
234eae561b3SGarrett Wollman id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
235eae561b3SGarrett Wollman id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
236eae561b3SGarrett Wollman id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
237eae561b3SGarrett Wollman (vd.mantissa3 << 13) |
238eae561b3SGarrett Wollman ((vd.mantissa4 >> 3) & MASK(13));
239eae561b3SGarrett Wollman shipit:
240eae561b3SGarrett Wollman id.sign = vd.sign;
2418360efbdSAlfred Perlstein lp = (int32_t *)&id;
2428360efbdSAlfred Perlstein return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp));
243eae561b3SGarrett Wollman #endif
244eae561b3SGarrett Wollman
245eae561b3SGarrett Wollman case XDR_DECODE:
246eae561b3SGarrett Wollman #ifdef IEEEFP
2478360efbdSAlfred Perlstein i32p = (int32_t *)(void *)dp;
248eae561b3SGarrett Wollman #if BYTE_ORDER == BIG_ENDIAN
2498360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p);
2501ad08a09SPeter Wemm if (!rv)
2511ad08a09SPeter Wemm return (rv);
2528360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p+1);
253eae561b3SGarrett Wollman #else
2548360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p+1);
2551ad08a09SPeter Wemm if (!rv)
2561ad08a09SPeter Wemm return (rv);
2578360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p);
258eae561b3SGarrett Wollman #endif
2591ad08a09SPeter Wemm return (rv);
260eae561b3SGarrett Wollman #else
2618360efbdSAlfred Perlstein lp = (int32_t *)&id;
2628360efbdSAlfred Perlstein if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp))
263eae561b3SGarrett Wollman return (FALSE);
264bf51882aSPedro F. Giffuni for (i = 0, lim = dbl_limits; i < nitems(dbl_limits);
265eae561b3SGarrett Wollman i++, lim++) {
266eae561b3SGarrett Wollman if ((id.mantissa2 == lim->ieee.mantissa2) &&
267eae561b3SGarrett Wollman (id.mantissa1 == lim->ieee.mantissa1) &&
268eae561b3SGarrett Wollman (id.exp == lim->ieee.exp)) {
269eae561b3SGarrett Wollman vd = lim->d;
270eae561b3SGarrett Wollman goto doneit;
271eae561b3SGarrett Wollman }
272eae561b3SGarrett Wollman }
273eae561b3SGarrett Wollman vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
274eae561b3SGarrett Wollman vd.mantissa1 = (id.mantissa1 >> 13);
275eae561b3SGarrett Wollman vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
276eae561b3SGarrett Wollman (id.mantissa2 >> 29);
277eae561b3SGarrett Wollman vd.mantissa3 = (id.mantissa2 >> 13);
278eae561b3SGarrett Wollman vd.mantissa4 = (id.mantissa2 << 3);
279eae561b3SGarrett Wollman doneit:
280eae561b3SGarrett Wollman vd.sign = id.sign;
281eae561b3SGarrett Wollman *dp = *((double *)&vd);
282eae561b3SGarrett Wollman return (TRUE);
283eae561b3SGarrett Wollman #endif
284eae561b3SGarrett Wollman
285eae561b3SGarrett Wollman case XDR_FREE:
286eae561b3SGarrett Wollman return (TRUE);
287eae561b3SGarrett Wollman }
2888360efbdSAlfred Perlstein /* NOTREACHED */
289eae561b3SGarrett Wollman return (FALSE);
290eae561b3SGarrett Wollman }
291