public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Michael Meissner <meissner@linux.ibm.com>
To: Bill Schmidt <wschmidt@linux.ibm.com>
Cc: Thomas Koenig <tkoenig@netcologne.de>,
	"fortran@gcc.gnu.org" <fortran@gcc.gnu.org>,
	Jakub Jelinek <jakub@redhat.com>,
	Segher Boessenkool <segher@kernel.crashing.org>,
	Peter Bergner <bergner@linux.ibm.com>,
	David Edelsohn <dje.gcc@gmail.com>,
	Michael Meissner <meissner@linux.ibm.com>
Subject: Re: [RFC] User-visible changes for powerpc64-le-linux ABI changes
Date: Mon, 1 Nov 2021 14:46:44 -0400	[thread overview]
Message-ID: <YYA2FMfDR0yehJLA@toto.the-meissners.org> (raw)
In-Reply-To: <bdc02706-a5ae-1389-906d-50c502b87d5f@linux.ibm.com>

On Mon, Nov 01, 2021 at 10:54:27AM -0500, Bill Schmidt wrote:
> Hi Thomas,
> 
> To me this looks excellent.  If you feel that support for both forms is achievable,
> that's certainly superior.  We had previously been concerned about whether the
> necessary name mangling support would be possible, but it sounds like you aren't
> overly worried about that.
> 
> I'll let Mike weigh in about using the same options as are present for C/C++, which
> I think should be the right approach, but I know I don't know all the subtleties.
> That would also help determine whether -freal-16=ibm is the right default.  I think
> it probably is, but I'll let those more familiar with the details weigh in.
> 
> Thanks again!
> Bill

Lets see if I can describe the C/C++ side of things.

Internally, we have 3 floating point types:

 * KFmode: IEEE 128-bit

 * IFmode: IBM 128-bit

 * TFmode: What long double maps to (either IEEE 128-bit or IBM 128-bit)

In general, you should use TFmode if the 128-bit type matches long double, and
only use IFmode/KFmode if you are using a 128-bit type that does not match long
double.

We support 3 keywords:

 * __float128: Historic keywork for IEEE 128-bit (both C/C++)

 * _Float128: IEEE 128-bit (from ISO/IEC TS 18661-‐3:2015, C only)

 * __ibm128: Keyword to access current IBM 128-bit.

There are 2 naming conventions for 128-bit IEEE functions:

 * Libquadmath: Math functions end in 'q'.

 * ISO/IEC TS 18661-2:2015: Math functions end in 'f128'.

While we still build libquadmath, the C/C++ compiler and Glibc no longer
generate the 'q' names.  Instead we use the new names that end in f128.
Starting with glibc 2.34, the glibc library supports the f128 names on PowerPC
64-bit little endian systems.

As far as I know, glibc does not not provide the f128 names for big endian
systems.  We do build libquadmath and those interfaces could be used (much like
the x86_64 does), but you may get issues of whether you are using a 'q' or
'f128' function.

With glibc 2.34 and beyond, math.h remaps all of the math functions from 'l'
suffix to 'f128' suffix if long double is IEEE 128-bit.  In addition, the
PowerPC back end does this mapping for built-in functions if you call the
function without including math.h.  Hence if you build a toolchain that
defaults to IEEE 128-bit long double, Fortran calls to these functions are
mapped.

I believe glibc only does the IEEE 128-bit mapping if either long double is
IEEE 128-bit or:

 * __STDC_WANT_IEC_60559_FUNCS_EXT__ is defined.

 * __STDC_WANT_IEC_60559_TYPES_EXT__ might also need to be defined.

However, not all of the math functions have built-in counterparts to the name.
The compiler does not map these functions.

The libstdc++ library also does this mapping, starting wtih GCC 11.

While we typically talk of going between IBM and IEEE 128-bit long doubles, the
PowerPC compiler actually has 3 long double variants:

 * -mabi=ieeelongdouble: Long double is IEEE 128-bit if long doubles are
    128-bits.

 * -mabi=ibmlongdouble: Long double is IBM 128-bit if long doubles are
    128-bits.

 * -mlong-double-64: Long double is 64-bits and the -mabi=ieeelongdouble and
    -mabi=ibmlongdouble are not used.

The following macros are defined:

 * __LONG_DOUBLE_IEEE128__: if long doubles are IEEE 128-bit;

 * __LONG_DOUBLE_IBM128__: If long doubles are IBM 128-bit;

 * __LONG_DOUBLE_128__: If long doubles are 128-bits (either IBM or IEEE).

