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