On Thu, 2021-01-14 at 11:59 -0500, Michael Meissner via Gcc-patches wrote:
> From 78435dee177447080434cdc08fc76b1029c7f576 Mon Sep 17 00:00:00 2001
> From: Michael Meissner <meiss...@linux.ibm.com>
> Date: Wed, 13 Jan 2021 21:47:03 -0500
> Subject: [PATCH] PowerPC: Map IEEE 128-bit long double built-ins.
> 
> This patch replaces patches previously submitted:
> 
> September 24th, 2020:
> Message-ID: <20200924203159.ga31...@ibm-toto.the-meissners.org>
> 
> October 9th, 2020:
> Message-ID: <20201009043543.ga11...@ibm-toto.the-meissners.org>
> 
> October 24th, 2020:
> Message-ID: <20201022220346.ga8...@ibm-toto.the-meissners.org>
> 
> November 19th, 2020:
> Message-ID: <20201119235814.ga...@ibm-toto.the-meissners.org>


Subject and date should be sufficient _if_ having the old versions
of the patchs are necessary to review the latest version of the
patch.  Which ideally is not the case.


> 
> This patch maps the built-in functions that take or return long double
> arguments on systems where long double is IEEE 128-bit.
> 
> If long double is IEEE 128-bit, 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.

ok.

> 
> In addition, changing the name in GCC allows the Fortran compiler to
> automatically use the correct name.

Does the fortran compiler currently use the wrong name? (pr?)

> 
> 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.

This appears to be  the rs6000_mangle_decl_assembler_name() function, which
also maps <name>l_r to <name>ieee128_r, and looks like some additional special
handling for printf and scanf.  


> 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 by doing builds, bootstraps, and make check with 3
> builds on a power9 little endian server:
> 
>     * Build one used the default long double being IBM 128-bit;
>     * Build two set the long double default to IEEE 128-bit; (and)
>     * Build three set the long double default to 64-bit.
> 

ok

> The compilers built fine providing I recompiled gmp, mpc, and mpfr with the
> appropriate long double options.

Presumably the build is otherwise broken... 
Does that mean more than invoking download_preqrequisites as part of the
build?   If there are specific options required during configure/build of
those packages, they should be called out.

> There were a few differences in the test
> suite runs that will be addressed in later patches, but over all it works
> well.

Presumably minimal. :-)


>       This patch is required to be able to build a toolchain where the default
> long double is IEEE 128-bit. 

Ok.   Could lead the patch description with this,.  I imagine this is
just one of several patches that are still required towrards that goal.



>  Can I check this patch into the master branch for
> GCC 11?





> 
> gcc/
> 2021-01-14  Michael Meissner  <meiss...@linux.ibm.com>
> 
>       * config/rs6000/rs6000.c (ieee128_builtin_name): New function.
>       (built_in_uses_long_double): New function.
>       (identifier_ends_in_suffix): New function.
>       (rs6000_mangle_decl_assembler_name): Update support for mapping built-in
>       function names for long double built-in functions if long double is
>       IEEE 128-bit to catch all of the built-in functions that take or
>       return long double arguments.
> 
> gcc/testsuite/
> 2021-01-14  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.  Add support for running test on power10.  Add
>       support for running if long double defaults to 64-bits.
> ---
>  gcc/config/rs6000/rs6000.c                    | 239 ++++++++--
>  .../powerpc/float128-longdouble-math.c        | 442 ++++++++++++++++++
>  .../powerpc/float128-longdouble-stdio.c       |  36 ++
>  .../gcc.target/powerpc/float128-math.c        |  16 +-
>  4 files changed, 694 insertions(+), 39 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 6f48dd6566d..282703b9715 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -27100,6 +27100,172 @@ rs6000_globalize_decl_name (FILE * stream, tree 
> decl)
>  #endif
> 
>  
> +/* If long double uses the IEEE 128-bit representation, return the name used
> +   within GLIBC for the IEEE 128-bit long double built-in, instead of the
> +   default IBM 128-bit long double built-in.  Or return NULL if the built-in
> +   function does not use long double.  */


