18360efbdSAlfred Perlstein /* $NetBSD: xdr_float.c,v 1.23 2000/07/17 04:59:51 matt Exp $ */ 28360efbdSAlfred Perlstein 3a204967aSHiroki Sato /*- 4a204967aSHiroki Sato * Copyright (c) 2010, Oracle America, Inc. 5eae561b3SGarrett Wollman * 6a204967aSHiroki Sato * Redistribution and use in source and binary forms, with or without 7a204967aSHiroki Sato * modification, are permitted provided that the following conditions are 8a204967aSHiroki Sato * met: 9eae561b3SGarrett Wollman * 10a204967aSHiroki Sato * * Redistributions of source code must retain the above copyright 11a204967aSHiroki Sato * notice, this list of conditions and the following disclaimer. 12a204967aSHiroki Sato * * Redistributions in binary form must reproduce the above 13a204967aSHiroki Sato * copyright notice, this list of conditions and the following 14a204967aSHiroki Sato * disclaimer in the documentation and/or other materials 15a204967aSHiroki Sato * provided with the distribution. 16a204967aSHiroki Sato * * Neither the name of the "Oracle America, Inc." nor the names of its 17a204967aSHiroki Sato * contributors may be used to endorse or promote products derived 18a204967aSHiroki Sato * from this software without specific prior written permission. 19eae561b3SGarrett Wollman * 20a204967aSHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21a204967aSHiroki Sato * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22a204967aSHiroki Sato * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23a204967aSHiroki Sato * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24a204967aSHiroki Sato * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25a204967aSHiroki Sato * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26a204967aSHiroki Sato * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27a204967aSHiroki Sato * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28a204967aSHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29a204967aSHiroki Sato * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30a204967aSHiroki Sato * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31a204967aSHiroki Sato * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32eae561b3SGarrett Wollman */ 33eae561b3SGarrett Wollman 34eae561b3SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 35a9bdcd37SDavid E. O'Brien static char *sccsid2 = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; 368360efbdSAlfred Perlstein static char *sccsid = "@(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC"; 37eae561b3SGarrett Wollman #endif 38333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 39333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 40eae561b3SGarrett Wollman 41eae561b3SGarrett Wollman /* 428360efbdSAlfred Perlstein * xdr_float.c, Generic XDR routines implementation. 43eae561b3SGarrett Wollman * 44eae561b3SGarrett Wollman * These are the "floating point" xdr routines used to (de)serialize 45eae561b3SGarrett Wollman * most common data items. See xdr.h for more info on the interface to 46eae561b3SGarrett Wollman * xdr. 47eae561b3SGarrett Wollman */ 48eae561b3SGarrett Wollman 498360efbdSAlfred Perlstein #include "namespace.h" 50eae561b3SGarrett Wollman #include <sys/types.h> 51eae561b3SGarrett Wollman #include <sys/param.h> 528360efbdSAlfred Perlstein 538360efbdSAlfred Perlstein #include <stdio.h> 548360efbdSAlfred Perlstein 55eae561b3SGarrett Wollman #include <rpc/types.h> 56eae561b3SGarrett Wollman #include <rpc/xdr.h> 578360efbdSAlfred Perlstein #include "un-namespace.h" 58eae561b3SGarrett Wollman 59eae561b3SGarrett Wollman /* 60eae561b3SGarrett Wollman * NB: Not portable. 611ad08a09SPeter Wemm * This routine works on machines with IEEE754 FP and Vaxen. 62eae561b3SGarrett Wollman */ 63eae561b3SGarrett Wollman 641ad08a09SPeter Wemm #if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 651ad08a09SPeter Wemm defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ 661d7c6c33SOlivier Houchard defined(__arm__) || defined(__ppc__) || defined(__ia64__) || \ 67f7f1bb14SPeter Wemm defined(__arm26__) || defined(__sparc64__) || defined(__amd64__) 681ad08a09SPeter Wemm #include <machine/endian.h> 69eae561b3SGarrett Wollman #define IEEEFP 70eae561b3SGarrett Wollman #endif 71eae561b3SGarrett Wollman 728360efbdSAlfred Perlstein #if defined(__vax__) 73eae561b3SGarrett Wollman 74eae561b3SGarrett Wollman /* What IEEE single precision floating point looks like on a Vax */ 75eae561b3SGarrett Wollman struct ieee_single { 76eae561b3SGarrett Wollman unsigned int mantissa: 23; 77eae561b3SGarrett Wollman unsigned int exp : 8; 78eae561b3SGarrett Wollman unsigned int sign : 1; 79eae561b3SGarrett Wollman }; 80eae561b3SGarrett Wollman 81eae561b3SGarrett Wollman /* Vax single precision floating point */ 82eae561b3SGarrett Wollman struct vax_single { 83eae561b3SGarrett Wollman unsigned int mantissa1 : 7; 84eae561b3SGarrett Wollman unsigned int exp : 8; 85eae561b3SGarrett Wollman unsigned int sign : 1; 86eae561b3SGarrett Wollman unsigned int mantissa2 : 16; 87eae561b3SGarrett Wollman }; 88eae561b3SGarrett Wollman 89eae561b3SGarrett Wollman #define VAX_SNG_BIAS 0x81 90eae561b3SGarrett Wollman #define IEEE_SNG_BIAS 0x7f 91eae561b3SGarrett Wollman 92eae561b3SGarrett Wollman static struct sgl_limits { 93eae561b3SGarrett Wollman struct vax_single s; 94eae561b3SGarrett Wollman struct ieee_single ieee; 95eae561b3SGarrett Wollman } sgl_limits[2] = { 96eae561b3SGarrett Wollman {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ 97eae561b3SGarrett Wollman { 0x0, 0xff, 0x0 }}, /* Max IEEE */ 98eae561b3SGarrett Wollman {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ 99eae561b3SGarrett Wollman { 0x0, 0x0, 0x0 }} /* Min IEEE */ 100eae561b3SGarrett Wollman }; 101eae561b3SGarrett Wollman #endif /* vax */ 102eae561b3SGarrett Wollman 103eae561b3SGarrett Wollman bool_t 104eae561b3SGarrett Wollman xdr_float(xdrs, fp) 1058360efbdSAlfred Perlstein XDR *xdrs; 1068360efbdSAlfred Perlstein float *fp; 107eae561b3SGarrett Wollman { 1088360efbdSAlfred Perlstein #ifndef IEEEFP 109eae561b3SGarrett Wollman struct ieee_single is; 110eae561b3SGarrett Wollman struct vax_single vs, *vsp; 111eae561b3SGarrett Wollman struct sgl_limits *lim; 112eae561b3SGarrett Wollman int i; 113eae561b3SGarrett Wollman #endif 114eae561b3SGarrett Wollman switch (xdrs->x_op) { 115eae561b3SGarrett Wollman 116eae561b3SGarrett Wollman case XDR_ENCODE: 117eae561b3SGarrett Wollman #ifdef IEEEFP 1188360efbdSAlfred Perlstein return (XDR_PUTINT32(xdrs, (int32_t *)fp)); 119eae561b3SGarrett Wollman #else 120eae561b3SGarrett Wollman vs = *((struct vax_single *)fp); 121eae561b3SGarrett Wollman for (i = 0, lim = sgl_limits; 122eae561b3SGarrett Wollman i < sizeof(sgl_limits)/sizeof(struct sgl_limits); 123eae561b3SGarrett Wollman i++, lim++) { 124eae561b3SGarrett Wollman if ((vs.mantissa2 == lim->s.mantissa2) && 125eae561b3SGarrett Wollman (vs.exp == lim->s.exp) && 126eae561b3SGarrett Wollman (vs.mantissa1 == lim->s.mantissa1)) { 127eae561b3SGarrett Wollman is = lim->ieee; 128eae561b3SGarrett Wollman goto shipit; 129eae561b3SGarrett Wollman } 130eae561b3SGarrett Wollman } 131eae561b3SGarrett Wollman is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; 132eae561b3SGarrett Wollman is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; 133eae561b3SGarrett Wollman shipit: 134eae561b3SGarrett Wollman is.sign = vs.sign; 1358360efbdSAlfred Perlstein return (XDR_PUTINT32(xdrs, (int32_t *)&is)); 136eae561b3SGarrett Wollman #endif 137eae561b3SGarrett Wollman 138eae561b3SGarrett Wollman case XDR_DECODE: 139eae561b3SGarrett Wollman #ifdef IEEEFP 1408360efbdSAlfred Perlstein return (XDR_GETINT32(xdrs, (int32_t *)fp)); 141eae561b3SGarrett Wollman #else 142eae561b3SGarrett Wollman vsp = (struct vax_single *)fp; 1438360efbdSAlfred Perlstein if (!XDR_GETINT32(xdrs, (int32_t *)&is)) 144eae561b3SGarrett Wollman return (FALSE); 145eae561b3SGarrett Wollman for (i = 0, lim = sgl_limits; 146eae561b3SGarrett Wollman i < sizeof(sgl_limits)/sizeof(struct sgl_limits); 147eae561b3SGarrett Wollman i++, lim++) { 148eae561b3SGarrett Wollman if ((is.exp == lim->ieee.exp) && 149eae561b3SGarrett Wollman (is.mantissa == lim->ieee.mantissa)) { 150eae561b3SGarrett Wollman *vsp = lim->s; 151eae561b3SGarrett Wollman goto doneit; 152eae561b3SGarrett Wollman } 153eae561b3SGarrett Wollman } 154eae561b3SGarrett Wollman vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; 155eae561b3SGarrett Wollman vsp->mantissa2 = is.mantissa; 156eae561b3SGarrett Wollman vsp->mantissa1 = (is.mantissa >> 16); 157eae561b3SGarrett Wollman doneit: 158eae561b3SGarrett Wollman vsp->sign = is.sign; 159eae561b3SGarrett Wollman return (TRUE); 160eae561b3SGarrett Wollman #endif 161eae561b3SGarrett Wollman 162eae561b3SGarrett Wollman case XDR_FREE: 163eae561b3SGarrett Wollman return (TRUE); 164eae561b3SGarrett Wollman } 1658360efbdSAlfred Perlstein /* NOTREACHED */ 166eae561b3SGarrett Wollman return (FALSE); 167eae561b3SGarrett Wollman } 168eae561b3SGarrett Wollman 1698360efbdSAlfred Perlstein #if defined(__vax__) 170eae561b3SGarrett Wollman /* What IEEE double precision floating point looks like on a Vax */ 171eae561b3SGarrett Wollman struct ieee_double { 172eae561b3SGarrett Wollman unsigned int mantissa1 : 20; 173eae561b3SGarrett Wollman unsigned int exp : 11; 174eae561b3SGarrett Wollman unsigned int sign : 1; 175eae561b3SGarrett Wollman unsigned int mantissa2 : 32; 176eae561b3SGarrett Wollman }; 177eae561b3SGarrett Wollman 178eae561b3SGarrett Wollman /* Vax double precision floating point */ 179eae561b3SGarrett Wollman struct vax_double { 180eae561b3SGarrett Wollman unsigned int mantissa1 : 7; 181eae561b3SGarrett Wollman unsigned int exp : 8; 182eae561b3SGarrett Wollman unsigned int sign : 1; 183eae561b3SGarrett Wollman unsigned int mantissa2 : 16; 184eae561b3SGarrett Wollman unsigned int mantissa3 : 16; 185eae561b3SGarrett Wollman unsigned int mantissa4 : 16; 186eae561b3SGarrett Wollman }; 187eae561b3SGarrett Wollman 188eae561b3SGarrett Wollman #define VAX_DBL_BIAS 0x81 189eae561b3SGarrett Wollman #define IEEE_DBL_BIAS 0x3ff 190eae561b3SGarrett Wollman #define MASK(nbits) ((1 << nbits) - 1) 191eae561b3SGarrett Wollman 192eae561b3SGarrett Wollman static struct dbl_limits { 193eae561b3SGarrett Wollman struct vax_double d; 194eae561b3SGarrett Wollman struct ieee_double ieee; 195eae561b3SGarrett Wollman } dbl_limits[2] = { 196eae561b3SGarrett Wollman {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ 197eae561b3SGarrett Wollman { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ 198eae561b3SGarrett Wollman {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ 199eae561b3SGarrett Wollman { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ 200eae561b3SGarrett Wollman }; 201eae561b3SGarrett Wollman 202eae561b3SGarrett Wollman #endif /* vax */ 203eae561b3SGarrett Wollman 204eae561b3SGarrett Wollman 205eae561b3SGarrett Wollman bool_t 206eae561b3SGarrett Wollman xdr_double(xdrs, dp) 2078360efbdSAlfred Perlstein XDR *xdrs; 208eae561b3SGarrett Wollman double *dp; 209eae561b3SGarrett Wollman { 2101ad08a09SPeter Wemm #ifdef IEEEFP 2118360efbdSAlfred Perlstein int32_t *i32p; 2121ad08a09SPeter Wemm bool_t rv; 2131ad08a09SPeter Wemm #else 2148360efbdSAlfred Perlstein int32_t *lp; 215eae561b3SGarrett Wollman struct ieee_double id; 216eae561b3SGarrett Wollman struct vax_double vd; 2178360efbdSAlfred Perlstein struct dbl_limits *lim; 218eae561b3SGarrett Wollman int i; 219eae561b3SGarrett Wollman #endif 220eae561b3SGarrett Wollman 221eae561b3SGarrett Wollman switch (xdrs->x_op) { 222eae561b3SGarrett Wollman 223eae561b3SGarrett Wollman case XDR_ENCODE: 224eae561b3SGarrett Wollman #ifdef IEEEFP 2258360efbdSAlfred Perlstein i32p = (int32_t *)(void *)dp; 226eae561b3SGarrett Wollman #if BYTE_ORDER == BIG_ENDIAN 2278360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p); 2281ad08a09SPeter Wemm if (!rv) 2291ad08a09SPeter Wemm return (rv); 2308360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p+1); 231eae561b3SGarrett Wollman #else 2328360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p+1); 2331ad08a09SPeter Wemm if (!rv) 2341ad08a09SPeter Wemm return (rv); 2358360efbdSAlfred Perlstein rv = XDR_PUTINT32(xdrs, i32p); 236eae561b3SGarrett Wollman #endif 2371ad08a09SPeter Wemm return (rv); 238eae561b3SGarrett Wollman #else 239eae561b3SGarrett Wollman vd = *((struct vax_double *)dp); 240eae561b3SGarrett Wollman for (i = 0, lim = dbl_limits; 241eae561b3SGarrett Wollman i < sizeof(dbl_limits)/sizeof(struct dbl_limits); 242eae561b3SGarrett Wollman i++, lim++) { 243eae561b3SGarrett Wollman if ((vd.mantissa4 == lim->d.mantissa4) && 244eae561b3SGarrett Wollman (vd.mantissa3 == lim->d.mantissa3) && 245eae561b3SGarrett Wollman (vd.mantissa2 == lim->d.mantissa2) && 246eae561b3SGarrett Wollman (vd.mantissa1 == lim->d.mantissa1) && 247eae561b3SGarrett Wollman (vd.exp == lim->d.exp)) { 248eae561b3SGarrett Wollman id = lim->ieee; 249eae561b3SGarrett Wollman goto shipit; 250eae561b3SGarrett Wollman } 251eae561b3SGarrett Wollman } 252eae561b3SGarrett Wollman id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; 253eae561b3SGarrett Wollman id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); 254eae561b3SGarrett Wollman id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | 255eae561b3SGarrett Wollman (vd.mantissa3 << 13) | 256eae561b3SGarrett Wollman ((vd.mantissa4 >> 3) & MASK(13)); 257eae561b3SGarrett Wollman shipit: 258eae561b3SGarrett Wollman id.sign = vd.sign; 2598360efbdSAlfred Perlstein lp = (int32_t *)&id; 2608360efbdSAlfred Perlstein return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp)); 261eae561b3SGarrett Wollman #endif 262eae561b3SGarrett Wollman 263eae561b3SGarrett Wollman case XDR_DECODE: 264eae561b3SGarrett Wollman #ifdef IEEEFP 2658360efbdSAlfred Perlstein i32p = (int32_t *)(void *)dp; 266eae561b3SGarrett Wollman #if BYTE_ORDER == BIG_ENDIAN 2678360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p); 2681ad08a09SPeter Wemm if (!rv) 2691ad08a09SPeter Wemm return (rv); 2708360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p+1); 271eae561b3SGarrett Wollman #else 2728360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p+1); 2731ad08a09SPeter Wemm if (!rv) 2741ad08a09SPeter Wemm return (rv); 2758360efbdSAlfred Perlstein rv = XDR_GETINT32(xdrs, i32p); 276eae561b3SGarrett Wollman #endif 2771ad08a09SPeter Wemm return (rv); 278eae561b3SGarrett Wollman #else 2798360efbdSAlfred Perlstein lp = (int32_t *)&id; 2808360efbdSAlfred Perlstein if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp)) 281eae561b3SGarrett Wollman return (FALSE); 282eae561b3SGarrett Wollman for (i = 0, lim = dbl_limits; 283eae561b3SGarrett Wollman i < sizeof(dbl_limits)/sizeof(struct dbl_limits); 284eae561b3SGarrett Wollman i++, lim++) { 285eae561b3SGarrett Wollman if ((id.mantissa2 == lim->ieee.mantissa2) && 286eae561b3SGarrett Wollman (id.mantissa1 == lim->ieee.mantissa1) && 287eae561b3SGarrett Wollman (id.exp == lim->ieee.exp)) { 288eae561b3SGarrett Wollman vd = lim->d; 289eae561b3SGarrett Wollman goto doneit; 290eae561b3SGarrett Wollman } 291eae561b3SGarrett Wollman } 292eae561b3SGarrett Wollman vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; 293eae561b3SGarrett Wollman vd.mantissa1 = (id.mantissa1 >> 13); 294eae561b3SGarrett Wollman vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | 295eae561b3SGarrett Wollman (id.mantissa2 >> 29); 296eae561b3SGarrett Wollman vd.mantissa3 = (id.mantissa2 >> 13); 297eae561b3SGarrett Wollman vd.mantissa4 = (id.mantissa2 << 3); 298eae561b3SGarrett Wollman doneit: 299eae561b3SGarrett Wollman vd.sign = id.sign; 300eae561b3SGarrett Wollman *dp = *((double *)&vd); 301eae561b3SGarrett Wollman return (TRUE); 302eae561b3SGarrett Wollman #endif 303eae561b3SGarrett Wollman 304eae561b3SGarrett Wollman case XDR_FREE: 305eae561b3SGarrett Wollman return (TRUE); 306eae561b3SGarrett Wollman } 3078360efbdSAlfred Perlstein /* NOTREACHED */ 308eae561b3SGarrett Wollman return (FALSE); 309eae561b3SGarrett Wollman } 310