On Thu, 2020-10-22 at 18:03 -0400, Michael Meissner via Gcc-patches wrote:
> PowerPC: Map IEEE 128-bit long double built-in functions
> 
> This patch is revised from the first and second versions of the patch posted.
> It now uses the names that are not in the user's namespace (i.e. __sinieee128
> instead of sinf128) that Joseph Myers suggested.
> 
> In addition, I added the changes suggested by Segher the last time this patch
> was submitted (changing where the default is, fixing the scalbl built-in name,
> using strlen and xaprintf).
> 
> I have split all of these patches into separate patches to hopefully get them
> into the tree.
> 
> This patch goes through the built-in functions and changes the name of the
> math, scanf, and printf built-in functions to use the functions that GLIBC
> provides when long double uses the IEEE 128-bit representation.
> 
> In addition, changing the name in GCC allows the Fortran compiler to
> automatically use the correct name.
> 
> To map the math functions, typically this patch changes <name>l to
> __<name>ieee128.  However there are some exceptions that are handled with this
> patch.
> 
> To map the printf functions, <name> is mapped to __<name>ieee128.
> 
> To map the scanf functions, <name> is mapped to __isoc99_<name>ieee128.
> 
> I have tested this patch with bootstrap builds on a little endian power9 
> system
> running Linux.  With the other patches, I have built two full bootstrap builds
> using this patch and the patches after this patch.  One build used the current
> default for long double (IBM extended double) and the other build switched the
> default to IEEE 128-bit.  I used the Advance Toolchain AT 14.0 compiler as the
> library used by this compiler.  There are no regressions between the tests.
> There are 3 fortran benchmarks (ieee/large_2.f90, default_format_2.f90, and
> default_format_denormal_2.f90) that now pass.
> 
> Can I install this into the trunk?
> 
> We have gotten some requests to back port these changes to GCC 10.x.  At the
> moment, I am not planning to do the back port, but I may need to in the 
> future.
> 
> gcc/
> 2020-10-22  Michael Meissner  <meiss...@linux.ibm.com>
> 
>       * config/rs6000/rs6000.c (rs6000_mangle_decl_assembler_name): Add
>       support for mapping built-in function names for long double
>       built-in functions if long double is IEEE 128-bit.

possibly redundant "built-in functions" in there, but OK. 

> 
> gcc/testsuite/
> 2020-10-22  Michael Meissner  <meiss...@linux.ibm.com>
> 
>       * gcc.target/powerpc/float128-longdouble-math.c: New test.
>       * gcc.target/powerpc/float128-longdouble-stdio.c: New test.
>       * gcc.target/powerpc/float128-math.c: Adjust test for new name
>       being generated.
> ---
>  gcc/config/rs6000/rs6000.c                    | 135 ++++-
>  .../powerpc/float128-longdouble-math.c        | 567 ++++++++++++++++++
>  .../powerpc/float128-longdouble-stdio.c       |  37 ++
>  .../gcc.target/powerpc/float128-math.c        |   6 +-
>  4 files changed, 710 insertions(+), 35 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
>  create mode 100644 
> gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
> 
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 141684e3157..8c2544ee88d 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -26893,56 +26893,127 @@ rs6000_globalize_decl_name (FILE * stream, tree 
> decl)
>     library before you can switch the real*16 type at compile time.
> 
>     We use the TARGET_MANGLE_DECL_ASSEMBLER_NAME hook to change this name.  We
> -   only do this if the default is that long double is IBM extended double, 
> and
> -   the user asked for IEEE 128-bit.  */
> +   only do this transformation if the __float128 type is enabled.  This
> +   prevents us from doing the transformation on older 32-bit ports that might
> +   have enabled using IEEE 128-bit floating point as the default long double
> +   type.  */
> 

ok


