mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-30 16:41:05 +08:00
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!
This commit is contained in:
parent
125c878e96
commit
fab3a6c9de
47
float.c
47
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;
|
||||
}
|
||||
|
4
nasm.c
4
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"
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user