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

4.104.114.84.9
Last change on this file since e5c8049 was e5c8049, checked in by Ralf Corsepius <ralf.corsepius@…>, on Sep 23, 2004 at 8:19:27 AM

2004-09-23 Ralf Corsepius <ralf_corsepius@…>

  • librpc/src/xdr/xdr_float.c: Add AVR.
  • Property mode set to 100644
File size: 8.1 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#include <stdio.h>
47#include <sys/types.h>
48#include <sys/param.h>
49#include <rpc/types.h>
50#include <rpc/xdr.h>
51
52/*
53 * NB: Not portable.
54 * This routine works on machines with IEEE754 FP and Vaxen.
55 */
56
57#if defined(__alpha__) || \
58    defined(_AM29K) || \
59    defined(__arm__) || \
60    defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || \
61    defined(__hppa__) || \
62    defined(__i386__) || \
63    defined(__i960__) || \
64    defined(__m68k__) || defined(__mc68000__) || \
65    defined(__mips__) || \
66    defined(__ns32k__) || \
67    defined(__sparc__) || \
68    defined(__ppc__) || defined(__PPC__) || \
69    defined(__sh__) || \
70    defined(__AVR__)
71
72#include <machine/endian.h>
73#if !defined(IEEEFP)
74#define IEEEFP
75#endif
76
77#elif defined(_TMS320C3x) || defined(_TMS320C4x)
78#error "Texas Instruments C3x/C4x Not supported."
79
80#elif defined(vax)
81
82/* What IEEE single precision floating point looks like on a Vax */
83struct  ieee_single {
84        unsigned int    mantissa: 23;
85        unsigned int    exp     : 8;
86        unsigned int    sign    : 1;
87};
88
89/* Vax single precision floating point */
90struct  vax_single {
91        unsigned int    mantissa1 : 7;
92        unsigned int    exp       : 8;
93        unsigned int    sign      : 1;
94        unsigned int    mantissa2 : 16;
95};
96
97#define VAX_SNG_BIAS    0x81
98#define IEEE_SNG_BIAS   0x7f
99
100static struct sgl_limits {
101        struct vax_single s;
102        struct ieee_single ieee;
103} sgl_limits[2] = {
104        {{ 0x7f, 0xff, 0x0, 0xffff },   /* Max Vax */
105        { 0x0, 0xff, 0x0 }},            /* Max IEEE */
106        {{ 0x0, 0x0, 0x0, 0x0 },        /* Min Vax */
107        { 0x0, 0x0, 0x0 }}              /* Min IEEE */
108};
109/* end of vax */
110#else
111#error "xdr_float.c: unknown CPU"
112#endif
113
114
115bool_t
116xdr_float(xdrs, fp)
117        register XDR *xdrs;
118        register float *fp;
119{
120#ifdef IEEEFP
121        bool_t rv;
122        long tmpl;
123#else
124        struct ieee_single is;
125        struct vax_single vs, *vsp;
126        struct sgl_limits *lim;
127        int i;
128#endif
129        switch (xdrs->x_op) {
130
131        case XDR_ENCODE:
132#ifdef IEEEFP
133                tmpl = *(int32_t *)fp;
134                return (XDR_PUTLONG(xdrs, &tmpl));
135#else
136                vs = *((struct vax_single *)fp);
137                for (i = 0, lim = sgl_limits;
138                        i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
139                        i++, lim++) {
140                        if ((vs.mantissa2 == lim->s.mantissa2) &&
141                                (vs.exp == lim->s.exp) &&
142                                (vs.mantissa1 == lim->s.mantissa1)) {
143                                is = lim->ieee;
144                                goto shipit;
145                        }
146                }
147                is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
148                is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
149        shipit:
150                is.sign = vs.sign;
151                return (XDR_PUTLONG(xdrs, (long *)&is));
152#endif
153
154        case XDR_DECODE:
155#ifdef IEEEFP
156                rv = XDR_GETLONG(xdrs, &tmpl);
157                *(int32_t *)fp = tmpl;
158                return (rv);
159#else
160                vsp = (struct vax_single *)fp;
161                if (!XDR_GETLONG(xdrs, (long *)&is))
162                        return (FALSE);
163                for (i = 0, lim = sgl_limits;
164                        i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
165                        i++, lim++) {
166                        if ((is.exp == lim->ieee.exp) &&
167                                (is.mantissa == lim->ieee.mantissa)) {
168                                *vsp = lim->s;
169                                goto doneit;
170                        }
171                }
172                vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
173                vsp->mantissa2 = is.mantissa;
174                vsp->mantissa1 = (is.mantissa >> 16);
175        doneit:
176                vsp->sign = is.sign;
177                return (TRUE);
178#endif
179
180        case XDR_FREE:
181                return (TRUE);
182        }
183        return (FALSE);
184}
185
186#ifdef vax
187/* What IEEE double precision floating point looks like on a Vax */
188struct  ieee_double {
189        unsigned int    mantissa1 : 20;
190        unsigned int    exp       : 11;
191        unsigned int    sign      : 1;
192        unsigned int    mantissa2 : 32;
193};
194
195/* Vax double precision floating point */
196struct  vax_double {
197        unsigned int    mantissa1 : 7;
198        unsigned int    exp       : 8;
199        unsigned int    sign      : 1;
200        unsigned int    mantissa2 : 16;
201        unsigned int    mantissa3 : 16;
202        unsigned int    mantissa4 : 16;
203};
204
205#define VAX_DBL_BIAS    0x81
206#define IEEE_DBL_BIAS   0x3ff
207#define MASK(nbits)     ((1 << nbits) - 1)
208
209static struct dbl_limits {
210        struct  vax_double d;
211        struct  ieee_double ieee;
212} dbl_limits[2] = {
213        {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },   /* Max Vax */
214        { 0x0, 0x7ff, 0x0, 0x0 }},                      /* Max IEEE */
215        {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},               /* Min Vax */
216        { 0x0, 0x0, 0x0, 0x0 }}                         /* Min IEEE */
217};
218
219#endif /* vax */
220
221
222bool_t
223xdr_double(xdrs, dp)
224        register XDR *xdrs;
225        double *dp;
226{
227#ifdef IEEEFP
228        register int32_t *i32p;
229        bool_t rv;
230        long tmpl;
231#else
232        register long *lp;
233        struct  ieee_double id;
234        struct  vax_double vd;
235        register struct dbl_limits *lim;
236        int i;
237#endif
238
239        switch (xdrs->x_op) {
240
241        case XDR_ENCODE:
242#ifdef IEEEFP
243                i32p = (int32_t *)dp;
244#if BYTE_ORDER == BIG_ENDIAN
245                tmpl = *i32p++;
246                rv = XDR_PUTLONG(xdrs, &tmpl);
247                if (!rv)
248                        return (rv);
249                tmpl = *i32p;
250                rv = XDR_PUTLONG(xdrs, &tmpl);
251#else
252                tmpl = *(i32p+1);
253                rv = XDR_PUTLONG(xdrs, &tmpl);
254                if (!rv)
255                        return (rv);
256                tmpl = *i32p;
257                rv = XDR_PUTLONG(xdrs, &tmpl);
258#endif
259                return (rv);
260#else
261                vd = *((struct vax_double *)dp);
262                for (i = 0, lim = dbl_limits;
263                        i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
264                        i++, lim++) {
265                        if ((vd.mantissa4 == lim->d.mantissa4) &&
266                                (vd.mantissa3 == lim->d.mantissa3) &&
267                                (vd.mantissa2 == lim->d.mantissa2) &&
268                                (vd.mantissa1 == lim->d.mantissa1) &&
269                                (vd.exp == lim->d.exp)) {
270                                id = lim->ieee;
271                                goto shipit;
272                        }
273                }
274                id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
275                id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
276                id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
277                                (vd.mantissa3 << 13) |
278                                ((vd.mantissa4 >> 3) & MASK(13));
279        shipit:
280                id.sign = vd.sign;
281                lp = (long *)&id;
282                return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
283#endif
284
285        case XDR_DECODE:
286#ifdef IEEEFP
287                i32p = (int32_t *)dp;
288#if BYTE_ORDER == BIG_ENDIAN
289                rv = XDR_GETLONG(xdrs, &tmpl);
290                *i32p++ = tmpl;
291                if (!rv)
292                        return (rv);
293                rv = XDR_GETLONG(xdrs, &tmpl);
294                *i32p = tmpl;
295#else
296                rv = XDR_GETLONG(xdrs, &tmpl);
297                *(i32p+1) = tmpl;
298                if (!rv)
299                        return (rv);
300                rv = XDR_GETLONG(xdrs, &tmpl);
301                *i32p = tmpl;
302#endif
303                return (rv);
304#else
305                lp = (long *)&id;
306                if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
307                        return (FALSE);
308                for (i = 0, lim = dbl_limits;
309                        i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
310                        i++, lim++) {
311                        if ((id.mantissa2 == lim->ieee.mantissa2) &&
312                                (id.mantissa1 == lim->ieee.mantissa1) &&
313                                (id.exp == lim->ieee.exp)) {
314                                vd = lim->d;
315                                goto doneit;
316                        }
317                }
318                vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
319                vd.mantissa1 = (id.mantissa1 >> 13);
320                vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
321                                (id.mantissa2 >> 29);
322                vd.mantissa3 = (id.mantissa2 >> 13);
323                vd.mantissa4 = (id.mantissa2 << 3);
324        doneit:
325                vd.sign = id.sign;
326                *dp = *((double *)&vd);
327                return (TRUE);
328#endif
329
330        case XDR_FREE:
331                return (TRUE);
332        }
333        return (FALSE);
334}
Note: See TracBrowser for help on using the repository browser.