https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101835
Tobias Burnus <burnus at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Last reconfirmed| |2021-08-11 Status|UNCONFIRMED |NEW Summary|Fortran 128-bit float |Fortran 128-bit float |support |support, | |__float128/c_float128 / | |Supporting PowerPC's three | |128-bit / 16-byte REAL data | |types CC| |burnus at gcc dot gnu.org, | |dje at gcc dot gnu.org, | |meissner at gcc dot gnu.org, | |segher at gcc dot gnu.org --- Comment #1 from Tobias Burnus <burnus at gcc dot gnu.org> --- See linked thread for a longer description, https://gcc.gnu.org/pipermail/fortran/2021-August/thread.html#56315 (the link in comment 0 is in the same thread) However, the following issues exist: * ISO_C_Binding's c_float128 (gfortran vendor extension) has to match __float128 (cf. also comment 0) * ISO_Fortran_env provides: - REAL128 (whose storage size expressed in bits is 128) [since Fortran 2008] - REAL_KINDS - array with supported real kinds (Fortran: no order requirements) In gfortran, it is ordered; e.g. on x86-64 w/ libquadmath: [4,8,10,16]. * gfortran currently uses: – float, double and long double – which used GCC's builtins, the 'f','','l' suffixes (sinf, sin, sinl) and uses in libgfortran those data types - TFmode - Other real types are filtered out. * If long double's mode != TFmode, the FE assumes that TFmode is for __float128 – and sets info->c_float128 / yield gfc_real16_is_float128() = true However, this assumption is wrong in the general case, e.g. PowerPC has __float128 == KFmode and TFmode == 'long double' (There is currently no clash as KFmode is filtered out and TFmode == long double's mode). If a real type is regarded as float128, the FE calls the functions with 'q' suffix (such as sinq), libgfortran uses __float128 for those and there is some implicit assumption that libquadmath is available, which provides those 'q' functions. * Kind values: Currently supported are 4, 8, 10 (80bits; i387), 11 (82bits; IA-64, RFmode), 16 However, kind=11 does not seem to be tested for (and could be better documented) The kind value is generated as: kind = (GET_MODE_PRECISION (mode) + 7) / 8; (The '+ 7' is for IA-64's RFmode to map to kind=11.) Fortran itself does not require IEEE support and the kind numbers are arbitrary, albeit users expect that 4 and 8 exists (and match float/double), some expect that 16 exists and – only with gfortran – kind=10. The proper use is to use either the constants like: REAL128, use REAL_KINDS and the function SELECTED_REAL_KIND [IEEE has to be supported for types where IEEE_SUPPORT_DATATYPE () returns .true.] * Plus PowerPC: #define FLOAT_PRECISION_IFmode 128 #define FLOAT_PRECISION_TFmode 127 #define FLOAT_PRECISION_KFmode 126 with IFmode (IBM 128-bit floating point), TFmode (long double mode), KFmode (explicit __float128). - The current 'kind =' calculation above has kind=16 for all of them. (except that IFmode and TFmode are filtered out) - When adding support for IFmode/KFmode PowerPC mode, the proper library function has to be called (suffix? ABI in libgfortran?) - PowerPC (rs6000) has the command line flags: -mfloat128 Enable/disable the __float128 keyword for IEEE 128-bit floating point and use either software emulation for IEEE 128-bit floating point or hardware instructions. -mabi=ibmlongdouble Change the current ABI to use IBM extended-precision long double. This is not likely to work if your system defaults to using IEEE extended-precision long double. -mabi=ieeelongdouble Change the current ABI to use IEEE extended-precision long double. This is not likely to work if your system defaults to using IBM extended-precision long double. - As kind=16 is explicitly used, it should be supported but, otherwise, the other kinds can be mapped to any kind value, e.g. 15,16,17. There are ABI and compatibility issues – but they should be similar to C/C++.