source: rtems-libbsd/freebsd/lib/libc/xdr/xdr_float.c @ a037da6

5-freebsd-12freebsd-9.3
Last change on this file since a037da6 was a037da6, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 9, 2016 at 9:48:16 AM

XDR(3): Port to RTEMS

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