# HG changeset patch # User Jason King # Date 1302138459 18000 # Node ID b9e92167922a586f5c1b327a87c93ea31df9164d # Parent 70ccb19abd772fd0dc8a6d677e3d1c89926456c9 166 CR6901979 error in xdr_float.c not fixed Reviewed by: garrett@nexenta.com Reviewed by: gwr@nexenta.com Reviewed by: richlowe@richlowe.net Approved by: gwr@nexenta.com diff -r 70ccb19abd77 -r b9e92167922a usr/src/lib/libnsl/rpc/xdr_float.c --- a/usr/src/lib/libnsl/rpc/xdr_float.c Wed Apr 06 07:45:22 2011 -0700 +++ b/usr/src/lib/libnsl/rpc/xdr_float.c Wed Apr 06 20:07:39 2011 -0500 @@ -46,40 +46,26 @@ #include "mt.h" #include #include +#include #include #include +#include -#if defined(_IEEE_754) -static bool_t ieee_float_to_xdr(XDR *, float *); -static bool_t ieee_xdr_to_float(XDR *, float *); -static bool_t ieee_double_to_xdr(XDR *, double *); -static bool_t ieee_xdr_to_double(XDR *, double *); -#define cvt_float_to_xdr ieee_float_to_xdr -#define cvt_xdr_to_float ieee_xdr_to_float -#define cvt_double_to_xdr ieee_double_to_xdr -#define cvt_xdr_to_double ieee_xdr_to_double -#else -#warning No platform specific float and double conversion routines defined -static bool_t def_float_to_xdr(XDR *, float *); -static bool_t def_xdr_to_float(XDR *, float *); -static bool_t def_double_to_xdr(XDR *, double *); -static bool_t def_xdr_to_double(XDR *, double *); -#define cvt_float_to_xdr def_float_to_xdr -#define cvt_xdr_to_float def_xdr_to_float -#define cvt_double_to_xdr def_double_to_xdr -#define cvt_xdr_to_double def_xdr_to_double -#endif +#ifdef _IEEE_754 +/* + * The OTW format is IEEE 754 with big endian ordering. + */ bool_t xdr_float(XDR *xdrs, float *fp) { switch (xdrs->x_op) { case XDR_ENCODE: - return (cvt_float_to_xdr(xdrs, fp)); + return (XDR_PUTINT32(xdrs, (int *)fp)); case XDR_DECODE: - return (cvt_xdr_to_float(xdrs, fp)); + return (XDR_GETINT32(xdrs, (int *)fp)); case XDR_FREE: return (TRUE); @@ -90,13 +76,21 @@ bool_t xdr_double(XDR *xdrs, double *dp) { + int64_t *i64p = (int64_t *)dp; + int64_t val; + bool_t ret; + switch (xdrs->x_op) { case XDR_ENCODE: - return (cvt_double_to_xdr(xdrs, dp)); + val = BE_64(*i64p); + return (XDR_PUTBYTES(xdrs, (char *)&val, sizeof (val))); case XDR_DECODE: - return (cvt_xdr_to_double(xdrs, dp)); + ret = XDR_GETBYTES(xdrs, (char *)dp, sizeof (double)); + if (ret) + *i64p = BE_64(*i64p); + return (ret); case XDR_FREE: return (TRUE); @@ -128,41 +122,12 @@ #endif } -#if defined(_IEEE_754) - -/* - * Over-the-wire format is IEEE, so just copy. Includes CPUs: - * amd64, i386, sparc, sparcv9 - */ - -static bool_t -ieee_float_to_xdr(XDR *xdrs, float *fp) -{ - return (XDR_PUTBYTES(xdrs, (char *)fp, sizeof (float))); -} +#else -static bool_t -ieee_xdr_to_float(XDR *xdrs, float *fp) -{ - return (XDR_GETBYTES(xdrs, (char *)fp, sizeof (float))); -} +#warn No platform specific implementation defined for floats -static bool_t -ieee_double_to_xdr(XDR *xdrs, double *dp) -{ - return (XDR_PUTBYTES(xdrs, (char *)dp, sizeof (double))); -} - -static bool_t -ieee_xdr_to_double(XDR *xdrs, double *dp) -{ - return (XDR_GETBYTES(xdrs, (char *)dp, sizeof (double))); -} - -#else /* !defined (_IEEE_794) */ - -static bool_t -def_float_to_xdr(XDR *xdrs, float *fp) +bool_t +xdr_float(XDR *xdrs, float *fp) { /* * Every machine can do this, its just not very efficient. @@ -174,81 +139,81 @@ int exp = 0; int32_t val; - f = *fp; - if (f == 0) { - val = 0; + switch (xdrs->x_op) { + case XDR_ENCODE: + f = *fp; + if (f == 0) { + val = 0; + return (XDR_PUTINT32(xdrs, &val)); + } + if (f < 0) { + f = 0 - f; + neg = 1; + } + while (f < 1) { + f = f * 2; + --exp; + } + while (f >= 2) { + f = f/2; + ++exp; + } + if ((exp > 128) || (exp < -127)) { + /* over or under flowing ieee exponent */ + return (FALSE); + } + val = neg; + val = val << 8; /* for the exponent */ + val += 127 + exp; /* 127 is the bias */ + val = val << 23; /* for the mantissa */ + val += (int32_t)((f - 1) * 8388608); /* 2 ^ 23 */ return (XDR_PUTINT32(xdrs, &val)); - } - if (f < 0) { - f = 0 - f; - neg = 1; - } - while (f < 1) { - f = f * 2; - --exp; + + case XDR_DECODE: + /* + * It assumes that the decoding machine's float can represent + * any value in the range of + * ieee largest float = (2 ^ 128) * 0x1.fffff + * to + * ieee smallest float = (2 ^ -127) * 0x1.00000 + * In addtion, some rounding errors may occur do to the + * calculations involved. + */ + + if (!XDR_GETINT32(xdrs, (int32_t *)&val)) + return (FALSE); + neg = val & 0x80000000; + exp = (val & 0x7f800000) >> 23; + exp -= 127; /* subtract exponent base */ + f = (val & 0x007fffff) * 0.00000011920928955078125; + /* 2 ^ -23 */ + f++; + + while (exp != 0) { + if (exp < 0) { + f = f/2.0; + ++exp; + } else { + f = f * 2.0; + --exp; + } + } + + if (neg) + f = 0 - f; + + *fp = f; + return (TRUE); + + case XDR_FREE: + return (TRUE); } - while (f >= 2) { - f = f/2; - ++exp; - } - if ((exp > 128) || (exp < -127)) { - /* over or under flowing ieee exponent */ - return (FALSE); - } - val = neg; - val = val << 8; /* for the exponent */ - val += 127 + exp; /* 127 is the bias */ - val = val << 23; /* for the mantissa */ - val += (int32_t)((f - 1) * 8388608); /* 2 ^ 23 */ - return (XDR_PUTINT32(xdrs, &val)); + + return (FALSE); } -static bool_t -def_xdr_to_float(XDR *xdrs, float *fp) -{ - /* - * Every machine can do this, its just not very - * efficient. It assumes that the decoding machine's - * float can represent any value in the range of - * ieee largest float = (2 ^ 128) * 0x1.fffff - * to - * ieee smallest float = (2 ^ -127) * 0x1.00000 - * In addtion, some rounding errors may occur do to the - * calculations involved. - */ - float f; - int neg = 0; - int exp = 0; - int32_t val; - - if (!XDR_GETINT32(xdrs, (int32_t *)&val)) - return (FALSE); - neg = val & 0x80000000; - exp = (val & 0x7f800000) >> 23; - exp -= 127; /* subtract exponent base */ - f = (val & 0x007fffff) * 0.00000011920928955078125; - /* 2 ^ -23 */ - f++; - - while (exp != 0) { - if (exp < 0) { - f = f/2.0; - ++exp; - } else { - f = f * 2.0; - --exp; - } - } - - if (neg) - f = 0 - f; - - *fp = f; - return (TRUE); -} - -static bool_t -def_double_to_xdr(XDR *xdrs, double *dp) +bool_t +xdr_double(XDR *xdrs, double *dp) { /* * Every machine can do this, its just not very efficient. @@ -262,85 +227,90 @@ int exp = 0; int32_t val[2]; - d = *dp; - if (d == 0) { - val[0] = 0; - val[1] = 0; + switch (xdrs->x_op) { + case XDR_ENCODE: + d = *dp; + if (d == 0) { + val[0] = 0; + val[1] = 0; + lp = val; + return (XDR_PUTINT32(xdrs, lp++) && + XDR_PUTINT32(xdrs, lp)); + } + if (d < 0) { + d = 0 - d; + neg = 1; + } + while (d < 1) { + d = d * 2; + --exp; + } + while (d >= 2) { + d = d/2; + ++exp; + } + if ((exp > 1024) || (exp < -1023)) { + /* over or under flowing ieee exponent */ + return (FALSE); + } + val[0] = (neg << 11); /* for the exponent */ + val[0] += 1023 + exp; /* 1023 is the bias */ + val[0] = val[0] << 20; /* for the mantissa */ + val[0] += (int32_t)((d - 1) * 1048576); /* 2 ^ 20 */ + val[1] += (uint32_t)((((d - 1) * 1048576) - val[0]) * + 4294967296); /* 2 ^ 32 */ lp = val; + return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp)); - } - if (d < 0) { - d = 0 - d; - neg = 1; - } - while (d < 1) { - d = d * 2; - --exp; + + case XDR_DECODE: + /* + * It assumes that the decoding machine's + * double can represent any value in the range of + * ieee largest double = (2 ^ 1024) * 0x1.fffffffffffff + * to + * ieee smallest double = (2 ^ -1023) * 0x1.0000000000000 + * In addtion, some rounding errors may occur do to the + * calculations involved. + */ + + lp = val; + if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp)) + return (FALSE); + neg = val[0] & 0x80000000; + exp = (val[0] & 0x7ff00000) >> 20; + exp -= 1023; /* subtract exponent base */ + d = (val[0] & 0x000fffff) * 0.00000095367431640625; + /* 2 ^ -20 */ + d += (val[1] * 0.0000000000000002220446049250313); + /* 2 ^ -52 */ + d++; + while (exp != 0) { + if (exp < 0) { + d = d/2.0; + ++exp; + } else { + d = d * 2.0; + --exp; + } + } + if (neg) + d = 0 - d; + + *dp = d; + return (TRUE); + + case XDR_FREE: + return (TRUE); } - while (d >= 2) { - d = d/2; - ++exp; - } - if ((exp > 1024) || (exp < -1023)) { - /* over or under flowing ieee exponent */ - return (FALSE); - } - val[0] = neg; - val[0] = val[0] << 11; /* for the exponent */ - val[0] += 1023 + exp; /* 1023 is the bias */ - val[0] = val[0] << 20; /* for the mantissa */ - val[0] += (int32_t)((d - 1) * 1048576); /* 2 ^ 20 */ - val[1] += (int32_t)((((d - 1) * 1048576) - val[0]) * 4294967296); - /* 2 ^ 32 */ - lp = val; - return (XDR_PUTINT32(xdrs, lp++) && XDR_PUTINT32(xdrs, lp)); + return (FALSE); } -static bool_t -def_xdr_to_double(XDR *, double *dp) +bool_t +xdr_quadruple(XDR *xdrs, long double *fp) { - /* - * Every machine can do this, its just not very - * efficient. It assumes that the decoding machine's - * double can represent any value in the range of - * ieee largest double = (2 ^ 1024) * 0x1.fffffffffffff - * to - * ieee smallest double = (2 ^ -1023) * 0x1.0000000000000 - * In addtion, some rounding errors may occur do to the - * calculations involved. - */ - int *lp; - double d; - int neg = 0; - int exp = 0; - int32_t val[2]; - - lp = val; - if (!XDR_GETINT32(xdrs, lp++) || !XDR_GETINT32(xdrs, lp)) - return (FALSE); - neg = val[0] & 0x80000000; - exp = (val[0] & 0x7ff00000) >> 20; - exp -= 1023; /* subtract exponent base */ - d = (val[0] & 0x000fffff) * 0.00000095367431640625; - /* 2 ^ -20 */ - d += (val[1] * 0.0000000000000002220446049250313); - /* 2 ^ -52 */ - d++; - while (exp != 0) { - if (exp < 0) { - d = d/2.0; - ++exp; - } else { - d = d * 2.0; - --exp; - } - } - if (neg) - d = 0 - d; - - *dp = d; - return (TRUE); + return (FALSE); } -#endif /* _IEEE_794 */ +#endif /* _IEEE_754 */