The following produces an internal compiler error:
[G4:~/gnu/testgpc/adriaan] adriaan% cat compare.pas program Compare; procedure R ( var r1, r2: real); begin if r1 <> r2 then r1:= r2 - 1.0 end; begin end.
[G4:~/gnu/testgpc/adriaan] adriaan% gpc -o compare compare.pas -mlong-double-128 compare.pas: In procedure `R': compare.pas:6: error: unrecognizable insn: (insn 26 34 27 2 0x0 (set (reg:SI 126) (subreg:SI (reg:TF 33 f1) 0)) -1 (nil) (nil)) compare.pas:6: internal compiler error: in extract_insn, at recog.c:2175
It may be, of course, that the Darwin target doesn't properly support the -mlong-double-128 PowerPC processor option. If it's a gcc back-end bug, I can report it to Bugzilla.
However, the "real" type used is 64-bit on the Darwin target, with or without -mlong-double-128 ... The option only changes the size of the "longreal" and "extended" types to 128-bit.
Regards,
Adriaan van Os
[G4:~/gnu/testgpc/adriaan] adriaan% gpc -v Reading specs from /Developer/Pascal/gpc33d7/lib/gcc-lib/powerpc-apple-darwin/3.3/specs Configured with: ../gpc-3.3d7/configure --enable-languages=pascal,c --enable-threads=posix --prefix=/Developer/Pascal/gpc33d7 --target=powerpc-apple-darwin Thread model: posix gpc version 20030507, based on gcc-3.3
Adriaan van Os wrote:
The following produces an internal compiler error:
[G4:~/gnu/testgpc/adriaan] adriaan% cat compare.pas program Compare; procedure R ( var r1, r2: real); begin if r1 <> r2 then r1:= r2 - 1.0 end; begin end.
[G4:~/gnu/testgpc/adriaan] adriaan% gpc -o compare compare.pas -mlong-double-128 compare.pas: In procedure `R': compare.pas:6: error: unrecognizable insn: (insn 26 34 27 2 0x0 (set (reg:SI 126) (subreg:SI (reg:TF 33 f1) 0)) -1 (nil) (nil)) compare.pas:6: internal compiler error: in extract_insn, at recog.c:2175
It may be, of course, that the Darwin target doesn't properly support the -mlong-double-128 PowerPC processor option. If it's a gcc back-end bug, I can report it to Bugzilla.
However, the "real" type used is 64-bit on the Darwin target, with or without -mlong-double-128 ... The option only changes the size of the "longreal" and "extended" types to 128-bit.
Perhaps GPC uses LongReal internally. Does it make a difference if you cast the constant to Real explicitly?
Anyway, if you can reproduce the problem in C code (possibly using `long double' variables or a constant casted to `long double'), then it's surely a backend bug.
Frank
The following produces an internal compiler error:
[G4:~/gnu/testgpc/adriaan] adriaan% cat compare.pas program Compare; procedure R ( var r1, r2: real); begin if r1 <> r2 then r1:= r2 - 1.0 end; begin end.
[G4:~/gnu/testgpc/adriaan] adriaan% gpc -o compare compare.pas -mlong-double-128 compare.pas: In procedure `R': compare.pas:6: error: unrecognizable insn: (insn 26 34 27 2 0x0 (set (reg:SI 126) (subreg:SI (reg:TF 33 f1) 0)) -1 (nil) (nil)) compare.pas:6: internal compiler error: in extract_insn, at recog.c:2175
It may be, of course, that the Darwin target doesn't properly support the -mlong-double-128 PowerPC processor option. If it's a gcc back-end bug, I can report it to Bugzilla.
However, the "real" type used is 64-bit on the Darwin target, with or without -mlong-double-128 ... The option only changes the size of the "longreal" and "extended" types to 128-bit.
I guess that the constant 1.0 is internally long double. In any case with the code below (which I belive is accurate translation of your functon) I got the same error from C compiler:
void R(double * r1, double *r2, long double * c) { if (*r1 != *r2) { *r1 = *r2 - *c; } }
hebisch@student:/arc/pom/gcc1/pp$ ../gpc-mac/gcc/xgcc -B../gpc-mac/gcc -mlong-double-128 -S longd.c longd.c: In function `R': longd.c:12: error: unrecognizable insn: (insn 27 35 28 2 (nil) (set (reg:SI 126) (subreg:SI (reg:TF 33 f1) 0)) -1 (nil) (nil)) longd.c:12: internal compiler error: in extract_insn, at recog.c:2175 Please submit a full bug report, with preprocessed source if appropriate. See URL:http://gcc.gnu.org/bugs.html for instructions. hebisch@student:/arc/pom/gcc1/pp$ ../gpc-mac/gcc/xgcc -v -B../gpc-mac/gcc -mlong-double-128 Reading specs from ../gpc-mac/gcc/specs Configured with: ../gcc-3.3.1/configure --enable-languages=pascal,c --enable-checking --target=ppc-darwin Thread model: single gcc version 3.3.1
If the third argument is changed to double then the error vanishes.
Waldek Hebisch wrote:
I guess that the constant 1.0 is internally long double. In any case with the code below (which I belive is accurate translation of your functon) I got the same error from C compiler:
void R(double * r1, double *r2, long double * c) { if (*r1 != *r2) { *r1 = *r2 - *c; } }
Yes, it's a backend bug.
By mistake I sent my follow-up on this thread to Frank's private private email address, rather than to the gpc mailing list. I discovered this only much later. I apologize for this, here is the follow-up:
Frank Heckenbach wrote:
Adriaan van Os wrote:
The following produces an internal compiler error:
Perhaps GPC uses LongReal internally. Does it make a difference if you cast the constant to Real explicitly?
GPC does not allow it:
compare.pas:6: error: reference expected, value given
Oh, yeah. I changed this recently, how should I know? ;-)
Anyway, if you can reproduce the problem in C code (possibly using `long double' variables or a constant casted to `long double'), then it's surely a backend bug.
It is a backend bug and I have reported it to bugzilla as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11848.
OK, thanks.
Frank
The bug was confirmed on the bugzilla list by Andrew Pinski.
Regards,
Adriaan van Os
Adriaan van Os wrote:
Waldek Hebisch wrote:
I guess that the constant 1.0 is internally long double. In any case with the code below (which I belive is accurate translation of your functon) I got the same error from C compiler:
void R(double * r1, double *r2, long double * c) { if (*r1 != *r2) { *r1 = *r2 - *c; } }
Yes, it's a backend bug.
Fixed in gcc mainline for the powerpc-apple-darwin target, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11848. Geoff Keating wrote:
Note that even when this is fixed, -mlong-double-128 (and especially this testcase) won't work on Darwin because the library support for it is not there. That's not a GCC problem.
Regards,
Adriaan van Os
Adriaan van Os wrote:
Waldek Hebisch wrote:
I guess that the constant 1.0 is internally long double. In any case with the code below (which I belive is accurate translation of your functon) I got the same error from C compiler:
void R(double * r1, double *r2, long double * c) { if (*r1 != *r2) { *r1 = *r2 - *c; } }
Yes, it's a backend bug.
Fixed in gcc mainline for the powerpc-apple-darwin target, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11848.
So, I now tried the testsuite with the gcc-3.4.3 based compiler. The result- several failures and crashes. I tried in C and reported it as a gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19993.
The answer to my bug report, I believe, is nonsense. Because of this and because of this earlier comment:
Geoff Keating wrote:
Note that even when this is fixed, -mlong-double-128 (and especially this testcase) won't work on Darwin because the library support for it is not there. That's not a GCC problem.
... I would be curious to know the result on ppc Linux or ppc AIX of the following (in Pascal and C)
program LongReals; var R: LongReal; begin R:= sin( 1.2345); WriteLn( 'SizeOf( LongReal) = ', SizeOf( LongReal)); WriteLn( 'sin( 1.2345) = ', R:1:30); WriteLn( 'sin( 1.2345) = ', R:1:30, ' = ', R:1:30); WriteLn( 'sin( 1.2345) = ', R:1:30, ' = ', R:1:30, ' = ', R:1:30); end.
#include <stdio.h>
int main( void ) { long double R; R = sin( 1.2345); printf( "sizeof( long double) = %d\n", sizeof( long double)); printf( "sin( 1.2345) = %1.30Lf = %1.30Lf\n", R, R); return 0; }
So, if someone has the hardware at hand (I have tried before to install debian ppc64 linux but it doesn't recognize any of my G5's IDE or SATA drives).
Regards,
Adriaan van Os
On 16 Feb 2005 at 14:40, Adriaan van Os wrote:
... I would be curious to know the result on ppc Linux or ppc AIX of the following (in Pascal and C)
I have built GPC 20041218 on GCC 3.3.4 on AIX 5.2 on an IBM p650 machine with multiple powerpc cpus. I have also installed the 64 bit library for GPC. http://www.gnu-pascal.de/crystal/gpc/en/mail11263.html
Using standard 32 bit compilation, I receive copious warnings along the lines of
/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/newgcc/lib/gcc- lib/powerpc-ibm-aix5.2.0.0/3.3.4/libgpc.a(files.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/newgcc/lib/gcc- lib/powerpc-ibm-aix5.2.0.0/3.3.4/libgpc.a(error.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/newgcc/lib/gcc- lib/powerpc-ibm-aix5.2.0.0/3.3.4/libgpc.a(rts.o)' is incompatible with rs6000:6000 output
and many more like this
however the program compiles and gives
SizeOf( LongReal) = 8 sin( 1.2345) = 0.943983323944511099057308456395 sin( 1.2345) = 0.943983323944511099057308456395 = 0.943983323944511099057308456395 sin( 1.2345) = 0.943983323944511099057308456395 = 0.943983323944511099057308456395 = 0.943983323944511099057308456395
64 bit compilation -maix64 gives the same answer
SizeOf( LongReal) = 8 sin( 1.2345) = 0.943983323944511099057308456395 sin( 1.2345) = 0.943983323944511099057308456395 = 0.943983323944511099057308456395 sin( 1.2345) = 0.943983323944511099057308456395 = 0.943983323944511099057308456395 = 0.943983323944511099057308456395
For the C version GCC gives /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc.a(_divdi3.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc.a(_moddi3.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc.a(_udivdi3.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc.a(_umoddi3.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc.a(_udivmoddi4.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc_eh.a(unwind-dw2.o)' is incompatible with rs6000:6000 output /home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc_eh.a(unwind-dw2-fde.o)' is incompatible with rs6000:6000 output /tmp//cch9Ygvn.o(.pr+0x94):longreal.c: undefined reference to `.sin' collect2: ld returned 1 exit status
GCC with -maix64 gives the error without the warnings
/tmp//ccuhHGVI.o(.pr+0x1c):longreal.c: undefined reference to `.sin' collect2: ld returned 1 exit status
the native AIX cc compiler gives ld: 0711-317 ERROR: Undefined symbol: .sin
hth Peter.
Peter Keenan wrote:
however the program compiles and gives
SizeOf( LongReal) = 8 sin( 1.2345) = 0.943983323944511099057308456395 sin( 1.2345) = 0.943983323944511099057308456395 = 0.943983323944511099057308456395 sin( 1.2345) = 0.943983323944511099057308456395 = 0.943983323944511099057308456395 = 0.943983323944511099057308456395
Ah, thanks but I forgot to ask passing -mlong-double-128 as a command-line option. Without that option, the output of gpc and gcc is correct on powerpc-apple-darwin.
/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/../../../../powerpc-ibm-aix5.2.0.0/bin/ld: warning: powerpc:601 architecture of input file `/home/pkeenan/local/bin/../lib/gcc-lib/powerpc-ibm- aix5.2.0.0/3.3.4/libgcc_eh.a(unwind-dw2-fde.o)' is incompatible with rs6000:6000 output /tmp//cch9Ygvn.o(.pr+0x94):longreal.c: undefined reference to `.sin' collect2: ld returned 1 exit status
I only know that IBM uses the POWER instruction set, where Apple uses the PowerPC instruction set <http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/RS_002f6000-and-PowerPC- Options.html>. However, the message speaks about "architecture of input file" not about instruction sets. Could it make a difference what linker you are using ? (I am guessing, I don't know AIX at all).
There have been threads about gpc on AIX ( e.g. http://www.gnu-pascal.de/crystal/gpc/en/mail10545.html).
the native AIX cc compiler gives ld: 0711-317 ERROR: Undefined symbol: .sin
The sin is not important in the test, here is another test:
program LongReals; var R: LongReal; begin R:= 1.234567890123456789012345678900; WriteLn( 'SizeOf( LongReal) = ', SizeOf( LongReal)); WriteLn( 'R = ', R:1:30); WriteLn( 'R = ', R:1:30, ' = ', R:1:30); WriteLn( 'R = ', R:1:30, ' = ', R:1:30, ' = ', R:1:30); end.
#include <stdio.h>
int main( void ) { long double R; R = 1.234567890123456789012345678900; printf( "sizeof( long double) = %d\n", sizeof( long double)); printf( "R = %1.30Lf = %1.30Lf\n", R, R); return 0; }
The results are remarkable:
For gcc-3.4.3:
[G5:gpc/testgpc/adriaan] adriaan% gcc longreals5.c -mlong-double-128 [G5:gpc/testgpc/adriaan] adriaan% ./a.out sizeof( long double) = 16 R = 1.234567890123456690432135474111 = 0.000000000000000000000000000000
For gcc version 4.0.0 20050213 (experimental):
[G5:gpc/testgpc/adriaan] adriaan% gcc4 longreals5.c -mlong-double-128 [G5:gpc/testgpc/adriaan] adriaan% ./a.out sizeof( long double) = 16 R = 1.234567890123456690432135474111 = 0.000000000000000000000000000000
For gpc-20041218 with gcc-3.4.3:
[G5:gpc/testgpc/adriaan] adriaan% gpc longreals5.pas -mlong-double-128 [G5:gpc/testgpc/adriaan] adriaan% ./a.out SizeOf( LongReal) = 16 R = 1 R = 1 = 1.234567890123456690432135474111419171094894409180 Segmentation fault
with backtrace:
Exception: EXC_BAD_ACCESS (0x0001) Codes: KERN_INVALID_ADDRESS (0x0001) at 0x8dccc770
Thread 0 Crashed: 0 a.out 0x0000ea9c _p_Write_Real + 0x3d4 (files.pas:2747) 1 a.out 0x0000e7b4 _p_Write_Real + 0xec (files.pas:2653) 2 a.out 0x00002bac _p__M0_main_program + 0x31c (crt.c:300) 3 a.out 0x00002ca4 main + 0x50 (crt.c:300) 4 a.out 0x000024c8 _start + 0x188 (crt.c:267) 5 dyld 0x8fe1a558 _dyld_start + 0x64
Regards,
Adriaan van Os
On 16 Feb 2005 at 18:36, Adriaan van Os wrote:
Ah, thanks but I forgot to ask passing -mlong-double-128 as a command-line option. Without that option, the output of gpc and gcc is correct on powerpc-apple-darwin.
Alas I also know little about AIX, having moved to the larger machine only when I had a Delphi program that needed more power.
There is some discussion of AIX and GCC at http://www-106.ibm.com/developerworks/eserver/articles/gnu.html
this suggests that from AIX 5.2 (which I am using) the default is - mcpu=powerpc.
Anyhow I've tried it with -mlong-double-128 and there does seem to be a lack of precision in the output, even when it works!
original test program with sin()
32 bit gpc compilation (with warnings)
SizeOf( LongReal) = 16
Program received signal SIGSEGV, Segmentation fault. $1000dd44 in _p_Write_Real ()
backtrace #0 $1000dd44 in _p_Write_Real () #1 $10000668 in pascal_main_program () at longreal.pas:13 #2 $10000984 in main (argc=1, argv=$2ff22b04, envp=$2ff22b0c) at longreal.pas:10
64 bit gpc compilation (-maix64) SizeOf( LongReal) = 16 sin( 1.2345) = 0.9 sin( 1.2345) = 0.9 = 0.9 sin( 1.2345) = 0.9 = 0.9 = 0.9
new version test program with R:= 1.234567890123456789012345678900;
32 bit gpc compilation (with warnings) SizeOf( LongReal) = 16 R = 1 R = 1 = 1 R = 1 = 1 = 1
64 bit gpc compilation (-maix64)
SizeOf( LongReal) = 16 R = 1.2 R = 1.2 = 1.2 R = 1.2 = 1.2 = 1.2
32 bit gcc compilation pkeenan@doc:~/opt04$ ~/local/bin/gcc -mlong-double-128 longreal2.c longreal2.c: In function `main': longreal2.c:10: error: insn does not satisfy its constraints: (insn 53 52 28 0 (set (reg:TF 4 r4) (mem:TF (plus:SI (reg/f:SI 31 r31) (const_int 80 [0x50])) [0 S16 A8])) 269 {*movtf_internal} (nil) (nil)) longreal2.c:10: internal compiler error: in extract_constrain_insn_cached, at recog.c:2090 Please submit a full bug report, with preprocessed source if appropriate.
Peter Keenan wrote:
There is some discussion of AIX and GCC at http://www-106.ibm.com/developerworks/eserver/articles/gnu.html
Interesting.
Anyhow I've tried it with -mlong-double-128 and there does seem to be a lack of precision in the output, even when it works!
Yeah, the precision is impressive, especially for 128-bit numbers ...
Do I have to rebuild the gpc runtime library when using -mlong-double-128 ? By adding that option to CFLAGS in Makefile.in ?
32 bit gcc compilation pkeenan@doc:~/opt04$ ~/local/bin/gcc -mlong-double-128 longreal2.c longreal2.c: In function `main': longreal2.c:10: error: insn does not satisfy its constraints: (insn 53 52 28 0 (set (reg:TF 4 r4) (mem:TF (plus:SI (reg/f:SI 31 r31) (const_int 80 [0x50])) [0 S16 A8])) 269 {*movtf_internal} (nil) (nil)) longreal2.c:10: internal compiler error: in extract_constrain_insn_cached, at recog.c:2090 Please submit a full bug report, with preprocessed source if appropriate.
That is gcc bug 11848 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11848 fixed in gcc 3.4.
Thanks for trying.
Regards,
Adriaan van Os
Adriaan van Os wrote:
So, I now tried the testsuite with the gcc-3.4.3 based compiler. The result- several failures and crashes. I tried in C and reported it as a gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19993.
The answer to my bug report, I believe, is nonsense. Because of this and because of this earlier comment:
Geoff Keating wrote:
Note that even when this is fixed, -mlong-double-128 (and especially this testcase) won't work on Darwin because the library support for it is not there. That's not a GCC problem.
... I would be curious to know the result on ppc Linux or ppc AIX of the following (in Pascal and C)
To clarify somewhat what Geoff Keating wrote: unsing -mlong-double-128 currenly means changed inteface. In first approximation all parts of the program need to be compiled with -mlong-double-128 -- _including_ runtime support (libgpc.a). At least part of the runtime must be re-coded to suppot better accuraccy. So using `libgpc.a' compiled with 64-bit long-double can not work with -mlong-double-128. The same applies to `libgcc.a' and `libc'. While updating `libgcc.a' and `libgpc.a' is part of compiler effort `libc' comes with OS and is beyond scope of GCC (Keating: "That's not a GCC problem").
In particular, gpc emits calls to `sin' and `Wirteln' using current size of long double, but libgpc.a uses 64-bit size, which causes problems.
In ideal world all this mess would be hidden from users of compiler, but using different size of fundamental types on single system is rare, and I can not see how one could make it transparent in C (in principle gpc has all relevant information in .gpi files, but C compiler have to translate different parts separately).
Waldek Hebisch wrote:
To clarify somewhat what Geoff Keating wrote: unsing -mlong-double-128 currenly means changed inteface. In first approximation all parts of the program need to be compiled with -mlong-double-128 -- _including_ runtime support (libgpc.a). At least part of the runtime must be re-coded to suppot better accuraccy. So using `libgpc.a' compiled with 64-bit long-double can not work with -mlong-double-128. The same applies to `libgcc.a' and `libc'. While updating `libgcc.a' and `libgpc.a' is part of compiler effort `libc' comes with OS and is beyond scope of GCC (Keating: "That's not a GCC problem").
In particular, gpc emits calls to `sin' and `Wirteln' using current size of long double, but libgpc.a uses 64-bit size, which causes problems.
In ideal world all this mess would be hidden from users of compiler, but using different size of fundamental types on single system is rare, and I can not see how one could make it transparent in C (in principle gpc has all relevant information in .gpi files, but C compiler have to translate different parts separately).
Thanks for the explanation. I found (http://gcc.gnu.org/ml/gcc-patches/2004-08/msg01093.html) that libc in Mac OS X 10.4 will support 128-bit long doubles, so I will be pleased to wait for that.
Regards,
Adriaan van Os
Adriaan van Os wrote:
So, I now tried the testsuite with the gcc-3.4.3 based compiler. The result- several failures and crashes. I tried in C and reported it as a gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19993.
The answer to my bug report, I believe, is nonsense.
: ------- Additional Comment [54]#1 From [55]Andrew Pinski 2005-02-16 : 02:01 ------- : First: : printf( "sin( 1.2345) = %.30f = %.30f\n", R, R); : : Is wrong, as R is pased as a two doubles (as this is the how 128bit long double : s are done in IBM's : 128bit format).
Indeed this C statement is wrong. One doesn't have to go into target specifics. The `%f' format expects an argument of type `double', as documented. Since `printf' is a varargs function, it doesn't do argument conversions (unlike Pascal's `WriteLn'), so passing any other type than `double' is wrong. So, this part of the answer is no nonsense.
: Second the following shows the correct result: : #include <stdio.h> : #include <math.h> : : int main( void ) : { : long double R; : R = sin( 1.2345); : printf( "sizeof( long double) = %d\n", sizeof( long double)); : printf( "sin( 1.2345) = %.30f = %.30f\n", (double)R, (double)R); : return 0; : }
This program is correct. However `sin' returns a `double' (this applies to your original test program as well), so all the program really does is convert a `double' to `long double' and back to `double' (both in the correct way, i.e. preserving values, not bit-patterns) and print this. (In C, `sin' is not a built-in, and it doesn't adapt to argument types, so it's just a plain function with one fixed argument and result type.) So, this part of the answer is not wrong, but not very meaningful, either.
BTW, to compute sine in `long double', you can use `sinl' if available. To print `long double', you can use `%Lf', again if available. It might be a GNU extension and not available at all on Mac OS X, or called differently there, though. And if it does, it might be questionable if the libc expects a 64 or 128 bit `long double' (since libc is fixed and doesn't know about the current compiler options).
The latter is probably also the problem with GPC. With `-mlong-double-128', you'll have to at least recompile the RTS with this option. (Then it won't work with 64 bit `long double' anymore, of course.)
Do I have to rebuild the gpc runtime library when using -mlong-double-128 ?
Yes, all libraries must be built with 128 bit support. I don't know the status of libc on this target, but for the GPC RTS you need to give this option, unless it's the default (I seem to understand it will be so in gcc-4.x).
By adding that option to CFLAGS in Makefile.in ?
CFLAGS also apply to building the compiler itself. I suppose this option won't hurt (if used througout, i.e. not just to recompile the frontend or so). Otherwise you could try RTSFLAGS (though I'm not sure if libgcc2.a needs it, so CFLAGS might be perferable). BTW, it's easier to set make options on the command line than changing the Makefiles.
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
... snip ...
Indeed this C statement is wrong. One doesn't have to go into target specifics. The `%f' format expects an argument of type `double', as documented. Since `printf' is a varargs function, it doesn't do argument conversions (unlike Pascal's `WriteLn'), so passing any other type than `double' is wrong. So, this part of the answer is no nonsense.
: Second the following shows the correct result: : #include <stdio.h> : #include <math.h> : : int main( void ) : { : long double R; : R = sin( 1.2345); : printf( "sizeof( long double) = %d\n", sizeof( long double)); : printf( "sin( 1.2345) = %.30f = %.30f\n", (double)R, (double)R); : return 0; : }
This program is correct. However `sin' returns a `double' (this
No it isn't. sizeof returns a size_t, which is not necessarily anything like an int, and is unsigned. The result should be cast to an unsigned long (in C90) and so treated in the format specification. I believe C99 has a %zu specifier available for size_t items. Similarly %td is available for ptrdiff_t items, which are signed, and which has no bearing on the above code.
CBFalconer wrote:
: Second the following shows the correct result: : #include <stdio.h> : #include <math.h> : : int main( void ) : { : long double R; : R = sin( 1.2345); : printf( "sizeof( long double) = %d\n", sizeof( long double)); : printf( "sin( 1.2345) = %.30f = %.30f\n", (double)R, (double)R); : return 0; : }
This program is correct. However `sin' returns a `double' (this
No it isn't. sizeof returns a size_t, which is not necessarily anything like an int, and is unsigned. The result should be cast to an unsigned long (in C90) and so treated in the format specification. I believe C99 has a %zu specifier available for size_t items. Similarly %td is available for ptrdiff_t items, which are signed, and which has no bearing on the above code.
You're right, I missed this one. (At least the statement with the doubles is right. ;-)
Frank