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

Last change on this file since f47dc8d was f47dc8d, checked in by Hesham Almatary <hesham@…>, on Oct 20, 2017 at 6:05:17 AM

cpukit: librpc - add riscv* to xdr_float.c v3

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