summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-11-24 16:47:18 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-11-24 16:47:18 (GMT)
commit6d8dd9c50412803fd3cc3af18c4e618c3b97cec3 (patch)
treee23e841019af738a69c2bf5633bd3a671dd4e3fb
parent2106568c9cf25cc350e688276268465366a50d8f (diff)
downloadhdf5-6d8dd9c50412803fd3cc3af18c4e618c3b97cec3.zip
hdf5-6d8dd9c50412803fd3cc3af18c4e618c3b97cec3.tar.gz
hdf5-6d8dd9c50412803fd3cc3af18c4e618c3b97cec3.tar.bz2
[svn-r7875] Purpose:
Omnibus floating-point bug fix changes Description: There are a number of problems in the floating-point conversion code that were exposed by Ray's recent int<->float checkin: - The 'my_isnan' code in test/dtypes.c was broken and would always return true. The meant that the actual values in the float<->float conversion tests were _never_ checked, hiding the other bugs included in this checkin. - A recent change I made to the type conversion code used "FLT_MIN" instead of "-FLT_MAX" for the most negative 'float' value for the double->float conversion, which meant that any the negative number that was converted from a double to a float would have been mapped to zero, essentially. - A change that Robb appeared to have made ~2.5 years ago to the "generic" float->float conversion routine appears to be incorrect and I've backed it out. - Floating-point conversions on SGI's which converted denormalized values would be mapped to zero instead of being propertly preserved in the new type. This was addressed by an SGI-specific system call to prevent the behavior. Solution: Described above, generally. Platforms tested: FreeBSD 4.9 (sleipnir) h5committest Misc. update: release_docs/RELEASE update forthcoming...
-rwxr-xr-xconfigure192
-rw-r--r--configure.in8
-rw-r--r--src/H5T.c178
-rw-r--r--src/H5Tconv.c21
-rw-r--r--src/H5Tpkg.h7
-rw-r--r--src/H5config.h.in6
-rw-r--r--test/dtypes.c130
7 files changed, 456 insertions, 86 deletions
diff --git a/configure b/configure
index 807e6ca..3933162 100755
--- a/configure
+++ b/configure
@@ -9727,6 +9727,198 @@ fi
done
;;
+ mips*-sgi*-irix*)
+
+for ac_header in sys/fpu.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ egrep -v '^ *\+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+ yes:no )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in get_fpc_csr
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+char (*f) ();
+
+#ifdef F77_DUMMY_MAIN
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ ;;
esac
case "$host_cpu-$host_vendor-$host_os" in
diff --git a/configure.in b/configure.in
index 0ef9848..b53ca00 100644
--- a/configure.in
+++ b/configure.in
@@ -692,6 +692,14 @@ case "$host" in
dnl many problems with including them.
AC_CHECK_HEADERS([sys/sysinfo.h sys/proc.h])
;;
+ mips*-sgi*-irix*)
+ dnl The <sys/fpu.h> is needed on the SGI machines to turn off
+ dnl denormalized floating-point values going to zero. We do *not*
+ dnl attempt to dnl locate these files on other systems because there
+ dnl may be problems with including them.
+ AC_CHECK_HEADERS([sys/fpu.h])
+ AC_CHECK_FUNCS([get_fpc_csr])
+ ;;
esac
dnl ----------------------------------------------------------------------
diff --git a/src/H5T.c b/src/H5T.c
index 0565a4c..e1e463c 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -35,6 +35,11 @@
#include "H5Pprivate.h" /* Property Lists */
#include "H5Tpkg.h" /*data-type functions */
+/* Check for header needed for SGI floating-point code */
+#ifdef H5_HAVE_SYS_FPU_H
+#include <sys/fpu.h>
+#endif /* H5_HAVE_SYS_FPU_H */
+
/* Interface initialization */
static int interface_initialize_g = 0;
#define INTERFACE_INIT H5T_init_interface
@@ -215,6 +220,13 @@ size_t H5T_NATIVE_UINT_LEAST64_ALIGN_g = 0;
size_t H5T_NATIVE_INT_FAST64_ALIGN_g = 0;
size_t H5T_NATIVE_UINT_FAST64_ALIGN_g = 0;
+/* Useful floating-point values for conversion routines */
+/* (+/- Inf for all floating-point types) */
+float H5T_NATIVE_FLOAT_POS_INF_g = 0.0;
+float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0;
+double H5T_NATIVE_DOUBLE_POS_INF_g = 0.0;
+double H5T_NATIVE_DOUBLE_NEG_INF_g = 0.0;
+
/*
* The path database. Each path has a source and destination data type pair
@@ -467,6 +479,165 @@ done:
}
+/*-------------------------------------------------------------------------
+ * Function: H5T_init_inf
+ *
+ * Purpose: Initialize the +/- Infinity floating-poing values for type
+ * conversion.
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 22, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5T_init_inf(void)
+{
+ H5T_t *dst_p; /* Datatype type operate on */
+ H5T_atomic_t *dst; /* Datatype's atomic info */
+ uint8_t *d; /* Pointer to value to set */
+ size_t half_size; /* Half the type size */
+ size_t u; /* Local index value */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5T_init_inf);
+
+ /* Get the float datatype */
+ if (NULL==(dst_p=H5I_object(H5T_NATIVE_FLOAT_g)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
+ dst = &dst_p->u.atomic;
+
+ /* Check that we can re-order the bytes correctly */
+ if (H5T_ORDER_LE!=dst->order && H5T_ORDER_BE!=dst->order)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
+
+ /* +Inf */
+ d=(uint8_t *)&H5T_NATIVE_FLOAT_POS_INF_g;
+ H5T_bit_set (d, dst->u.f.sign, 1, FALSE);
+ H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+
+ /* Swap the bytes if the machine architecture is big-endian */
+ if (H5T_ORDER_BE==dst->order) {
+ half_size = dst_p->size/2;
+ for (u=0; u<half_size; u++) {
+ uint8_t tmp = d[dst_p->size-(u+1)];
+ d[dst_p->size-(u+1)] = d[u];
+ d[u] = tmp;
+ }
+ }
+
+ /* -Inf */
+ d=(uint8_t *)&H5T_NATIVE_FLOAT_NEG_INF_g;
+ H5T_bit_set (d, dst->u.f.sign, 1, TRUE);
+ H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+
+ /* Swap the bytes if the machine architecture is big-endian */
+ if (H5T_ORDER_BE==dst->order) {
+ half_size = dst_p->size/2;
+ for (u=0; u<half_size; u++) {
+ uint8_t tmp = d[dst_p->size-(u+1)];
+ d[dst_p->size-(u+1)] = d[u];
+ d[u] = tmp;
+ }
+ }
+
+ /* Get the double datatype */
+ if (NULL==(dst_p=H5I_object(H5T_NATIVE_DOUBLE_g)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
+ dst = &dst_p->u.atomic;
+
+ /* Check that we can re-order the bytes correctly */
+ if (H5T_ORDER_LE!=dst->order && H5T_ORDER_BE!=dst->order)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
+
+ /* +Inf */
+ d=(uint8_t *)&H5T_NATIVE_DOUBLE_POS_INF_g;
+ H5T_bit_set (d, dst->u.f.sign, 1, FALSE);
+ H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+
+ /* Swap the bytes if the machine architecture is big-endian */
+ if (H5T_ORDER_BE==dst->order) {
+ half_size = dst_p->size/2;
+ for (u=0; u<half_size; u++) {
+ uint8_t tmp = d[dst_p->size-(u+1)];
+ d[dst_p->size-(u+1)] = d[u];
+ d[u] = tmp;
+ }
+ }
+
+ /* -Inf */
+ d=(uint8_t *)&H5T_NATIVE_DOUBLE_NEG_INF_g;
+ H5T_bit_set (d, dst->u.f.sign, 1, TRUE);
+ H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+
+ /* Swap the bytes if the machine architecture is big-endian */
+ if (H5T_ORDER_BE==dst->order) {
+ half_size = dst_p->size/2;
+ for (u=0; u<half_size; u++) {
+ uint8_t tmp = d[dst_p->size-(u+1)];
+ d[dst_p->size-(u+1)] = d[u];
+ d[u] = tmp;
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_init_hw
+ *
+ * Purpose: Perform hardware specific [floating-point] initialization
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, November 24, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5T_init_hw(void)
+{
+#ifdef H5_HAVE_GET_FPC_CSR
+ union fpc_csr csr; /* Union to hold results of floating-point status register query */
+#endif /* H5_HAVE_GET_FPC_CSR */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5T_init_hw);
+
+#ifdef H5_HAVE_GET_FPC_CSR
+ /* [This code is specific to SGI machines] */
+
+ /* Get the floating-point status register */
+ csr.fc_word=get_fpc_csr();
+
+ /* If the "flush denormalized values to zero" flag is set, unset it */
+ if(csr.fc_struct.flush) {
+ csr.fc_struct.flush=0;
+ set_fpc_csr(csr.fc_word);
+ } /* end if */
+#endif /* H5_HAVE_GET_FPC_CSR */
+
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
/*--------------------------------------------------------------------------
NAME
H5T_init_interface -- Initialize interface-specific information
@@ -529,6 +700,10 @@ H5T_init_interface(void)
/* Only 16 (numbered 0-15) are supported in the current file format */
assert(H5T_NCLASSES<16);
+ /* Perform any necessary hardware initializations */
+ if(H5T_init_hw()<0)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface");
+
/*
* Initialize pre-defined native data types from code generated during
* the library configuration by H5detect.
@@ -993,6 +1168,9 @@ H5T_init_interface(void)
*/
status |= H5T_register(H5T_PERS_HARD, "no-op", native_int, native_int, H5T_conv_noop, H5AC_dxpl_id);
+ /* Initialize the +/- Infinity values for floating-point types */
+ status |= H5T_init_inf();
+
if (status<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function(s)");
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 8e40b0a..53f0b29 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -307,9 +307,23 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5T_CONV(H5T_CONV_xX, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
+/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN
+ * when an overflow occurs, use the 'float' infinity values.
+ */
+#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
+ if (*((ST*)S) > (DT)(D_MAX)) { \
+ if (!H5T_overflow_g || (H5T_overflow_g)(src_id, dst_id, S, D)<0) \
+ *((DT*)D) = (H5T_NATIVE_FLOAT_POS_INF_g); \
+ } else if (*((ST*)S) < (D_MIN)) { \
+ if (!H5T_overflow_g || (H5T_overflow_g)(src_id, dst_id, S, D)<0) \
+ *((DT*)D) = (H5T_NATIVE_FLOAT_NEG_INF_g); \
+ } else \
+ *((DT*)D) = (DT)(*((ST*)S)); \
+}
+
#define H5T_CONV_Ff(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
- H5T_CONV(H5T_CONV_Xx, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_Ff, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_xF(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
@@ -3351,6 +3365,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
}
/* Write the exponent */
+#ifdef OLD_WAY
+/* It appears to be incorrect to increment the exponent when the carry is set -QAK */
if (carry) {
expo++;
if (expo>=expo_max) {
@@ -3379,6 +3395,7 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE);
}
}
+#endif /* OLD_WAY */
H5_CHECK_OVERFLOW(expo,hssize_t,hsize_t);
H5T_bit_set_d(d, dst.u.f.epos, dst.u.f.esize, (hsize_t)expo);
@@ -6674,7 +6691,7 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
FUNC_ENTER_NOAPI(H5T_conv_float_double, FAIL);
- H5T_CONV_Ff(DOUBLE, FLOAT, double, float, FLT_MIN, FLT_MAX);
+ H5T_CONV_Ff(DOUBLE, FLOAT, double, float, -FLT_MAX, FLT_MAX);
done:
FUNC_LEAVE_NOAPI(ret_value);
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 9058d90..d87cc2f 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -305,6 +305,13 @@ H5_DLLVAR size_t H5T_NATIVE_UINT_LEAST64_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_INT_FAST64_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_UINT_FAST64_ALIGN_g;
+/* Useful floating-point values for conversion routines */
+/* (+/- Inf for all floating-point types) */
+H5_DLLVAR float H5T_NATIVE_FLOAT_POS_INF_g;
+H5_DLLVAR float H5T_NATIVE_FLOAT_NEG_INF_g;
+H5_DLLVAR double H5T_NATIVE_DOUBLE_POS_INF_g;
+H5_DLLVAR double H5T_NATIVE_DOUBLE_NEG_INF_g;
+
/* Common functions */
H5_DLL herr_t H5T_init_interface(void);
H5_DLL H5T_t *H5T_create(H5T_class_t type, size_t size);
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 20ea728..f2348c4 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -69,6 +69,9 @@
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
+/* Define to 1 if you have the `get_fpc_csr' function. */
+#undef HAVE_GET_FPC_CSR
+
/* Define to 1 if you have the <globus_common.h> header file. */
#undef HAVE_GLOBUS_COMMON_H
@@ -272,6 +275,9 @@
/* Define to 1 if you have the <sys/filio.h> header file. */
#undef HAVE_SYS_FILIO_H
+/* Define to 1 if you have the <sys/fpu.h> header file. */
+#undef HAVE_SYS_FPU_H
+
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
diff --git a/test/dtypes.c b/test/dtypes.c
index 3dc06ba..448115c 100644
--- a/test/dtypes.c
+++ b/test/dtypes.c
@@ -107,8 +107,9 @@ static int num_opaque_conversions_g = 0;
#define aligned_free(M) free((char*)(M)-ALIGNMENT)
void some_dummy_func(float x);
-hbool_t overflows(unsigned char *origin_bits, dtype_t src_dtype,
+static hbool_t overflows(unsigned char *origin_bits, dtype_t src_dtype,
size_t src_size_bytes, size_t dst_num_bits);
+static int my_isnan(dtype_t type, void *val);
/*-------------------------------------------------------------------------
@@ -2971,10 +2972,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_char = (char)(*((unsigned long_long*)aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_UCHAR==dst_type) {
@@ -3028,10 +3026,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
hw_uchar = (unsigned char)(*((unsigned long_long*)
aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_SHORT==dst_type) {
@@ -3084,10 +3079,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
hw_short = (short)(*((unsigned long_long*)aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_USHORT==dst_type) {
@@ -3140,10 +3132,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
hw_ushort = (unsigned short)(*((unsigned long_long*)
aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_INT==dst_type) {
@@ -3195,10 +3184,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_int = (int)(*((unsigned long_long*)aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_UINT==dst_type) {
@@ -3251,10 +3237,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_uint = (unsigned int)(*((unsigned long_long*)aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_LONG==dst_type) {
@@ -3307,10 +3290,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_long = (long int)(*((unsigned long_long*)aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_ULONG==dst_type) {
@@ -3364,10 +3344,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
hw_ulong = (unsigned long)(*((unsigned long_long*)
aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_LLONG==dst_type) {
@@ -3420,10 +3397,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_llong = (long_long)(*((unsigned long_long*)aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
} else if (INT_ULLONG==dst_type) {
@@ -3481,10 +3455,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
hw_ullong = (unsigned long_long)(*((unsigned long_long*)
aligned));
break;
- case FLT_FLOAT:
- case FLT_DOUBLE:
- case FLT_LDOUBLE:
- case OTHER:
+ default:
break;
}
}
@@ -3680,7 +3651,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n",
*((unsigned long_long*)aligned));
break;
- case OTHER:
+ default:
break;
}
@@ -3733,7 +3704,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n",
*((unsigned long_long*)aligned));
break;
- case OTHER:
+ default:
break;
}
@@ -3774,7 +3745,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst)
case INT_ULLONG:
HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)hw));
break;
- case OTHER:
+ default:
break;
}
@@ -4083,7 +4054,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
/*
* Initialize the source buffers to random bits. The `buf' buffer
* will be used for the conversion while the `saved' buffer will be
- * sed for the comparison later.
+ * used for the comparison later.
*/
for (j=0; j<nelmts*src_size; j++) buf[j] = saved[j] = rand();
@@ -4092,11 +4063,9 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
/* Check the results from the library against hardware */
for (j=0; j<nelmts; j++) {
- /* There's a bug in my_isnan. I suspect it'll trigger some failures
- * in float-float tests
- * if(FLT_FLOAT==src_type || FLT_DOUBLE==src_type || FLT_LDOUBLE==src_type)
- * if(my_isnan(src_type, saved+j*src_size))
- * continue;*/
+ if(FLT_FLOAT==src_type || FLT_DOUBLE==src_type || FLT_LDOUBLE==src_type)
+ if(my_isnan(src_type, saved+j*src_size))
+ continue;
if (FLT_FLOAT==dst_type) {
hw = (unsigned char*)&hw_float;
@@ -4146,7 +4115,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_float = (float)(*((unsigned long_long*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (FLT_DOUBLE==dst_type) {
@@ -4198,7 +4167,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(unsigned long_long));
hw_double = (double)(*((unsigned long_long*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (FLT_LDOUBLE==dst_type) {
@@ -4256,7 +4225,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
hw_ldouble = (long double)(*((unsigned long_long*)
aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_CHAR==dst_type) {
@@ -4275,7 +4244,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_char = (char)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_UCHAR==dst_type) {
@@ -4294,7 +4263,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_uchar = (unsigned char)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_SHORT==dst_type) {
@@ -4313,7 +4282,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_short = (short)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_USHORT==dst_type) {
@@ -4332,7 +4301,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_ushort = (unsigned short)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_INT==dst_type) {
@@ -4351,7 +4320,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_int = (int)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_UINT==dst_type) {
@@ -4370,7 +4339,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_uint = (unsigned int)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_LONG==dst_type) {
@@ -4389,7 +4358,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_long = (long)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_ULONG==dst_type) {
@@ -4408,7 +4377,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
sizeof(long double));
hw_ulong = (unsigned long)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_LLONG==dst_type) {
@@ -4426,7 +4395,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
memcpy(aligned, saved+j*sizeof(long double), sizeof(double));
hw_llong = (long long)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
} else if (INT_ULLONG==dst_type) {
@@ -4444,17 +4413,17 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
memcpy(aligned, saved+j*sizeof(long double), sizeof(double));
hw_ullong = (unsigned long long)(*((long double*)aligned));
break;
- case OTHER:
+ default:
break;
}
}
- /* Make certain that there isn't some weird number of destination bits */
- assert(dst_nbits%8==0);
+ /* Make certain that there isn't some weird number of destination bits */
+ assert(dst_nbits%8==0);
- /* Are the two results the same */
- for (k=(dst_size-(dst_nbits/8)); k<dst_size; k++) {
- if (buf[j*dst_size+k]!=hw[k]) break;
+ /* Are the two results the same */
+ for (k=(dst_size-(dst_nbits/8)); k<dst_size; k++) {
+ if (buf[j*dst_size+k]!=hw[k]) break;
}
if (k==dst_size) continue; /*no error*/
@@ -4768,7 +4737,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst)
*
*-------------------------------------------------------------------------
*/
-hbool_t
+static hbool_t
overflows(unsigned char *origin_bits, dtype_t src_dtype, size_t src_size_bytes, size_t dst_num_bits)
{
hbool_t ret_value=FALSE;
@@ -4779,15 +4748,14 @@ overflows(unsigned char *origin_bits, dtype_t src_dtype, size_t src_size_bytes,
memcpy(bits, origin_bits, src_size_bytes);
- if(src_size_bytes==4) {
- frct_digits = 23;
- expt_digits = 8;
- bias = 0x7f;
- } else if(src_size_bytes==8) {
- frct_digits = 52;
- expt_digits = 11;
- bias = 0x3ff;
+ if(src_dtype==FLT_FLOAT) {
+ frct_digits = (FLT_MANT_DIG-1);
+ expt_digits = (sizeof(float)*8)-(frct_digits+1);
+ } else if(src_dtype==FLT_DOUBLE) {
+ frct_digits = (DBL_MANT_DIG-1);
+ expt_digits = (sizeof(double)*8)-(frct_digits+1);
}
+ bias = (1<<(expt_digits-2)) - 1;
/* get exponent */
expt = H5T_bit_get_d(bits, frct_digits, expt_digits) - bias;
@@ -4814,8 +4782,6 @@ overflows(unsigned char *origin_bits, dtype_t src_dtype, size_t src_size_bytes,
if(indx>=dst_num_bits)
ret_value=TRUE;
- free(bits);
-
done:
return ret_value;
}
@@ -4881,12 +4847,8 @@ my_isnan(dtype_t type, void *val)
} else {
return 0;
}
- /* Bug here. Ought to be
- * if (strstr(s, "NaN") || strstr(s, "NAN") || strstr(s, "nan"))
- */
- if (!strstr(s, "NaN") || !strstr(s, "NAN") || !strstr(s, "nan")) {
+ if (strstr(s, "NaN") || strstr(s, "NAN") || strstr(s, "nan"))
retval = 1;
- }
}
return retval;