xdr_float.c revision 136582
174462Salfred/* $NetBSD: xdr_float.c,v 1.23 2000/07/17 04:59:51 matt Exp $ */ 274462Salfred 31902Swollman/* 41902Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 51902Swollman * unrestricted use provided that this legend is included on all tape 61902Swollman * media and as a part of the software program in whole or part. Users 71902Swollman * may copy or modify Sun RPC without charge, but are not authorized 81902Swollman * to license or distribute it to anyone else except as part of a product or 91902Swollman * program developed by the user. 108870Srgrimes * 111902Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 121902Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 131902Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 148870Srgrimes * 151902Swollman * Sun RPC is provided with no support and without any obligation on the 161902Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 171902Swollman * modification or enhancement. 188870Srgrimes * 191902Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 201902Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 211902Swollman * OR ANY PART THEREOF. 228870Srgrimes * 231902Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 241902Swollman * or profits or other special, indirect and consequential damages, even if 251902Swollman * Sun has been advised of the possibility of such damages. 268870Srgrimes * 271902Swollman * Sun Microsystems, Inc. 281902Swollman * 2550 Garcia Avenue 291902Swollman * Mountain View, California 94043 301902Swollman */ 311902Swollman 321902Swollman#if defined(LIBC_SCCS) && !defined(lint) 33136582Sobrienstatic char *sccsid2 = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; 3474462Salfredstatic char *sccsid = "@(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC"; 351902Swollman#endif 3692986Sobrien#include <sys/cdefs.h> 3792986Sobrien__FBSDID("$FreeBSD: head/lib/libc/xdr/xdr_float.c 136582 2004-10-16 06:32:43Z obrien $"); 381902Swollman 391902Swollman/* 4074462Salfred * xdr_float.c, Generic XDR routines implementation. 411902Swollman * 421902Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 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#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 6521062Speter defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ 66129201Scognet defined(__arm__) || defined(__ppc__) || defined(__ia64__) || \ 67114322Speter defined(__arm26__) || defined(__sparc64__) || defined(__amd64__) 6821062Speter#include <machine/endian.h> 691902Swollman#define IEEEFP 701902Swollman#endif 711902Swollman 7274462Salfred#if defined(__vax__) 731902Swollman 741902Swollman/* What IEEE single precision floating point looks like on a Vax */ 751902Swollmanstruct ieee_single { 761902Swollman unsigned int mantissa: 23; 771902Swollman unsigned int exp : 8; 781902Swollman unsigned int sign : 1; 791902Swollman}; 801902Swollman 811902Swollman/* Vax single precision floating point */ 821902Swollmanstruct vax_single { 831902Swollman unsigned int mantissa1 : 7; 841902Swollman unsigned int exp : 8; 851902Swollman unsigned int sign : 1; 861902Swollman unsigned int mantissa2 : 16; 871902Swollman}; 881902Swollman 891902Swollman#define VAX_SNG_BIAS 0x81 901902Swollman#define IEEE_SNG_BIAS 0x7f 911902Swollman 921902Swollmanstatic struct sgl_limits { 931902Swollman struct vax_single s; 941902Swollman struct ieee_single ieee; 951902Swollman} sgl_limits[2] = { 961902Swollman {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ 971902Swollman { 0x0, 0xff, 0x0 }}, /* Max IEEE */ 981902Swollman {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ 991902Swollman { 0x0, 0x0, 0x0 }} /* Min IEEE */ 1001902Swollman}; 1011902Swollman#endif /* vax */ 1021902Swollman 1031902Swollmanbool_t 1041902Swollmanxdr_float(xdrs, fp) 10574462Salfred XDR *xdrs; 10674462Salfred float *fp; 1071902Swollman{ 10874462Salfred#ifndef IEEEFP 1091902Swollman struct ieee_single is; 1101902Swollman struct vax_single vs, *vsp; 1111902Swollman struct sgl_limits *lim; 1121902Swollman int i; 1131902Swollman#endif 1141902Swollman switch (xdrs->x_op) { 1151902Swollman 1161902Swollman case XDR_ENCODE: 1178870Srgrimes#ifdef IEEEFP 11874462Salfred return (XDR_PUTINT32(xdrs, (int32_t *)fp)); 1191902Swollman#else 1201902Swollman vs = *((struct vax_single *)fp); 1211902Swollman for (i = 0, lim = sgl_limits; 1221902Swollman i < sizeof(sgl_limits)/sizeof(struct sgl_limits); 1231902Swollman i++, lim++) { 1241902Swollman if ((vs.mantissa2 == lim->s.mantissa2) && 1251902Swollman (vs.exp == lim->s.exp) && 1261902Swollman (vs.mantissa1 == lim->s.mantissa1)) { 1271902Swollman is = lim->ieee; 1281902Swollman goto shipit; 1291902Swollman } 1301902Swollman } 1311902Swollman is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; 1321902Swollman is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; 1331902Swollman shipit: 1341902Swollman is.sign = vs.sign; 13574462Salfred return (XDR_PUTINT32(xdrs, (int32_t *)&is)); 1361902Swollman#endif 1371902Swollman 1381902Swollman case XDR_DECODE: 1391902Swollman#ifdef IEEEFP 14074462Salfred return (XDR_GETINT32(xdrs, (int32_t *)fp)); 1411902Swollman#else 1421902Swollman vsp = (struct vax_single *)fp; 14374462Salfred if (!XDR_GETINT32(xdrs, (int32_t *)&is)) 1441902Swollman return (FALSE); 1451902Swollman for (i = 0, lim = sgl_limits; 1461902Swollman i < sizeof(sgl_limits)/sizeof(struct sgl_limits); 1471902Swollman i++, lim++) { 1481902Swollman if ((is.exp == lim->ieee.exp) && 1491902Swollman (is.mantissa == lim->ieee.mantissa)) { 1501902Swollman *vsp = lim->s; 1511902Swollman goto doneit; 1521902Swollman } 1531902Swollman } 1541902Swollman vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; 1551902Swollman vsp->mantissa2 = is.mantissa; 1561902Swollman vsp->mantissa1 = (is.mantissa >> 16); 1571902Swollman doneit: 1581902Swollman vsp->sign = is.sign; 1591902Swollman return (TRUE); 1601902Swollman#endif 1611902Swollman 1621902Swollman case XDR_FREE: 1631902Swollman return (TRUE); 1641902Swollman } 16574462Salfred /* NOTREACHED */ 1661902Swollman return (FALSE); 1671902Swollman} 1681902Swollman 16974462Salfred#if defined(__vax__) 1701902Swollman/* What IEEE double precision floating point looks like on a Vax */ 1711902Swollmanstruct ieee_double { 1721902Swollman unsigned int mantissa1 : 20; 1731902Swollman unsigned int exp : 11; 1741902Swollman unsigned int sign : 1; 1751902Swollman unsigned int mantissa2 : 32; 1761902Swollman}; 1771902Swollman 1781902Swollman/* Vax double precision floating point */ 1791902Swollmanstruct vax_double { 1801902Swollman unsigned int mantissa1 : 7; 1811902Swollman unsigned int exp : 8; 1821902Swollman unsigned int sign : 1; 1831902Swollman unsigned int mantissa2 : 16; 1841902Swollman unsigned int mantissa3 : 16; 1851902Swollman unsigned int mantissa4 : 16; 1861902Swollman}; 1871902Swollman 1881902Swollman#define VAX_DBL_BIAS 0x81 1891902Swollman#define IEEE_DBL_BIAS 0x3ff 1901902Swollman#define MASK(nbits) ((1 << nbits) - 1) 1911902Swollman 1921902Swollmanstatic struct dbl_limits { 1931902Swollman struct vax_double d; 1941902Swollman struct ieee_double ieee; 1951902Swollman} dbl_limits[2] = { 1961902Swollman {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ 1971902Swollman { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ 1981902Swollman {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ 1991902Swollman { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ 2001902Swollman}; 2011902Swollman 2021902Swollman#endif /* vax */ 2031902Swollman 2041902Swollman 2051902Swollmanbool_t 2061902Swollmanxdr_double(xdrs, dp) 20774462Salfred XDR *xdrs; 2081902Swollman double *dp; 2091902Swollman{ 21021062Speter#ifdef IEEEFP 21174462Salfred int32_t *i32p; 21221062Speter bool_t rv; 21321062Speter#else 21474462Salfred int32_t *lp; 2151902Swollman struct ieee_double id; 2161902Swollman struct vax_double vd; 21774462Salfred struct dbl_limits *lim; 2181902Swollman int i; 2191902Swollman#endif 2201902Swollman 2211902Swollman switch (xdrs->x_op) { 2221902Swollman 2231902Swollman case XDR_ENCODE: 2241902Swollman#ifdef IEEEFP 22574462Salfred i32p = (int32_t *)(void *)dp; 2261902Swollman#if BYTE_ORDER == BIG_ENDIAN 22774462Salfred rv = XDR_PUTINT32(xdrs, i32p); 22821062Speter if (!rv) 22921062Speter return (rv); 23074462Salfred rv = XDR_PUTINT32(xdrs, i32p+1); 2311902Swollman#else 23274462Salfred rv = XDR_PUTINT32(xdrs, i32p+1); 23321062Speter if (!rv) 23421062Speter return (rv); 23574462Salfred rv = XDR_PUTINT32(xdrs, i32p); 2361902Swollman#endif 23721062Speter return (rv); 2381902Swollman#else 2391902Swollman vd = *((struct vax_double *)dp); 2401902Swollman for (i = 0, lim = dbl_limits; 2411902Swollman i < sizeof(dbl_limits)/sizeof(struct dbl_limits); 2421902Swollman i++, lim++) { 2431902Swollman if ((vd.mantissa4 == lim->d.mantissa4) && 2441902Swollman (vd.mantissa3 == lim->d.mantissa3) && 2451902Swollman (vd.mantissa2 == lim->d.mantissa2) && 2461902Swollman (vd.mantissa1 == lim->d.mantissa1) && 2471902Swollman (vd.exp == lim->d.exp)) { 2481902Swollman id = lim->ieee; 2491902Swollman goto shipit; 2501902Swollman } 2511902Swollman } 2521902Swollman id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; 2531902Swollman id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); 2541902Swollman id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | 2551902Swollman (vd.mantissa3 << 13) | 2561902Swollman ((vd.mantissa4 >> 3) & MASK(13)); 2571902Swollman shipit: 2581902Swollman id.sign = vd.sign; 25974462Salfred lp = (int32_t *)&id; 26074462Salfred return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp)); 2611902Swollman#endif 2621902Swollman 2631902Swollman case XDR_DECODE: 2641902Swollman#ifdef IEEEFP 26574462Salfred i32p = (int32_t *)(void *)dp; 2661902Swollman#if BYTE_ORDER == BIG_ENDIAN 26774462Salfred rv = XDR_GETINT32(xdrs, i32p); 26821062Speter if (!rv) 26921062Speter return (rv); 27074462Salfred rv = XDR_GETINT32(xdrs, i32p+1); 2711902Swollman#else 27274462Salfred rv = XDR_GETINT32(xdrs, i32p+1); 27321062Speter if (!rv) 27421062Speter return (rv); 27574462Salfred rv = XDR_GETINT32(xdrs, i32p); 2761902Swollman#endif 27721062Speter return (rv); 2781902Swollman#else 27974462Salfred lp = (int32_t *)&id; 28074462Salfred if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp)) 2811902Swollman return (FALSE); 2821902Swollman for (i = 0, lim = dbl_limits; 2831902Swollman i < sizeof(dbl_limits)/sizeof(struct dbl_limits); 2841902Swollman i++, lim++) { 2851902Swollman if ((id.mantissa2 == lim->ieee.mantissa2) && 2861902Swollman (id.mantissa1 == lim->ieee.mantissa1) && 2871902Swollman (id.exp == lim->ieee.exp)) { 2881902Swollman vd = lim->d; 2891902Swollman goto doneit; 2901902Swollman } 2911902Swollman } 2921902Swollman vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; 2931902Swollman vd.mantissa1 = (id.mantissa1 >> 13); 2941902Swollman vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | 2951902Swollman (id.mantissa2 >> 29); 2961902Swollman vd.mantissa3 = (id.mantissa2 >> 13); 2971902Swollman vd.mantissa4 = (id.mantissa2 << 3); 2981902Swollman doneit: 2991902Swollman vd.sign = id.sign; 3001902Swollman *dp = *((double *)&vd); 3011902Swollman return (TRUE); 3021902Swollman#endif 3031902Swollman 3041902Swollman case XDR_FREE: 3051902Swollman return (TRUE); 3061902Swollman } 30774462Salfred /* NOTREACHED */ 3081902Swollman return (FALSE); 3091902Swollman} 310