This doesn't have any checks for mode, this only returns the name used
for the IEEE built-in.   (so, you can drop the "If .. representation, "
and "instead of .." built-in" portions of that comment.)
Does the
default case occur naturally?  May be worth a debug-builtin printf/info
statement there.
(Actually I see there is a debug_builtin info blurb in
the caller of this function, so probably OK there.. )

> +
> +static const char *
> +ieee128_builtin_name (built_in_function fn)
> +{
> +  switch (fn)
> +    {
> +    default:                 return NULL;
> +    case BUILT_IN_ACOSHL:    return "__acoshieee128";
> +    case BUILT_IN_ACOSL:     return "__acosieee128";
> +    case BUILT_IN_ASINHL:    return "__asinhieee128";
> +    case BUILT_IN_ASINL:     return "__asinieee128";
> +    case BUILT_IN_ATAN2L:    return "__atan2ieee128";
> +    case BUILT_IN_ATANHL:    return "__atanhieee128";
> +    case BUILT_IN_ATANL:     return "__atanieee128";
> +    case BUILT_IN_CABSL:     return "__cabsieee128";
> +    case BUILT_IN_CACOSHL:   return "__cacoshieee128";
> +    case BUILT_IN_CACOSL:    return "__cacosieee128";
> +    case BUILT_IN_CARGL:     return "__cargieee128";
> +    case BUILT_IN_CASINHL:   return "__casinhieee128";
> +    case BUILT_IN_CASINL:    return "__casinieee128";
> +    case BUILT_IN_CATANHL:   return "__catanhieee128";
> +    case BUILT_IN_CATANL:    return "__catanieee128";
> +    case BUILT_IN_CBRTL:     return "__cbrtieee128";
> +    case BUILT_IN_CCOSHL:    return "__ccoshieee128";
> +    case BUILT_IN_CCOSL:     return "__ccosieee128";
> +    case BUILT_IN_CEILL:     return "__ceilieee128";
> +    case BUILT_IN_CEXPL:     return "__cexpieee128";
> +    case BUILT_IN_CIMAGL:    return "__cimagieee128";
> +    case BUILT_IN_CLOG10L:   return "__clog10ieee128";
> +    case BUILT_IN_CLOGL:     return "__clogieee128";
> +    case BUILT_IN_CONJL:     return "__conjieee128";
> +    case BUILT_IN_COPYSIGNL: return "__copysignieee128";
> +    case BUILT_IN_COSHL:     return "__coshieee128";
> +    case BUILT_IN_COSL:              return "__cosieee128";
> +    case BUILT_IN_CPOWL:     return "__cpowieee128";
> +    case BUILT_IN_CPROJL:    return "__cprojieee128";
> +    case BUILT_IN_CREALL:    return "__crealieee128";
> +    case BUILT_IN_CSINHL:    return "__csinhieee128";
> +    case BUILT_IN_CSINL:     return "__csinieee128";
> +    case BUILT_IN_CSQRTL:    return "__csqrtieee128";
> +    case BUILT_IN_CTANHL:    return "__ctanhieee128";
> +    case BUILT_IN_CTANL:     return "__ctanieee128";
> +    case BUILT_IN_DREML:     return "__remainderieee128";
> +    case BUILT_IN_ERFCL:     return "__erfcieee128";
> +    case BUILT_IN_ERFL:              return "__erfieee128";
> +    case BUILT_IN_EXP10L:    return "__exp10ieee128";
> +    case BUILT_IN_EXP2L:     return "__exp2ieee128";
> +    case BUILT_IN_EXPL:              return "__expieee128";
> +    case BUILT_IN_EXPM1L:    return "__expm1ieee128";
> +    case BUILT_IN_FABSL:     return "__fabsieee128";
> +    case BUILT_IN_FDIML:     return "__fdimieee128";
> +    case BUILT_IN_FINITEL:   return "__finiteieee128";
> +    case BUILT_IN_FLOORL:    return "__floorieee128";
> +    case BUILT_IN_FMAL:              return "__fmaieee128";
> +    case BUILT_IN_FMAXL:     return "__fmaxieee128";
> +    case BUILT_IN_FMINL:     return "__fminieee128";
> +    case BUILT_IN_FMODL:     return "__fmodieee128";
> +    case BUILT_IN_FPRINTF:   return "__fprintfieee128";
> +    case BUILT_IN_FREXPL:    return "__frexpieee128";
> +    case BUILT_IN_FSCANF:    return "__isoc99_fscanfieee128";
> +    case BUILT_IN_GAMMAL:    return "__lgammaieee128";
> +    case BUILT_IN_GAMMAL_R:  return "__lgammaieee128_r";
> +    case BUILT_IN_HYPOTL:    return "__hypotieee128";
> +    case BUILT_IN_ILOGBL:    return "__ilogbieee128";
> +    case BUILT_IN_ISINFL:    return "__isinfieee128";
> +    case BUILT_IN_ISNANL:    return "__isnanieee128";
> +    case BUILT_IN_J0L:               return "__j0ieee128";
> +    case BUILT_IN_J1L:               return "__j1ieee128";
> +    case BUILT_IN_JNL:               return "__jnieee128";
> +    case BUILT_IN_LDEXPL:    return "__ldexpieee128";
> +    case BUILT_IN_LGAMMAL:   return "__lgammaieee128";
> +    case BUILT_IN_LGAMMAL_R: return "__lgammaieee128_r";
> +    case BUILT_IN_LLRINTL:   return "__llrintieee128";
> +    case BUILT_IN_LLROUNDL:  return "__llroundieee128";
> +    case BUILT_IN_LOG10L:    return "__log10ieee128";
> +    case BUILT_IN_LOG1PL:    return "__log1pieee128";
> +    case BUILT_IN_LOG2L:     return "__log2ieee128";
> +    case BUILT_IN_LOGBL:     return "__logbieee128";
> +    case BUILT_IN_LOGL:              return "__logieee128";
> +    case BUILT_IN_LRINTL:    return "__lrintieee128";
> +    case BUILT_IN_LROUNDL:   return "__lroundieee128";
> +    case BUILT_IN_MODFL:     return "__modfieee128";
> +    case BUILT_IN_NEARBYINTL:        return "__nearbyintieee128";
> +    case BUILT_IN_NEXTAFTERL:        return "__nextafterieee128";
> +    case BUILT_IN_NEXTTOWARD:        return "__nexttoward_to_ieee128";
> +    case BUILT_IN_NEXTTOWARDF:       return "__nexttowardf_to_ieee128";
> +    case BUILT_IN_NEXTTOWARDL:       return "__nexttowardieee128";
> +    case BUILT_IN_POW10L:    return "__exp10ieee128";
> +    case BUILT_IN_POWL:              return "__powieee128";
> +    case BUILT_IN_PRINTF:    return "__printfieee128";
> +    case BUILT_IN_REMAINDERL:        return "__remainderieee128";
> +    case BUILT_IN_REMQUOL:   return "__remquoieee128";
> +    case BUILT_IN_RINTL:     return "__rintieee128";
> +    case BUILT_IN_ROUNDEVENL:        return "__roundevenieee128";
> +    case BUILT_IN_ROUNDL:    return "__roundieee128";
> +    case BUILT_IN_SCALBL:    return "__scalbieee128";
> +    case BUILT_IN_SCALBLNL:  return "__scalblnieee128";
> +    case BUILT_IN_SCALBNL:   return "__scalbnieee128";
> +    case BUILT_IN_SCANF:     return "__isoc99_scanfieee128";
> +    case BUILT_IN_SIGNBITL:  return "__signbitieee128";
> +    case BUILT_IN_SIGNIFICANDL:      return "__significandieee128";
> +    case BUILT_IN_SINCOSL:   return "__sincosieee128";
> +    case BUILT_IN_SINHL:     return "__sinhieee128";
> +    case BUILT_IN_SINL:              return "__sinieee128";
> +    case BUILT_IN_SNPRINTF:  return "__snprintfieee128";
> +    case BUILT_IN_SPRINTF:   return "__sprintfieee128";
> +    case BUILT_IN_SQRTL:     return "__sqrtieee128";
> +    case BUILT_IN_SSCANF:    return "__isoc99_sscanfieee128";
> +    case BUILT_IN_TANHL:     return "__tanhieee128";
> +    case BUILT_IN_TANL:              return "__tanieee128";
> +    case BUILT_IN_TGAMMAL:   return "__tgammaieee128";
> +    case BUILT_IN_TRUNCL:    return "__truncieee128";
> +    case BUILT_IN_VFPRINTF:  return "__vfprintfieee128";
> +    case BUILT_IN_VFSCANF:   return "__isoc99_vfscanfieee128";
> +    case BUILT_IN_VPRINTF:   return "__vprintfieee128";
> +    case BUILT_IN_VSCANF:    return "__isoc99_vscanfieee128";
> +    case BUILT_IN_VSNPRINTF: return "__vsnprintfieee128";
> +    case BUILT_IN_VSPRINTF:  return "__vsprintfieee128";
> +    case BUILT_IN_VSSCANF:   return "__isoc99_vsscanfieee128";
> +    case BUILT_IN_Y0L:               return "__y0ieee128";
> +    case BUILT_IN_Y1L:               return "__y1ieee128";
> +    case BUILT_IN_YNL:               return "__ynieee128";
> +    }
> +}
> +
> +/* Return true if a built-in function returns or passes a long double type.  
> */
> +static bool
> +built_in_uses_long_double (tree decl)
> +{
> +  tree type = TREE_TYPE (decl);
> +  machine_mode ret_mode = TYPE_MODE (type);
> +
> +  /* See if the function returns a long double type.  */
> +  if (ret_mode == TFmode || ret_mode == TCmode)
> +    return true;
> +
> +  function_args_iterator args_iter;
> +  tree arg;
> +
> +  /* See if the function passes a long double type.  */
> +  FOREACH_FUNCTION_ARGS (type, arg, args_iter)
> +    {
> +      machine_mode arg_mode = TYPE_MODE (arg);
> +      if (arg_mode == TFmode || arg_mode == TCmode)
> +     return true;
> +    }
> +
> +  return false;
> +}

ok


> +
> +/* Return true if an identifier ends in a specific suffix.  */
> +static bool
> +identifier_ends_in_suffix (tree id, const char *suffix)
> +{
> +  size_t suffix_len = strlen (suffix);
> +  size_t id_len = IDENTIFIER_LENGTH (id);
> +
> +  return (id_len > suffix_len
> +       && strcmp (IDENTIFIER_POINTER (id), suffix) == 0);
> +}
> +


ok

> +
>  /* On 64-bit Linux and Freebsd systems, possibly switch the long double 
> library
>     function names from <foo>l to <foo>f128 if the default long double type is
>     IEEE 128-bit.  Typically, with the C and C++ languages, the standard 
> math.h
> @@ -27120,51 +27286,62 @@ rs6000_globalize_decl_name (FILE * stream, tree 
> decl)
>  static tree
>  rs6000_mangle_decl_assembler_name (tree decl, tree id)
>  {
> -  if (!TARGET_IEEEQUAD_DEFAULT && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
> +  if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
>        && TREE_CODE (decl) == FUNCTION_DECL
> -      && DECL_IS_UNDECLARED_BUILTIN (decl))
> +      && DECL_IS_UNDECLARED_BUILTIN (decl)
> +      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
>      {
> -      size_t len = IDENTIFIER_LENGTH (id);
> -      const char *name = IDENTIFIER_POINTER (id);
> +      const char *ieee_name = ieee128_builtin_name (DECL_FUNCTION_CODE 
> (decl));
> +      tree id_orig = id;
> 
> -      if (name[len - 1] == 'l')
> +      if (ieee_name)
> +     id = get_identifier (ieee_name);
> +
> +      /* If we did not get an IEEE 128-bit built-in name, check to see if a 
> new
> +      math built-in function that is passed or returns long double arguments.
> +      If it ends in 'l' or 'l_r', convert the name the GLIBC IEEE 128-bit
> +      built-in name.  Also convert any printf/scanf functions that were not
> +      handled.  */
> +      if (!ieee_name)
>       {
> -       bool uses_ieee128_p = false;
> -       tree type = TREE_TYPE (decl);
> -       machine_mode ret_mode = TYPE_MODE (type);
> +       const char *name = IDENTIFIER_POINTER (id);
> +       char *new_name = NULL;
> +       size_t len = IDENTIFIER_LENGTH (id);
> 
> -       /* 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
> +       if (built_in_uses_long_double (decl))
>           {
> -           function_args_iterator args_iter;
> -           tree arg;
> +           if (identifier_ends_in_suffix (id, "l"))
> +             {
> +               int len_m1 = len - 1;         /* eliminate 'l'.  */
> +               new_name = xasprintf ("__%.*sieee128", len_m1, name);
> +             }
> 
> -           /* See if the function passes a IEEE 128-bit floating point type
> -              or complex type.  */
> -           FOREACH_FUNCTION_ARGS (type, arg, args_iter)
> +           else if (identifier_ends_in_suffix (id, "l_r"))
>               {
> -               machine_mode arg_mode = TYPE_MODE (arg);
> -               if (arg_mode == TFmode || arg_mode == TCmode)
> -                 {
> -                   uses_ieee128_p = true;
> -                   break;
> -                 }
> +               int len_m3 = len - 3;         /* eliminate 'l_r'.  */
> +               new_name = xasprintf ("__%.*sieee128_r", len_m3, name);
>               }
>           }
> 
> -       /* If we passed or returned an IEEE 128-bit floating point type,
> -          change the name.  */
> -       if (uses_ieee128_p)
> +       /* Check that no new printf/scanf functions were added.  */
> +       else if (identifier_ends_in_suffix (id, "printf"))
> +         new_name = xasprintf ("__%sieee128", name);
> +
> +       else if (identifier_ends_in_suffix (id, "scanf"))
> +         new_name = xasprintf ("__isoc99_%sieee128", name);
> +
> +       if (new_name)
>           {
> -           char *name2 = (char *) alloca (len + 4);
> -           memcpy (name2, name, len - 1);
> -           strcpy (name2 + len - 1, "f128");
> -           id = get_identifier (name2);
> +           id = get_identifier (new_name);
> +           free ((void *)new_name);
>           }
>       }
> +
> +      if (id != id_orig && TARGET_DEBUG_BUILTIN)
> +     fprintf (stderr, "Map %s => %s%s\n",
> +              IDENTIFIER_POINTER (id_orig),
> +              IDENTIFIER_POINTER (id),
> +              ieee_name != NULL ? "" : " (not in table)");
>      }
> 
>    return id;
> 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..07934bb7357
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
> @@ -0,0 +1,442 @@
> +/* { dg-require-effective-target ppc_float128_hw } */
> +/* { dg-options "-mdejagnu-cpu=power9 -O2 -mlong-double-128 -Wno-psabi 
> -mabi=ieeelongdouble" } */
> +
> +/* Test if switching long double to IEEE 128-bit maps all of the math 
> built-in
> +   function names correctly.  We leave off the \M in matching the calls, so
> +   power10 will match using bl foo@notoc.  */
> +
> +#ifdef DO_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 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
> +
> +/* 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 {\mbl __acoshieee128} } }  */
> +  *p++ = BUILTIN1 (acoshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __acosieee128} } }  */
> +  *p++ = BUILTIN1 (acosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __asinhieee128} } }  */
> +  *p++ = BUILTIN1 (asinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __asinieee128} } }  */
> +  *p++ = BUILTIN1 (asinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __atanhieee128} } }  */
> +  *p++ = BUILTIN1 (atanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __atanieee128} } }  */
> +  *p++ = BUILTIN1 (atanl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __cbrtieee128} } }  */
> +  *p++ = BUILTIN1 (cbrtl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,2} } }  */
> +  *p++ = BUILTIN1 (ceill, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __coshieee128} } }  */
> +  *p++ = BUILTIN1 (coshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __cosieee128} } }  */
> +  *p++ = BUILTIN1 (cosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __erfcieee128} } }  */
> +  *p++ = BUILTIN1 (erfcl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __erfieee128} } }  */
> +  *p++ = BUILTIN1 (erfl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __exp10ieee128} } }  */
> +  *p++ = BUILTIN1 (exp10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __exp2ieee128} } }  */
> +  *p++ = BUILTIN1 (exp2l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __expieee128} } }  */
> +  *p++ = BUILTIN1 (expl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __expm1ieee128} } }  */
> +  *p++ = BUILTIN1 (expm1l, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsabsqp} } }  */
> +  *p++ = BUILTIN1 (fabsl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,3} } }  */
> +  *p++ = BUILTIN1 (floorl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __lgammaieee128} } }  */
> +  *p++ = BUILTIN1 (gammal, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __j0ieee128} } }  */
> +  *p++ = BUILTIN1 (j0l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __j1ieee128} } }  */
> +  *p++ = BUILTIN1 (j1l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __log10ieee128} } }  */
> +  *p++ = BUILTIN1 (log10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __log1pieee128} } }  */
> +  *p++ = BUILTIN1 (log1pl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __log2ieee128} } }  */
> +  *p++ = BUILTIN1 (log2l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __logbieee128} } }  */
> +  *p++ = BUILTIN1 (logbl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __logieee128} } }  */
> +  *p++ = BUILTIN1 (logl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __nearbyintieee128} } }  */
> +  *p++ = BUILTIN1 (nearbyintl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __exp10ieee128} } }  */
> +  *p++ = BUILTIN1 (pow10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __rintieee128} } }  */
> +  *p++ = BUILTIN1 (rintl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __roundevenieee128} } }  */
> +  *p++ = BUILTIN1 (roundevenl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,0} } }  */
> +  *p++ = BUILTIN1 (roundl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __significandieee128} } }  */
> +  *p++ = BUILTIN1 (significandl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __sinhieee128} } }  */
> +  *p++ = BUILTIN1 (sinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __sinieee128} } }  */
> +  *p++ = BUILTIN1 (sinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __sqrtieee128} } }  */
> +  *p++ = BUILTIN1 (sqrtl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __tanhieee128} } }  */
> +  *p++ = BUILTIN1 (tanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __tanieee128} } }  */
> +  *p++ = BUILTIN1 (tanl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __tgammaieee128} } }  */
> +  *p++ = BUILTIN1 (tgammal, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,1} } }  */
> +  *p++ = BUILTIN1 (truncl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __y0ieee128} } }  */
> +  *p++ = BUILTIN1 (y0l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __y1ieee128} } }  */
> +  *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 {\mbl __atan2ieee128} } }  */
> +  *p++ = BUILTIN2 (atan2l, *q++, *r++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxscpsgnqp} } }  */
> +  *p++ = BUILTIN2 (copysignl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __remainderieee128} } }  */
> +  *p++ = BUILTIN2 (dreml, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __fdimieee128} } }  */
> +  *p++ = BUILTIN2 (fdiml, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __fmaxieee128} } }  */
> +  *p++ = BUILTIN2 (fmaxl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __fminieee128} } }  */
> +  *p++ = BUILTIN2 (fminl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __fmodieee128} } }  */
> +  *p++ = BUILTIN2 (fmodl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __hypotieee128} } }  */
> +  *p++ = BUILTIN2 (hypotl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __nextafterieee128} } }  */
> +  *p++ = BUILTIN2 (nextafterl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __nexttowardieee128} } }  */
> +  *p++ = BUILTIN2 (nexttowardl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __powieee128} } }  */
> +  *p++ = BUILTIN2 (powl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __scalbnieee128} } }  */
> +  *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} } }  */
> +  *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 {\mbl __cabsieee128} } }  */
> +  *p++ = BUILTIN1 (cabsl, *q++);
> +}
> +
> +/* 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 {\mbl __cacoshieee128} } }  */
> +  *p++ = BUILTIN1 (cacoshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __cacosieee128} } }  */
> +  *p++ = BUILTIN1 (cacosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __casinhieee128} } }  */
> +  *p++ = BUILTIN1 (casinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __casinieee128} } }  */
> +  *p++ = BUILTIN1 (casinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __catanhieee128} } }  */
> +  *p++ = BUILTIN1 (catanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __catanieee128} } }  */
> +  *p++ = BUILTIN1 (catanl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __ccoshieee128} } }  */
> +  *p++ = BUILTIN1 (ccoshl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __ccosieee128} } }  */
> +  *p++ = BUILTIN1 (ccosl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __cexpieee128} } }  */
> +  *p++ = BUILTIN1 (cexpl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __clogieee128} } }  */
> +  *p++ = BUILTIN1 (clogl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __clog10ieee128} } }  */
> +  *p++ = BUILTIN1 (clog10l, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __cprojieee128} } }  */
> +  *p++ = BUILTIN1 (cprojl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __csinhieee128} } }  */
> +  *p++ = BUILTIN1 (csinhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __csinieee128} } }  */
> +  *p++ = BUILTIN1 (csinl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __csqrtieee128} } }  */
> +  *p++ = BUILTIN1 (csqrtl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __ctanhieee128} } }  */
> +  *p++ = BUILTIN1 (ctanhl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __ctanieee128} } }  */
> +  *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 {\mbl __sincosieee128} } }  */
> +  *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 {\mbl __cpowieee128} } }  */
> +  *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 {\mbl __frexpieee128} } }  */
> +  *p++ = BUILTIN2 (frexpl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __lgammaieee128_r} } }  */
> +  *p++ = BUILTIN2 (gammal_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 {\mbl __ldexpieee128} } }  */
> +  *p++ = BUILTIN2 (ldexpl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __powikf2} } }  */
> +  *p++ = BUILTIN2 (powil, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __scalbnieee128} } }  */
> +  *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 {\mbl __scalblnieee128} } }  */
> +  *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 {\mbl __jnieee128} } }  */
> +  *p++ = BUILTIN2 (jnl, *q++, *r++);
> +
> +  /* { dg-final { scan-assembler {\mbl __ynieee128} } }  */
> +  *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 {\mbl __modfieee128} } }  */
> +  *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 {\mbl __remquoieee128} } }  */
> +  *p = BUILTIN3 (remquol, *q, *r, *s);
> +}
> +
> +/* 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 {\mbl __ceilieee128} } }  */
> +  *p++ = BUILTIN1 (iceill, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __floorieee128} } }  */
> +  *p++ = BUILTIN1 (ifloorl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __ilogbieee128} } }  */
> +  *p++ = BUILTIN1 (ilogbl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __lrintieee128} } }  */
> +  *p++ = BUILTIN1 (irintl, *q++);
> +
> +  /* { dg-final { scan-assembler {\mbl __lroundieee128} } }  */
> +  *p++ = BUILTIN1 (iroundl, *q++);
> +
> +  /* inline code.  */
> +  /* { dg-final { scan-assembler {\mxscvqpswz} } }  */
> +  *p++ = BUILTIN1 (signbitl, *q++);
> +}
> +
> +/* 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 {\mbl __nexttoward_to_ieee128} } }  */
> +  *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 {\mbl __nexttowardf_to_ieee128} } }  */
> +  *p = BUILTIN2 (nexttowardf, *q, *r);
> +}
> 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..39e59d949f9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
> @@ -0,0 +1,36 @@
> +/* { dg-require-effective-target ppc_float128_hw } */
> +/* { dg-options "-mdejagnu-cpu=power9 -O2 -mlong-double-128 -Wno-psabi 
> -mabi=ieeelongdouble" } */
> +
> +/* Test if switching long double to IEEE 128-bit maps the printf and scanf
> +   function names correctly.  We leave off the \M in matching the calls, so
> +   power10 will match using bl foo@notoc.  */
> +
> +#include <stdlib.h>
> +
> +volatile long double x = 1.0L;
> +volatile long double y, z;
> +
> +int
> +main (void)
> +{
> +  char buffer[100];
> +
> +  /* { dg-final { scan-assembler {\mbl __sprintfieee128} } }  */
> +  __builtin_sprintf (buffer, "%Lg", x);
> +
> +  /* { dg-final { scan-assembler {\mbl __printfieee128} } }  */
> +  __builtin_printf ("x is %Lg [%s]\n", x, buffer);
> +
> +  /* { dg-final { scan-assembler {\mbl __isoc99_sscanfieee128} } }  */
> +  __builtin_sscanf (buffer, "%Lg", &y);
> +
> +  __builtin_printf ("Type 1.0: ");
> +
> +  /* { dg-final { scan-assembler {\mbl __isoc99_scanfieee128} } }  */
> +  __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..d1e22239718 100644
> --- a/gcc/testsuite/gcc.target/powerpc/float128-math.c
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-math.c
> @@ -1,20 +1,20 @@
> -/* { dg-do compile { target { powerpc*-*-linux* } } } */
>  /* { dg-require-effective-target ppc_float128_sw } */
>  /* { dg-require-effective-target vsx_hw } */
> -/* { dg-options "-mvsx -O2 -mfloat128 -mabi=ieeelongdouble -Wno-psabi" } */
> +/* { dg-options "-mvsx -O2 -mfloat128 -mlong-double-128 -mabi=ieeelongdouble 
> -Wno-psabi" } */
> 
>  /* Test whether we convert __builtin_<math>l to __builtin_<math>f128 if the
> -   default long double type is IEEE 128-bit.  Also test that using the 
> explicit
> -   __builtin_<math>f128 function does not interfere with the 
> __builtin_<math>l
> -   function.  */
> +   default long double type is IEEE 128-bit.  We leave off the \M in matching
> +   the calls, so power10 will match using bl foo@notoc.  Also test that using
> +   the explicit __builtin_<math>f128 function does not interfere with the
> +   __builtin_<math>l function.  */
> 
>  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} } } */
> +/* { dg-final { scan-assembler-not {\mbl sinl}         } } */
> -- 
> 2.22.0
> 
> 

Reply via email to