diff options
author | John David Anglin <dave.anglin@bell.net> | 2012-04-01 12:57:18 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2013-01-07 17:06:22 -0500 |
commit | cabd91c3bb74a5bc43c3192126af752891d11d77 (patch) | |
tree | 96be8d73cfe3a5228ecfee947d5dc6b2498503e8 /arch/parisc/math-emu | |
parent | d287b8750e47c1702dab0e37ac11012bb751ece0 (diff) |
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>
Diffstat (limited to 'arch/parisc/math-emu')
-rw-r--r-- | arch/parisc/math-emu/cnv_float.h | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/arch/parisc/math-emu/cnv_float.h b/arch/parisc/math-emu/cnv_float.h index 9071e093164a..933423fa5144 100644 --- a/arch/parisc/math-emu/cnv_float.h +++ b/arch/parisc/math-emu/cnv_float.h | |||
@@ -347,16 +347,15 @@ | |||
347 | Sgl_isinexact_to_fix(sgl_value,exponent) | 347 | Sgl_isinexact_to_fix(sgl_value,exponent) |
348 | 348 | ||
349 | #define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \ | 349 | #define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \ |
350 | {Sall(sgl_value) <<= SGL_EXP_LENGTH; /* left-justify */ \ | 350 | {unsigned int val = Sall(sgl_value) << SGL_EXP_LENGTH; \ |
351 | if (exponent <= 31) { \ | 351 | if (exponent <= 31) { \ |
352 | Dintp1(dresultA) = 0; \ | 352 | Dintp1(dresultA) = 0; \ |
353 | Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \ | 353 | Dintp2(dresultB) = val >> (31 - exponent); \ |
354 | } \ | 354 | } \ |
355 | else { \ | 355 | else { \ |
356 | Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent); \ | 356 | Dintp1(dresultA) = val >> (63 - exponent); \ |
357 | Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31); \ | 357 | Dintp2(dresultB) = exponent <= 62 ? val << (exponent - 31) : 0; \ |
358 | } \ | 358 | } \ |
359 | Sall(sgl_value) >>= SGL_EXP_LENGTH; /* return to original */ \ | ||
360 | } | 359 | } |
361 | 360 | ||
362 | #define Duint_setzero(dresultA,dresultB) \ | 361 | #define Duint_setzero(dresultA,dresultB) \ |