>  static tree
>  rs6000_mangle_decl_assembler_name (tree decl, tree id)
>  {
> -  if (!TARGET_IEEEQUAD_DEFAULT && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
> -      && TREE_CODE (decl) == FUNCTION_DECL && DECL_IS_BUILTIN (decl) )
> +  if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
> +      && TREE_CODE (decl) == FUNCTION_DECL
> +      && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
>      {
>        size_t len = IDENTIFIER_LENGTH (id);
>        const char *name = IDENTIFIER_POINTER (id);
> +      char *newname = NULL;
> 
> -      if (name[len - 1] == 'l')
> +      /* See if it is one of the built-in functions with an unusual name.  */
> +      switch (DECL_FUNCTION_CODE (decl))
>       {
> -       bool uses_ieee128_p = false;
> -       tree type = TREE_TYPE (decl);
> -       machine_mode ret_mode = TYPE_MODE (type);
> +     case BUILT_IN_DREML:
> +       newname = xstrdup ("__remainderieee128");
> +       break;
> 
> -       /* See if the function returns a IEEE 128-bit floating point type or
> -          complex type.  */
> -       if (ret_mode == TFmode || ret_mode == TCmode)
> -         uses_ieee128_p = true;
> -       else
> -         {
> -           function_args_iterator args_iter;
> -           tree arg;
> +     case BUILT_IN_GAMMAL:
> +       newname = xstrdup ("__lgammaieee128");
> +       break;
> +
> +     case BUILT_IN_GAMMAL_R:
> +     case BUILT_IN_LGAMMAL_R:
> +       newname = xstrdup ("__lgammaieee128_r");
> +       break;
> +
> +     case BUILT_IN_NEXTTOWARD:
> +       newname = xstrdup ("__nexttoward_to_ieee128");
> +       break;
> +
> +     case BUILT_IN_NEXTTOWARDF:
> +       newname = xstrdup ("__nexttowardf_to_ieee128");
> +       break;
> +
> +     case BUILT_IN_NEXTTOWARDL:
> +       newname = xstrdup ("__nexttowardieee128");
> +       break;
> +
> +     case BUILT_IN_POW10L:
> +       newname = xstrdup ("__exp10ieee128");
> +       break;
> +
> +     case BUILT_IN_SCALBL:
> +       newname = xstrdup ("__scalbieee128");
> +       break;
> +
> +     case BUILT_IN_SIGNIFICANDL:
> +       newname = xstrdup ("__significandieee128");
> +       break;
> +
> +     case BUILT_IN_SINCOSL:
> +       newname = xstrdup ("__sincosieee128");
> +       break;
> 
> -           /* See if the function passes a IEEE 128-bit floating point type
> -              or complex type.  */
> -           FOREACH_FUNCTION_ARGS (type, arg, args_iter)
> +     default:
> +       break;
> +     }
> +
> +      /* Update the __builtin_*printf && __builtin_*scanf functions.  */

Given your patch description:
        To map the printf functions, <name> is mapped to
        __<name>ieee128.>  To map the scanf functions, <name> is
         mapped to __isoc99_<name>ieee128.

It may be worthwhile to update that comment to STL 
        /* Map the __builtin_*printf and __builtin_*scanf functions
        to their __<>ieee128 and __isoc99_<>ieee128 counterparts.  */


> +      if (!newname)
> +     {
> +       size_t printf_len = strlen ("printf");
> +       size_t scanf_len = strlen ("scanf");
> +
> +       if (len >= printf_len
> +           && strcmp (name + len - printf_len, "printf") == 0)
> +         newname = xasprintf ("__%sieee128", name);
> +
> +       else if (len >= scanf_len
> +                && strcmp (name + len - scanf_len, "scanf") == 0)
> +         newname = xasprintf ("__isoc99_%sieee128", name);


Ok, i think.  The len >= scanf_len check there gives me pause, but I
expect those are there to help protect the strcmp() from badness, so
OK. 


> +
> +       else if (name[len - 1] == 'l')
> +         {
> +           bool uses_ieee128_p = false;
> +           tree type = TREE_TYPE (decl);
> +           machine_mode ret_mode = TYPE_MODE (type);
> +
> +           /* See if the function returns a IEEE 128-bit floating point type 
> or
> +              complex type.  */
> +           if (ret_mode == TFmode || ret_mode == TCmode)
> +             uses_ieee128_p = true;
> +           else
>               {
> -               machine_mode arg_mode = TYPE_MODE (arg);
> -               if (arg_mode == TFmode || arg_mode == TCmode)
> +               function_args_iterator args_iter;
> +               tree arg;
> +
> +               /* See if the function passes a IEEE 128-bit floating point 
> type
> +                  or complex type.  */
> +               FOREACH_FUNCTION_ARGS (type, arg, args_iter)
>                   {
> -                   uses_ieee128_p = true;
> -                   break;
> +                   machine_mode arg_mode = TYPE_MODE (arg);
> +                   if (arg_mode == TFmode || arg_mode == TCmode)
> +                     {
> +                       uses_ieee128_p = true;
> +                       break;
> +                     }

ok

>                   }
>               }
> -         }
> 
> -       /* If we passed or returned an IEEE 128-bit floating point type,
> -          change the name.  */
> -       if (uses_ieee128_p)
> -         {
> -           char *name2 = (char *) alloca (len + 4);
> -           memcpy (name2, name, len - 1);
> -           strcpy (name2 + len - 1, "f128");
> -           id = get_identifier (name2);
> +           /* If we passed or returned an IEEE 128-bit floating point type,
> +              change the name.  Use __<name>ieee128, instead of <name>l.  */
> +           if (uses_ieee128_p)
> +             newname = xasprintf ("__%.*sieee128", (int)(len - 1), name);

ok

>           }
>       }
> +
> +      if (newname)
> +     {
> +       if (TARGET_DEBUG_BUILTIN)
> +         fprintf (stderr, "Map %s => %s\n", name, newname);
> +
> +       id = get_identifier (newname);
> +       free (newname);
> +     }
>      }
> 
>    return id;

ok


> diff --git a/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c 
> b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
> new file mode 100644
> index 00000000000..50d40180fdc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
> @@ -0,0 +1,567 @@
> +/* { dg-require-effective-target ppc_float128_hw } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power9 -mno-pcrel -O2 -Wno-psabi 
> -mabi=ieeelongdouble" } */
> +
> +/* Test if switching long double to IEEE 128-bit maps all of the math 
> built-in
> +   function names correctly.  We explicitly turn off PC-relative support to
> +   make it simpler to compare the call without having a @notoc qualifier.  */
> +
> +/* Debugging support to use 'name' instead of '__builtin_name'.  Note if you
> +   enable this, you will likely need additional flags to get all of the
> +   functions defined.  */
> +#ifdef DO_FUNC
> +#ifndef DO_MATH_H
> +#define DO_MATH_H    1
> +#endif
> +
> +#define BUILTIN0(FUNC)                   FUNC ()
> +#define BUILTIN1(FUNC, ARG1)             FUNC (ARG1)
> +#define BUILTIN2(FUNC, ARG1, ARG2)       FUNC (ARG1, ARG2)
> +#define BUILTIN3(FUNC, ARG1, ARG2, ARG3) FUNC (ARG1, ARG2, ARG3)
> +
> +#else
> +#define BUILTIN0(FUNC)                   __builtin_ ## FUNC ()
> +#define BUILTIN1(FUNC, ARG1)             __builtin_ ## FUNC (ARG1)
> +#define BUILTIN2(FUNC, ARG1, ARG2)       __builtin_ ## FUNC (ARG1, ARG2)
> +#define BUILTIN3(FUNC, ARG1, ARG2, ARG3) __builtin_ ## FUNC (ARG1, ARG2, 
> ARG3)
> +#endif
> +
> +/* Debugging support to compare using math.h with the raw built-in 
> functions.  */
> +#ifdef DO_MATH_H
> +#define __STDC_WANT_IEC_60559_TYPES_EXT__    1
> +#define __STDC_WANT_IEC_60559_FUNCS_EXT__    1
> +#define _GNU_SOURCE                          1
> +#define _XOPEN_SOURCE                                1
> +
> +#include <math.h>
> +#include <complex.h>
> +#endif
> +
> +/* Built-in functions that returns a long double and take one long double
> +   argument.  */
> +
> +void
> +return_ld_arg_ld (long double *p,
> +               long double *q)
> +{
> +  /* { dg-final { scan-assembler {\m__acoshieee128\M} } }  */
> +  *p++ = BUILTIN1 (acoshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__acosieee128\M} } }  */
> +  *p++ = BUILTIN1 (acosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__asinhieee128\M} } }  */
> +  *p++ = BUILTIN1 (asinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__asinieee128\M} } }  */
> +  *p++ = BUILTIN1 (asinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__atanhieee128\M} } }  */
> +  *p++ = BUILTIN1 (atanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__atanieee128\M} } }  */
> +  *p++ = BUILTIN1 (atanl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__cbrtieee128\M} } }  */
> +  *p++ = BUILTIN1 (cbrtl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,2\M} } }  */
> +  *p++ = BUILTIN1 (ceill, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__coshieee128\M} } }  */
> +  *p++ = BUILTIN1 (coshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__cosieee128\M} } }  */
> +  *p++ = BUILTIN1 (cosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__erfcieee128\M} } }  */
> +  *p++ = BUILTIN1 (erfcl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__erfieee128\M} } }  */
> +  *p++ = BUILTIN1 (erfl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__exp10ieee128\M} } }  */
> +  *p++ = BUILTIN1 (exp10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__exp2ieee128\M} } }  */
> +  *p++ = BUILTIN1 (exp2l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__expieee128\M} } }  */
> +  *p++ = BUILTIN1 (expl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__expm1ieee128\M} } }  */
> +  *p++ = BUILTIN1 (expm1l, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsabsqp\M} } }  */
> +  *p++ = BUILTIN1 (fabsl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,3\M} } }  */
> +  *p++ = BUILTIN1 (floorl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__lgammaieee128\M} } }  */
> +  *p++ = BUILTIN1 (gammal, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__j0ieee128\M} } }  */
> +  *p++ = BUILTIN1 (j0l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__j1ieee128\M} } }  */
> +  *p++ = BUILTIN1 (j1l, *q++);
> +
> +  /* lgammaf128 mentioned previously.  */

