xref: /original-bsd/lib/librpc/rpc/xdr_float.c (revision a0212cc2)
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