parisc: avoid undefined shift in cnv_float.h
The attached change fixes a float conversion problem found running the GCC testsuite with GCC configured with --with-arch=2.0. The actual problem occurs for an exponent value of 63. This is the maximum exponent value that can be passed. This causes a left shift by 32 in the else hunk of the macro. This causes undefined behavior and the wrong value is returned for dresultB. The fix is the check "exponent <= 62". If the exponent is 63, dresultB is set to 0. The patch also optimizes the operation a bit by copying "Sall(sgl_value) << SGL_EXP_LENGTH" to val, so that sgl_value is not modified. Signed-off-by: John David Anglin <dave.anglin@bell.net> Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
parent
d287b8750e
commit
cabd91c3bb
|
@ -347,16 +347,15 @@
|
||||||
Sgl_isinexact_to_fix(sgl_value,exponent)
|
Sgl_isinexact_to_fix(sgl_value,exponent)
|
||||||
|
|
||||||
#define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \
|
#define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \
|
||||||
{Sall(sgl_value) <<= SGL_EXP_LENGTH; /* left-justify */ \
|
{unsigned int val = Sall(sgl_value) << SGL_EXP_LENGTH; \
|
||||||
if (exponent <= 31) { \
|
if (exponent <= 31) { \
|
||||||
Dintp1(dresultA) = 0; \
|
Dintp1(dresultA) = 0; \
|
||||||
Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \
|
Dintp2(dresultB) = val >> (31 - exponent); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent); \
|
Dintp1(dresultA) = val >> (63 - exponent); \
|
||||||
Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31); \
|
Dintp2(dresultB) = exponent <= 62 ? val << (exponent - 31) : 0; \
|
||||||
} \
|
} \
|
||||||
Sall(sgl_value) >>= SGL_EXP_LENGTH; /* return to original */ \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Duint_setzero(dresultA,dresultB) \
|
#define Duint_setzero(dresultA,dresultB) \
|
||||||
|
|
Loading…
Reference in New Issue