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

5
Last change on this file was bb80d9d, checked in by Sebastian Huber <sebastian.huber@…>, on Aug 9, 2018 at 12:02:09 PM

Update to FreeBSD head 2017-12-01

Git mirror commit e724f51f811a4b2bd29447f8b85ab5c2f9b88266.

Update #3472.

  • Property mode set to 100644
File size: 7.6 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 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 * Copyright (c) 2010, Oracle America, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met:
13 *
14 *     * Redistributions of source code must retain the above copyright
15 *       notice, this list of conditions and the following disclaimer.
16 *     * Redistributions in binary form must reproduce the above
17 *       copyright notice, this list of conditions and the following
18 *       disclaimer in the documentation and/or other materials
19 *       provided with the distribution.
20 *     * Neither the name of the "Oracle America, Inc." nor the names of its
21 *       contributors may be used to endorse or promote products derived
22 *       from this software without specific prior written permission.
23 *
24 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#if defined(LIBC_SCCS) && !defined(lint)
39static char *sccsid2 = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
40static char *sccsid = "@(#)xdr_float.c  2.1 88/07/29 4.0 RPCSRC";
41#endif
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD$");
44
45/*
46 * xdr_float.c, Generic XDR routines implementation.
47 *
48 * These are the "floating point" xdr routines used to (de)serialize
49 * most common data items.  See xdr.h for more info on the interface to
50 * xdr.
51 */
52
53#include "namespace.h"
54#include <sys/param.h>
55
56#include <stdio.h>
57
58#include <rpc/types.h>
59#include <rpc/xdr.h>
60#include "un-namespace.h"
61
62/*
63 * NB: Not portable.
64 * This routine works on machines with IEEE754 FP and Vaxen.
65 */
66
67#include <machine/endian.h>
68#define IEEEFP
69
70#if defined(__vax__)
71
72/* What IEEE single precision floating point looks like on a Vax */
73struct  ieee_single {
74        unsigned int    mantissa: 23;
75        unsigned int    exp     : 8;
76        unsigned int    sign    : 1;
77};
78
79/* Vax single precision floating point */
80struct  vax_single {
81        unsigned int    mantissa1 : 7;
82        unsigned int    exp       : 8;
83        unsigned int    sign      : 1;
84        unsigned int    mantissa2 : 16;
85};
86
87#define VAX_SNG_BIAS    0x81
88#define IEEE_SNG_BIAS   0x7f
89
90static struct sgl_limits {
91        struct vax_single s;
92        struct ieee_single ieee;
93} sgl_limits[2] = {
94        {{ 0x7f, 0xff, 0x0, 0xffff },   /* Max Vax */
95        { 0x0, 0xff, 0x0 }},            /* Max IEEE */
96        {{ 0x0, 0x0, 0x0, 0x0 },        /* Min Vax */
97        { 0x0, 0x0, 0x0 }}              /* Min IEEE */
98};
99#endif /* vax */
100
101bool_t
102xdr_float(XDR *xdrs, float *fp)
103{
104#ifndef IEEEFP
105        struct ieee_single is;
106        struct vax_single vs, *vsp;
107        struct sgl_limits *lim;
108        u_int i;
109#endif
110        switch (xdrs->x_op) {
111
112        case XDR_ENCODE:
113#ifdef IEEEFP
114                return (XDR_PUTINT32(xdrs, (int32_t *)fp));
115#else
116                vs = *((struct vax_single *)fp);
117                for (i = 0, lim = sgl_limits; i < nitems(sgl_limits);
118                    i++, lim++) {
119                        if ((vs.mantissa2 == lim->s.mantissa2) &&
120                                (vs.exp == lim->s.exp) &&
121                                (vs.mantissa1 == lim->s.mantissa1)) {
122                                is = lim->ieee;
123                                goto shipit;
124                        }
125                }
126                is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
127                is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
128        shipit:
129                is.sign = vs.sign;
130                return (XDR_PUTINT32(xdrs, (int32_t *)&is));
131#endif
132
133        case XDR_DECODE:
134#ifdef IEEEFP
135                return (XDR_GETINT32(xdrs, (int32_t *)fp));
136#else
137                vsp = (struct vax_single *)fp;
138                if (!XDR_GETINT32(xdrs, (int32_t *)&is))
139                        return (FALSE);
140                for (i = 0, lim = sgl_limits; i < nitems(sgl_limits);
141                    i++, lim++) {
142                        if ((is.exp == lim->ieee.exp) &&
143                                (is.mantissa == lim->ieee.mantissa)) {
144                                *vsp = lim->s;
145                                goto doneit;
146                        }
147                }
148                vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
149                vsp->mantissa2 = is.mantissa;
150                vsp->mantissa1 = (is.mantissa >> 16);
151        doneit:
152                vsp->sign = is.sign;
153                return (TRUE);
154#endif
155
156        case XDR_FREE:
157                return (TRUE);
158        }
159        /* NOTREACHED */
160        return (FALSE);
161}
162
163#if defined(__vax__)
164/* What IEEE double precision floating point looks like on a Vax */
165struct  ieee_double {
166        unsigned int    mantissa1 : 20;
167        unsigned int    exp       : 11;
168        unsigned int    sign      : 1;
169        unsigned int    mantissa2 : 32;
170};
171
172/* Vax double precision floating point */
173struct  vax_double {
174        unsigned int    mantissa1 : 7;
175        unsigned int    exp       : 8;
176        unsigned int    sign      : 1;
177        unsigned int    mantissa2 : 16;
178        unsigned int    mantissa3 : 16;
179        unsigned int    mantissa4 : 16;
180};
181
182#define VAX_DBL_BIAS    0x81
183#define IEEE_DBL_BIAS   0x3ff
184#define MASK(nbits)     ((1 << nbits) - 1)
185
186static struct dbl_limits {
187        struct  vax_double d;
188        struct  ieee_double ieee;
189} dbl_limits[2] = {
190        {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },   /* Max Vax */
191        { 0x0, 0x7ff, 0x0, 0x0 }},                      /* Max IEEE */
192        {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},               /* Min Vax */
193        { 0x0, 0x0, 0x0, 0x0 }}                         /* Min IEEE */
194};
195
196#endif /* vax */
197
198
199bool_t
200xdr_double(XDR *xdrs, double *dp)
201{
202#ifdef IEEEFP
203        int32_t *i32p;
204        bool_t rv;
205#else
206        int32_t *lp;
207        struct  ieee_double id;
208        struct  vax_double vd;
209        struct dbl_limits *lim;
210        u_int i;
211#endif
212
213        switch (xdrs->x_op) {
214
215        case XDR_ENCODE:
216#ifdef IEEEFP
217                i32p = (int32_t *)(void *)dp;
218#if BYTE_ORDER == BIG_ENDIAN
219                rv = XDR_PUTINT32(xdrs, i32p);
220                if (!rv)
221                        return (rv);
222                rv = XDR_PUTINT32(xdrs, i32p+1);
223#else
224                rv = XDR_PUTINT32(xdrs, i32p+1);
225                if (!rv)
226                        return (rv);
227                rv = XDR_PUTINT32(xdrs, i32p);
228#endif
229                return (rv);
230#else
231                vd = *((struct vax_double *)dp);
232                for (i = 0, lim = dbl_limits; i < nitems(dbl_limits);
233                    i++, lim++) {
234                        if ((vd.mantissa4 == lim->d.mantissa4) &&
235                                (vd.mantissa3 == lim->d.mantissa3) &&
236                                (vd.mantissa2 == lim->d.mantissa2) &&
237                                (vd.mantissa1 == lim->d.mantissa1) &&
238                                (vd.exp == lim->d.exp)) {
239                                id = lim->ieee;
240                                goto shipit;
241                        }
242                }
243                id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
244                id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
245                id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
246                                (vd.mantissa3 << 13) |
247                                ((vd.mantissa4 >> 3) & MASK(13));
248        shipit:
249                id.sign = vd.sign;
250                lp = (int32_t *)&id;
251                return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp));
252#endif
253
254        case XDR_DECODE:
255#ifdef IEEEFP
256                i32p = (int32_t *)(void *)dp;
257#if BYTE_ORDER == BIG_ENDIAN
258                rv = XDR_GETINT32(xdrs, i32p);
259                if (!rv)
260                        return (rv);
261                rv = XDR_GETINT32(xdrs, i32p+1);
262#else
263                rv = XDR_GETINT32(xdrs, i32p+1);
264                if (!rv)
265                        return (rv);
266                rv = XDR_GETINT32(xdrs, i32p);
267#endif
268                return (rv);
269#else
270                lp = (int32_t *)&id;
271                if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp))
272                        return (FALSE);
273                for (i = 0, lim = dbl_limits; i < nitems(dbl_limits);
274                    i++, lim++) {
275                        if ((id.mantissa2 == lim->ieee.mantissa2) &&
276                                (id.mantissa1 == lim->ieee.mantissa1) &&
277                                (id.exp == lim->ieee.exp)) {
278                                vd = lim->d;
279                                goto doneit;
280                        }
281                }
282                vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
283                vd.mantissa1 = (id.mantissa1 >> 13);
284                vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
285                                (id.mantissa2 >> 29);
286                vd.mantissa3 = (id.mantissa2 >> 13);
287                vd.mantissa4 = (id.mantissa2 << 3);
288        doneit:
289                vd.sign = id.sign;
290                *dp = *((double *)&vd);
291                return (TRUE);
292#endif
293
294        case XDR_FREE:
295                return (TRUE);
296        }
297        /* NOTREACHED */
298        return (FALSE);
299}
Note: See TracBrowser for help on using the repository browser.