Fix conversion from uint64 to float128
PATCH 1/1 Fix conversion from uint64 to float128
The significand is passed to normalizeRoundAndPackFloat128() as high first, low second. The current code passes the integer first, so the result is incorrectly shifted left by 64 bits.
This bug affects the emulation of s390x instruction CXLGBR (convert from logical 64-bit binary-integer operand to extended BFP result).
--- fpu/softfloat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fpu/softfloat.c +1 -1
@@ -3139,7 +3139,7 @@ float128 uint64_to_float128(uint64_t a, float_status *status)if (a ==0 ) {return float128_zero; } -return normalizeRoundAndPackFloat128 (0 ,0x406E , a,0 , status); +return normalizeRoundAndPackFloat128 (0 ,0x406E ,0 , a, status); }
Signature · 1 line
2.13.6
Quoted 6 lines · On Fri, 11 May 2018 09:10:52 +0200 Petr Tesarik <[email protected]> wrote:
The significand is passed to
normalizeRoundAndPackFloat128()as high first, low second. The current code passes the integer first, so the result is incorrectly shifted left by 64 bits.This bug affects the emulation of s390x instruction CXLGBR (convert from logical 64-bit binary-integer operand to extended BFP result).
I forgot to add a simple reproducer:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
unsigned long long x = atoll(argv[1]);
long double d = x;
printf("%llu -> %Lf\n", x, d);
return 0;
}On a real s390x, I get this:
linux-nig1:~ # ./cast 1
1 -> 1.000000
An s390x emulated with (unpatched) qemu-system-s390x gives:
linux-2s2c:~ # ./cast 1
1 -> 18446744073709551616.000000
That is 2^64.
Petr T
Quoted 18 lines · Petr Tesarik
The significand is passed to
normalizeRoundAndPackFloat128()as high first, low second. The current code passes the integer first, so the result is incorrectly shifted left by 64 bits.This bug affects the emulation of s390x instruction CXLGBR (convert from logical 64-bit binary-integer operand to extended BFP result).
Signed-off-by Petr Tesarik <[email protected]>--- fpu/softfloat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)fpu/softfloat.c +0
-0
fpu/softfloat.c float128 uint64_to_float128(uint64_t a, float_status *status) · line 3143
Quoted 6 lines
fpu/softfloat.c +1
-1@@ -3139,7 +3139,7 @@ float128 uint64_to_float128(uint64_t a, float_status *status)if (a ==0 ) {return float128_zero; } -return normalizeRoundAndPackFloat128 (0 ,0x406E , a,0 , status); +return normalizeRoundAndPackFloat128 (0 ,0x406E ,0 , a, status); }
thanks
-- PMM
Richard Henderson
AppliedQuoted 4 lines · Petr Tesarik
The significand is passed to
normalizeRoundAndPackFloat128()as high first, low second. The current code passes the integer first, so the result is incorrectly shifted left by 64 bits.
Quoted 8 lines
This bug affects the emulation of s390x instruction CXLGBR (convert from logical 64-bit binary-integer operand to extended BFP result).
Signed-off-by Petr Tesarik <[email protected]>--- fpu/softfloat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Queued, thanks.
r~