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