source: rtems/cpukit/librpc/src/xdr/xdr_float.c @ 37da47a

4.104.115
Last change on this file since 37da47a was 37da47a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/28/10 at 02:40:16

Add HAVE_CONFIG_H support to let files receive configure defines.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part.  Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
8 *
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12 *
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
16 *
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
20 *
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
24 *
25 * Sun Microsystems, Inc.
26 * 2550 Garcia Avenue
27 * Mountain View, California  94043
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
32/*static char *sccsid = "from: @(#)xdr_float.c  2.1 88/07/29 4.0 RPCSRC";*/
33static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_float.c,v 1.7 1999/08/28 00:02:55 peter Exp $";
34#endif
35
36/*
37 * xdr_float.c, Generic XDR routines impelmentation.
38 *
39 * Copyright (C) 1984, Sun Microsystems, Inc.
40 *
41 * These are the "floating point" xdr routines used to (de)serialize
42 * most common data items.  See xdr.h for more info on the interface to
43 * xdr.
44 */
45
46#ifdef HAVE_CONFIG_H
47#include "config.h"
48#endif
49
50#include <stdio.h>
51#include <sys/types.h>
52#include <sys/param.h>
53#include <rpc/types.h>
54#include <rpc/xdr.h>
55
56/*
57 * NB: Not portable.
58 * This routine works on machines with IEEE754 FP and Vaxen.
59 */
60
61#if defined(__alpha__) || \
62    defined(_AM29K) || \
63    defined(__arm__) || \
64    defined(__H8300__) || defined(__h8300__) || \
65    defined(__hppa__) || \
66    defined(__i386__) || \
67    defined(__lm32__) || \
68    defined(__m68k__) || defined(__mc68000__) || \
69    defined(__mips__) || \
70    defined(__nios2__) || \
71    defined(__ns32k__) || \
72    defined(__sparc__) || \
73    defined(__ppc__) || defined(__PPC__) || \
74    defined(__sh__) || \
75    defined(__AVR__) || \
76    defined(__BFIN__) || \
77    defined(__m32c__) || \
78    defined(__M32R__)
79
80#include <rtems/endian.h>
81#if !defined(IEEEFP)
82#define IEEEFP
83#endif
84
85#elif defined(_TMS320C3x) || defined(_TMS320C4x)
86#error "Texas Instruments C3x/C4x Not supported."
87
88#elif defined(vax)
89
90/* What IEEE single precision floating point looks like on a Vax */
91struct  ieee_single {
92        unsigned int    mantissa: 23;
93        unsigned int    exp     : 8;
94        unsigned int    sign    : 1;
95};
96
97/* Vax single precision floating point */
98struct  vax_single {
99        unsigned int    mantissa1 : 7;
100        unsigned int    exp       : 8;
101        unsigned int    sign      : 1;
102        unsigned int    mantissa2 : 16;
103};
104
105#define VAX_SNG_BIAS    0x81
106#define IEEE_SNG_BIAS   0x7f
107
108static struct sgl_limits {
109        struct vax_single s;
110        struct ieee_single ieee;
111} sgl_limits[2] = {
112        {{ 0x7f, 0xff, 0x0, 0xffff },   /* Max Vax */
113        { 0x0, 0xff, 0x0 }},            /* Max IEEE */
114        {{ 0x0, 0x0, 0x0, 0x0 },        /* Min Vax */
115        { 0x0, 0x0, 0x0 }}              /* Min IEEE */
116};
117/* end of vax */
118#else
119#error "xdr_float.c: unknown CPU"
120#endif
121
122
123bool_t
124xdr_float(
125        register XDR *xdrs,
126        register float *fp)
127{
128#ifdef IEEEFP
129        bool_t rv;
130        long tmpl;
131#else
132        struct ieee_single is;
133        struct vax_single vs, *vsp;
134        struct sgl_limits *lim;
135        int i;
136#endif
137        switch (xdrs->x_op) {
138
139        case XDR_ENCODE:
140#ifdef IEEEFP
141                tmpl = *(int32_t *)fp;
142                return (XDR_PUTLONG(xdrs, &tmpl));
143#else
144                vs = *((struct vax_single *)fp);
145                for (i = 0, lim = sgl_limits;
146                        i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
147                        i++, lim++) {
148                        if ((vs.mantissa2 == lim->s.mantissa2) &&
149                                (vs.exp == lim->s.exp) &&
150                                (vs.mantissa1 == lim->s.mantissa1)) {
151                                is = lim->ieee;
152                                goto shipit;
153                        }
154                }
155                is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
156                is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
157        shipit:
158                is.sign = vs.sign;
159                return (XDR_PUTLONG(xdrs, (long *)&is));
160#endif
161
162        case XDR_DECODE:
163#ifdef IEEEFP
164                rv = XDR_GETLONG(xdrs, &tmpl);
165                *(int32_t *)fp = tmpl;
166                return (rv);
167#else
168                vsp = (struct vax_single *)fp;
169                if (!XDR_GETLONG(xdrs, (long *)&is))
170                        return (FALSE);
171                for (i = 0, lim = sgl_limits;
172                        i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
173                        i++, lim++) {
174                        if ((is.exp == lim->ieee.exp) &&
175                                (is.mantissa == lim->ieee.mantissa)) {
176                                *vsp = lim->s;
177                                goto doneit;
178                        }
179                }
180                vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
181                vsp->mantissa2 = is.mantissa;
182                vsp->mantissa1 = (is.mantissa >> 16);
183        doneit:
184                vsp->sign = is.sign;
185                return (TRUE);
186#endif
187
188        case XDR_FREE:
189                return (TRUE);
190        }
191        return (FALSE);
192}
193
194#ifdef vax
195/* What IEEE double precision floating point looks like on a Vax */
196struct  ieee_double {
197        unsigned int    mantissa1 : 20;
198        unsigned int    exp       : 11;
199        unsigned int    sign      : 1;
200        unsigned int    mantissa2 : 32;
201};
202
203/* Vax double precision floating point */
204struct  vax_double {
205        unsigned int    mantissa1 : 7;
206        unsigned int    exp       : 8;
207        unsigned int    sign      : 1;
208        unsigned int    mantissa2 : 16;
209        unsigned int    mantissa3 : 16;
210        unsigned int    mantissa4 : 16;
211};
212
213#define VAX_DBL_BIAS    0x81
214#define IEEE_DBL_BIAS   0x3ff
215#define MASK(nbits)     ((1 << nbits) - 1)
216
217static struct dbl_limits {
218        struct  vax_double d;
219        struct  ieee_double ieee;
220} dbl_limits[2] = {
221        {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },   /* Max Vax */
222        { 0x0, 0x7ff, 0x0, 0x0 }},                      /* Max IEEE */
223        {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},               /* Min Vax */
224        { 0x0, 0x0, 0x0, 0x0 }}                         /* Min IEEE */
225};
226
227#endif /* vax */
228
229
230bool_t
231xdr_double(
232        register XDR *xdrs,
233        double *dp)
234{
235#ifdef IEEEFP
236        register int32_t *i32p;
237        bool_t rv;
238        long tmpl;
239#else
240        register long *lp;
241        struct  ieee_double id;
242        struct  vax_double vd;
243        register struct dbl_limits *lim;
244        int i;
245#endif
246
247        switch (xdrs->x_op) {
248
249        case XDR_ENCODE:
250#ifdef IEEEFP
251                i32p = (int32_t *)dp;
252#if BYTE_ORDER == BIG_ENDIAN
253                tmpl = *i32p++;
254                rv = XDR_PUTLONG(xdrs, &tmpl);
255                if (!rv)
256                        return (rv);
257                tmpl = *i32p;
258                rv = XDR_PUTLONG(xdrs, &tmpl);
259#else
260                tmpl = *(i32p+1);
261                rv = XDR_PUTLONG(xdrs, &tmpl);
262                if (!rv)
263                        return (rv);
264                tmpl = *i32p;
265                rv = XDR_PUTLONG(xdrs, &tmpl);
266#endif
267                return (rv);
268#else
269                vd = *((struct vax_double *)dp);
270                for (i = 0, lim = dbl_limits;
271                        i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
272                        i++, lim++) {
273                        if ((vd.mantissa4 == lim->d.mantissa4) &&
274                                (vd.mantissa3 == lim->d.mantissa3) &&
275                                (vd.mantissa2 == lim->d.mantissa2) &&
276                                (vd.mantissa1 == lim->d.mantissa1) &&
277                                (vd.exp == lim->d.exp)) {
278                                id = lim->ieee;
279                                goto shipit;
280                        }
281                }
282                id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
283                id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
284                id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
285                                (vd.mantissa3 << 13) |
286                                ((vd.mantissa4 >> 3) & MASK(13));
287        shipit:
288                id.sign = vd.sign;
289                lp = (long *)&id;
290                return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
291#endif
292
293        case XDR_DECODE:
294#ifdef IEEEFP
295                i32p = (int32_t *)dp;
296#if BYTE_ORDER == BIG_ENDIAN
297                rv = XDR_GETLONG(xdrs, &tmpl);
298                *i32p++ = tmpl;
299                if (!rv)
300                        return (rv);
301                rv = XDR_GETLONG(xdrs, &tmpl);
302                *i32p = tmpl;
303#else
304                rv = XDR_GETLONG(xdrs, &tmpl);
305                *(i32p+1) = tmpl;
306                if (!rv)
307                        return (rv);
308                rv = XDR_GETLONG(xdrs, &tmpl);
309                *i32p = tmpl;
310#endif
311                return (rv);
312#else
313                lp = (long *)&id;
314                if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
315                        return (FALSE);
316                for (i = 0, lim = dbl_limits;
317                        i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
318                        i++, lim++) {
319                        if ((id.mantissa2 == lim->ieee.mantissa2) &&
320                                (id.mantissa1 == lim->ieee.mantissa1) &&
321                                (id.exp == lim->ieee.exp)) {
322                                vd = lim->d;
323                                goto doneit;
324                        }
325                }
326                vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
327                vd.mantissa1 = (id.mantissa1 >> 13);
328                vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
329                                (id.mantissa2 >> 29);
330                vd.mantissa3 = (id.mantissa2 >> 13);
331                vd.mantissa4 = (id.mantissa2 << 3);
332        doneit:
333                vd.sign = id.sign;
334                *dp = *((double *)&vd);
335                return (TRUE);
336#endif
337
338        case XDR_FREE:
339                return (TRUE);
340        }
341        return (FALSE);
342}
Note: See TracBrowser for help on using the repository browser.