aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-04-24 21:19:38 +0000
committerGuy Harris <guy@alum.mit.edu>2002-04-24 21:19:38 +0000
commit7d96eec76b5e0615595b881bc87df50d3d258411 (patch)
tree7988e4fe3dc2c15092ca3a7ee0facd437a7e977a
parent6c12522f42b34467cff3872dcb7f039f4523f474 (diff)
downloadwireshark-7d96eec76b5e0615595b881bc87df50d3d258411.tar.gz
wireshark-7d96eec76b5e0615595b881bc87df50d3d258411.tar.bz2
wireshark-7d96eec76b5e0615595b881bc87df50d3d258411.zip
Use Ashok's IEEE-float-to-long code as the basis for
IEEE-float-to-native-float code, and use that as the basis for IEEE-double-to-native-double code. Use that code on VAXes. Eliminate "ieee-float.h", as we no longer use it; instead, we use the tvbuff routines for extracting IEEE floating-point numbers. svn path=/trunk/; revision=5243
-rw-r--r--Makefile.am3
-rw-r--r--epan/tvbuff.c199
-rw-r--r--ieee-float.h84
3 files changed, 171 insertions, 115 deletions
diff --git a/Makefile.am b/Makefile.am
index 323619221d..cf5b8a3171 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.422 2002/04/18 00:29:16 guy Exp $
+# $Id: Makefile.am,v 1.423 2002/04/24 21:19:37 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -841,7 +841,6 @@ EXTRA_DIST = \
getopt.c \
getopt.h \
idl2eth.sh \
- ieee-float.h \
image/Makefile.nmake \
image/README.image \
image/clist_ascend.xpm \
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index 7a30620ec3..817ab8b9a3 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -9,10 +9,13 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
- * $Id: tvbuff.c,v 1.32 2002/04/12 23:25:24 guy Exp $
+ * $Id: tvbuff.c,v 1.33 2002/04/24 21:19:38 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
*
+ * Code to convert IEEE floating point formats to native floating point
+ * derived from code Copyright (c) Ashok Narayanan, 2000
+ *
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
@@ -1006,6 +1009,152 @@ tvb_get_ntohl(tvbuff_t *tvb, gint offset)
}
/*
+ * Stuff for IEEE float handling on platforms that don't have IEEE
+ * format as the native floating-point format.
+ *
+ * For now, we treat only the VAX as such a platform.
+ *
+ * XXX - other non-IEEE boxes that can run UNIX include some Crays,
+ * and possibly other machines.
+ *
+ * It appears that the official Linux port to System/390 and
+ * zArchitecture uses IEEE format floating point (not a
+ * huge surprise).
+ *
+ * I don't know whether there are any other machines that
+ * could run Ethereal and that don't use IEEE format.
+ * As far as I know, all of the main commercial microprocessor
+ * families on which OSes that support Ethereal can run
+ * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
+ * IA-64, and so on).
+ */
+
+#if defined(vax)
+
+#include <math.h>
+
+/*
+ * Single-precision.
+ */
+#define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
+#define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
+#define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
+
+#define IEEE_SP_SIGN_MASK 0x80000000
+#define IEEE_SP_EXPONENT_MASK 0x7F800000
+#define IEEE_SP_MANTISSA_MASK 0x007FFFFF
+#define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
+
+#define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
+#define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
+#define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
+
+static int
+ieee_float_is_zero(guint32 w)
+{
+ return ((w & ~IEEE_SP_SIGN_MASK) == 0);
+}
+
+static float
+get_ieee_float(guint32 w)
+{
+ long sign;
+ long exponent;
+ long mantissa;
+
+ sign = w & IEEE_SP_SIGN_MASK;
+ exponent = w & IEEE_SP_EXPONENT_MASK;
+ mantissa = w & IEEE_SP_MANTISSA_MASK;
+
+ if (ieee_float_is_zero(w)) {
+ /* number is zero, unnormalized, or not-a-number */
+ return 0.0;
+ }
+#if 0
+ /*
+ * XXX - how to handle this?
+ */
+ if (IEEE_SP_INFINITY == exponent) {
+ /*
+ * number is positive or negative infinity, or a special value
+ */
+ return (sign? MINUS_INFINITY: PLUS_INFINITY);
+ }
+#endif
+
+ exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
+ IEEE_SP_MANTISSA_WIDTH;
+ mantissa |= IEEE_SP_IMPLIED_BIT;
+
+ if (sign)
+ return -mantissa * pow(2, exponent);
+ else
+ return mantissa * pow(2, exponent);
+}
+
+/*
+ * Double-precision.
+ * We assume that if you don't have IEEE floating-point, you have a
+ * compiler that understands 64-bit integral quantities.
+ */
+#define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
+#define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
+#define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
+
+#define IEEE_DP_SIGN_MASK 0x8000000000000000LL
+#define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
+#define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
+#define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
+
+#define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
+#define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
+#define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
+
+static int
+ieee_double_is_zero(guint64 w)
+{
+ return ((w & ~IEEE_SP_SIGN_MASK) == 0);
+}
+
+static double
+get_ieee_double(guint64 w)
+{
+ gint64 sign;
+ gint64 exponent;
+ gint64 mantissa;
+
+ sign = w & IEEE_DP_SIGN_MASK;
+ exponent = w & IEEE_DP_EXPONENT_MASK;
+ mantissa = w & IEEE_DP_MANTISSA_MASK;
+
+ if (ieee_double_is_zero(w)) {
+ /* number is zero, unnormalized, or not-a-number */
+ return 0.0;
+ }
+#if 0
+ /*
+ * XXX - how to handle this?
+ */
+ if (IEEE_DP_INFINITY == exponent) {
+ /*
+ * number is positive or negative infinity, or a special value
+ */
+ return (sign? MINUS_INFINITY: PLUS_INFINITY);
+ }
+#endif
+
+ exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
+ IEEE_DP_MANTISSA_WIDTH;
+ mantissa |= IEEE_DP_IMPLIED_BIT;
+
+ if (sign)
+ return -mantissa * pow(2, exponent);
+ else
+ return mantissa * pow(2, exponent);
+}
+#endif
+
+/*
* Fetches an IEEE single-precision floating-point number, in
* big-endian form, and returns a "float".
*
@@ -1016,23 +1165,8 @@ tvb_get_ntohl(tvbuff_t *tvb, gint offset)
float
tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
{
- /*
- * XXX - other non-IEEE boxes that can run UNIX include some
- * Crays, and possibly other machines.
- *
- * It appears that the official Linux port to System/390 and
- * zArchitecture uses IEEE format floating point (not a
- * huge surprise).
- *
- * I don't know whether there are any other machines that
- * could run Ethereal and that don't use IEEE format.
- * As far as I know, all of the main commercial microprocessor
- * families on which OSes that support Ethereal can run
- * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
- * IA-64, and so on).
- */
#if defined(vax)
-#error "Sorry, you'll have to write code to translate to VAX format"
+ return get_ieee_float(tvb_get_ntohl(tvb, offset));
#else
union {
float f;
@@ -1052,12 +1186,17 @@ double
tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
{
#if defined(vax)
-#error "Sorry, you'll have to write code to translate to VAX format"
+ union {
+ double d;
+ guint32 w[2];
+ guint64 dw;
+ } ieee_fp_union;
#else
union {
double d;
guint32 w[2];
} ieee_fp_union;
+#endif
#ifdef WORDS_BIGENDIAN
ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
@@ -1066,6 +1205,9 @@ tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
#endif
+#if defined(vax)
+ return get_ieee_double(dw);
+#else
return ieee_fp_union.d;
#endif
}
@@ -1108,17 +1250,8 @@ tvb_get_letohl(tvbuff_t *tvb, gint offset)
float
tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
{
- /*
- * XXX - other non-IEEE boxes that can run UNIX include Crays
- * and System/3x0 and zArchitecture, although later S/390
- * and zArchitecture machines also support IEEE floating
- * point; I don't know what the compilers used by Linux
- * for S/390 and zArchitecture use - they might have chosen
- * to support only machines with IEEE format, and used IEEE
- * format to avoid portability headaches.
- */
#if defined(vax)
-#error "Sorry, you'll have to write code to translate to VAX format"
+ return get_ieee_float(tvb_get_letohl(tvb, offset));
#else
union {
float f;
@@ -1138,12 +1271,17 @@ double
tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
{
#if defined(vax)
-#error "Sorry, you'll have to write code to translate to VAX format"
+ union {
+ double d;
+ guint32 w[2];
+ guint64 dw;
+ } ieee_fp_union;
#else
union {
double d;
guint32 w[2];
} ieee_fp_union;
+#endif
#ifdef WORDS_BIGENDIAN
ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
@@ -1152,6 +1290,9 @@ tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
#endif
+#if defined(vax)
+ return get_ieee_double(dw);
+#else
return ieee_fp_union.d;
#endif
}
diff --git a/ieee-float.h b/ieee-float.h
deleted file mode 100644
index 03d1629ddb..0000000000
--- a/ieee-float.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**********************************************************************
- *
- * ieee-float.h
- *
- * Implements simple stuff to convert from IEEE float types
- * to 32-bit longs
- *
- * (C) Ashok Narayanan, 2000
- *
- * $Id: ieee-float.h,v 1.2 2001/02/04 08:21:35 guy Exp $
- *
- * For license details, see the COPYING file with this distribution
- *
- **********************************************************************/
-
-#ifndef IEEE_FLOAT_H
-#define IEEE_FLOAT_H
-
-/* Stuff for IEEE float handling */
-
-#define IEEE_NUMBER_WIDTH 32 /* bits in number */
-#define IEEE_EXP_WIDTH 8 /* bits in exponent */
-#define IEEE_MANTISSA_WIDTH 23 /* IEEE_NUMBER_WIDTH - 1 - IEEE_EXP_WIDTH */
-
-#define IEEE_SIGN_MASK 0x80000000
-#define IEEE_EXPONENT_MASK 0x7F800000
-#define IEEE_MANTISSA_MASK 0x007FFFFF
-#define IEEE_INFINITY IEEE_EXPONENT_MASK
-
-#define IEEE_IMPLIED_BIT (1 << IEEE_MANTISSA_WIDTH)
-#define IEEE_INFINITE ((1 << IEEE_EXP_WIDTH) - 1)
-#define IEEE_BIAS ((1 << (IEEE_EXP_WIDTH - 1)) - 1)
-
-#define MINUS_INFINITY (signed)0x80000000L
-#define PLUS_INFINITY 0x7FFFFFFF
-
-static inline int ieee_float_is_zero (long number)
-{
- return(!(number & ~IEEE_SIGN_MASK));
-}
-
-/*
- * simple conversion: ieee floating point to long
- */
-static long tvb_ieee_to_long (tvbuff_t *tvb, int offset)
-{
- long number;
- long sign;
- long exponent;
- long mantissa;
-
- number = tvb_get_ntohl(tvb, offset);
- sign = number & IEEE_SIGN_MASK;
- exponent = number & IEEE_EXPONENT_MASK;
- mantissa = number & IEEE_MANTISSA_MASK;
-
- if (ieee_float_is_zero(number)) {
- /* number is zero, unnormalized, or not-a-number */
- return 0;
- }
- if (IEEE_INFINITY == exponent) {
- /* number is positive or negative infinity, or a special value */
- return (sign? MINUS_INFINITY: PLUS_INFINITY);
- }
-
- exponent = (exponent >> IEEE_MANTISSA_WIDTH) - IEEE_BIAS;
- if (exponent < 0) {
- /* number is between zero and one */
- return 0;
- }
-
- mantissa |= IEEE_IMPLIED_BIT;
- if (exponent <= IEEE_MANTISSA_WIDTH)
- mantissa >>= IEEE_MANTISSA_WIDTH - exponent;
- else
- mantissa <<= exponent - IEEE_MANTISSA_WIDTH;
-
- if (sign)
- return -mantissa;
- else
- return mantissa;
-}
-
-#endif