From: H. Peter Anvin Date: Tue, 16 Oct 2007 18:48:07 +0000 (-0700) Subject: Floating-point warning fixes; fix round-to-overflow X-Git-Tag: nasm-2.11.05~1856 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fab3a6c9de9c56f1db7770c7c5e0271e33455ea2;p=platform%2Fupstream%2Fnasm.git Floating-point warning fixes; fix round-to-overflow Actually generate the appropriate floating-point warnings, and only one per assembly, pretty please. Correct the round-to-overflow condition; as written all numbers with a positive exponent were considered overflows! --- diff --git a/float.c b/float.c index 9230781..18156ef 100644 --- a/float.c +++ b/float.c @@ -128,7 +128,8 @@ static bool ieee_flconvert(const char *string, uint16_t * mant, bool started, seendot, warned; p = digits; tenpwr = 0; - started = seendot = warned = false; + started = seendot = false; + warned = (pass0 != 1); while (*string && *string != 'E' && *string != 'e') { if (*string == '.') { if (!seendot) { @@ -541,11 +542,23 @@ static void set_bit(uint16_t *mant, int bit) } /* Test a single bit */ -static int test_bit(uint16_t *mant, int bit) +static int test_bit(const uint16_t *mant, int bit) { return (mant[bit >> 4] >> (~bit & 15)) & 1; } +/* Report if the mantissa value is all zero */ +static bool is_zero(const uint16_t *mant) +{ + int i; + + for (i = 0; i < MANT_WORDS; i++) + if (mant[i]) + return false; + + return true; +} + /* Produce standard IEEE formats, with implicit or explicit integer bit; this makes the following assumptions: @@ -643,11 +656,15 @@ static int to_float(const char *str, int sign, uint8_t * result, exponent >= 2 - expmax - fmt->mantissa) { type = FL_DENORMAL; } else if (exponent > 0) { - error(ERR_WARNING|ERR_WARN_FL_OVERFLOW, - "overflow in floating-point constant"); + if (pass0 == 1) + error(ERR_WARNING|ERR_WARN_FL_OVERFLOW, + "overflow in floating-point constant"); type = FL_INFINITY; } else { /* underflow */ + if (pass0 == 1) + error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW, + "underflow in floating-point constant"); type = FL_ZERO; } } else { @@ -674,9 +691,18 @@ static int to_float(const char *str, int sign, uint8_t * result, if (!fmt->explicit) mant[one_pos] &= ~one_mask; /* remove explicit one */ mant[0] |= exponent << (15 - fmt->exponent); - } else if (daz) { - /* Flush denormals to zero */ - goto zero; + } else { + if (daz || is_zero(mant)) { + /* Flush denormals to zero */ + if (pass0 == 1) + error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW, + "underflow in floating-point constant"); + goto zero; + } else { + if (pass0 == 1) + error(ERR_WARNING|ERR_WARN_FL_DENORM, + "denormal floating-point constant"); + } } break; } @@ -689,9 +715,10 @@ static int to_float(const char *str, int sign, uint8_t * result, if (test_bit(mant, fmt->exponent+fmt->explicit-1)) { ieee_shr(mant, 1); exponent++; - if (exponent >= expmax) { - error(ERR_WARNING|ERR_WARN_FL_OVERFLOW, - "overflow in floating-point constant"); + if (exponent >= (expmax << 1)-1) { + if (pass0 == 1) + error(ERR_WARNING|ERR_WARN_FL_OVERFLOW, + "overflow in floating-point constant"); type = FL_INFINITY; goto overflow; } diff --git a/nasm.c b/nasm.c index 3045534..04f4190 100644 --- a/nasm.c +++ b/nasm.c @@ -116,11 +116,11 @@ static const char *suppressed_what[1 + ERR_WARN_MAX] = { "cyclic macro self-references", "labels alone on lines without trailing `:'", "numeric constants do not fit in 32 bits", - "using 8- or 16-bit relocation in ELF32, a GNU extension" + "using 8- or 16-bit relocation in ELF32, a GNU extension", "floating point overflow", "floating point denormal", "floating point underflow", - "too many digits in floating-point number", + "too many digits in floating-point number" }; /* diff --git a/nasmlib.h b/nasmlib.h index 08a68a5..30f0065 100644 --- a/nasmlib.h +++ b/nasmlib.h @@ -73,7 +73,7 @@ typedef void (*efunc) (int severity, const char *fmt, ...); #define ERR_WARN_FL_DENORM WARN(7) /* FP denormal */ #define ERR_WARN_FL_UNDERFLOW WARN(8) /* FP underflow */ #define ERR_WARN_FL_TOOLONG WARN(9) /* FP too many digits */ -#define ERR_WARN_MAX 8 /* the highest numbered one */ +#define ERR_WARN_MAX 9 /* the highest numbered one */ /* * Wrappers around malloc, realloc and free. nasm_malloc will