1*a0212cc2Smckusick /* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */
2*a0212cc2Smckusick /*
3*a0212cc2Smckusick * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4*a0212cc2Smckusick * unrestricted use provided that this legend is included on all tape
5*a0212cc2Smckusick * media and as a part of the software program in whole or part. Users
6*a0212cc2Smckusick * may copy or modify Sun RPC without charge, but are not authorized
7*a0212cc2Smckusick * to license or distribute it to anyone else except as part of a product or
8*a0212cc2Smckusick * program developed by the user.
9*a0212cc2Smckusick *
10*a0212cc2Smckusick * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11*a0212cc2Smckusick * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12*a0212cc2Smckusick * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13*a0212cc2Smckusick *
14*a0212cc2Smckusick * Sun RPC is provided with no support and without any obligation on the
15*a0212cc2Smckusick * part of Sun Microsystems, Inc. to assist in its use, correction,
16*a0212cc2Smckusick * modification or enhancement.
17*a0212cc2Smckusick *
18*a0212cc2Smckusick * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19*a0212cc2Smckusick * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20*a0212cc2Smckusick * OR ANY PART THEREOF.
21*a0212cc2Smckusick *
22*a0212cc2Smckusick * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23*a0212cc2Smckusick * or profits or other special, indirect and consequential damages, even if
24*a0212cc2Smckusick * Sun has been advised of the possibility of such damages.
25*a0212cc2Smckusick *
26*a0212cc2Smckusick * Sun Microsystems, Inc.
27*a0212cc2Smckusick * 2550 Garcia Avenue
28*a0212cc2Smckusick * Mountain View, California 94043
29*a0212cc2Smckusick */
30*a0212cc2Smckusick #if !defined(lint) && defined(SCCSIDS)
31*a0212cc2Smckusick static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
32*a0212cc2Smckusick #endif
33*a0212cc2Smckusick
34*a0212cc2Smckusick /*
35*a0212cc2Smckusick * xdr_float.c, Generic XDR routines impelmentation.
36*a0212cc2Smckusick *
37*a0212cc2Smckusick * Copyright (C) 1984, Sun Microsystems, Inc.
38*a0212cc2Smckusick *
39*a0212cc2Smckusick * These are the "floating point" xdr routines used to (de)serialize
40*a0212cc2Smckusick * most common data items. See xdr.h for more info on the interface to
41*a0212cc2Smckusick * xdr.
42*a0212cc2Smckusick */
43*a0212cc2Smckusick
44*a0212cc2Smckusick #include <stdio.h>
45*a0212cc2Smckusick
46*a0212cc2Smckusick #include <rpc/types.h>
47*a0212cc2Smckusick #include <rpc/xdr.h>
48*a0212cc2Smckusick
49*a0212cc2Smckusick /*
50*a0212cc2Smckusick * NB: Not portable.
51*a0212cc2Smckusick * This routine works on Suns (Sky / 68000's) and Vaxen.
52*a0212cc2Smckusick */
53*a0212cc2Smckusick
54*a0212cc2Smckusick #ifdef vax
55*a0212cc2Smckusick
56*a0212cc2Smckusick /* What IEEE single precision floating point looks like on a Vax */
57*a0212cc2Smckusick struct ieee_single {
58*a0212cc2Smckusick unsigned int mantissa: 23;
59*a0212cc2Smckusick unsigned int exp : 8;
60*a0212cc2Smckusick unsigned int sign : 1;
61*a0212cc2Smckusick };
62*a0212cc2Smckusick
63*a0212cc2Smckusick /* Vax single precision floating point */
64*a0212cc2Smckusick struct vax_single {
65*a0212cc2Smckusick unsigned int mantissa1 : 7;
66*a0212cc2Smckusick unsigned int exp : 8;
67*a0212cc2Smckusick unsigned int sign : 1;
68*a0212cc2Smckusick unsigned int mantissa2 : 16;
69*a0212cc2Smckusick };
70*a0212cc2Smckusick
71*a0212cc2Smckusick #define VAX_SNG_BIAS 0x81
72*a0212cc2Smckusick #define IEEE_SNG_BIAS 0x7f
73*a0212cc2Smckusick
74*a0212cc2Smckusick static struct sgl_limits {
75*a0212cc2Smckusick struct vax_single s;
76*a0212cc2Smckusick struct ieee_single ieee;
77*a0212cc2Smckusick } sgl_limits[2] = {
78*a0212cc2Smckusick {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
79*a0212cc2Smckusick { 0x0, 0xff, 0x0 }}, /* Max IEEE */
80*a0212cc2Smckusick {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
81*a0212cc2Smckusick { 0x0, 0x0, 0x0 }} /* Min IEEE */
82*a0212cc2Smckusick };
83*a0212cc2Smckusick #endif /* vax */
84*a0212cc2Smckusick
85*a0212cc2Smckusick bool_t
xdr_float(xdrs,fp)86*a0212cc2Smckusick xdr_float(xdrs, fp)
87*a0212cc2Smckusick register XDR *xdrs;
88*a0212cc2Smckusick register float *fp;
89*a0212cc2Smckusick {
90*a0212cc2Smckusick #if !defined(mc68000) && !defined(sparc)
91*a0212cc2Smckusick struct ieee_single is;
92*a0212cc2Smckusick struct vax_single vs, *vsp;
93*a0212cc2Smckusick struct sgl_limits *lim;
94*a0212cc2Smckusick int i;
95*a0212cc2Smckusick #endif
96*a0212cc2Smckusick switch (xdrs->x_op) {
97*a0212cc2Smckusick
98*a0212cc2Smckusick case XDR_ENCODE:
99*a0212cc2Smckusick #if defined(mc68000) || defined(sparc)
100*a0212cc2Smckusick return (XDR_PUTLONG(xdrs, (long *)fp));
101*a0212cc2Smckusick #else
102*a0212cc2Smckusick vs = *((struct vax_single *)fp);
103*a0212cc2Smckusick for (i = 0, lim = sgl_limits;
104*a0212cc2Smckusick i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
105*a0212cc2Smckusick i++, lim++) {
106*a0212cc2Smckusick if ((vs.mantissa2 == lim->s.mantissa2) &&
107*a0212cc2Smckusick (vs.exp == lim->s.exp) &&
108*a0212cc2Smckusick (vs.mantissa1 == lim->s.mantissa1)) {
109*a0212cc2Smckusick is = lim->ieee;
110*a0212cc2Smckusick goto shipit;
111*a0212cc2Smckusick }
112*a0212cc2Smckusick }
113*a0212cc2Smckusick is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
114*a0212cc2Smckusick is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
115*a0212cc2Smckusick shipit:
116*a0212cc2Smckusick is.sign = vs.sign;
117*a0212cc2Smckusick return (XDR_PUTLONG(xdrs, (long *)&is));
118*a0212cc2Smckusick #endif
119*a0212cc2Smckusick
120*a0212cc2Smckusick case XDR_DECODE:
121*a0212cc2Smckusick #if defined(mc68000) || defined(sparc)
122*a0212cc2Smckusick return (XDR_GETLONG(xdrs, (long *)fp));
123*a0212cc2Smckusick #else
124*a0212cc2Smckusick vsp = (struct vax_single *)fp;
125*a0212cc2Smckusick if (!XDR_GETLONG(xdrs, (long *)&is))
126*a0212cc2Smckusick return (FALSE);
127*a0212cc2Smckusick for (i = 0, lim = sgl_limits;
128*a0212cc2Smckusick i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
129*a0212cc2Smckusick i++, lim++) {
130*a0212cc2Smckusick if ((is.exp == lim->ieee.exp) &&
131*a0212cc2Smckusick (is.mantissa == lim->ieee.mantissa)) {
132*a0212cc2Smckusick *vsp = lim->s;
133*a0212cc2Smckusick goto doneit;
134*a0212cc2Smckusick }
135*a0212cc2Smckusick }
136*a0212cc2Smckusick vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
137*a0212cc2Smckusick vsp->mantissa2 = is.mantissa;
138*a0212cc2Smckusick vsp->mantissa1 = (is.mantissa >> 16);
139*a0212cc2Smckusick doneit:
140*a0212cc2Smckusick vsp->sign = is.sign;
141*a0212cc2Smckusick return (TRUE);
142*a0212cc2Smckusick #endif
143*a0212cc2Smckusick
144*a0212cc2Smckusick case XDR_FREE:
145*a0212cc2Smckusick return (TRUE);
146*a0212cc2Smckusick }
147*a0212cc2Smckusick return (FALSE);
148*a0212cc2Smckusick }
149*a0212cc2Smckusick
150*a0212cc2Smckusick /*
151*a0212cc2Smckusick * This routine works on Suns (Sky / 68000's) and Vaxen.
152*a0212cc2Smckusick */
153*a0212cc2Smckusick
154*a0212cc2Smckusick #ifdef vax
155*a0212cc2Smckusick /* What IEEE double precision floating point looks like on a Vax */
156*a0212cc2Smckusick struct ieee_double {
157*a0212cc2Smckusick unsigned int mantissa1 : 20;
158*a0212cc2Smckusick unsigned int exp : 11;
159*a0212cc2Smckusick unsigned int sign : 1;
160*a0212cc2Smckusick unsigned int mantissa2 : 32;
161*a0212cc2Smckusick };
162*a0212cc2Smckusick
163*a0212cc2Smckusick /* Vax double precision floating point */
164*a0212cc2Smckusick struct vax_double {
165*a0212cc2Smckusick unsigned int mantissa1 : 7;
166*a0212cc2Smckusick unsigned int exp : 8;
167*a0212cc2Smckusick unsigned int sign : 1;
168*a0212cc2Smckusick unsigned int mantissa2 : 16;
169*a0212cc2Smckusick unsigned int mantissa3 : 16;
170*a0212cc2Smckusick unsigned int mantissa4 : 16;
171*a0212cc2Smckusick };
172*a0212cc2Smckusick
173*a0212cc2Smckusick #define VAX_DBL_BIAS 0x81
174*a0212cc2Smckusick #define IEEE_DBL_BIAS 0x3ff
175*a0212cc2Smckusick #define MASK(nbits) ((1 << nbits) - 1)
176*a0212cc2Smckusick
177*a0212cc2Smckusick static struct dbl_limits {
178*a0212cc2Smckusick struct vax_double d;
179*a0212cc2Smckusick struct ieee_double ieee;
180*a0212cc2Smckusick } dbl_limits[2] = {
181*a0212cc2Smckusick {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
182*a0212cc2Smckusick { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
183*a0212cc2Smckusick {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
184*a0212cc2Smckusick { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
185*a0212cc2Smckusick };
186*a0212cc2Smckusick
187*a0212cc2Smckusick #endif /* vax */
188*a0212cc2Smckusick
189*a0212cc2Smckusick
190*a0212cc2Smckusick bool_t
xdr_double(xdrs,dp)191*a0212cc2Smckusick xdr_double(xdrs, dp)
192*a0212cc2Smckusick register XDR *xdrs;
193*a0212cc2Smckusick double *dp;
194*a0212cc2Smckusick {
195*a0212cc2Smckusick register long *lp;
196*a0212cc2Smckusick #if !defined(mc68000) && !defined(sparc)
197*a0212cc2Smckusick struct ieee_double id;
198*a0212cc2Smckusick struct vax_double vd;
199*a0212cc2Smckusick register struct dbl_limits *lim;
200*a0212cc2Smckusick int i;
201*a0212cc2Smckusick #endif
202*a0212cc2Smckusick
203*a0212cc2Smckusick switch (xdrs->x_op) {
204*a0212cc2Smckusick
205*a0212cc2Smckusick case XDR_ENCODE:
206*a0212cc2Smckusick #if defined(mc68000) || defined(sparc)
207*a0212cc2Smckusick lp = (long *)dp;
208*a0212cc2Smckusick #else
209*a0212cc2Smckusick vd = *((struct vax_double *)dp);
210*a0212cc2Smckusick for (i = 0, lim = dbl_limits;
211*a0212cc2Smckusick i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
212*a0212cc2Smckusick i++, lim++) {
213*a0212cc2Smckusick if ((vd.mantissa4 == lim->d.mantissa4) &&
214*a0212cc2Smckusick (vd.mantissa3 == lim->d.mantissa3) &&
215*a0212cc2Smckusick (vd.mantissa2 == lim->d.mantissa2) &&
216*a0212cc2Smckusick (vd.mantissa1 == lim->d.mantissa1) &&
217*a0212cc2Smckusick (vd.exp == lim->d.exp)) {
218*a0212cc2Smckusick id = lim->ieee;
219*a0212cc2Smckusick goto shipit;
220*a0212cc2Smckusick }
221*a0212cc2Smckusick }
222*a0212cc2Smckusick id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
223*a0212cc2Smckusick id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
224*a0212cc2Smckusick id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
225*a0212cc2Smckusick (vd.mantissa3 << 13) |
226*a0212cc2Smckusick ((vd.mantissa4 >> 3) & MASK(13));
227*a0212cc2Smckusick shipit:
228*a0212cc2Smckusick id.sign = vd.sign;
229*a0212cc2Smckusick lp = (long *)&id;
230*a0212cc2Smckusick #endif
231*a0212cc2Smckusick return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
232*a0212cc2Smckusick
233*a0212cc2Smckusick case XDR_DECODE:
234*a0212cc2Smckusick #if defined(mc68000) || defined(sparc)
235*a0212cc2Smckusick lp = (long *)dp;
236*a0212cc2Smckusick return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
237*a0212cc2Smckusick #else
238*a0212cc2Smckusick lp = (long *)&id;
239*a0212cc2Smckusick if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
240*a0212cc2Smckusick return (FALSE);
241*a0212cc2Smckusick for (i = 0, lim = dbl_limits;
242*a0212cc2Smckusick i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
243*a0212cc2Smckusick i++, lim++) {
244*a0212cc2Smckusick if ((id.mantissa2 == lim->ieee.mantissa2) &&
245*a0212cc2Smckusick (id.mantissa1 == lim->ieee.mantissa1) &&
246*a0212cc2Smckusick (id.exp == lim->ieee.exp)) {
247*a0212cc2Smckusick vd = lim->d;
248*a0212cc2Smckusick goto doneit;
249*a0212cc2Smckusick }
250*a0212cc2Smckusick }
251*a0212cc2Smckusick vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
252*a0212cc2Smckusick vd.mantissa1 = (id.mantissa1 >> 13);
253*a0212cc2Smckusick vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
254*a0212cc2Smckusick (id.mantissa2 >> 29);
255*a0212cc2Smckusick vd.mantissa3 = (id.mantissa2 >> 13);
256*a0212cc2Smckusick vd.mantissa4 = (id.mantissa2 << 3);
257*a0212cc2Smckusick doneit:
258*a0212cc2Smckusick vd.sign = id.sign;
259*a0212cc2Smckusick *dp = *((double *)&vd);
260*a0212cc2Smckusick return (TRUE);
261*a0212cc2Smckusick #endif
262*a0212cc2Smckusick
263*a0212cc2Smckusick case XDR_FREE:
264*a0212cc2Smckusick return (TRUE);
265*a0212cc2Smckusick }
266*a0212cc2Smckusick return (FALSE);
267*a0212cc2Smckusick }
268