Good comment.  A few more spaces below where something similar may be
helpful.
Was/is this one the lgammaieee128 reference 9 lines up?


> +  *p++ = BUILTIN1 (lgammal, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__log10ieee128\M} } }  */
> +  *p++ = BUILTIN1 (log10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__log1pieee128\M} } }  */
> +  *p++ = BUILTIN1 (log1pl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__log2ieee128\M} } }  */
> +  *p++ = BUILTIN1 (log2l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__logbieee128\M} } }  */
> +  *p++ = BUILTIN1 (logbl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__logieee128\M} } }  */
> +  *p++ = BUILTIN1 (logl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__nearbyintieee128\M} } }  */
> +  *p++ = BUILTIN1 (nearbyintl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__exp10ieee128\M} } }  */
> +  *p++ = BUILTIN1 (pow10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__rintieee128\M} } }  */
> +  *p++ = BUILTIN1 (rintl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__roundevenieee128\M} } }  */
> +  *p++ = BUILTIN1 (roundevenl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,0\M} } }  */
> +  *p++ = BUILTIN1 (roundl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__significandieee128\M} } }  */
> +  *p++ = BUILTIN1 (significandl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__sinhieee128\M} } }  */
> +  *p++ = BUILTIN1 (sinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__sinieee128\M} } }  */
> +  *p++ = BUILTIN1 (sinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__sqrtieee128\M} } }  */
> +  *p++ = BUILTIN1 (sqrtl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__tanhieee128\M} } }  */
> +  *p++ = BUILTIN1 (tanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__tanieee128\M} } }  */
> +  *p++ = BUILTIN1 (tanl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__tgammaieee128\M} } }  */
> +  *p++ = BUILTIN1 (tgammal, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,1\M} } }  */
> +  *p++ = BUILTIN1 (truncl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__y0ieee128\M} } }  */
> +  *p++ = BUILTIN1 (y0l, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__y1ieee128\M} } }  */
> +  *p   = BUILTIN1 (y1l, *q);  
> +
> +}
> +
> +/* Built-in functions that returns a long double and take two long double
> +   arguments.  */
> +
> +void
> +return_ld_arg_ld_ld (long double *p,
> +                  long double *q,
> +                  long double *r)
> +{
> +  /* { dg-final { scan-assembler {\m__atan2ieee128\M} } }  */
> +  *p++ = BUILTIN2 (atan2l, *q++, *r++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxscpsgnqp\M} } }  */
> +  *p++ = BUILTIN2 (copysignl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__remainderieee128\M} } }  */
> +  *p++ = BUILTIN2 (dreml, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__fdimieee128\M} } }  */
> +  *p++ = BUILTIN2 (fdiml, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__fmaxieee128\M} } }  */
> +  *p++ = BUILTIN2 (fmaxl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__fminieee128\M} } }  */
> +  *p++ = BUILTIN2 (fminl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__fmodieee128\M} } }  */
> +  *p++ = BUILTIN2 (fmodl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__hypotieee128\M} } }  */
> +  *p++ = BUILTIN2 (hypotl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__nextafterieee128\M} } }  */
> +  *p++ = BUILTIN2 (nextafterl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__nexttowardieee128\M} } }  */
> +  *p++ = BUILTIN2 (nexttowardl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__powieee128\M} } }  */
> +  *p++ = BUILTIN2 (powl, *q++, *r++);
> +
> +  /* remainderf128 mentioned previously.  */
> +  *p++ = BUILTIN2 (remainderl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__scalbnieee128\M} } }  */
> +  *p   = BUILTIN2 (scalbl, *q, *r);  
> +}
> +
> +/* Built-in function that returns a long double and take three long double
> +   arguments.  */
> +
> +void
> +return_ld_arg_ld_ld_ld (long double *p,
> +                     long double *q,
> +                     long double *r,
> +                     long double *s)
> +{
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsmaddqp\M} } }  */
> +  *p = BUILTIN3 (fmal, *q, *r, *s);
> +}
> +
> +/* Built-in functions that returns a long double and take one
> +   _Complex long double argument.  */
> +
> +void
> +return_ld_arg_cld (long double *p,
> +                _Complex long double *q)
> +{
> +  /* { dg-final { scan-assembler {\m__cabsieee128\M} } }  */
> +  *p++ = BUILTIN1 (cabsl, *q++);
> +
> +  /* inline code.  */
> +  *p++ = BUILTIN1 (cargl, *q++);
> +
> +  /* inline code.  */
> +  *p++ = BUILTIN1 (cimagl, *q++);
> +
> +  /* inline code.  */
> +  *p   = BUILTIN1 (creall, *q);  

These three already handled?


> +}
> +
> +/* Built-in functions that returns a _Complex long double and takes one
> +   _Complex long double argument.  */
> +
> +void
> +return_cld_arg_cld (_Complex long double *p,
> +                 _Complex long double *q)
> +{
> +  /* { dg-final { scan-assembler {\m__cacoshieee128\M} } }  */
> +  *p++ = BUILTIN1 (cacoshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__cacosieee128\M} } }  */
> +  *p++ = BUILTIN1 (cacosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__casinhieee128\M} } }  */
> +  *p++ = BUILTIN1 (casinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__casinieee128\M} } }  */
> +  *p++ = BUILTIN1 (casinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__catanhieee128\M} } }  */
> +  *p++ = BUILTIN1 (catanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__catanieee128\M} } }  */
> +  *p++ = BUILTIN1 (catanl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__ccoshieee128\M} } }  */
> +  *p++ = BUILTIN1 (ccoshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__ccosieee128\M} } }  */
> +  *p++ = BUILTIN1 (ccosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__cexpieee128\M} } }  */
> +  *p++ = BUILTIN1 (cexpl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__clogieee128\M} } }  */
> +  *p++ = BUILTIN1 (clogl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__clog10ieee128\M} } }  */
> +  *p++ = BUILTIN1 (clog10l, *q++);
> +
> +  /* inline code.  */
> +  *p++ = BUILTIN1 (conjl, *q++);

