When cc1 for powerpc64-linux is a 32-bit binary, compiling _Decimal32 x = 1.2df; with "-m64 -S" results in: .file "df.c" .section ".toc","aw" .section ".text" .globl x .section ".data" .align 2 .type x, @object .size x, 4 x: .long 574619666 .ident "GCC: (GNU) 4.5.0 20090430 (experimental) [trunk revision 147009]" When the same compiler is built to be a 64-bit binary then the result is the same except for .size x, 4 x: .long 2467972673108443136 I normally configure GCC using --with-cpu=default32 and haven't yet checked to see long the bug has existed; perhaps as long as GCC has supported decimal float arithmetic. If check_effective_target_dfprt_nocache fails then the tests in gcc.dg/dfp are treated as compile-only and the struct-layout-1 tests do not support decimal float types, and currently there is no test for the correct constant value so the bug was not detected by running the testsuite.
The problem is that in dfp.c, functions encode_decimal* and decode_decimal* use memcpy from a 32-bit int to a long for 32 bits. This works fine with -32 where long is 32 bits, but not for -m64 where long is 32 bits. I assume that it magically works fine on little-endian systems like x86_64. This is not a regression, just a horrible wrong-code bug. I'm testing a patch.
D'oh, I of course meant that long is 32-bits when GCC is build with default -m32 and that long is 64-bits when GCC is built with default -m64; the host size of long, not the target size.
On x86_64 with a 64-bit compiler, positive decimal float constants are OK, negative decimal float constants are wrong for both -m64 (the default) and -m32.
Subject: Bug 39986 Author: janis Date: Wed May 6 16:59:53 2009 New Revision: 147188 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147188 Log: PR middle-end/39986 * dfp.c (encode_decimal32, decode_decimal32, encode_decimal64, decode_decimal64, encode_decimal128, decode_decimal128): Avoid 32-bit memcpy into long. * gcc.dg/dfp/pr39986.c: New test. Added: trunk/gcc/testsuite/gcc.dg/dfp/pr39986.c Modified: trunk/gcc/ChangeLog trunk/gcc/dfp.c trunk/gcc/testsuite/ChangeLog
This was a regression after all, release branches do not have the bug. I added the new test case to the 4.4 and 4.3 branches.
Only the testcase was checked into 4.4 branch: http://gcc.gnu.org/ml/gcc-cvs/2009-05/msg00163.html The dfp.c change is missing on 4.4 branch.
Gcc 4.4.1 revision 147214 gave: FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1572863965|-1308622825)\n FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1572863965|-1308622825)\n FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1574174720|-1319108608)\n FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1574174720|-1319108608)\n FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1576681472|-1339162624)\n FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1576681472|-1339162624)\n on Linux/Intel64.
Subject: Bug 39986 Author: janis Date: Thu May 7 21:38:46 2009 New Revision: 147253 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147253 Log: PR middle-end/39986 * dfp.c (encode_decimal32, decode_decimal32, encode_decimal64, decode_decimal64, encode_decimal128, decode_decimal128): Avoid 32-bit memcpy into long. Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/dfp.c
Subject: Bug 39986 Author: janis Date: Thu May 7 21:43:32 2009 New Revision: 147255 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147255 Log: PR middle-end/39986 * dfp.c (encode_decimal32, decode_decimal32, encode_decimal64, decode_decimal64, encode_decimal128, decode_decimal128): Avoid 32-bit copy into long. Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/dfp.c
Fixed.