[gcc(refs/users/meissner/heads/work033)] PowerPC: Map IEEE 128-bit long double built-ins.
Michael Meissner
meissner@gcc.gnu.org
Tue Jan 19 17:52:26 GMT 2021
https://gcc.gnu.org/g:206961af2c755f34cf00ffd9b2577516318b7b1e
commit 206961af2c755f34cf00ffd9b2577516318b7b1e
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Jan 19 12:51:10 2021 -0500
PowerPC: Map IEEE 128-bit long double built-ins.
This patch replaces patches previously submitted:
September 24th, 2020:
Message-ID: <20200924203159.GA31597@ibm-toto.the-meissners.org>
October 9th, 2020:
Message-ID: <20201009043543.GA11343@ibm-toto.the-meissners.org>
October 24th, 2020:
Message-ID: <20201022220346.GA8151@ibm-toto.the-meissners.org>
November 19th, 2020:
Message-ID: <20201119235814.GA322@ibm-toto.the-meissners.org>
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.
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.
gcc/
2021-01-19 Michael Meissner <meissner@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-19 Michael Meissner <meissner@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.
Diff:
---
gcc/config/rs6000/rs6000.c | 239 +++++++++--
.../gcc.target/powerpc/float128-longdouble-math.c | 442 +++++++++++++++++++++
.../gcc.target/powerpc/float128-longdouble-stdio.c | 36 ++
gcc/testsuite/gcc.target/powerpc/float128-math.c | 16 +-
4 files changed, 694 insertions(+), 39 deletions(-)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b9e90ae0468..77f255163fe 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -27112,6 +27112,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. */
+
+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;
+}
+
+/* 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);
+}
+
+
/* 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
@@ -27132,51 +27298,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} } } */
More information about the Gcc-cvs
mailing list