AC_REQUIRE_AUX_FILE([tap-driver.sh])
AC_PROG_CC
-AM_PROG_CC_C_O
+AC_PROG_CC_C99
AC_PROG_LIBTOOL
AC_PROG_AWK
+if test "x$ac_cv_prog_cc_c99" = "xno"; then
+ AC_MSG_ERROR([Could not enable C99 support in compiler.])
+fi
+
AM_CFLAGS="-Wall -Werror"
AM_CPPFLAGS="-I\$(abs_top_srcdir)/include"
#include <stdio.h>
typedef union {
- union {
- uint64_t bits;
- double value;
- };
+ uint64_t bits;
+ double value;
} fp64_t;
int
fp80_sgn(fp80_t fp80)
{
- return (fp80.u.repr.se & FP80_SIGN_BIT) ? -1 : 1;
+ return (fp80.repr.se & FP80_SIGN_BIT) ? -1 : 1;
}
int
int
fp80_isqnani(fp80_t fp80)
{
- const uint64_t frac_low = fp80.u.repr.fi & (FP80_FRAC_MASK >> 1);
+ const uint64_t frac_low = fp80.repr.fi & (FP80_FRAC_MASK >> 1);
- return fp80_isqnan(fp80) && (fp80.u.repr.se & FP80_SIGN_BIT) && !frac_low;
+ return fp80_isqnan(fp80) && (fp80.repr.se & FP80_SIGN_BIT) && !frac_low;
}
int
int
fp80_iszero(fp80_t fp80)
{
- return fp80.u.repr.fi == 0 && FP80_EXP(fp80) == 0 ? fp80_sgn(fp80) : 0;
+ return fp80.repr.fi == 0 && FP80_EXP(fp80) == 0 ? fp80_sgn(fp80) : 0;
}
int
double
fp80_cvtd(fp80_t fp80)
{
- const int sign = fp80.u.repr.se & FP80_SIGN_BIT;
+ const int sign = fp80.repr.se & FP80_SIGN_BIT;
if (!fp80_isspecial(fp80)) {
- const uint64_t frac = fp80.u.repr.fi;
+ const uint64_t frac = fp80.repr.fi;
const int unb_exp = FP80_EXP(fp80) - FP80_EXP_BIAS;
const int fp64_exp = unb_exp + FP64_EXP_BIAS;
const uint64_t fp64_frac = frac >> (FP80_FRAC_BITS - FP64_FRAC_BITS);
fp80_debug_dump(FILE *fout, fp80_t fp80)
{
fprintf(fout, "sgn: %i, int: %i, frac: 0x%llx, exp: 0x%x (%i)\n",
- fp80_sgn(fp80), !!(fp80.u.repr.fi & FP80_INT_BIT), FP80_FRAC(fp80),
+ fp80_sgn(fp80), !!(fp80.repr.fi & FP80_INT_BIT), FP80_FRAC(fp80),
FP80_EXP(fp80), FP80_EXP(fp80) - FP80_EXP_BIAS);
}
#define BUILD_FP80(sign, frac, exp) \
{ \
- .u.repr.se = BUILD_FP80_SE(sign, exp), \
- .u.repr.fi = BUILD_FP80_FI(frac, exp) \
+ .repr.se = BUILD_FP80_SE(sign, exp), \
+ .repr.fi = BUILD_FP80_FI(frac, exp) \
}
#define FP80_FRAC(fp80) \
- (fp80.u.repr.fi & FP80_FRAC_MASK)
+ (fp80.repr.fi & FP80_FRAC_MASK)
#define FP80_EXP(fp80) \
- (fp80.u.repr.se & FP80_EXP_MASK)
+ (fp80.repr.se & FP80_EXP_MASK)
#define FP64_FRAC(fp64) \
(fp64.bits & FP64_FRAC_MASK)
*/
/** Internal representation of an 80-bit float. */
-typedef struct {
- union {
- char bits[10];
- struct {
- uint64_t fi;
- uint16_t se;
- } repr;
- } u;
+typedef union {
+ char bits[10];
+ struct {
+ uint64_t fi;
+ uint16_t se;
+ } repr;
} fp80_t;
/** Constant representing +inf */
#include <stdio.h>
#include <stdlib.h>
+/* We provide our own version of isinf_sgn since the C99 standard
+ * doesn't guarantee that isinf() returns the sign of the infinity
+ * (most implementations do). */
+static inline int
+isinf_sgn(double x)
+{
+ return isinf(x) ? (signbit(x) ? -1 : 1) : 0;
+}
+
static void
test_fp80_cvtd_class(const char *name, fp80_t fin, int class)
{
}
static void
-test_fp80_cvtd_inf(const char *name, fp80_t fin, int inf_class)
+test_fp80_cvtd_inf(const char *name, fp80_t fin, int expected_inf_class)
{
double d = fp80_cvtd(fin);
- if (isinf(d) != inf_class) {
+ if (isinf_sgn(d) != expected_inf_class) {
test_diag("wrong infinity type");
test_fail(name);
} else {