Skip to content

Long double functions are not compiled when their size is greater than 64 bits

Hello,

I'm using LibmCS on a recent computer and by default long double functions are not compiled, even if 64 bits is managed.

Steps to reproduce

  • OS: Ubuntu 22 "jammy"
  • Compiler : GCC 11.4
  • CPU : Intel® Core™ Ultra 5 135H
$ ./configure --cross-compile "" --compilation-flags "" --enable-denormal-handling --enable-long-double-procedures --enable-complex-procedures
Arguments are:  --cross-compile '' --compilation-flags '' --enable-denormal-handling --enable-long-double-procedures --enable-complex-procedures --
Creating minimal .c file to check type sizes.
Found compiler:
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Build and run type sizes check to assign defines.
Found long double to be not 64bit. The library will not have long double procedures.
Check toolchain for endianness.
Found endianness to be __ORDER_LITTLE_ENDIAN__.
Creating configuration Makefile.
Added the following extra compilation flags to make:  -DLIBMCS_FPU_DAZ
See user manual (SUM) for the limitations and inaccuracies in complex procedures!
$ make -j 4
 [...]
$ nm build-x86_64-linux-gnu/bin/libm.a | grep cosl
$

Expected output

$ ./configure --cross-compile "" --compilation-flags "" --enable-denormal-handling --enable-long-double-procedures --enable-complex-procedures
Arguments are:  --cross-compile '' --compilation-flags '' --enable-denormal-handling --enable-long-double-procedures --enable-complex-procedures --
Creating minimal .c file to check type sizes.
Found compiler:
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Build and run type sizes check to assign defines.
Found long double to be 64bit.
Check toolchain for endianness.
Found endianness to be __ORDER_LITTLE_ENDIAN__.
Creating configuration Makefile.
Added the following extra compilation flags to make:  -DLIBMCS_FPU_DAZ -DLIBMCS_LONG_DOUBLE_IS_64BITS
See user manual (SUM) for the limitations and inaccuracies in complex procedures!
$ make -j 4
 [...]
$ nm build-x86_64-linux-gnu/bin/libm.a | grep cosl
## SOMETHING DISPLAYED HERE
$

Further analysis

I tried to manually reproduce the behaviour of configure script to detect the system long double size:

$ printf "double d_data[16];\\nlong double l_data[16];\\nlong int li_data[16];\\n" > sizeoftypes.c
$ gcc -c sizeoftypes.c
$ nm -S -t d sizeoftypes.o | grep "l_data" | awk '{print $2/16*8}'
128
$ 

The detected size of long double on my system is 128 bits. However, the configure script expects a size of 32 or 64 bits.

A turnaround solution is replacing in configure the line 161:

       if [ "$long_double_size" -eq "64" ]; then

By the following:

       if [ "$long_double_size" -ge "64" ]; then

New behaviour with this modification:

$ ./configure --cross-compile "" --compilation-flags "" --enable-denormal-handling --enable-long-double-procedures --enable-complex-procedures
Arguments are:  --cross-compile '' --compilation-flags '' --enable-denormal-handling --enable-long-double-procedures --enable-complex-procedures --
Creating minimal .c file to check type sizes.
Found compiler:
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Build and run type sizes check to assign defines.
Found long double to be 64bit.
Check toolchain for endianness.
Found endianness to be __ORDER_LITTLE_ENDIAN__.
Creating configuration Makefile.
Added the following extra compilation flags to make:  -DLIBMCS_FPU_DAZ -DLIBMCS_LONG_DOUBLE_IS_64BITS
See user manual (SUM) for the limitations and inaccuracies in complex procedures!
$ make -j 4
 [...]
$ nm build-x86_64-linux-gnu/bin/libm.a | grep cosl
00000000000003d0 T acosl
00000000000001f0 T cosl
0000000000000070 T cacosl
00000000000000e0 T ccosl
$