On Wed, Aug 04, 2021 at 02:14:07PM -0600, Sandra Loosemore wrote: > I was trying last week to run my not-yet-committed TS29113 testsuite > on a powerpc64le-linux-gnu target and ran into some problems with > the kind constants c_float128 and c_float128_complex from the > ISO_C_BINDING module; per the gfortran manual they are supposed to > represent the kind of the gcc extension type __float128 and the > corresponding complex type. They were being set to -4 (e.g., not > supported) instead of 16, although this target does define > __float128 and real(16) is accepted as a supported type by the > Fortran front end. > > Anyway, the root of the problem is that the definition of these > constants only looked at gfc_float128_type_node, which only gets set > if TFmode is not the same type as long_double_type_node. I > experimented with setting gfc_float128_type_node = > long_double_type_node but that caused various Bad Things to happen > elsewhere in code that expected them to be distinct types, so I > ended up with this minimally intrusive patch that only tweaks the > definitions of the c_float128 and c_float128_complex constants. > > I'm not sure this is completely correct, though. I see PowerPC > supports 2 different 128-bit encodings and it looks like TFmode/long > double is mapped onto the one selected by the ABI and/or > command-line options; that's the only one the Fortran front end > knows about. All of TFmode, IFmode, and KFmode would map onto kind > 16 anyway (in spite of having different TYPE_PRECISION values) so > Fortran wouldn't be able to distinguish them. The thing that > confuses me is how/when the rs6000 backend defines __float128; it > looks like the documentation in the GCC manual doesn't agree with > the code, and I'm not sure what the intended behavior really is. Is > it possible that __float128 could end up defined but specifying a > different type than TFmode, and if so is there a target-independent > way to identify that situation? Can the PowerPC experts help > straighten me out? > > -Sandra
At the moment, we only fully support C and C++ when changing the long double format (between IEEE 128-bit, IBM 128-bit, and 64-bit) when the compiler is invoked (and assuming you are using GLIBC 2.32 or newer). For Fortran and the other languages, the only way to change the floating point format is to configure the compiler with the '--with-long-double-format=ieee' configuration option. This makes TFmode use IEEE 128-bit floating point instead of IBM 128-bit floating point. It would take somebody familar with the Fortran front end and libraries to make the same sort of modifications that were made for the C and C++ languages. Basically you need build libgfortran so that it has support for both floating point formats, using different names. You would need to modify the fortran front end to call the alternate functions when the switch is used to change the floating point format. It might be nice to have a Fortran specific way to specify which of the two floating point formats are used for REAL*16 (similar to the use of __float128 and __ibm128 in C/C++, and also _Float128 in just C). If you are going to do it, good luck. FWIW, I have built GCC compilers with the alternate floating point format, and I've been able to run the test suite and compile the Spec 2017 test suite with it. Generally to build a bootstrap compiler with the alternate long double representation I go through the following steps. 1) Make sure you have a GLIBC that supports switching long double representation (2.32 or new). I tend to use the IBM Advance Toolchain AT 14.0-3 to provide the new library, but if the native GLIBC on your system is new enough you could use that. I've discovered that there are problems if the GCC zlib is use, so I use the system zlib. The options I use when configuring the compiler include: --with-advance-toolchain=at14.0 --with-system-zlib --with-native-system-header-dir=/opt/at14.0/include If you are building and running on a power9 system, it is helpful if you add the option to set the default CPU to power9, since that way the compiler will automatically use the hardware IEEE 128-bit instructions that were added in power9. Otherwise it has to go through a call to do each operation. If you are running on a power9, we use the ifunc attribute to select modules that are built to use the hardware instruction. --with-cpu=power9 2) Build a non-bootstrap compiler with the '--with-long-double-format=ieee' configuration option, and install it somewhere. 3) With the compiler built in step #2, build the three libraries GCC uses (MPC, MPFR, and GMP), and install them some place. You need to do this because these libraries have functions in them with long double arguments. GCC doesn't actually use the functions with the long double arguments, but you will get a linker warning about mixing long double floating point type. 4) With the compiler built in step #2 and the libraries built in step #3, build a non-bootstrap compiler using '--with-long-double-format=ieee' and install it. You don't need to do this step, but when I was doing the development, I found it easier to track down problems with the non-bootstrap compiler. 5) If you haven't had any errors, go on to building a full bootstrap version of the compiler using the compiler built in step #4 for stage1 and the libraries built in step #2. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797