And this one? 

> +
> +  /* { dg-final { scan-assembler {\m__cprojieee128\M} } }  */
> +  *p++ = BUILTIN1 (cprojl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__csinhieee128\M} } }  */
> +  *p++ = BUILTIN1 (csinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__csinieee128\M} } }  */
> +  *p++ = BUILTIN1 (csinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__csqrtieee128\M} } }  */
> +  *p++ = BUILTIN1 (csqrtl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__ctanhieee128\M} } }  */
> +  *p++ = BUILTIN1 (ctanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__ctanieee128\M} } }  */
> +  *p   = BUILTIN1 (ctanl, *q);  
> +}
> +
> +/* Built-in functions that returns a _Complex long double and takes one
> +   long double argument.  */
> +
> +void
> +return_cld_arg_ld (_Complex long double *p,
> +                long double *q)
> +{
> +  /* { dg-final { scan-assembler {\m__sincosieee128\M} } }  */
> +  *p = BUILTIN1 (cexpil, *q);
> +}
> +
> +/* Built-in function that returns a _Complex long double and takes two
> +   _Complex long double arguments.  */
> +
> +void
> +return_cld_arg_cld_cld (_Complex long double *p,
> +                     _Complex long double *q,
> +                     _Complex long double *r)
> +{
> +  /* { dg-final { scan-assembler {\m__cpowieee128\M} } }  */
> +  *p = BUILTIN2 (cpowl, *q, *r);
> +}
> +
> +/* Built-in functions that returns a long double and takes a long double and 
> a
> +   pointer to an int arguments.  */
> +
> +void
> +return_ld_arg_ld_pi (long double *p,
> +                  long double *q,
> +                  int **r)
> +{
> +  /* { dg-final { scan-assembler {\m__frexpieee128\M} } }  */
> +  *p++ = BUILTIN2 (frexpl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__lgammaieee128_r\M} } }  */
> +  *p++ = BUILTIN2 (gammal_r, *q++, *r++);
> +
> +  /* __lgammaieee128_r mentioned previously.  */
> +  *p   = BUILTIN2 (lgammal_r, *q, *r);  
> +}
> +
> +/* Built-in functions that returns a long double and takes a long double and 
> an
> +   int arguments.  */
> +
> +void
> +return_ld_arg_ld_i (long double *p,
> +                 long double *q,
> +                 int *r)
> +{
> +  /* { dg-final { scan-assembler {\m__ldexpieee128\M} } }  */
> +  *p++ = BUILTIN2 (ldexpl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__powikf2\M} } }  */
> +  *p++ = BUILTIN2 (powil, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__scalbnieee128\M} } }  */
> +  *p   = BUILTIN2 (scalbnl, *q, *r);  
> +}
> +
> +/* Built-in function that returns a long double and takes a long double and a
> +   long arguments.  */
> +
> +void
> +return_ld_arg_ld_l (long double *p,
> +                 long double *q,
> +                 long *r)
> +{
> +  /* { dg-final { scan-assembler {\m__scalblnieee128\M} } }  */
> +  *p = BUILTIN2 (scalblnl, *q, *r);
> +}
> +
> +/* Built-in functions that returns a long double and takes a long double and 
> a
> +   long long arguments.  */
> +
> +void
> +return_ld_arg_i_ld (long double *p,
> +                 int *q,
> +                 long double *r)
> +{
> +  /* { dg-final { scan-assembler {\m__jnieee128\M} } }  */
> +  *p++ = BUILTIN2 (jnl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\m__ynieee128\M} } }  */
> +  *p   = BUILTIN2 (ynl, *q, *r);  
> +}
> +
> +/* Built-in functions that returns a long double and takes a long double and 
> a
> +   pointer to a long double arguments.  */
> +
> +void
> +return_ld_arg_ld_pld (long double *p,
> +                   long double *q,
> +                   long double **r)
> +{
> +  /* { dg-final { scan-assembler {\m__modfieee128\M} } }  */
> +  *p = BUILTIN2 (modfl, *q, *r);
> +}
> +
> +/* Built-in function that returns a long double and takes two long double 
> and a
> +   pointer to an int arguments.  */
> +
> +void
> +return_ld_arg_ld_ld_pi (long double *p,
> +                     long double *q,
> +                     long double *r,
> +                     int **s)
> +{
> +  /* { dg-final { scan-assembler {\m__remquoieee128\M} } }  */
> +  *p = BUILTIN3 (remquol, *q, *r, *s);
> +}
> +
> +/* Built-in functions that returns a long double and take no arguments.  */
> +
> +void
> +return_ld_no_arg (long double *p)
> +{
> +  /* inline code.  */
> +  *p++ = BUILTIN0 (huge_vall);
> +
> +  /* inline code.  */
> +  *p   = BUILTIN0 (infl);     
> +}
> +
> +/* Built-in functions that return san int and takes one long double 
> argument.  */
> +
> +void
> +return_i_arg_ld (int *p,
> +              long double *q)
> +{
> +  /* { dg-final { scan-assembler {\m__ceilieee128\M} } }  */
> +  *p++ = BUILTIN1 (iceill, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__floorieee128\M} } }  */
> +  *p++ = BUILTIN1 (ifloorl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__ilogbieee128\M} } }  */
> +  *p++ = BUILTIN1 (ilogbl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__lrintieee128\M} } }  */
> +  *p++ = BUILTIN1 (irintl, *q++);
> +
> +  /* { dg-final { scan-assembler {\m__lroundieee128\M} } }  */
> +  *p++ = BUILTIN1 (iroundl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxscvqpswz\M} } }  */
> +  *p++ = BUILTIN1 (signbitl, *q++);
> +
> +  /* inline code.  */
> +  *p++ = BUILTIN1 (finitel, *q++);
> +
> +  /* inline code.  */
> +  *p++ = BUILTIN1 (isinfl, *q++);
> +
> +  /* inline code.  */
> +  *p   = BUILTIN1 (isnanl, *q);  
> +}
> +
> +/* Built-in functions that returns a long and takes one long double 
> argument.  */
> +
> +void
> +return_l_arg_ld (long *p,
> +              long double *q)
> +{
> +  /* ceilf128 mentioned previouly.  */
> +  *p++ = BUILTIN1 (lceill, *q++);
> +
> +  /* floorf128 mentioned previously.  */
> +  *p++ = BUILTIN1 (lfloorl, *q++);
> +
> +  /* lrintf128 mentioned previously.  */
> +  *p++ = BUILTIN1 (lrintl, *q++);
> +
> +  /* lroundf128 mentioned previously.  */
> +  *p   = BUILTIN1 (lroundl, *q);  
> +}
> +
> +/* Built-in functions that returns a long long and takes one long double
> +   argument.  */
> +
> +void
> +return_ll_arg_ld (long long *p,
> +               long double *r)
> +{
> +  /* ceilf128 mentioned previous.  */
> +  *p++ = BUILTIN1 (llceill, *r++);
> +
> +  /* floorf128 mentioned previously.  */
> +  *p++ = BUILTIN1 (llfloorl, *r++);
> +
> +  /* llrintf128 mentioned previously.  */
> +  *p++ = BUILTIN1 (llrintl, *r++);
> +
> +  /* llroundf128 mentioned previously.  */
> +  *p   = BUILTIN1 (llroundl, *r);  
> +}
> +
> +/* Built-in function that returns a double and takes one double and one long
> +   double arguments.  */
> +
> +void
> +return_d_arg_d_ld (double *p,
> +                double *q,
> +                long double *r)
> +{
> +  /* { dg-final { scan-assembler {\m__nexttoward_to_ieee128\M} } }  */
> +  *p = BUILTIN2 (nexttoward, *q, *r);
> +}
> +
> +/* Built-in function that returns a float and takes one float and one long
> +   double arguments.  */
> +
> +void
> +return_f_arg_f_ld (float *p,
> +                float *q,
> +                long double *r)
> +{
> +  /* { dg-final { scan-assembler {\m__nexttowardf_to_ieee128\M} } }  */
> +  *p = BUILTIN2 (nexttowardf, *q, *r);
> +}
> +
> +/* Built-in function that returns void and takes one long double and two
> +   pointers to long double arguments.  */
> +
> +void
> +return_void_arg_ld_pld_pld (long double *p,
> +                         long double **q,
> +                         long double **r)
> +{
> +  /* __sincosieee128 mentioned previously.  */
> +  BUILTIN3 (sincosl, *p, *q, *r);
> +}
> +
> +/* Debug main program to determine if the library has all of the mapped
> +   external functions.  Note, you need a new enough glibc to provide all of 
> the
> +   f128 functions.  */
> +#ifdef DO_MAIN