The ELF object file uses .gnu_attribute #4 to encode the current long double
format.  This is only set if calls are made using long double types (note, it
is somewhat buggy, and it misses things like using long double in the code, but
not doing a call, and the bit for 64-bit long doubles gets set if you pass or
return normal 64-bit doubles when the 64-bit long switch is set.  The bits are:

 * 0x1: Hardware 32/64-bit floating point is used.

 * 0x2: Software 32/64-bit floating point is used.  Note, this bit is not set
   if IEEE 128-bit is emulated (power8).

 * Bits 0x4 and 0x8 are a 2 bit field:

    * 0x4: 64-bit long doubles are passed and returned;
    * 0x8: IBM 128-bit long doubles are passed and returned;
    * 0xc: IEEE 128-bit long doubles are passed and returned.

If you are building libraries that contain modules with multiple long double
types, you must use the '-mno-gnu-attribute'.  We also use the '-Wno-psabi'
option, which silences the warning that you are switching long double types (if
glibc is not 2.34 or newer).  We may need to tweak -Wno-psabi for use with
Fortran.

For shared libraries, the linker complains if any of the modules in the library
set .gnu_attribute #4 to a different value than the current modules.  When
building the glibc and libstdc++ libraries

There are 3 configuration options to chose the long double type:

 * --with-long-double-format=ibm: Chooses IBM 128-bit long double;

 * --with-long-double-format=ieee: Chooses IEEE 128-bit long double;

 * --without-long-double-128: Choose 64-bit long double.

While I have tried to minimize the differences in running the test suites, if
you change the long double type, there will be changes in what tests pass or
fail.

 * A lot of the C++ modules tests fail when you switch the long double type.

 * 3 Fortran tests that tradionally fail, actually pass now.

 * There are a bunch of tests that fail when long double is 64-bits.

 * There are 2 C tests that fail due to issues with signalling NaNs with
   explicit _Float128 support that fail if long double is IEEE 128.

In order to build a toolchain that defaults to IEEE 128-bit long double (or
64-bit long double), I go through the following steps:

 * Build a standard toolchain (either stage1 or bootstrap);

 * Build gmp, mpfr, and mpc with that toolchain, using the appropriate long
   double option and the compiler built above.  I disable building shared
   libraries of these functions.  Even though the compiler does not call any
   long double function from these libraries, the libraries do define long
   double variants.

 * Build a stage1 compiler configured for the intended floating point type
   using the compiler built in the first step.

 * Using the stage1 compiler built in the third step, then build a bootstrap
   compiler.  In theory, you can omit the stage1 build, but I found it easier
   to debug things using the stage1 build instead of bootstrap.

With the hacks that I did last week, I suspect the path of least resistance to
the users is make KIND=16 match the long double format, and then have both
floating point modules in libgfortran.  On one hand, I can certainly understand
the position that long double should always be IEEE 128-bit and KIND=16, but
again people are using the existing support and don't want their code to
change.

It would be nice if we could make Fortran switch long double types via command
line (though in general, there are a lot of places that you run into when doing
this switch, such as using third party libraries).  It would also be nice if
users could explicitly ask for the IEEE 128-bit type.

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meissner@linux.ibm.com

  parent reply	other threads:[~2021-11-01 18:46 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-31 14:43 Thomas Koenig
2021-11-01 15:54 ` Bill Schmidt
2021-11-01 17:32   ` Thomas Koenig
2021-11-01 17:45     ` Jakub Jelinek
2021-11-02  6:19       ` Thomas Koenig
2021-11-04  4:41         ` Michael Meissner
2021-11-01 18:46   ` Michael Meissner [this message]
2021-11-15 20:27     ` Thomas Koenig
2021-11-15 22:14       ` Peter Bergner
2021-11-15 23:42       ` Michael Meissner
2021-11-16  7:51         ` Thomas Koenig
2021-11-19 14:19           ` Jakub Jelinek
2021-11-19 17:30         ` Segher Boessenkool
2021-11-19 19:09           ` Thomas Koenig
2021-11-19 19:36             ` Peter Bergner
2021-11-19 21:30               ` Segher Boessenkool
2022-01-02 22:58     ` [power-iee128] How to specify linker flags Thomas Koenig
2022-01-03 10:19       ` Thomas Koenig
2022-01-03 10:33         ` Jakub Jelinek
2022-01-03 15:23           ` [power-iee128] libgfortran: Use -mno-gnu-attribute in libgfortran Jakub Jelinek
2022-01-03 15:27             ` Thomas Koenig
2022-01-03 10:34         ` [power-iee128] How to specify linker flags Segher Boessenkool
2022-01-05 21:20       ` Michael Meissner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YYA2FMfDR0yehJLA@toto.the-meissners.org \
    --to=meissner@linux.ibm.com \
    --cc=bergner@linux.ibm.com \
    --cc=dje.gcc@gmail.com \
    --cc=fortran@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=segher@kernel.crashing.org \
    --cc=tkoenig@netcologne.de \
    --cc=wschmidt@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).