summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-10-16 11:48:07 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-10-16 11:48:07 -0700
commitfab3a6c9de9c56f1db7770c7c5e0271e33455ea2 (patch)
treec46a56d27737c008cdd2b8c30edcacf433847379
parent125c878e96b5aeb50ae0c7f68847200262a9340f (diff)
downloadnasm-fab3a6c9de9c56f1db7770c7c5e0271e33455ea2.tar.gz
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!
-rw-r--r--float.c47
-rw-r--r--nasm.c4
-rw-r--r--nasmlib.h2
3 files changed, 40 insertions, 13 deletions
diff --git a/float.c b/float.c
index 92307817..18156efa 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 3045534a..04f41909 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 08a68a5c..30f0065d 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