I don't see any obvious hook for setting DO_MAIN under a debug flag. 
(Which is fine, just a nit and to indicate I've read this far.. )

> +int
> +main (void)
> +{
> +  return 0;
> +}
> +#endif
> diff --git a/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c 
> b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
> new file mode 100644
> index 00000000000..570f3e071b9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
> @@ -0,0 +1,37 @@
> +/* { dg-require-effective-target ppc_float128_hw } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power9 -mno-pcrel -O2 -Wno-psabi 
> -mabi=ieeelongdouble" } */
> +
> +/* Test if switching long double to IEEE 128-bit maps the printf and scanf
> +   function names correctly.  We explicitly turn off PC-relative support to
> +   make it simpler to compare the call without having a @notoc qualifier.  */
> +
> +#include <stdlib.h>
> +
> +volatile long double x = 1.0L;
> +volatile long double y, z;
> +
> +int
> +main (void)
> +{
> +  char buffer[100];
> +
> +  /* { dg-final { scan-assembler {\m__sprintfieee128\M} } }  */
> +  __builtin_sprintf (buffer, "%Lg", x);
> +
> +  /* { dg-final { scan-assembler {\m__printfieee128\M} } }  */
> +  __builtin_printf ("x is %Lg [%s]\n", x, buffer);
> +
> +  /* { dg-final { scan-assembler {\m__isoc99_sscanfieee128\M} } }  */
> +  __builtin_sscanf (buffer, "%Lg", &y);
> +
> +  __builtin_printf ("Type 1.0: ");

Does "Type 1.0" have meaning?

> +
> +  /* { dg-final { scan-assembler {\m__isoc99_scanfieee128\M} } }  */
> +  __builtin_scanf ("%Lg", &z);
> +
> +  if (x != y || x != z)
> +    abort ();
> +
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/float128-math.c 
> b/gcc/testsuite/gcc.target/powerpc/float128-math.c
> index 4ad3b5b8363..ea5cb43bcf1 100644
> --- a/gcc/testsuite/gcc.target/powerpc/float128-math.c
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-math.c
> @@ -10,11 +10,11 @@
> 
>  extern __float128 sinf128 (__float128);
> 
> -void foo (__float128 *p, long double *q, long double *r)
> +void foo (__float128 *p, long double *q)
>  {
>    *p = sinf128 (*p);
>    *q = __builtin_sinl (*q);
>  }
> 
> -/* { dg-final { scan-assembler-times {\mbl sinf128\M} 2 } } */
> -/* { dg-final { scan-assembler-not   {\mbl sinl\M}      } } */
> +/* { dg-final { scan-assembler     {\mbl __sinieee128\M} } } */
> +/* { dg-final { scan-assembler-not {\mbl sinl\M}         } } */
> -- 
> 2.22.0
> 

no functional issues jumped out..  lgtm, 
thanks
-Will

> 

Reply via email to