xdr_float.c revision 21062
11902Swollman/* 21902Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 31902Swollman * unrestricted use provided that this legend is included on all tape 41902Swollman * media and as a part of the software program in whole or part. Users 51902Swollman * may copy or modify Sun RPC without charge, but are not authorized 61902Swollman * to license or distribute it to anyone else except as part of a product or 71902Swollman * program developed by the user. 88870Srgrimes * 91902Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 101902Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 111902Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 128870Srgrimes * 131902Swollman * Sun RPC is provided with no support and without any obligation on the 141902Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 151902Swollman * modification or enhancement. 168870Srgrimes * 171902Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 181902Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 191902Swollman * OR ANY PART THEREOF. 208870Srgrimes * 211902Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 221902Swollman * or profits or other special, indirect and consequential damages, even if 231902Swollman * Sun has been advised of the possibility of such damages. 248870Srgrimes * 251902Swollman * Sun Microsystems, Inc. 261902Swollman * 2550 Garcia Avenue 271902Swollman * Mountain View, California 94043 281902Swollman */ 291902Swollman 301902Swollman#if defined(LIBC_SCCS) && !defined(lint) 311902Swollman/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/ 321902Swollman/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/ 3321062Speterstatic char *rcsid = "$Id: xdr_float.c,v 1.2 1995/05/30 05:42:04 rgrimes Exp $"; 341902Swollman#endif 351902Swollman 361902Swollman/* 371902Swollman * xdr_float.c, Generic XDR routines impelmentation. 381902Swollman * 391902Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 401902Swollman * 411902Swollman * These are the "floating point" xdr routines used to (de)serialize 421902Swollman * most common data items. See xdr.h for more info on the interface to 431902Swollman * xdr. 441902Swollman */ 451902Swollman 461902Swollman#include <stdio.h> 471902Swollman#include <sys/types.h> 481902Swollman#include <sys/param.h> 491902Swollman#include <rpc/types.h> 501902Swollman#include <rpc/xdr.h> 511902Swollman 521902Swollman/* 531902Swollman * NB: Not portable. 5421062Speter * This routine works on machines with IEEE754 FP and Vaxen. 551902Swollman */ 561902Swollman 5721062Speter#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 5821062Speter defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ 5921062Speter defined(__arm32__) || defined(__ppc__) 6021062Speter#include <machine/endian.h> 611902Swollman#define IEEEFP 621902Swollman#endif 631902Swollman 641902Swollman#ifdef vax 651902Swollman 661902Swollman/* What IEEE single precision floating point looks like on a Vax */ 671902Swollmanstruct ieee_single { 681902Swollman unsigned int mantissa: 23; 691902Swollman unsigned int exp : 8; 701902Swollman unsigned int sign : 1; 711902Swollman}; 721902Swollman 731902Swollman/* Vax single precision floating point */ 741902Swollmanstruct vax_single { 751902Swollman unsigned int mantissa1 : 7; 761902Swollman unsigned int exp : 8; 771902Swollman unsigned int sign : 1; 781902Swollman unsigned int mantissa2 : 16; 791902Swollman}; 801902Swollman 811902Swollman#define VAX_SNG_BIAS 0x81 821902Swollman#define IEEE_SNG_BIAS 0x7f 831902Swollman 841902Swollmanstatic struct sgl_limits { 851902Swollman struct vax_single s; 861902Swollman struct ieee_single ieee; 871902Swollman} sgl_limits[2] = { 881902Swollman {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ 891902Swollman { 0x0, 0xff, 0x0 }}, /* Max IEEE */ 901902Swollman {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ 911902Swollman { 0x0, 0x0, 0x0 }} /* Min IEEE */ 921902Swollman}; 931902Swollman#endif /* vax */ 941902Swollman 951902Swollmanbool_t 961902Swollmanxdr_float(xdrs, fp) 971902Swollman register XDR *xdrs; 981902Swollman register float *fp; 991902Swollman{ 10021062Speter#ifdef IEEEFP 10121062Speter bool_t rv; 10221062Speter long tmpl; 10321062Speter#else 1041902Swollman struct ieee_single is; 1051902Swollman struct vax_single vs, *vsp; 1061902Swollman struct sgl_limits *lim; 1071902Swollman int i; 1081902Swollman#endif 1091902Swollman switch (xdrs->x_op) { 1101902Swollman 1111902Swollman case XDR_ENCODE: 1128870Srgrimes#ifdef IEEEFP 11321062Speter tmpl = *(int32_t *)fp; 11421062Speter return (XDR_PUTLONG(xdrs, &tmpl)); 1151902Swollman#else 1161902Swollman vs = *((struct vax_single *)fp); 1171902Swollman for (i = 0, lim = sgl_limits; 1181902Swollman i < sizeof(sgl_limits)/sizeof(struct sgl_limits); 1191902Swollman i++, lim++) { 1201902Swollman if ((vs.mantissa2 == lim->s.mantissa2) && 1211902Swollman (vs.exp == lim->s.exp) && 1221902Swollman (vs.mantissa1 == lim->s.mantissa1)) { 1231902Swollman is = lim->ieee; 1241902Swollman goto shipit; 1251902Swollman } 1261902Swollman } 1271902Swollman is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; 1281902Swollman is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; 1291902Swollman shipit: 1301902Swollman is.sign = vs.sign; 1311902Swollman return (XDR_PUTLONG(xdrs, (long *)&is)); 1321902Swollman#endif 1331902Swollman 1341902Swollman case XDR_DECODE: 1351902Swollman#ifdef IEEEFP 13621062Speter rv = XDR_GETLONG(xdrs, &tmpl); 13721062Speter *(int32_t *)fp = tmpl; 13821062Speter return (rv); 1391902Swollman#else 1401902Swollman vsp = (struct vax_single *)fp; 1411902Swollman if (!XDR_GETLONG(xdrs, (long *)&is)) 1421902Swollman return (FALSE); 1431902Swollman for (i = 0, lim = sgl_limits; 1441902Swollman i < sizeof(sgl_limits)/sizeof(struct sgl_limits); 1451902Swollman i++, lim++) { 1461902Swollman if ((is.exp == lim->ieee.exp) && 1471902Swollman (is.mantissa == lim->ieee.mantissa)) { 1481902Swollman *vsp = lim->s; 1491902Swollman goto doneit; 1501902Swollman } 1511902Swollman } 1521902Swollman vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; 1531902Swollman vsp->mantissa2 = is.mantissa; 1541902Swollman vsp->mantissa1 = (is.mantissa >> 16); 1551902Swollman doneit: 1561902Swollman vsp->sign = is.sign; 1571902Swollman return (TRUE); 1581902Swollman#endif 1591902Swollman 1601902Swollman case XDR_FREE: 1611902Swollman return (TRUE); 1621902Swollman } 1631902Swollman return (FALSE); 1641902Swollman} 1651902Swollman 1661902Swollman#ifdef vax 1671902Swollman/* What IEEE double precision floating point looks like on a Vax */ 1681902Swollmanstruct ieee_double { 1691902Swollman unsigned int mantissa1 : 20; 1701902Swollman unsigned int exp : 11; 1711902Swollman unsigned int sign : 1; 1721902Swollman unsigned int mantissa2 : 32; 1731902Swollman}; 1741902Swollman 1751902Swollman/* Vax double precision floating point */ 1761902Swollmanstruct vax_double { 1771902Swollman unsigned int mantissa1 : 7; 1781902Swollman unsigned int exp : 8; 1791902Swollman unsigned int sign : 1; 1801902Swollman unsigned int mantissa2 : 16; 1811902Swollman unsigned int mantissa3 : 16; 1821902Swollman unsigned int mantissa4 : 16; 1831902Swollman}; 1841902Swollman 1851902Swollman#define VAX_DBL_BIAS 0x81 1861902Swollman#define IEEE_DBL_BIAS 0x3ff 1871902Swollman#define MASK(nbits) ((1 << nbits) - 1) 1881902Swollman 1891902Swollmanstatic struct dbl_limits { 1901902Swollman struct vax_double d; 1911902Swollman struct ieee_double ieee; 1921902Swollman} dbl_limits[2] = { 1931902Swollman {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ 1941902Swollman { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ 1951902Swollman {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ 1961902Swollman { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ 1971902Swollman}; 1981902Swollman 1991902Swollman#endif /* vax */ 2001902Swollman 2011902Swollman 2021902Swollmanbool_t 2031902Swollmanxdr_double(xdrs, dp) 2041902Swollman register XDR *xdrs; 2051902Swollman double *dp; 2061902Swollman{ 20721062Speter#ifdef IEEEFP 20821062Speter register int32_t *i32p; 20921062Speter bool_t rv; 21021062Speter long tmpl; 21121062Speter#else 2121902Swollman register long *lp; 2131902Swollman struct ieee_double id; 2141902Swollman struct vax_double vd; 2151902Swollman register struct dbl_limits *lim; 2161902Swollman int i; 2171902Swollman#endif 2181902Swollman 2191902Swollman switch (xdrs->x_op) { 2201902Swollman 2211902Swollman case XDR_ENCODE: 2221902Swollman#ifdef IEEEFP 22321062Speter i32p = (int32_t *)dp; 2241902Swollman#if BYTE_ORDER == BIG_ENDIAN 22521062Speter tmpl = *i32p++; 22621062Speter rv = XDR_PUTLONG(xdrs, &tmpl); 22721062Speter if (!rv) 22821062Speter return (rv); 22921062Speter tmpl = *i32p; 23021062Speter rv = XDR_PUTLONG(xdrs, &tmpl); 2311902Swollman#else 23221062Speter tmpl = *(i32p+1); 23321062Speter rv = XDR_PUTLONG(xdrs, &tmpl); 23421062Speter if (!rv) 23521062Speter return (rv); 23621062Speter tmpl = *i32p; 23721062Speter rv = XDR_PUTLONG(xdrs, &tmpl); 2381902Swollman#endif 23921062Speter return (rv); 2401902Swollman#else 2411902Swollman vd = *((struct vax_double *)dp); 2421902Swollman for (i = 0, lim = dbl_limits; 2431902Swollman i < sizeof(dbl_limits)/sizeof(struct dbl_limits); 2441902Swollman i++, lim++) { 2451902Swollman if ((vd.mantissa4 == lim->d.mantissa4) && 2461902Swollman (vd.mantissa3 == lim->d.mantissa3) && 2471902Swollman (vd.mantissa2 == lim->d.mantissa2) && 2481902Swollman (vd.mantissa1 == lim->d.mantissa1) && 2491902Swollman (vd.exp == lim->d.exp)) { 2501902Swollman id = lim->ieee; 2511902Swollman goto shipit; 2521902Swollman } 2531902Swollman } 2541902Swollman id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; 2551902Swollman id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); 2561902Swollman id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | 2571902Swollman (vd.mantissa3 << 13) | 2581902Swollman ((vd.mantissa4 >> 3) & MASK(13)); 2591902Swollman shipit: 2601902Swollman id.sign = vd.sign; 2611902Swollman lp = (long *)&id; 2621902Swollman return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); 2631902Swollman#endif 2641902Swollman 2651902Swollman case XDR_DECODE: 2661902Swollman#ifdef IEEEFP 26721062Speter i32p = (int32_t *)dp; 2681902Swollman#if BYTE_ORDER == BIG_ENDIAN 26921062Speter rv = XDR_GETLONG(xdrs, &tmpl); 27021062Speter *i32p++ = tmpl; 27121062Speter if (!rv) 27221062Speter return (rv); 27321062Speter rv = XDR_GETLONG(xdrs, &tmpl); 27421062Speter *i32p = tmpl; 2751902Swollman#else 27621062Speter rv = XDR_GETLONG(xdrs, &tmpl); 27721062Speter *(i32p+1) = tmpl; 27821062Speter if (!rv) 27921062Speter return (rv); 28021062Speter rv = XDR_GETLONG(xdrs, &tmpl); 28121062Speter *i32p = tmpl; 2821902Swollman#endif 28321062Speter return (rv); 2841902Swollman#else 2851902Swollman lp = (long *)&id; 2861902Swollman if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) 2871902Swollman return (FALSE); 2881902Swollman for (i = 0, lim = dbl_limits; 2891902Swollman i < sizeof(dbl_limits)/sizeof(struct dbl_limits); 2901902Swollman i++, lim++) { 2911902Swollman if ((id.mantissa2 == lim->ieee.mantissa2) && 2921902Swollman (id.mantissa1 == lim->ieee.mantissa1) && 2931902Swollman (id.exp == lim->ieee.exp)) { 2941902Swollman vd = lim->d; 2951902Swollman goto doneit; 2961902Swollman } 2971902Swollman } 2981902Swollman vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; 2991902Swollman vd.mantissa1 = (id.mantissa1 >> 13); 3001902Swollman vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | 3011902Swollman (id.mantissa2 >> 29); 3021902Swollman vd.mantissa3 = (id.mantissa2 >> 13); 3031902Swollman vd.mantissa4 = (id.mantissa2 << 3); 3041902Swollman doneit: 3051902Swollman vd.sign = id.sign; 3061902Swollman *dp = *((double *)&vd); 3071902Swollman return (TRUE); 3081902Swollman#endif 3091902Swollman 3101902Swollman case XDR_FREE: 3111902Swollman return (TRUE); 3121902Swollman } 3131902Swollman return (FALSE); 3141902Swollman} 315