xdr_float.c revision 298120
174462Salfred/* $NetBSD: xdr_float.c,v 1.23 2000/07/17 04:59:51 matt Exp $ */ 274462Salfred 3259118Shrs/*- 4259118Shrs * Copyright (c) 2010, Oracle America, Inc. 58870Srgrimes * 6259118Shrs * Redistribution and use in source and binary forms, with or without 7259118Shrs * modification, are permitted provided that the following conditions are 8259118Shrs * met: 98870Srgrimes * 10259118Shrs * * Redistributions of source code must retain the above copyright 11259118Shrs * notice, this list of conditions and the following disclaimer. 12259118Shrs * * Redistributions in binary form must reproduce the above 13259118Shrs * copyright notice, this list of conditions and the following 14259118Shrs * disclaimer in the documentation and/or other materials 15259118Shrs * provided with the distribution. 16259118Shrs * * Neither the name of the "Oracle America, Inc." nor the names of its 17259118Shrs * contributors may be used to endorse or promote products derived 18259118Shrs * from this software without specific prior written permission. 198870Srgrimes * 20259118Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21259118Shrs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22259118Shrs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23259118Shrs * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24259118Shrs * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25259118Shrs * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26259118Shrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27259118Shrs * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28259118Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29259118Shrs * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30259118Shrs * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31259118Shrs * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321902Swollman */ 331902Swollman 341902Swollman#if defined(LIBC_SCCS) && !defined(lint) 35136582Sobrienstatic char *sccsid2 = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; 3674462Salfredstatic char *sccsid = "@(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC"; 371902Swollman#endif 3892986Sobrien#include <sys/cdefs.h> 3992986Sobrien__FBSDID("$FreeBSD: head/lib/libc/xdr/xdr_float.c 298120 2016-04-16 17:52:00Z pfg $"); 401902Swollman 411902Swollman/* 4274462Salfred * xdr_float.c, Generic XDR routines implementation. 431902Swollman * 441902Swollman * These are the "floating point" xdr routines used to (de)serialize 451902Swollman * most common data items. See xdr.h for more info on the interface to 461902Swollman * xdr. 471902Swollman */ 481902Swollman 4974462Salfred#include "namespace.h" 501902Swollman#include <sys/types.h> 511902Swollman#include <sys/param.h> 5274462Salfred 5374462Salfred#include <stdio.h> 5474462Salfred 551902Swollman#include <rpc/types.h> 561902Swollman#include <rpc/xdr.h> 5774462Salfred#include "un-namespace.h" 581902Swollman 591902Swollman/* 601902Swollman * NB: Not portable. 6121062Speter * This routine works on machines with IEEE754 FP and Vaxen. 621902Swollman */ 631902Swollman 6421062Speter#include <machine/endian.h> 651902Swollman#define IEEEFP 661902Swollman 6774462Salfred#if defined(__vax__) 681902Swollman 691902Swollman/* What IEEE single precision floating point looks like on a Vax */ 701902Swollmanstruct ieee_single { 711902Swollman unsigned int mantissa: 23; 721902Swollman unsigned int exp : 8; 731902Swollman unsigned int sign : 1; 741902Swollman}; 751902Swollman 761902Swollman/* Vax single precision floating point */ 771902Swollmanstruct vax_single { 781902Swollman unsigned int mantissa1 : 7; 791902Swollman unsigned int exp : 8; 801902Swollman unsigned int sign : 1; 811902Swollman unsigned int mantissa2 : 16; 821902Swollman}; 831902Swollman 841902Swollman#define VAX_SNG_BIAS 0x81 851902Swollman#define IEEE_SNG_BIAS 0x7f 861902Swollman 871902Swollmanstatic struct sgl_limits { 881902Swollman struct vax_single s; 891902Swollman struct ieee_single ieee; 901902Swollman} sgl_limits[2] = { 911902Swollman {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ 921902Swollman { 0x0, 0xff, 0x0 }}, /* Max IEEE */ 931902Swollman {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ 941902Swollman { 0x0, 0x0, 0x0 }} /* Min IEEE */ 951902Swollman}; 961902Swollman#endif /* vax */ 971902Swollman 981902Swollmanbool_t 99288040Srodrigcxdr_float(XDR *xdrs, float *fp) 1001902Swollman{ 10174462Salfred#ifndef IEEEFP 1021902Swollman struct ieee_single is; 1031902Swollman struct vax_single vs, *vsp; 1041902Swollman struct sgl_limits *lim; 1051902Swollman int i; 1061902Swollman#endif 1071902Swollman switch (xdrs->x_op) { 1081902Swollman 1091902Swollman case XDR_ENCODE: 1108870Srgrimes#ifdef IEEEFP 11174462Salfred return (XDR_PUTINT32(xdrs, (int32_t *)fp)); 1121902Swollman#else 1131902Swollman vs = *((struct vax_single *)fp); 114298120Spfg for (i = 0, lim = sgl_limits; i < nitems(sgl_limits); 115298120Spfg i++, lim++) { 1161902Swollman if ((vs.mantissa2 == lim->s.mantissa2) && 1171902Swollman (vs.exp == lim->s.exp) && 1181902Swollman (vs.mantissa1 == lim->s.mantissa1)) { 1191902Swollman is = lim->ieee; 1201902Swollman goto shipit; 1211902Swollman } 1221902Swollman } 1231902Swollman is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; 1241902Swollman is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; 1251902Swollman shipit: 1261902Swollman is.sign = vs.sign; 12774462Salfred return (XDR_PUTINT32(xdrs, (int32_t *)&is)); 1281902Swollman#endif 1291902Swollman 1301902Swollman case XDR_DECODE: 1311902Swollman#ifdef IEEEFP 13274462Salfred return (XDR_GETINT32(xdrs, (int32_t *)fp)); 1331902Swollman#else 1341902Swollman vsp = (struct vax_single *)fp; 13574462Salfred if (!XDR_GETINT32(xdrs, (int32_t *)&is)) 1361902Swollman return (FALSE); 137298120Spfg for (i = 0, lim = sgl_limits; i < nitems(sgl_limits); 138298120Spfg i++, lim++) { 1391902Swollman if ((is.exp == lim->ieee.exp) && 1401902Swollman (is.mantissa == lim->ieee.mantissa)) { 1411902Swollman *vsp = lim->s; 1421902Swollman goto doneit; 1431902Swollman } 1441902Swollman } 1451902Swollman vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; 1461902Swollman vsp->mantissa2 = is.mantissa; 1471902Swollman vsp->mantissa1 = (is.mantissa >> 16); 1481902Swollman doneit: 1491902Swollman vsp->sign = is.sign; 1501902Swollman return (TRUE); 1511902Swollman#endif 1521902Swollman 1531902Swollman case XDR_FREE: 1541902Swollman return (TRUE); 1551902Swollman } 15674462Salfred /* NOTREACHED */ 1571902Swollman return (FALSE); 1581902Swollman} 1591902Swollman 16074462Salfred#if defined(__vax__) 1611902Swollman/* What IEEE double precision floating point looks like on a Vax */ 1621902Swollmanstruct ieee_double { 1631902Swollman unsigned int mantissa1 : 20; 1641902Swollman unsigned int exp : 11; 1651902Swollman unsigned int sign : 1; 1661902Swollman unsigned int mantissa2 : 32; 1671902Swollman}; 1681902Swollman 1691902Swollman/* Vax double precision floating point */ 1701902Swollmanstruct vax_double { 1711902Swollman unsigned int mantissa1 : 7; 1721902Swollman unsigned int exp : 8; 1731902Swollman unsigned int sign : 1; 1741902Swollman unsigned int mantissa2 : 16; 1751902Swollman unsigned int mantissa3 : 16; 1761902Swollman unsigned int mantissa4 : 16; 1771902Swollman}; 1781902Swollman 1791902Swollman#define VAX_DBL_BIAS 0x81 1801902Swollman#define IEEE_DBL_BIAS 0x3ff 1811902Swollman#define MASK(nbits) ((1 << nbits) - 1) 1821902Swollman 1831902Swollmanstatic struct dbl_limits { 1841902Swollman struct vax_double d; 1851902Swollman struct ieee_double ieee; 1861902Swollman} dbl_limits[2] = { 1871902Swollman {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ 1881902Swollman { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ 1891902Swollman {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ 1901902Swollman { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ 1911902Swollman}; 1921902Swollman 1931902Swollman#endif /* vax */ 1941902Swollman 1951902Swollman 1961902Swollmanbool_t 197283833Srodrigcxdr_double(XDR *xdrs, double *dp) 1981902Swollman{ 19921062Speter#ifdef IEEEFP 20074462Salfred int32_t *i32p; 20121062Speter bool_t rv; 20221062Speter#else 20374462Salfred int32_t *lp; 2041902Swollman struct ieee_double id; 2051902Swollman struct vax_double vd; 20674462Salfred struct dbl_limits *lim; 2071902Swollman int i; 2081902Swollman#endif 2091902Swollman 2101902Swollman switch (xdrs->x_op) { 2111902Swollman 2121902Swollman case XDR_ENCODE: 2131902Swollman#ifdef IEEEFP 21474462Salfred i32p = (int32_t *)(void *)dp; 2151902Swollman#if BYTE_ORDER == BIG_ENDIAN 21674462Salfred rv = XDR_PUTINT32(xdrs, i32p); 21721062Speter if (!rv) 21821062Speter return (rv); 21974462Salfred rv = XDR_PUTINT32(xdrs, i32p+1); 2201902Swollman#else 22174462Salfred rv = XDR_PUTINT32(xdrs, i32p+1); 22221062Speter if (!rv) 22321062Speter return (rv); 22474462Salfred rv = XDR_PUTINT32(xdrs, i32p); 2251902Swollman#endif 22621062Speter return (rv); 2271902Swollman#else 2281902Swollman vd = *((struct vax_double *)dp); 229298120Spfg for (i = 0, lim = dbl_limits; i < nitems(dbl_limits); 230298120Spfg i++, lim++) { 2311902Swollman if ((vd.mantissa4 == lim->d.mantissa4) && 2321902Swollman (vd.mantissa3 == lim->d.mantissa3) && 2331902Swollman (vd.mantissa2 == lim->d.mantissa2) && 2341902Swollman (vd.mantissa1 == lim->d.mantissa1) && 2351902Swollman (vd.exp == lim->d.exp)) { 2361902Swollman id = lim->ieee; 2371902Swollman goto shipit; 2381902Swollman } 2391902Swollman } 2401902Swollman id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; 2411902Swollman id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); 2421902Swollman id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | 2431902Swollman (vd.mantissa3 << 13) | 2441902Swollman ((vd.mantissa4 >> 3) & MASK(13)); 2451902Swollman shipit: 2461902Swollman id.sign = vd.sign; 24774462Salfred lp = (int32_t *)&id; 24874462Salfred return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp)); 2491902Swollman#endif 2501902Swollman 2511902Swollman case XDR_DECODE: 2521902Swollman#ifdef IEEEFP 25374462Salfred i32p = (int32_t *)(void *)dp; 2541902Swollman#if BYTE_ORDER == BIG_ENDIAN 25574462Salfred rv = XDR_GETINT32(xdrs, i32p); 25621062Speter if (!rv) 25721062Speter return (rv); 25874462Salfred rv = XDR_GETINT32(xdrs, i32p+1); 2591902Swollman#else 26074462Salfred rv = XDR_GETINT32(xdrs, i32p+1); 26121062Speter if (!rv) 26221062Speter return (rv); 26374462Salfred rv = XDR_GETINT32(xdrs, i32p); 2641902Swollman#endif 26521062Speter return (rv); 2661902Swollman#else 26774462Salfred lp = (int32_t *)&id; 26874462Salfred if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp)) 2691902Swollman return (FALSE); 270298120Spfg for (i = 0, lim = dbl_limits; i < nitems(dbl_limits); 271298120Spfg i++, lim++) { 2721902Swollman if ((id.mantissa2 == lim->ieee.mantissa2) && 2731902Swollman (id.mantissa1 == lim->ieee.mantissa1) && 2741902Swollman (id.exp == lim->ieee.exp)) { 2751902Swollman vd = lim->d; 2761902Swollman goto doneit; 2771902Swollman } 2781902Swollman } 2791902Swollman vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; 2801902Swollman vd.mantissa1 = (id.mantissa1 >> 13); 2811902Swollman vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | 2821902Swollman (id.mantissa2 >> 29); 2831902Swollman vd.mantissa3 = (id.mantissa2 >> 13); 2841902Swollman vd.mantissa4 = (id.mantissa2 << 3); 2851902Swollman doneit: 2861902Swollman vd.sign = id.sign; 2871902Swollman *dp = *((double *)&vd); 2881902Swollman return (TRUE); 2891902Swollman#endif 2901902Swollman 2911902Swollman case XDR_FREE: 2921902Swollman return (TRUE); 2931902Swollman } 29474462Salfred /* NOTREACHED */ 2951902Swollman return (FALSE); 2961902Swollman} 297