1 
2 /*
3  * Copyright (c) 2009, Sun Microsystems, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * - Redistributions of source code must retain the above copyright notice,
9  *   this list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright notice,
11  *   this list of conditions and the following disclaimer in the documentation
12  *   and/or other materials provided with the distribution.
13  * - Neither the name of Sun Microsystems, Inc. nor the names of its
14  *   contributors may be used to endorse or promote products derived
15  *   from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * xdr_float_vax.c, XDR floating point routines for vax.
32  *
33  * Copyright (C) 1984, Sun Microsystems, Inc.
34  *
35  * These are the "floating point" xdr routines used to (de)serialize
36  * most common data items.  See xdr.h for more info on the interface to
37  * xdr.
38  */
39 #define _DEFAULT_SOURCE
40 #ifndef XDR_FLOAT_C
41 #error "Must be included from xdr_float.c"
42 #endif
43 
44 /* What IEEE single precision floating point looks like on a Vax */
45 struct ieee_single
46 {
47   unsigned int mantissa:23;
48   unsigned int exp:8;
49   unsigned int sign:1;
50 };
51 
52 /* Vax single precision floating point */
53 struct vax_single
54 {
55   unsigned int mantissa1:7;
56   unsigned int exp:8;
57   unsigned int sign:1;
58   unsigned int mantissa2:16;
59 };
60 
61 # define VAX_SNG_BIAS   0x81
62 # define IEEE_SNG_BIAS  0x7f
63 
64 /* *INDENT-OFF*
65 */
66 static struct sgl_limits
67 {
68   struct vax_single s;
69   struct ieee_single ieee;
70 } sgl_limits[2] =
71 {
72   {
73     {0x7f, 0xff, 0x0, 0xffff},   /* Max Vax */
74     {0x0, 0xff, 0x0}             /* Max IEEE */
75   },
76   {
77     {0x0, 0x0, 0x0, 0x0},        /* Min Vax */
78     {0x0, 0x0, 0x0}              /* Min IEEE */
79   }
80 };
81 /* *INDENT-ON*
82 */
83 
84 bool_t
xdr_float(XDR * xdrs,float * fp)85 xdr_float (XDR * xdrs,
86        float *fp)
87 {
88   struct ieee_single is;
89   struct vax_single vs, *vsp;
90   struct sgl_limits *lim;
91   int i;
92   switch (xdrs->x_op)
93     {
94 
95     case XDR_ENCODE:
96       vs = *((struct vax_single *) fp);
97       for (i = 0, lim = sgl_limits;
98            i < sizeof (sgl_limits) / sizeof (struct sgl_limits); i++, lim++)
99         {
100           if ((vs.mantissa2 == lim->s.mantissa2) &&
101               (vs.exp == lim->s.exp) && (vs.mantissa1 == lim->s.mantissa1))
102             {
103               is = lim->ieee;
104               goto shipit;
105             }
106         }
107       is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
108       is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
109     shipit:
110       is.sign = vs.sign;
111       return (XDR_PUTINT32 (xdrs, (int32_t *) & is));
112 
113     case XDR_DECODE:
114       vsp = (struct vax_single *) fp;
115       if (!XDR_GETINT32 (xdrs, (int32_t *) & is))
116         return FALSE;
117       for (i = 0, lim = sgl_limits;
118            i < sizeof (sgl_limits) / sizeof (struct sgl_limits); i++, lim++)
119         {
120           if ((is.exp == lim->ieee.exp) &&
121               (is.mantissa == lim->ieee.mantissa))
122             {
123               *vsp = lim->s;
124               goto doneit;
125             }
126         }
127       vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
128       vsp->mantissa2 = is.mantissa;
129       vsp->mantissa1 = (is.mantissa >> 16);
130     doneit:
131       vsp->sign = is.sign;
132       return TRUE;
133 
134     case XDR_FREE:
135       return TRUE;
136     }
137   return FALSE;
138 }
139 
140 #if !defined(_DOUBLE_IS_32BITS)
141 
142 /* What IEEE double precision floating point looks like on a Vax */
143 struct ieee_double
144 {
145   unsigned int mantissa1:20;
146   unsigned int exp:11;
147   unsigned int sign:1;
148   unsigned int mantissa2:32;
149 };
150 
151 /* Vax double precision floating point */
152 struct vax_double
153 {
154   unsigned int mantissa1:7;
155   unsigned int exp:8;
156   unsigned int sign:1;
157   unsigned int mantissa2:16;
158   unsigned int mantissa3:16;
159   unsigned int mantissa4:16;
160 };
161 
162 # define VAX_DBL_BIAS   0x81
163 # define IEEE_DBL_BIAS  0x3ff
164 # define MASK(nbits)    ((1 << nbits) - 1)
165 
166 /* *INDENT-OFF*
167 */
168 static struct dbl_limits
169 {
170   struct vax_double d;
171   struct ieee_double ieee;
172 } dbl_limits[2] =
173 {
174   {
175     {0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff},  /* Max Vax */
176     {0x0, 0x7ff, 0x0, 0x0}                      /* Max IEEE */
177   },
178   {
179     {0x0, 0x0, 0x0, 0x0, 0x0, 0x0},             /* Min Vax */
180     {0x0, 0x0, 0x0, 0x0}                        /* Min IEEE */
181   }
182 };
183 /* *INDENT-ON*
184 */
185 
186 bool_t
xdr_double(XDR * xdrs,double * dp)187 xdr_double (XDR * xdrs,
188 	double *dp)
189 {
190   int32_t *lp;
191   struct ieee_double id;
192   struct vax_double vd;
193   struct dbl_limits *lim;
194   int i;
195 
196   switch (xdrs->x_op)
197     {
198 
199     case XDR_ENCODE:
200       vd = *((struct vax_double *) dp);
201       for (i = 0, lim = dbl_limits;
202            i < sizeof (dbl_limits) / sizeof (struct dbl_limits); i++, lim++)
203         {
204           if ((vd.mantissa4 == lim->d.mantissa4) &&
205               (vd.mantissa3 == lim->d.mantissa3) &&
206               (vd.mantissa2 == lim->d.mantissa2) &&
207               (vd.mantissa1 == lim->d.mantissa1) && (vd.exp == lim->d.exp))
208             {
209               id = lim->ieee;
210               goto shipit;
211             }
212         }
213       id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
214       id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
215       id.mantissa2 = ((vd.mantissa2 & MASK (3)) << 29) |
216         (vd.mantissa3 << 13) | ((vd.mantissa4 >> 3) & MASK (13));
217     shipit:
218       id.sign = vd.sign;
219       lp = (int32_t *) & id;
220       return (XDR_PUTINT32 (xdrs, lp++) && XDR_PUTINT32 (xdrs, lp));
221 
222     case XDR_DECODE:
223       lp = (int32_t *) & id;
224       if (!XDR_GETINT32 (xdrs, lp++) || !XDR_GETINT32 (xdrs, lp))
225         return FALSE;
226       for (i = 0, lim = dbl_limits;
227            i < sizeof (dbl_limits) / sizeof (struct dbl_limits); i++, lim++)
228         {
229           if ((id.mantissa2 == lim->ieee.mantissa2) &&
230               (id.mantissa1 == lim->ieee.mantissa1) &&
231               (id.exp == lim->ieee.exp))
232             {
233               vd = lim->d;
234               goto doneit;
235             }
236         }
237       vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
238       vd.mantissa1 = (id.mantissa1 >> 13);
239       vd.mantissa2 = ((id.mantissa1 & MASK (13)) << 3) | (id.mantissa2 >> 29);
240       vd.mantissa3 = (id.mantissa2 >> 13);
241       vd.mantissa4 = (id.mantissa2 << 3);
242     doneit:
243       vd.sign = id.sign;
244       *dp = *((double *) &vd);
245       return TRUE;
246 
247     case XDR_FREE:
248       return TRUE;
249     }
250   return FALSE;
251 }
252 #endif /* !_DOUBLE_IS_32BITS */
253 
254