public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Enable non-complex math builtins from C99 for Bionic
@ 2012-11-30 13:25 Alexander Ivchenko
  2012-11-30 13:42 ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2012-11-30 13:25 UTC (permalink / raw)
  To: gcc-patches, Maxim Kuvyrkov, pavel.v.chupin, Kirill Yukhin, H.J. Lu

[-- Attachment #1: Type: text/plain, Size: 537 bytes --]

Bionic has the support of almost all built-in functions from C99 iso
standard except for only complex math functions.
(I assume because bionic wants to be as small as possible and nobody
wants to do complex arithmetic on Android).
GCC however checks whether the runtime has the full support of C99 or
not, and if not it completely turns off all C99 builtins.

It seems that we are missing the optimization opportunity here and
this patch (attached) is intended to turn on built-ins that are
supported
in bionic.

bootstrap/tests are ok.

[-- Attachment #2: builtins_bionic.patch --]
[-- Type: application/octet-stream, Size: 20836 bytes --]

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef32e39..8a71a57 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2012-11-30  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+	* gcc/builtins.def (DEF_C94_BUILTIN): Add TARGET_HAS_BIONIC
+	to the condition.
+	(DEF_C99_BUILTIN): Ditto.
+	(DEF_C99_C90RES_BUILTIN): Ditto.
+	(DEF_C99_COMPL_BUILTIN): New define. Change all complex c99 builtin
+	definitions to using this define.
+	* gcc/convert.c (convert_to_integer): Add support of Bionic for
+	BUILT_IN_CEIL, BUILT_IN_FLOOR, BUILT_IN_ROUND, BUILT_IN_RINT cases.
+
 2012-11-28  Joern Rennecke  <joern.rennecke@embecosm.com>
 
 	* config/epiphany/predicates.md (move_double_src_operand):
diff --git a/gcc/builtins.def b/gcc/builtins.def
index bfafa53..82dac29 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -103,13 +103,21 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C94_BUILTIN
 #define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS	\
+	       || TARGET_HAS_BIONIC, true)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C99 or above.  */
 #undef DEF_C99_BUILTIN
 #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS	\
+	       || TARGET_HAS_BIONIC, true)
+
+/* Like DEF_C99_BUILTIN, but for complex functions.  */
+#undef DEF_C99_COMPL_BUILTIN
+#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
 	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
 
 /* Builtin that is specified by C99 and C90 reserve the name for future use.
@@ -118,7 +126,8 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C99_C90RES_BUILTIN
 #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS	\
+	       || TARGET_HAS_BIONIC, true)
 
 /* Builtin that C99 reserve the name for future use. We can still recognize
    the builtin in C99 mode but we can't produce it implicitly.  */
@@ -459,78 +468,78 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 
 /* Category: _Complex math builtins.  */
-DEF_C99_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 
 /* Category: string/memory builtins.  */
 /* bcmp, bcopy and bzero have traditionally accepted NULL pointers
diff --git a/gcc/convert.c b/gcc/convert.c
index 5e6b09e..3f0d482 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -386,8 +386,8 @@ convert_to_integer (tree type, tree expr)
       switch (fcode)
         {
 	CASE_FLT_FN (BUILT_IN_CEIL):
-	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  /* Only convert in ISO C99 mode or if we use Bionic.  */
+	  if (!TARGET_C99_FUNCTIONS && !TARGET_HAS_BIONIC)
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -402,8 +402,8 @@ convert_to_integer (tree type, tree expr)
 	  break;
 
 	CASE_FLT_FN (BUILT_IN_FLOOR):
-	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  /* Only convert in ISO C99 mode or if we use Bionic.  */
+	  if (!TARGET_C99_FUNCTIONS && !TARGET_HAS_BIONIC)
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -418,8 +418,8 @@ convert_to_integer (tree type, tree expr)
 	  break;
 
 	CASE_FLT_FN (BUILT_IN_ROUND):
-	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  /* Only convert in ISO C99 mode or if we use Bionic.  */
+	  if (!TARGET_C99_FUNCTIONS && !TARGET_HAS_BIONIC)
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -439,8 +439,8 @@ convert_to_integer (tree type, tree expr)
 	    break;
 	  /* ... Fall through ...  */
 	CASE_FLT_FN (BUILT_IN_RINT):
-	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  /* Only convert in ISO C99 mode or if we use Bionic.  */
+	  if (!TARGET_C99_FUNCTIONS && !TARGET_HAS_BIONIC)
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2012-11-30 13:25 [PATCH] Enable non-complex math builtins from C99 for Bionic Alexander Ivchenko
@ 2012-11-30 13:42 ` Richard Biener
  2012-11-30 21:48   ` Joseph S. Myers
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2012-11-30 13:42 UTC (permalink / raw)
  To: Alexander Ivchenko
  Cc: gcc-patches, Maxim Kuvyrkov, pavel.v.chupin, Kirill Yukhin,
	H.J. Lu, Joseph S. Myers

On Fri, Nov 30, 2012 at 2:17 PM, Alexander Ivchenko <aivchenk@gmail.com> wrote:
> Bionic has the support of almost all built-in functions from C99 iso
> standard except for only complex math functions.
> (I assume because bionic wants to be as small as possible and nobody
> wants to do complex arithmetic on Android).
> GCC however checks whether the runtime has the full support of C99 or
> not, and if not it completely turns off all C99 builtins.
>
> It seems that we are missing the optimization opportunity here and
> this patch (attached) is intended to turn on built-ins that are
> supported
> in bionic.

If you want to split TARGET_C99_FUNCTIONS then split it properly,
don't add TARGET_HAS_BIONIC to the selection.

Joseph may provide some guidance here.

Richard.

> bootstrap/tests are ok.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2012-11-30 13:42 ` Richard Biener
@ 2012-11-30 21:48   ` Joseph S. Myers
  2012-12-13 15:30     ` Alexander Ivchenko
  0 siblings, 1 reply; 30+ messages in thread
From: Joseph S. Myers @ 2012-11-30 21:48 UTC (permalink / raw)
  To: Richard Biener
  Cc: Alexander Ivchenko, gcc-patches, Maxim Kuvyrkov, pavel.v.chupin,
	Kirill Yukhin, H.J. Lu

On Fri, 30 Nov 2012, Richard Biener wrote:

> If you want to split TARGET_C99_FUNCTIONS then split it properly,
> don't add TARGET_HAS_BIONIC to the selection.
> 
> Joseph may provide some guidance here.

My suggested interface would be a target hook such as 
targetm.libc_has_function, taking two arguments, one of which is an enum 
value describing the general class of function (e.g. 
function_c99_misc, function_c99_math_complex, function_gnu) and the other 
of which is a string with the exact function name.  This could replace 
both the target macros TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS.

I think the default version of the hook should be that all C99 functions 
are present, but not sincos, though that requires some care in the 
conversion to keep the settings for all systems the same, since the 
present default for TARGET_C99_FUNCTIONS is 0.  There would then be an 
always-true version of the hook for non-Linux glibc systems, and one that 
checks which C library is in use for Linux systems that might or might not 
be using glibc; this last one is where the Bionic check would go.

(Given this is mainly about the target OS rather than the target CPU 
architecture, I guess the macro choosing a hook implementation would get 
defined in .h files rather than directly in <arch>.c.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2012-11-30 21:48   ` Joseph S. Myers
@ 2012-12-13 15:30     ` Alexander Ivchenko
  2012-12-19 17:57       ` Joseph S. Myers
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2012-12-13 15:30 UTC (permalink / raw)
  To: Joseph S. Myers, Richard Biener
  Cc: gcc-patches, Maxim Kuvyrkov, pavel.v.chupin, Kirill Yukhin, H.J. Lu

[-- Attachment #1: Type: text/plain, Size: 1696 bytes --]

Hello!

Could you please take a look at the attached patch that implements
the target libc_has_function hook? I didn't change so far the default presence
of c99, but rather tried to preserve the current behaviour of
TARGET_C99_FUNCTIONS.

Thank you,
Alexander

2012/12/1 Joseph S. Myers <joseph@codesourcery.com>:
> On Fri, 30 Nov 2012, Richard Biener wrote:
>
>> If you want to split TARGET_C99_FUNCTIONS then split it properly,
>> don't add TARGET_HAS_BIONIC to the selection.
>>
>> Joseph may provide some guidance here.
>
> My suggested interface would be a target hook such as
> targetm.libc_has_function, taking two arguments, one of which is an enum
> value describing the general class of function (e.g.
> function_c99_misc, function_c99_math_complex, function_gnu) and the other
> of which is a string with the exact function name.  This could replace
> both the target macros TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS.
>
> I think the default version of the hook should be that all C99 functions
> are present, but not sincos, though that requires some care in the
> conversion to keep the settings for all systems the same, since the
> present default for TARGET_C99_FUNCTIONS is 0.  There would then be an
> always-true version of the hook for non-Linux glibc systems, and one that
> checks which C library is in use for Linux systems that might or might not
> be using glibc; this last one is where the Bionic check would go.
>
> (Given this is mainly about the target OS rather than the target CPU
> architecture, I guess the macro choosing a hook implementation would get
> defined in .h files rather than directly in <arch>.c.)
>
> --
> Joseph S. Myers
> joseph@codesourcery.com

[-- Attachment #2: libc_has_function.patch --]
[-- Type: application/octet-stream, Size: 38685 bytes --]

diff --git a/gcc/builtins.c b/gcc/builtins.c
index fb7b537..fa26e8e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -248,6 +248,48 @@ is_builtin_fn (tree decl)
   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
 }
 
+/* By default we assume that c99 functions and sincos are not present
+   at the runtime.  */
+bool
+default_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+			   const char *name ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
+bool
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+		       const char *name ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+bool
+c99_libc_has_function (enum function_class fn_class,
+		       const char *name ATTRIBUTE_UNUSED)
+{
+  if (fn_class == function_c94
+      || fn_class == function_c99_misc
+      || fn_class == function_c99_math_complex)
+    return true;
+
+  return false;
+}
+
+bool
+linux_libc_has_function (enum function_class fn_class,
+			 const char *name ATTRIBUTE_UNUSED)
+{
+  if (OPTION_GLIBC)
+    return true;
+  if (OPTION_BIONIC)
+    if (fn_class == function_c94
+	|| fn_class == function_c99_misc
+	|| fn_class == function_sincos)
+	return true;
+
+  return false;
+}
 
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
@@ -7803,7 +7845,7 @@ fold_builtin_sincos (location_t loc,
     return res;
 
   /* Canonicalize sincos to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function(function_c99_math_complex, ""))
     return NULL_TREE;
   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
   if (!fn)
@@ -7843,7 +7885,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
 
   /* In case we can figure out the real part of arg0 and it is constant zero
      fold to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function(function_c99_math_complex, ""))
     return NULL_TREE;
   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
   if (!ifn)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index bfafa53..e6fca4f 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -103,14 +103,20 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C94_BUILTIN
 #define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc94, ATTRS, targetm.libc_has_function(function_c94, NAME), true)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C99 or above.  */
 #undef DEF_C99_BUILTIN
 #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function(function_c99_misc, NAME), true)
+
+/* Like DEF_C99_BUILTIN, but for complex math functions.  */
+#undef DEF_C99_COMPL_BUILTIN
+#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function(function_c99_math_complex, NAME), true)
 
 /* Builtin that is specified by C99 and C90 reserve the name for future use.
    We can still recognize the builtin in C90 mode but we can't produce it
@@ -118,7 +124,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C99_C90RES_BUILTIN
 #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function(function_c99_misc, NAME), true)
 
 /* Builtin that C99 reserve the name for future use. We can still recognize
    the builtin in C99 mode but we can't produce it implicitly.  */
@@ -459,78 +465,78 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 
 /* Category: _Complex math builtins.  */
-DEF_C99_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 
 /* Category: string/memory builtins.  */
 /* bcmp, bcopy and bzero have traditionally accepted NULL pointers
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index 8856874..82ba454 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -64,12 +64,10 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* Determine whether the entire c99 runtime is present in the
-   runtime library.  */
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 #define TARGET_POSIX_IO
 
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 0eb3474..6684c61 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -877,9 +877,10 @@ void add_framework_path (char *);
 
 #define TARGET_POSIX_IO
 
-/* All new versions of Darwin have C99 functions.  */
-
-#define TARGET_C99_FUNCTIONS 1
+/* Determine what functions are present at the runtime;
+   all new versions of Darwin have C99 functions.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 #define WINT_TYPE "int"
 
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index 8c4bbc6..f8e24cc 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -96,8 +96,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #define TARGET_POSIX_IO
 
-#define TARGET_C99_FUNCTIONS 1
-#define TARGET_HAS_SINCOS 1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
 
 /* Additional libraries needed by -static-libasan.  */
 #undef STATIC_LIBASAN_LIBS
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 4c23f57..51e6c05 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -173,6 +173,8 @@ extern int ix86_mode_after (int, int, rtx);
 extern int ix86_mode_entry (int);
 extern int ix86_mode_exit (int);
 
+extern bool ix86_libc_has_function (enum function_class fn_class, const char *name);
+
 #ifdef HARD_CONST
 extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
 #endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index eeb5ac8..d530855 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5529,6 +5529,14 @@ ix86_function_type_abi (const_tree fntype)
   return ix86_abi;
 }
 
+/* We add this as a workaround in order to use libc_has_function
+   hook in i386.md.  */
+bool
+ix86_libc_has_function (enum function_class fn_class, const char *name)
+{
+  return targetm.libc_has_function (fn_class, name);
+}
+
 static bool
 ix86_function_ms_hook_prologue (const_tree fn)
 {
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3846065..c6b5214 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15230,7 +15230,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:XF 1 "register_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS"
+   && ix86_libc_has_function (function_c99_misc, 0)"
 {
   rtx mask = GEN_INT (0x45);
   rtx val = GEN_INT (0x05);
@@ -15256,7 +15256,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS
+   && ix86_libc_has_function (function_c99_misc, 0)
    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
   rtx mask = GEN_INT (0x45);
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index d9ae109..694eef1 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -180,9 +180,10 @@ do {								\
 #undef  TARGET_ASM_RELOC_RW_MASK
 #define TARGET_ASM_RELOC_RW_MASK  ia64_hpux_reloc_rw_mask
 
-/* ia64 HPUX has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
+/* Determine what functions are present at the runtime;
+   ia64 HPUX has the float and long double forms of math functions.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index fb459e6..04a8b86 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -96,14 +96,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
 			 BIONIC_DYNAMIC_LINKERX32)
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 /* Whether we have Bionic libc runtime */
 #undef TARGET_HAS_BIONIC
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
index 87c4ce2..245ff9a 100644
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -146,8 +146,10 @@ while (0)
 
 #define TARGET_POSIX_IO
 
-/* All new versions of OpenBSD have C99 functions.  */
-#define TARGET_C99_FUNCTIONS 1
+/* Determine what functions are present at the runtime;
+   all new versions of OpenBSD have C99 functions.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 \f
 /* Runtime target specification.  */
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index a37ce62..1806e44 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -167,8 +167,8 @@ do {									\
 #define LD_INIT_SWITCH "-binitfini"
 
 /* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index baafb51..ed89e37 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -166,11 +166,11 @@ do {									\
 #define LD_INIT_SWITCH "-binitfini"
 
 /* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 #ifndef _AIX52
-extern long long int    atoll(const char *);  
+extern long long int    atoll(const char *);
 #endif
 
 /* This target uses the aix64.opt file.  */
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index 063cb26..3f3e998 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -186,11 +186,11 @@ do {									\
 #define LD_INIT_SWITCH "-binitfini"
 
 /* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 #ifndef _AIX52
-extern long long int    atoll(const char *);  
+extern long long int    atoll(const char *);
 #endif
 
 /* This target uses the aix64.opt file.  */
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 48f9fcc..0ec1c44 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -384,11 +384,10 @@ extern int darwin_emit_branch_islands;
 /* This is the reserved ivar address Objective-C.  */
 #define OFFS_ASSIGNIVAR_FAST		0xFFFEFEC0
 
-/* Old versions of Mac OS/Darwin don't have C99 functions available.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS					\
-  (TARGET_64BIT							\
-   || strverscmp (darwin_macosx_version_min, "10.3") >= 0)
+/* Determine what functions are present at the runtime;
+   all new versions of Darwin have C99 functions.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 /* When generating kernel code or kexts, we don't use Altivec by
    default, as kernel code doesn't save/restore those registers.  */
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 02477df..f3aa2e8 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -33,13 +33,10 @@
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()		\
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 4d2c365..36a2075 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -300,13 +300,10 @@ extern int dot_symbols;
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()			\
diff --git a/gcc/config/s390/tpf.h b/gcc/config/s390/tpf.h
index 4727a29..039daa6 100644
--- a/gcc/config/s390/tpf.h
+++ b/gcc/config/s390/tpf.h
@@ -95,8 +95,9 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*} \
                   -alshd=%b.lst"
 
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
+/* Determine what functions are present at the runtime.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
 
 #define ENTRY_SPEC "%{mmain:-entry=_start} \
                     %{!mmain:-entry=0}"
diff --git a/gcc/config/sol2-10.h b/gcc/config/sol2-10.h
index edea655..e118453 100644
--- a/gcc/config/sol2-10.h
+++ b/gcc/config/sol2-10.h
@@ -18,5 +18,8 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-/* Solaris 10 has the float and long double forms of math functions.  */
-#define TARGET_C99_FUNCTIONS 1
+
+/* Determine what functions are present at the runtime;
+   Solaris 10 has the float and long double forms of math functions.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION c99_libc_has_function
diff --git a/gcc/convert.c b/gcc/convert.c
index 5e6b09e..a98d834 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "convert.h"
 #include "diagnostic-core.h"
+#include "target.h"
 #include "langhooks.h"
 
 /* Convert EXPR to some pointer or reference type TYPE.
@@ -387,7 +388,7 @@ convert_to_integer (tree type, tree expr)
         {
 	CASE_FLT_FN (BUILT_IN_CEIL):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function(function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -403,7 +404,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_FLOOR):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function(function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -419,7 +420,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_ROUND):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function(function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -440,7 +441,7 @@ convert_to_integer (tree type, tree expr)
 	  /* ... Fall through ...  */
 	CASE_FLT_FN (BUILT_IN_RINT):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function(function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 3bc2f40..d30ebb3 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -180,6 +180,16 @@ union _dont_use_tree_here_;
 
 #endif
 
+/* Classes of functions that compiler needs to check
+   whether they are present at the runtime or not.  */
+enum function_class {
+  function_c94,
+  function_c99_misc,
+  function_c99_math_complex,
+  function_gnu,
+  function_sincos
+};
+
 /* Memory model types for the __atomic* builtins. 
    This must match the order in libstdc++-v3/include/bits/atomic_base.h.  */
 enum memmodel
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index ef47b14..8485350 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5344,6 +5344,14 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum @var{function_class}, const char *@var{name})
+This hook determines whether a function with name @var{name} from a class
+of functions @var{class} is present at the runtime. If the @var{name} is
+the empty string, then this hook will check whether the class of functions
+@var{class} is generally present at the runtime.
+
+@end deftypefn
+
 @cindex C99 math functions, implicit usage
 @defmac TARGET_C99_FUNCTIONS
 When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f3945a4..8a223aa 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5260,6 +5260,14 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
+@hook TARGET_LIBC_HAS_FUNCTION
+This hook determines whether a function with name @var{name} from a class
+of functions @var{class} is present at the runtime. If the @var{name} is
+the empty string, then this hook will check whether the class of functions
+@var{class} is generally present at the runtime.
+
+@end deftypefn
+
 @cindex C99 math functions, implicit usage
 @defmac TARGET_C99_FUNCTIONS
 When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index be0d99f..64d0016 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -828,7 +828,7 @@ gfc_init_builtin_functions (void)
 		      BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
 
 
-  if (TARGET_C99_FUNCTIONS)
+  if (targetm.libc_has_function(function_c99_math_complex, ""))
     {
       gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
 			  BUILT_IN_CBRTL, "cbrtl",
@@ -850,7 +850,7 @@ gfc_init_builtin_functions (void)
 			  ATTR_CONST_NOTHROW_LEAF_LIST);
     }
 
-  if (TARGET_HAS_SINCOS)
+  if (targetm.libc_has_function(function_sincos, ""))
     {
       gfc_define_builtin ("__builtin_sincosl",
 			  func_longdouble_longdoublep_longdoublep,
diff --git a/gcc/output.h b/gcc/output.h
index 3fb743a..e137b02 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -595,7 +595,6 @@ extern void default_asm_declare_constant_name (FILE *, const char *,
 extern void default_file_start (void);
 extern void file_end_indicate_exec_stack (void);
 extern void file_end_indicate_split_stack (void);
-
 extern void default_elf_asm_output_external (FILE *file, tree,
 					     const char *);
 extern void default_elf_asm_output_limited_string (FILE *, const char *);
@@ -606,6 +605,11 @@ extern void default_elf_init_array_asm_out_constructor (rtx, int);
 extern void default_elf_fini_array_asm_out_destructor (rtx, int);
 extern int maybe_assemble_visibility (tree);
 
+extern bool default_libc_has_function (enum function_class, const char *name);
+extern bool c99_libc_has_function (enum function_class, const char *name);
+extern bool gnu_libc_has_function (enum function_class, const char *name);
+extern bool linux_libc_has_function (enum function_class, const char *name);
+
 extern int default_address_cost (rtx, enum machine_mode, addr_space_t, bool);
 
 /* Output stack usage information.  */
diff --git a/gcc/target.def b/gcc/target.def
index 6d00262..40aa183 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1373,6 +1373,12 @@ DEFHOOK
  unsigned int, (tree decl, const char *name, int reloc),
  default_section_type_flags)
 
+DEFHOOK
+(libc_has_function,
+ "",
+ bool, (enum function_class, const char *name),
+ default_libc_has_function)
+
 /* True if new jumps cannot be created, to replace existing ones or
    not, at the current point in the compilation.  */
 DEFHOOK
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 7a41cfe..914f3a4 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1409,7 +1409,8 @@ execute_cse_sincos (void)
 		CASE_FLT_FN (BUILT_IN_SIN):
 		CASE_FLT_FN (BUILT_IN_CEXPI):
 		  /* Make sure we have either sincos or cexp.  */
-		  if (!TARGET_HAS_SINCOS && !TARGET_C99_FUNCTIONS)
+		  if (!targetm.libc_has_function(function_c99_math_complex, "")
+		      && !targetm.libc_has_function(function_sincos, ""))
 		    break;
 
 		  arg = gimple_call_arg (stmt, 0);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2012-12-13 15:30     ` Alexander Ivchenko
@ 2012-12-19 17:57       ` Joseph S. Myers
  2012-12-21 15:57         ` Alexander Ivchenko
  0 siblings, 1 reply; 30+ messages in thread
From: Joseph S. Myers @ 2012-12-19 17:57 UTC (permalink / raw)
  To: Alexander Ivchenko
  Cc: Richard Biener, gcc-patches, Maxim Kuvyrkov, pavel.v.chupin,
	Kirill Yukhin, H.J. Lu

On Thu, 13 Dec 2012, Alexander Ivchenko wrote:

> Could you please take a look at the attached patch that implements
> the target libc_has_function hook? I didn't change so far the default presence
> of c99, but rather tried to preserve the current behaviour of
> TARGET_C99_FUNCTIONS.

It looks like a plausible starting point, given the changed default, 
coding style fixes (you're missing spaces before '('), documentation text 
moved from tm.texi.in to target.def, removal of TARGET_C99_FUNCTIONS 
documentation, poisoning of TARGET_C99_FUNCTIONS in system.h and moving 
the Linux implementation of the hook from builtins.c to some 
Linux-specific file since you can't assume OPTION_GLIBC or OPTION_BIONIC 
are defined for other targets.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2012-12-19 17:57       ` Joseph S. Myers
@ 2012-12-21 15:57         ` Alexander Ivchenko
  2013-01-07 16:19           ` Joseph S. Myers
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2012-12-21 15:57 UTC (permalink / raw)
  To: Joseph S. Myers
  Cc: Richard Biener, gcc-patches, Maxim Kuvyrkov, pavel.v.chupin,
	Kirill Yukhin, H.J. Lu, Sergey Ostanevich

[-- Attachment #1: Type: text/plain, Size: 1414 bytes --]

Hi,

Thank you very much for your input! Please, take a look at the updated version:
I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
to target.def.
Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
influence and moved the implementation of linux_libc_has_function to
host-linux.c.
	I changed the defaults: now it is assumed that we have C99 runtime,
but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
this part,
cause I don't have the opportunity to test it properly...

thank you,
Alexander

2012/12/19 Joseph S. Myers <joseph@codesourcery.com>:
> On Thu, 13 Dec 2012, Alexander Ivchenko wrote:
>
>> Could you please take a look at the attached patch that implements
>> the target libc_has_function hook? I didn't change so far the default presence
>> of c99, but rather tried to preserve the current behaviour of
>> TARGET_C99_FUNCTIONS.
>
> It looks like a plausible starting point, given the changed default,
> coding style fixes (you're missing spaces before '('), documentation text
> moved from tm.texi.in to target.def, removal of TARGET_C99_FUNCTIONS
> documentation, poisoning of TARGET_C99_FUNCTIONS in system.h and moving
> the Linux implementation of the hook from builtins.c to some
> Linux-specific file since you can't assume OPTION_GLIBC or OPTION_BIONIC
> are defined for other targets.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com

[-- Attachment #2: libc_has_function_3.patch --]
[-- Type: application/octet-stream, Size: 46836 bytes --]

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8708f83..f7f0072 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,65 @@
+2012-12-21  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+	* gcc/target.def (TARGET_LIBC_HAS_FUNCTION): New target hook.
+	* gcc/builtins.c (default_libc_has_function): New.
+	(gnu_libc_has_function): Ditto.
+	(no_c99_libc_has_function): Ditto.
+	(expand_builtin_cexpi): Using new target hook TARGET_LIBC_HAS_FUNCTION
+	istead of TARGET_HAS_SINCOS and TARGET_C99_FUNCTIONS.
+	(fold_builtin_sincos): Likewise.
+	(fold_builtin_cexp): Likewise.
+	* gcc/builtins.def (DEF_C94_BUILTIN): Likewise.
+	(DEF_C99_BUILTIN): Likewise.
+	(DEF_C99_C90RES_BUILTIN): Likewise.
+	(DEF_C99_COMPL_BUILTIN): New define. Change all complex c99 builtin
+	definitions to using this define.
+	* gcc/config/alpha/linux.h: Remove TARGET_C99_FUNCTIONS and
+	TARGET_HAS_SINCOS. Redefine TARGET_LIBC_HAS_FUNCTION.
+	* gcc/config/darwin.h: Ditto.
+	* gcc/config/darwin10.h: Ditto.
+	* gcc/config/darwin9.h: Ditto.
+	* gcc/config/elfos.h: Ditto.
+	* gcc/config/freebsd.h: Ditto.
+	* gcc/config/gnu-user.h: Ditto.
+	* gcc/config/ia64/hpux.h: Ditto.
+	* gcc/config/linux.h: Ditto.
+	* gcc/config/netbsd.h: Ditto.
+	* gcc/config/openbsd.h: Ditto.
+	* gcc/config/rs6000/aix52.h: Ditto.
+	* gcc/config/rs6000/aix53.h: Ditto.
+	* gcc/config/rs6000/aix61.h: Ditto.
+	* gcc/config/rs6000/darwin.h: Ditto.
+	* gcc/config/rs6000/linux.h: Ditto.
+	* gcc/config/rs6000/linux64.h: Ditto.
+	* gcc/config/s390/tpf.h: Ditto.
+	* gcc/config/sol2-10.h: Ditto.
+	* gcc/config/sol2.h: Ditto.
+	* gcc/config/vxworks.h: Ditto.
+	* gcc/config/host-linux.c (linux_libc_has_function): New linux-specific
+	implementation of TARGET_LIBC_HAS_FUNCTION.
+	* gcc/config/i386/i386.c (ix86_libc_has_function): New.
+	* gcc/config/i386/i386-protos.h
+	(ix86_libc_has_function): New declaration.
+	* gcc/config/i386/i386.md
+	("isinfxf2"): Change condition for TARGET_LIBC_HAS_FUNCTION.
+	("isinf<mode>2): Likewise.
+	* gcc/convert.c (convert_to_integer): Using new target hook
+	TARGET_LIBC_HAS_FUNCTION istead of TARGET_HAS_SINCOS and
+	TARGET_C99_FUNCTIONS.
+	* gcc/fortran/f95-lang.c (gfc_init_builtin_functions): Ditto.
+	* gcc/tree-ssa-math-opts.c (execute_cse_sincos): Ditto.
+	* gcc/coretypes.h (function_class): New enum for different
+	classes of functions.
+	* gcc/defaults.h: Remove TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS.
+	* gcc/doc/tm.texi.in (TARGET_C99_FUNCTIONS): Remove documentation.
+	(TARGET_HAS_SINCOS): Likewise.
+	(TARGET_LIBC_HAS_FUNCTION): New.
+	* gcc/doc/tm.texi: Regenerated.
+	* gcc/output.h (default_libc_has_function): New declaration.
+	(no_c99_libc_has_function): Ditto.
+	(gnu_libc_has_function): Ditto.
+	(linux_libc_has_function): Ditto.
+
 2012-12-20  Thomas Schwinge  <thomas@codesourcery.com>
 
 	PR bootstrap/55202
diff --git a/gcc/builtins.c b/gcc/builtins.c
index fb7b537..940b1e1 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -248,6 +248,33 @@ is_builtin_fn (tree decl)
   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
 }
 
+/* By default we assume that c99 functions are present at the runtime,
+   but sincos is not.  */
+bool
+default_libc_has_function (enum function_class fn_class,
+			   const char *name ATTRIBUTE_UNUSED)
+{
+  if (fn_class == function_c94
+      || fn_class == function_c99_misc
+      || fn_class == function_c99_math_complex)
+    return true;
+
+  return false;
+}
+
+bool
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+		       const char *name ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+bool
+no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+			  const char *name ATTRIBUTE_UNUSED)
+{
+  return false;
+}
 
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
@@ -2535,7 +2562,7 @@ expand_builtin_cexpi (tree exp, rtx target)
       /* Compute into op1 and op2.  */
       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
     }
-  else if (TARGET_HAS_SINCOS)
+  else if (targetm.libc_has_function (function_sincos, ""))
     {
       tree call, fn = NULL_TREE;
       tree top1, top2;
@@ -7803,7 +7830,7 @@ fold_builtin_sincos (location_t loc,
     return res;
 
   /* Canonicalize sincos to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex, ""))
     return NULL_TREE;
   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
   if (!fn)
@@ -7843,7 +7870,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
 
   /* In case we can figure out the real part of arg0 and it is constant zero
      fold to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex, ""))
     return NULL_TREE;
   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
   if (!ifn)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 9f0692d..6f209a3 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -103,14 +103,20 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C94_BUILTIN
 #define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc94, ATTRS, targetm.libc_has_function (function_c94, NAME), true)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C99 or above.  */
 #undef DEF_C99_BUILTIN
 #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc, NAME), true)
+
+/* Like DEF_C99_BUILTIN, but for complex math functions.  */
+#undef DEF_C99_COMPL_BUILTIN
+#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_math_complex, NAME), true)
 
 /* Builtin that is specified by C99 and C90 reserve the name for future use.
    We can still recognize the builtin in C90 mode but we can't produce it
@@ -118,7 +124,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C99_C90RES_BUILTIN
 #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc, NAME), true)
 
 /* Builtin that C99 reserve the name for future use. We can still recognize
    the builtin in C99 mode but we can't produce it implicitly.  */
@@ -459,78 +465,78 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 
 /* Category: _Complex math builtins.  */
-DEF_C99_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 
 /* Category: string/memory builtins.  */
 /* bcmp, bcopy and bzero have traditionally accepted NULL pointers
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index 8856874..82ba454 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -64,12 +64,10 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* Determine whether the entire c99 runtime is present in the
-   runtime library.  */
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 #define TARGET_POSIX_IO
 
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 3a99670..3b25d71 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -875,10 +875,6 @@ void add_framework_path (char *);
 
 #define TARGET_POSIX_IO
 
-/* All new versions of Darwin have C99 functions.  */
-
-#define TARGET_C99_FUNCTIONS 1
-
 #define WINT_TYPE "int"
 
 /* Every program on darwin links against libSystem which contains the pthread
diff --git a/gcc/config/darwin10.h b/gcc/config/darwin10.h
index fd664c3..68f33b2 100644
--- a/gcc/config/darwin10.h
+++ b/gcc/config/darwin10.h
@@ -32,3 +32,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef DEF_MIN_OSX_VERSION
 #define DEF_MIN_OSX_VERSION "10.6"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/darwin9.h b/gcc/config/darwin9.h
index 92429ca..11d13e1 100644
--- a/gcc/config/darwin9.h
+++ b/gcc/config/darwin9.h
@@ -63,3 +63,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef STACK_CHECK_STATIC_BUILTIN
 #define STACK_CHECK_STATIC_BUILTIN 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 4c74883..26e5180 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -434,3 +434,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
   default_elf_asm_output_external (FILE, DECL, NAME)
 #endif
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
index f9a4713..0ba766a 100644
--- a/gcc/config/freebsd.h
+++ b/gcc/config/freebsd.h
@@ -53,6 +53,9 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared}"
 #endif
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Use --as-needed -lgcc_s for eh support.  */
 #ifdef HAVE_LD_AS_NEEDED
 #define USE_LD_AS_NEEDED 1
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index 8c4bbc6..f8e24cc 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -96,8 +96,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #define TARGET_POSIX_IO
 
-#define TARGET_C99_FUNCTIONS 1
-#define TARGET_HAS_SINCOS 1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
 
 /* Additional libraries needed by -static-libasan.  */
 #undef STATIC_LIBASAN_LIBS
diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c
index b535758..8188a31 100644
--- a/gcc/config/host-linux.c
+++ b/gcc/config/host-linux.c
@@ -22,6 +22,7 @@
 #include "coretypes.h"
 #include "hosthooks.h"
 #include "hosthooks-def.h"
+#include "tm.h"
 
 
 /* Linux has a feature called exec-shield-randomize that perturbs the
@@ -222,5 +223,20 @@ linux_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
   return 1;
 }
 
+bool
+linux_libc_has_function (enum function_class fn_class,
+			 const char *name ATTRIBUTE_UNUSED)
+{
+  if (OPTION_GLIBC)
+    return true;
+  if (OPTION_BIONIC)
+    if (fn_class == function_c94
+	|| fn_class == function_c99_misc
+	|| fn_class == function_sincos)
+	return true;
+
+  return false;
+}
+
 \f
 const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 4c23f57..51e6c05 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -173,6 +173,8 @@ extern int ix86_mode_after (int, int, rtx);
 extern int ix86_mode_entry (int);
 extern int ix86_mode_exit (int);
 
+extern bool ix86_libc_has_function (enum function_class fn_class, const char *name);
+
 #ifdef HARD_CONST
 extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
 #endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b466a4f..dfe066a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5533,6 +5533,14 @@ ix86_function_type_abi (const_tree fntype)
   return ix86_abi;
 }
 
+/* We add this as a workaround in order to use libc_has_function
+   hook in i386.md.  */
+bool
+ix86_libc_has_function (enum function_class fn_class, const char *name)
+{
+  return targetm.libc_has_function (fn_class, name);
+}
+
 static bool
 ix86_function_ms_hook_prologue (const_tree fn)
 {
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 95a52cd..52ead79 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15230,7 +15230,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:XF 1 "register_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS"
+   && ix86_libc_has_function (function_c99_misc, 0)"
 {
   rtx mask = GEN_INT (0x45);
   rtx val = GEN_INT (0x05);
@@ -15256,7 +15256,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS
+   && ix86_libc_has_function (function_c99_misc, 0)
    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
   rtx mask = GEN_INT (0x45);
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index d9ae109..238a75a 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -180,10 +180,6 @@ do {								\
 #undef  TARGET_ASM_RELOC_RW_MASK
 #define TARGET_ASM_RELOC_RW_MASK  ia64_hpux_reloc_rw_mask
 
-/* ia64 HPUX has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
 
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index fb459e6..04a8b86 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -96,14 +96,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
 			 BIONIC_DYNAMIC_LINKERX32)
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 /* Whether we have Bionic libc runtime */
 #undef TARGET_HAS_BIONIC
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
index e9290c2..eff4afd 100644
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -140,6 +140,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef LIBGCC_SPEC
 #define LIBGCC_SPEC NETBSD_LIBGCC_SPEC
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* When building shared libraries, the initialization and finalization 
    functions for the library are .init and .fini respectively.  */
 
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
index 87c4ce2..c374811 100644
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -146,9 +146,6 @@ while (0)
 
 #define TARGET_POSIX_IO
 
-/* All new versions of OpenBSD have C99 functions.  */
-#define TARGET_C99_FUNCTIONS 1
-
 \f
 /* Runtime target specification.  */
 
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index a37ce62..05528f6 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -166,10 +166,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index baafb51..1e64986 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -165,12 +165,8 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
-extern long long int    atoll(const char *);  
+extern long long int    atoll(const char *);
 #endif
 
 /* This target uses the aix64.opt file.  */
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index 063cb26..dcca1f4 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -185,12 +185,8 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
-extern long long int    atoll(const char *);  
+extern long long int    atoll(const char *);
 #endif
 
 /* This target uses the aix64.opt file.  */
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 48f9fcc..77bded1 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -384,12 +384,6 @@ extern int darwin_emit_branch_islands;
 /* This is the reserved ivar address Objective-C.  */
 #define OFFS_ASSIGNIVAR_FAST		0xFFFEFEC0
 
-/* Old versions of Mac OS/Darwin don't have C99 functions available.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS					\
-  (TARGET_64BIT							\
-   || strverscmp (darwin_macosx_version_min, "10.3") >= 0)
-
 /* When generating kernel code or kexts, we don't use Altivec by
    default, as kernel code doesn't save/restore those registers.  */
 #define OS_MISSING_ALTIVEC (flag_mkernel || flag_apple_kext)
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 02477df..f3aa2e8 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -33,13 +33,10 @@
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()		\
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 4d2c365..36a2075 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -300,13 +300,10 @@ extern int dot_symbols;
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()			\
diff --git a/gcc/config/s390/tpf.h b/gcc/config/s390/tpf.h
index 4727a29..570831e 100644
--- a/gcc/config/s390/tpf.h
+++ b/gcc/config/s390/tpf.h
@@ -95,9 +95,6 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*} \
                   -alshd=%b.lst"
 
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
 #define ENTRY_SPEC "%{mmain:-entry=_start} \
                     %{!mmain:-entry=0}"
 
diff --git a/gcc/config/sol2-10.h b/gcc/config/sol2-10.h
index edea655..d926596 100644
--- a/gcc/config/sol2-10.h
+++ b/gcc/config/sol2-10.h
@@ -17,6 +17,3 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
-
-/* Solaris 10 has the float and long double forms of math functions.  */
-#define TARGET_C99_FUNCTIONS 1
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 4cbb308..8d31a54 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -281,6 +281,9 @@ along with GCC; see the file COPYING3.  If not see
 
 #define TARGET_POSIX_IO
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 extern GTY(()) tree solaris_pending_aligns;
 extern GTY(()) tree solaris_pending_inits;
 extern GTY(()) tree solaris_pending_finis;
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index 000de36..f141a23 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -115,6 +115,9 @@ extern void vxworks_asm_out_destructor (rtx symbol, int priority);
 #undef SIZE_TYPE
 #define SIZE_TYPE "unsigned int"
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Both kernels and RTPs have the facilities required by this macro.  */
 #define TARGET_POSIX_IO
 
diff --git a/gcc/convert.c b/gcc/convert.c
index 5e6b09e..983cf8c 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "convert.h"
 #include "diagnostic-core.h"
+#include "target.h"
 #include "langhooks.h"
 
 /* Convert EXPR to some pointer or reference type TYPE.
@@ -387,7 +388,7 @@ convert_to_integer (tree type, tree expr)
         {
 	CASE_FLT_FN (BUILT_IN_CEIL):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -403,7 +404,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_FLOOR):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -419,7 +420,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_ROUND):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -440,7 +441,7 @@ convert_to_integer (tree type, tree expr)
 	  /* ... Fall through ...  */
 	CASE_FLT_FN (BUILT_IN_RINT):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 4672877..eaa108e 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -182,6 +182,16 @@ union _dont_use_tree_here_;
 
 #endif
 
+/* Classes of functions that compiler needs to check
+   whether they are present at the runtime or not.  */
+enum function_class {
+  function_c94,
+  function_c99_misc,
+  function_c99_math_complex,
+  function_gnu,
+  function_sincos
+};
+
 /* Memory model types for the __atomic* builtins. 
    This must match the order in libstdc++-v3/include/bits/atomic_base.h.  */
 enum memmodel
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 76909ab..0998a34 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1042,18 +1042,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #endif /* old constraint mechanism in use */
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#ifndef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 0
-#endif
-
-/* Determine whether the target runtime library has
-   a sincos implementation following the GNU extension.  */
-#ifndef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS 0
-#endif
-
 /* Determin whether the target runtime library is Bionic */
 #ifndef TARGET_HAS_BIONIC
 #define TARGET_HAS_BIONIC 0
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 75aa867..df64624 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5342,26 +5342,12 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard.  The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}.  The
-default is zero.  The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class}, const char *@var{name})
+This hook determines whether a function with name @var{name} from a class
+of functions @var{fn_class} is present at the runtime. If the @var{name} is
+the empty string, then this hook will check whether the class of functions
+@var{fn_class} is generally present at the runtime.
+@end deftypefn
 
 @defmac NEXT_OBJC_RUNTIME
 Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 95fab18..bf10dde 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5258,26 +5258,7 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard.  The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}.  The
-default is zero.  The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@hook TARGET_LIBC_HAS_FUNCTION
 
 @defmac NEXT_OBJC_RUNTIME
 Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index be0d99f..546cfa0 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -828,7 +828,7 @@ gfc_init_builtin_functions (void)
 		      BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
 
 
-  if (TARGET_C99_FUNCTIONS)
+  if (targetm.libc_has_function (function_c99_math_complex, ""))
     {
       gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
 			  BUILT_IN_CBRTL, "cbrtl",
@@ -850,7 +850,7 @@ gfc_init_builtin_functions (void)
 			  ATTR_CONST_NOTHROW_LEAF_LIST);
     }
 
-  if (TARGET_HAS_SINCOS)
+  if (targetm.libc_has_function (function_sincos, ""))
     {
       gfc_define_builtin ("__builtin_sincosl",
 			  func_longdouble_longdoublep_longdoublep,
diff --git a/gcc/output.h b/gcc/output.h
index 3fb743a..79df53c 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -595,7 +595,6 @@ extern void default_asm_declare_constant_name (FILE *, const char *,
 extern void default_file_start (void);
 extern void file_end_indicate_exec_stack (void);
 extern void file_end_indicate_split_stack (void);
-
 extern void default_elf_asm_output_external (FILE *file, tree,
 					     const char *);
 extern void default_elf_asm_output_limited_string (FILE *, const char *);
@@ -606,6 +605,11 @@ extern void default_elf_init_array_asm_out_constructor (rtx, int);
 extern void default_elf_fini_array_asm_out_destructor (rtx, int);
 extern int maybe_assemble_visibility (tree);
 
+extern bool default_libc_has_function (enum function_class, const char *name);
+extern bool no_c99_libc_has_function (enum function_class, const char *name);
+extern bool gnu_libc_has_function (enum function_class, const char *name);
+extern bool linux_libc_has_function (enum function_class, const char *name);
+
 extern int default_address_cost (rtx, enum machine_mode, addr_space_t, bool);
 
 /* Output stack usage information.  */
diff --git a/gcc/target.def b/gcc/target.def
index bbda6c2..5d712b3 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1373,6 +1373,15 @@ DEFHOOK
  unsigned int, (tree decl, const char *name, int reloc),
  default_section_type_flags)
 
+DEFHOOK
+(libc_has_function,
+ "This hook determines whether a function with name @var{name} from a class\n\
+of functions @var{fn_class} is present at the runtime. If the @var{name} is\n\
+the empty string, then this hook will check whether the class of functions\n\
+@var{fn_class} is generally present at the runtime.",
+ bool, (enum function_class fn_class, const char *name),
+ default_libc_has_function)
+
 /* True if new jumps cannot be created, to replace existing ones or
    not, at the current point in the compilation.  */
 DEFHOOK
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 7a41cfe..f56cbcc 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1409,7 +1409,8 @@ execute_cse_sincos (void)
 		CASE_FLT_FN (BUILT_IN_SIN):
 		CASE_FLT_FN (BUILT_IN_CEXPI):
 		  /* Make sure we have either sincos or cexp.  */
-		  if (!TARGET_HAS_SINCOS && !TARGET_C99_FUNCTIONS)
+		  if (!targetm.libc_has_function (function_c99_math_complex, "")
+		      && !targetm.libc_has_function (function_sincos, ""))
 		    break;
 
 		  arg = gimple_call_arg (stmt, 0);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2012-12-21 15:57         ` Alexander Ivchenko
@ 2013-01-07 16:19           ` Joseph S. Myers
  2013-03-28 11:46             ` Alexander Ivchenko
  0 siblings, 1 reply; 30+ messages in thread
From: Joseph S. Myers @ 2013-01-07 16:19 UTC (permalink / raw)
  To: Alexander Ivchenko
  Cc: Richard Biener, gcc-patches, Maxim Kuvyrkov, pavel.v.chupin,
	Kirill Yukhin, H.J. Lu, Sergey Ostanevich

On Fri, 21 Dec 2012, Alexander Ivchenko wrote:

> Hi,
> 
> Thank you very much for your input! Please, take a look at the updated version:
> I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
> to target.def.
> Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
> influence and moved the implementation of linux_libc_has_function to
> host-linux.c.
> 	I changed the defaults: now it is assumed that we have C99 runtime,
> but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
> this part,
> cause I don't have the opportunity to test it properly...

This patch seems mostly plausible, though there are various places that 
call targetm.libc_has_function with and empty string as second argument, 
that should be naming the specific function instead.  I haven't reviewed 
the details, and at this development stage I think it will need to wait 
until after 4.8 branches.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-01-07 16:19           ` Joseph S. Myers
@ 2013-03-28 11:46             ` Alexander Ivchenko
  2013-04-23 15:00               ` Alexander Ivchenko
  2013-07-08 22:30               ` Joseph S. Myers
  0 siblings, 2 replies; 30+ messages in thread
From: Alexander Ivchenko @ 2013-03-28 11:46 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Richard Biener, gcc-patches, Maxim Kuvyrkov

[-- Attachment #1: Type: text/plain, Size: 1662 bytes --]

Hi,

4.8 is now branched, lets come back to the discussion that we had
before. I updated the patch a little
bit since we now have linux-protos.h and linux-android.c files.

I tried to preserve the avaiability of c99 for all targets, but it's
pretty difficult, because we are changing
the defaults. Passing an empty string as second argument doesn't look
very good, but on the other hand
the user has one clear way for checking the presence of a certain
function. But of course we can create
another function, that will call targetm.libc_has_function
(function_class, "") within itself.

best regards,
Alexander

2013/1/7 Joseph S. Myers <joseph@codesourcery.com>:
> On Fri, 21 Dec 2012, Alexander Ivchenko wrote:
>
>> Hi,
>>
>> Thank you very much for your input! Please, take a look at the updated version:
>> I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
>> to target.def.
>> Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
>> influence and moved the implementation of linux_libc_has_function to
>> host-linux.c.
>>       I changed the defaults: now it is assumed that we have C99 runtime,
>> but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
>> this part,
>> cause I don't have the opportunity to test it properly...
>
> This patch seems mostly plausible, though there are various places that
> call targetm.libc_has_function with and empty string as second argument,
> that should be naming the specific function instead.  I haven't reviewed
> the details, and at this development stage I think it will need to wait
> until after 4.8 branches.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com

[-- Attachment #2: libc_has_function_04.patch --]
[-- Type: application/octet-stream, Size: 46665 bytes --]

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f00cb04..31dc1e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,66 @@
+2013-03-28  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+	* gcc/target.def (TARGET_LIBC_HAS_FUNCTION): New target hook.
+	* gcc/builtins.c (default_libc_has_function): New.
+	(gnu_libc_has_function): Ditto.
+	(no_c99_libc_has_function): Ditto.
+	(expand_builtin_cexpi): Using new target hook TARGET_LIBC_HAS_FUNCTION
+	instead of TARGET_HAS_SINCOS and TARGET_C99_FUNCTIONS.
+	(fold_builtin_sincos): Likewise.
+	(fold_builtin_cexp): Likewise.
+	* gcc/builtins.def (DEF_C94_BUILTIN): Likewise.
+	(DEF_C99_BUILTIN): Likewise.
+	(DEF_C99_C90RES_BUILTIN): Likewise.
+	(DEF_C99_COMPL_BUILTIN): New define. Change all complex c99 builtin
+	definitions to using this define.
+	* gcc/config/alpha/linux.h: Remove TARGET_C99_FUNCTIONS and
+	TARGET_HAS_SINCOS. Redefine TARGET_LIBC_HAS_FUNCTION.
+	* gcc/config/darwin.h: Ditto.
+	* gcc/config/darwin10.h: Ditto.
+	* gcc/config/darwin9.h: Ditto.
+	* gcc/config/elfos.h: Ditto.
+	* gcc/config/freebsd.h: Ditto.
+	* gcc/config/gnu-user.h: Ditto.
+	* gcc/config/ia64/hpux.h: Ditto.
+	* gcc/config/linux.h: Ditto.
+	* gcc/config/netbsd.h: Ditto.
+	* gcc/config/openbsd.h: Ditto.
+	* gcc/config/rs6000/aix52.h: Ditto.
+	* gcc/config/rs6000/aix53.h: Ditto.
+	* gcc/config/rs6000/aix61.h: Ditto.
+	* gcc/config/rs6000/darwin.h: Ditto.
+	* gcc/config/rs6000/linux.h: Ditto.
+	* gcc/config/rs6000/linux64.h: Ditto.
+	* gcc/config/s390/tpf.h: Ditto.
+	* gcc/config/sol2-10.h: Ditto.
+	* gcc/config/sol2.h: Ditto.
+	* gcc/config/vxworks.h: Ditto.
+	* gcc/config/linux-android.c (linux_android_libc_has_function):
+	New linux-specific implementation of TARGET_LIBC_HAS_FUNCTION.
+	* gcc/config/linux-protos.h (linux_android_libc_has_function):
+	New declaration.
+	* gcc/config/i386/i386.c (ix86_libc_has_function): New.
+	* gcc/config/i386/i386-protos.h
+	(ix86_libc_has_function): New declaration.
+	* gcc/config/i386/i386.md
+	("isinfxf2"): Change condition for TARGET_LIBC_HAS_FUNCTION.
+	("isinf<mode>2): Likewise.
+	* gcc/convert.c (convert_to_integer): Using new target hook
+	TARGET_LIBC_HAS_FUNCTION istead of TARGET_HAS_SINCOS and
+	TARGET_C99_FUNCTIONS.
+	* gcc/fortran/f95-lang.c (gfc_init_builtin_functions): Ditto.
+	* gcc/tree-ssa-math-opts.c (execute_cse_sincos): Ditto.
+	* gcc/coretypes.h (function_class): New enum for different
+	classes of functions.
+	* gcc/defaults.h: Remove TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS.
+	* gcc/doc/tm.texi.in (TARGET_C99_FUNCTIONS): Remove documentation.
+	(TARGET_HAS_SINCOS): Likewise.
+	(TARGET_LIBC_HAS_FUNCTION): New.
+	* gcc/doc/tm.texi: Regenerated.
+	* gcc/targhooks.h (default_libc_has_function): New declaration.
+	(no_c99_libc_has_function): Ditto.
+	(gnu_libc_has_function): Ditto.
+
 2013-03-27  Alexander Ivchenko  <alexander.ivchenko@intel.com>
 
 	* gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 68b6a2c..620e032 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -246,6 +246,33 @@ is_builtin_fn (tree decl)
   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
 }
 
+/* By default we assume that c99 functions are present at the runtime,
+   but sincos is not.  */
+bool
+default_libc_has_function (enum function_class fn_class,
+			   const char *name ATTRIBUTE_UNUSED)
+{
+  if (fn_class == function_c94
+      || fn_class == function_c99_misc
+      || fn_class == function_c99_math_complex)
+    return true;
+
+  return false;
+}
+
+bool
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+		       const char *name ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+bool
+no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+			  const char *name ATTRIBUTE_UNUSED)
+{
+  return false;
+}
 
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
@@ -2529,7 +2556,7 @@ expand_builtin_cexpi (tree exp, rtx target)
       /* Compute into op1 and op2.  */
       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
     }
-  else if (TARGET_HAS_SINCOS)
+  else if (targetm.libc_has_function (function_sincos, ""))
     {
       tree call, fn = NULL_TREE;
       tree top1, top2;
@@ -7796,7 +7823,7 @@ fold_builtin_sincos (location_t loc,
     return res;
 
   /* Canonicalize sincos to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex, ""))
     return NULL_TREE;
   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
   if (!fn)
@@ -7836,7 +7863,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
 
   /* In case we can figure out the real part of arg0 and it is constant zero
      fold to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex, ""))
     return NULL_TREE;
   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
   if (!ifn)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 4f378fa..6ff898d 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -102,14 +102,20 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C94_BUILTIN
 #define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc94, ATTRS, targetm.libc_has_function (function_c94, NAME), true)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C99 or above.  */
 #undef DEF_C99_BUILTIN
 #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc, NAME), true)
+
+/* Like DEF_C99_BUILTIN, but for complex math functions.  */
+#undef DEF_C99_COMPL_BUILTIN
+#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_math_complex, NAME), true)
 
 /* Builtin that is specified by C99 and C90 reserve the name for future use.
    We can still recognize the builtin in C90 mode but we can't produce it
@@ -117,7 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C99_C90RES_BUILTIN
 #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc, NAME), true)
 
 /* Builtin that C99 reserve the name for future use. We can still recognize
    the builtin in C99 mode but we can't produce it implicitly.  */
@@ -458,78 +464,78 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 
 /* Category: _Complex math builtins.  */
-DEF_C99_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 
 /* Category: string/memory builtins.  */
 /* bcmp, bcopy and bzero have traditionally accepted NULL pointers
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index fbf4a07..68423c5 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -63,12 +63,10 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* Determine whether the entire c99 runtime is present in the
-   runtime library.  */
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
 
 #define TARGET_POSIX_IO
 
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 82a42c8..d87cd8e 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -874,10 +874,6 @@ void add_framework_path (char *);
 
 #define TARGET_POSIX_IO
 
-/* All new versions of Darwin have C99 functions.  */
-
-#define TARGET_C99_FUNCTIONS 1
-
 #define WINT_TYPE "int"
 
 /* Every program on darwin links against libSystem which contains the pthread
diff --git a/gcc/config/darwin10.h b/gcc/config/darwin10.h
index cd5f421..f0e960b 100644
--- a/gcc/config/darwin10.h
+++ b/gcc/config/darwin10.h
@@ -32,3 +32,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef DEF_MIN_OSX_VERSION
 #define DEF_MIN_OSX_VERSION "10.6"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/darwin9.h b/gcc/config/darwin9.h
index 65efb5a..3209c4b 100644
--- a/gcc/config/darwin9.h
+++ b/gcc/config/darwin9.h
@@ -63,3 +63,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef STACK_CHECK_STATIC_BUILTIN
 #define STACK_CHECK_STATIC_BUILTIN 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 4383023..9606fe0 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -433,3 +433,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
   default_elf_asm_output_external (FILE, DECL, NAME)
 #endif
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
index 87c0acf..da66253 100644
--- a/gcc/config/freebsd.h
+++ b/gcc/config/freebsd.h
@@ -52,6 +52,9 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared}"
 #endif
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Use --as-needed -lgcc_s for eh support.  */
 #ifdef HAVE_LD_AS_NEEDED
 #define USE_LD_AS_NEEDED 1
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index bcdf0e6..757a571 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -95,8 +95,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #define TARGET_POSIX_IO
 
-#define TARGET_C99_FUNCTIONS 1
-#define TARGET_HAS_SINCOS 1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
 
 /* Link -lasan early on the command line.  For -static-libasan, don't link
    it for -shared link, the executable should be compiled with -static-libasan
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 602e6fc..3611d7e 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -171,6 +171,8 @@ extern int ix86_mode_after (int, int, rtx);
 extern int ix86_mode_entry (int);
 extern int ix86_mode_exit (int);
 
+extern bool ix86_libc_has_function (enum function_class fn_class, const char *name);
+
 #ifdef HARD_CONST
 extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
 #endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 030183c..547a83e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5545,6 +5545,14 @@ ix86_function_type_abi (const_tree fntype)
   return ix86_abi;
 }
 
+/* We add this as a workaround in order to use libc_has_function
+   hook in i386.md.  */
+bool
+ix86_libc_has_function (enum function_class fn_class, const char *name)
+{
+  return targetm.libc_has_function (fn_class, name);
+}
+
 static bool
 ix86_function_ms_hook_prologue (const_tree fn)
 {
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index bf0020c..8fc7e09 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14798,7 +14798,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:XF 1 "register_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS"
+   && ix86_libc_has_function (function_c99_misc, 0)"
 {
   rtx mask = GEN_INT (0x45);
   rtx val = GEN_INT (0x05);
@@ -14824,7 +14824,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS
+   && ix86_libc_has_function (function_c99_misc, 0)
    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
   rtx mask = GEN_INT (0x45);
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index 22cfe9f..09ba7c3 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -179,10 +179,6 @@ do {								\
 #undef  TARGET_ASM_RELOC_RW_MASK
 #define TARGET_ASM_RELOC_RW_MASK  ia64_hpux_reloc_rw_mask
 
-/* ia64 HPUX has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
 
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
index d6e47a7..a6e20a3 100644
--- a/gcc/config/linux-android.c
+++ b/gcc/config/linux-android.c
@@ -31,3 +31,18 @@ linux_android_has_ifunc_p (void)
 {
   return TARGET_ANDROID ? false : HAVE_GNU_INDIRECT_FUNCTION;
 }
+
+bool
+linux_android_libc_has_function (enum function_class fn_class,
+				 const char *name ATTRIBUTE_UNUSED)
+{
+  if (OPTION_GLIBC)
+    return true;
+  if (OPTION_BIONIC)
+    if (fn_class == function_c94
+	|| fn_class == function_c99_misc
+	|| fn_class == function_sincos)
+	return true;
+
+  return false;
+}
diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h
index 3f926e5..c9009fe 100644
--- a/gcc/config/linux-protos.h
+++ b/gcc/config/linux-protos.h
@@ -19,3 +19,6 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 extern bool linux_android_has_ifunc_p (void);
+
+extern bool linux_android_libc_has_function (enum function_class fn_class,
+					     const char *name ATTRIBUTE_UNUSED);
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index 2be1079..8116e69 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -95,15 +95,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
 			 BIONIC_DYNAMIC_LINKERX32)
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
-
 /* Whether we have Bionic libc runtime */
 #undef TARGET_HAS_BIONIC
 #define TARGET_HAS_BIONIC (OPTION_BIONIC)
+
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
index 71c9183..dd50dcc 100644
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -139,6 +139,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef LIBGCC_SPEC
 #define LIBGCC_SPEC NETBSD_LIBGCC_SPEC
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* When building shared libraries, the initialization and finalization 
    functions for the library are .init and .fini respectively.  */
 
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
index 6537451..9bc5e4e 100644
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -145,9 +145,6 @@ while (0)
 
 #define TARGET_POSIX_IO
 
-/* All new versions of OpenBSD have C99 functions.  */
-#define TARGET_C99_FUNCTIONS 1
-
 \f
 /* Runtime target specification.  */
 
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index c57271a..5195471 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -166,10 +166,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index b1b0759..b3bd73a 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -166,10 +166,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index cd341b9..b077814 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -190,10 +190,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 9d92d2a..b2df62e 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -384,12 +384,6 @@ extern int darwin_emit_branch_islands;
 /* This is the reserved ivar address Objective-C.  */
 #define OFFS_ASSIGNIVAR_FAST		0xFFFEFEC0
 
-/* Old versions of Mac OS/Darwin don't have C99 functions available.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS					\
-  (TARGET_64BIT							\
-   || strverscmp (darwin_macosx_version_min, "10.3") >= 0)
-
 /* When generating kernel code or kexts, we don't use Altivec by
    default, as kernel code doesn't save/restore those registers.  */
 #define OS_MISSING_ALTIVEC (flag_mkernel || flag_apple_kext)
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 8ec3548..ac13626 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -32,13 +32,10 @@
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()		\
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index dc6f67f..2dee718 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -299,13 +299,10 @@ extern int dot_symbols;
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()			\
diff --git a/gcc/config/s390/tpf.h b/gcc/config/s390/tpf.h
index a2bde82..a54442b 100644
--- a/gcc/config/s390/tpf.h
+++ b/gcc/config/s390/tpf.h
@@ -94,9 +94,6 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*} \
                   -alshd=%b.lst"
 
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
 #define ENTRY_SPEC "%{mmain:-entry=_start} \
                     %{!mmain:-entry=0}"
 
diff --git a/gcc/config/sol2-10.h b/gcc/config/sol2-10.h
index 81d0f51..72c57a6 100644
--- a/gcc/config/sol2-10.h
+++ b/gcc/config/sol2-10.h
@@ -17,6 +17,3 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
-
-/* Solaris 10 has the float and long double forms of math functions.  */
-#define TARGET_C99_FUNCTIONS 1
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 23a5bf5..ab3d6d5 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -280,6 +280,9 @@ along with GCC; see the file COPYING3.  If not see
 
 #define TARGET_POSIX_IO
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 extern GTY(()) tree solaris_pending_aligns;
 extern GTY(()) tree solaris_pending_inits;
 extern GTY(()) tree solaris_pending_finis;
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index d91a8b1..72f344b 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -114,6 +114,9 @@ extern void vxworks_asm_out_destructor (rtx symbol, int priority);
 #undef SIZE_TYPE
 #define SIZE_TYPE "unsigned int"
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Both kernels and RTPs have the facilities required by this macro.  */
 #define TARGET_POSIX_IO
 
diff --git a/gcc/convert.c b/gcc/convert.c
index e124e7a..250839b 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "convert.h"
 #include "diagnostic-core.h"
+#include "target.h"
 #include "langhooks.h"
 
 /* Convert EXPR to some pointer or reference type TYPE.
@@ -385,7 +386,7 @@ convert_to_integer (tree type, tree expr)
         {
 	CASE_FLT_FN (BUILT_IN_CEIL):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -401,7 +402,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_FLOOR):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -417,7 +418,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_ROUND):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -438,7 +439,7 @@ convert_to_integer (tree type, tree expr)
 	  /* ... Fall through ...  */
 	CASE_FLT_FN (BUILT_IN_RINT):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc, ""))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 320b4dd..a515953 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -181,6 +181,16 @@ union _dont_use_tree_here_;
 
 #endif
 
+/* Classes of functions that compiler needs to check
+   whether they are present at the runtime or not.  */
+enum function_class {
+  function_c94,
+  function_c99_misc,
+  function_c99_math_complex,
+  function_gnu,
+  function_sincos
+};
+
 /* Memory model types for the __atomic* builtins. 
    This must match the order in libstdc++-v3/include/bits/atomic_base.h.  */
 enum memmodel
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 4f43f6f0..3fa105d 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1040,18 +1040,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #endif /* old constraint mechanism in use */
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#ifndef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 0
-#endif
-
-/* Determine whether the target runtime library has
-   a sincos implementation following the GNU extension.  */
-#ifndef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS 0
-#endif
-
 /* Determin whether the target runtime library is Bionic */
 #ifndef TARGET_HAS_BIONIC
 #define TARGET_HAS_BIONIC 0
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 9f78ae4..89712b0 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5340,26 +5340,12 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard.  The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}.  The
-default is zero.  The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class}, const char *@var{name})
+This hook determines whether a function with name @var{name} from a class
+of functions @var{fn_class} is present at the runtime. If the @var{name} is
+the empty string, then this hook will check whether the class of functions
+@var{fn_class} is generally present at the runtime.
+@end deftypefn
 
 @defmac NEXT_OBJC_RUNTIME
 Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index b67df84..b570833 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5256,26 +5256,7 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard.  The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}.  The
-default is zero.  The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@hook TARGET_LIBC_HAS_FUNCTION
 
 @defmac NEXT_OBJC_RUNTIME
 Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 60d790b..1b851d0 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -826,7 +826,7 @@ gfc_init_builtin_functions (void)
 		      BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
 
 
-  if (TARGET_C99_FUNCTIONS)
+  if (targetm.libc_has_function (function_c99_math_complex, ""))
     {
       gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
 			  BUILT_IN_CBRTL, "cbrtl",
@@ -848,7 +848,7 @@ gfc_init_builtin_functions (void)
 			  ATTR_CONST_NOTHROW_LEAF_LIST);
     }
 
-  if (TARGET_HAS_SINCOS)
+  if (targetm.libc_has_function (function_sincos, ""))
     {
       gfc_define_builtin ("__builtin_sincosl",
 			  func_longdouble_longdoublep_longdoublep,
diff --git a/gcc/target.def b/gcc/target.def
index 3ad5870..1369ef2 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1371,6 +1371,15 @@ DEFHOOK
  unsigned int, (tree decl, const char *name, int reloc),
  default_section_type_flags)
 
+DEFHOOK
+(libc_has_function,
+ "This hook determines whether a function with name @var{name} from a class\n\
+of functions @var{fn_class} is present at the runtime. If the @var{name} is\n\
+the empty string, then this hook will check whether the class of functions\n\
+@var{fn_class} is generally present at the runtime.",
+ bool, (enum function_class fn_class, const char *name),
+ default_libc_has_function)
+
 /* True if new jumps cannot be created, to replace existing ones or
    not, at the current point in the compilation.  */
 DEFHOOK
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 0837c09..7dcff28 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -165,6 +165,10 @@ extern rtx default_addr_space_convert (rtx, tree, tree);
 extern unsigned int default_case_values_threshold (void);
 extern bool default_have_conditional_execution (void);
 
+extern bool default_libc_has_function (enum function_class, const char *name);
+extern bool no_c99_libc_has_function (enum function_class, const char *name);
+extern bool gnu_libc_has_function (enum function_class, const char *name);
+
 extern tree default_builtin_tm_load_store (tree);
 
 extern int default_memory_move_cost (enum machine_mode, reg_class_t, bool);
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 2140ced..b80744c 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1414,7 +1414,8 @@ execute_cse_sincos (void)
 		CASE_FLT_FN (BUILT_IN_SIN):
 		CASE_FLT_FN (BUILT_IN_CEXPI):
 		  /* Make sure we have either sincos or cexp.  */
-		  if (!TARGET_HAS_SINCOS && !TARGET_C99_FUNCTIONS)
+		  if (!targetm.libc_has_function (function_c99_math_complex, "")
+		      && !targetm.libc_has_function (function_sincos, ""))
 		    break;
 
 		  arg = gimple_call_arg (stmt, 0);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-03-28 11:46             ` Alexander Ivchenko
@ 2013-04-23 15:00               ` Alexander Ivchenko
  2013-05-27  9:15                 ` Alexander Ivchenko
  2013-07-08 22:30               ` Joseph S. Myers
  1 sibling, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2013-04-23 15:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joseph S. Myers

*ping*

thanks
Alexander

2013/3/28 Alexander Ivchenko <aivchenk@gmail.com>:
> Hi,
>
> 4.8 is now branched, lets come back to the discussion that we had
> before. I updated the patch a little
> bit since we now have linux-protos.h and linux-android.c files.
>
> I tried to preserve the avaiability of c99 for all targets, but it's
> pretty difficult, because we are changing
> the defaults. Passing an empty string as second argument doesn't look
> very good, but on the other hand
> the user has one clear way for checking the presence of a certain
> function. But of course we can create
> another function, that will call targetm.libc_has_function
> (function_class, "") within itself.
>
> best regards,
> Alexander
>
> 2013/1/7 Joseph S. Myers <joseph@codesourcery.com>:
>> On Fri, 21 Dec 2012, Alexander Ivchenko wrote:
>>
>>> Hi,
>>>
>>> Thank you very much for your input! Please, take a look at the updated version:
>>> I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
>>> to target.def.
>>> Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
>>> influence and moved the implementation of linux_libc_has_function to
>>> host-linux.c.
>>>       I changed the defaults: now it is assumed that we have C99 runtime,
>>> but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
>>> this part,
>>> cause I don't have the opportunity to test it properly...
>>
>> This patch seems mostly plausible, though there are various places that
>> call targetm.libc_has_function with and empty string as second argument,
>> that should be naming the specific function instead.  I haven't reviewed
>> the details, and at this development stage I think it will need to wait
>> until after 4.8 branches.
>>
>> --
>> Joseph S. Myers
>> joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-04-23 15:00               ` Alexander Ivchenko
@ 2013-05-27  9:15                 ` Alexander Ivchenko
  2013-06-13  8:36                   ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2013-05-27  9:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joseph S. Myers, Richard Biener

Hi,

While discussing the issue with the command line option for sincos here:
http://gcc.1065356.n5.nabble.com/PATCH-bionic-Add-foptimize-sincos-tp940918.html

Richard wrote:
> I'd rather think about a way to specify, for all known builtins, whether GCC
> should generate calls to such function where they are not in the source
> program.  That is, similar to how we have -f[no-]builtin-FOO introduce
> -f[no-]libc-FOO (with a better name for 'libc'?).  That way there would be
> a way to specify that -floop-distribute-patterns should not produce calls
> to memset () for example.

This patch is related to that idea: in the target hook
libc_has_function we can check whether
the compiler should generate calls to a particular function or not.
The command line support for
each function could be the next step.

Could you please take a look?

thanks
Alexander

2013/4/23 Alexander Ivchenko <aivchenk@gmail.com>:
> *ping*
>
> thanks
> Alexander
>
> 2013/3/28 Alexander Ivchenko <aivchenk@gmail.com>:
>> Hi,
>>
>> 4.8 is now branched, lets come back to the discussion that we had
>> before. I updated the patch a little
>> bit since we now have linux-protos.h and linux-android.c files.
>>
>> I tried to preserve the avaiability of c99 for all targets, but it's
>> pretty difficult, because we are changing
>> the defaults. Passing an empty string as second argument doesn't look
>> very good, but on the other hand
>> the user has one clear way for checking the presence of a certain
>> function. But of course we can create
>> another function, that will call targetm.libc_has_function
>> (function_class, "") within itself.
>>
>> best regards,
>> Alexander
>>
>> 2013/1/7 Joseph S. Myers <joseph@codesourcery.com>:
>>> On Fri, 21 Dec 2012, Alexander Ivchenko wrote:
>>>
>>>> Hi,
>>>>
>>>> Thank you very much for your input! Please, take a look at the updated version:
>>>> I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
>>>> to target.def.
>>>> Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
>>>> influence and moved the implementation of linux_libc_has_function to
>>>> host-linux.c.
>>>>       I changed the defaults: now it is assumed that we have C99 runtime,
>>>> but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
>>>> this part,
>>>> cause I don't have the opportunity to test it properly...
>>>
>>> This patch seems mostly plausible, though there are various places that
>>> call targetm.libc_has_function with and empty string as second argument,
>>> that should be naming the specific function instead.  I haven't reviewed
>>> the details, and at this development stage I think it will need to wait
>>> until after 4.8 branches.
>>>
>>> --
>>> Joseph S. Myers
>>> joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-05-27  9:15                 ` Alexander Ivchenko
@ 2013-06-13  8:36                   ` Richard Biener
  2013-06-19 11:32                     ` Alexander Ivchenko
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2013-06-13  8:36 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: gcc-patches, Joseph S. Myers

On Mon, May 27, 2013 at 11:15 AM, Alexander Ivchenko <aivchenk@gmail.com> wrote:
> Hi,
>
> While discussing the issue with the command line option for sincos here:
> http://gcc.1065356.n5.nabble.com/PATCH-bionic-Add-foptimize-sincos-tp940918.html
>
> Richard wrote:
>> I'd rather think about a way to specify, for all known builtins, whether GCC
>> should generate calls to such function where they are not in the source
>> program.  That is, similar to how we have -f[no-]builtin-FOO introduce
>> -f[no-]libc-FOO (with a better name for 'libc'?).  That way there would be
>> a way to specify that -floop-distribute-patterns should not produce calls
>> to memset () for example.
>
> This patch is related to that idea: in the target hook
> libc_has_function we can check whether
> the compiler should generate calls to a particular function or not.
> The command line support for
> each function could be the next step.
>
> Could you please take a look?

I don't see how a target hook is required for the command-line idea.
Targets already have a perfectly working way of changing the default
of a command-line option.

Richard.

> thanks
> Alexander
>
> 2013/4/23 Alexander Ivchenko <aivchenk@gmail.com>:
>> *ping*
>>
>> thanks
>> Alexander
>>
>> 2013/3/28 Alexander Ivchenko <aivchenk@gmail.com>:
>>> Hi,
>>>
>>> 4.8 is now branched, lets come back to the discussion that we had
>>> before. I updated the patch a little
>>> bit since we now have linux-protos.h and linux-android.c files.
>>>
>>> I tried to preserve the avaiability of c99 for all targets, but it's
>>> pretty difficult, because we are changing
>>> the defaults. Passing an empty string as second argument doesn't look
>>> very good, but on the other hand
>>> the user has one clear way for checking the presence of a certain
>>> function. But of course we can create
>>> another function, that will call targetm.libc_has_function
>>> (function_class, "") within itself.
>>>
>>> best regards,
>>> Alexander
>>>
>>> 2013/1/7 Joseph S. Myers <joseph@codesourcery.com>:
>>>> On Fri, 21 Dec 2012, Alexander Ivchenko wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> Thank you very much for your input! Please, take a look at the updated version:
>>>>> I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
>>>>> to target.def.
>>>>> Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
>>>>> influence and moved the implementation of linux_libc_has_function to
>>>>> host-linux.c.
>>>>>       I changed the defaults: now it is assumed that we have C99 runtime,
>>>>> but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
>>>>> this part,
>>>>> cause I don't have the opportunity to test it properly...
>>>>
>>>> This patch seems mostly plausible, though there are various places that
>>>> call targetm.libc_has_function with and empty string as second argument,
>>>> that should be naming the specific function instead.  I haven't reviewed
>>>> the details, and at this development stage I think it will need to wait
>>>> until after 4.8 branches.
>>>>
>>>> --
>>>> Joseph S. Myers
>>>> joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-06-13  8:36                   ` Richard Biener
@ 2013-06-19 11:32                     ` Alexander Ivchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Alexander Ivchenko @ 2013-06-19 11:32 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Joseph S. Myers

> I don't see how a target hook is required for the command-line idea.
> Targets already have a perfectly working way of changing the default
> of a command-line option.

That's true.. sorry, my bad.

Anyway, could somebody take a look at the patch itself?

--Alexander



>> 2013/4/23 Alexander Ivchenko <aivchenk@gmail.com>:
>>> *ping*
>>>
>>> thanks
>>> Alexander
>>>
>>> 2013/3/28 Alexander Ivchenko <aivchenk@gmail.com>:
>>>> Hi,
>>>>
>>>> 4.8 is now branched, lets come back to the discussion that we had
>>>> before. I updated the patch a little
>>>> bit since we now have linux-protos.h and linux-android.c files.
>>>>
>>>> I tried to preserve the avaiability of c99 for all targets, but it's
>>>> pretty difficult, because we are changing
>>>> the defaults. Passing an empty string as second argument doesn't look
>>>> very good, but on the other hand
>>>> the user has one clear way for checking the presence of a certain
>>>> function. But of course we can create
>>>> another function, that will call targetm.libc_has_function
>>>> (function_class, "") within itself.
>>>>
>>>> best regards,
>>>> Alexander
>>>>
>>>> 2013/1/7 Joseph S. Myers <joseph@codesourcery.com>:
>>>>> On Fri, 21 Dec 2012, Alexander Ivchenko wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Thank you very much for your input! Please, take a look at the updated version:
>>>>>> I fixed coding style, moved documentation for TARGET_LIBC_HAS_FUNCTION
>>>>>> to target.def.
>>>>>> Removed TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS and all their
>>>>>> influence and moved the implementation of linux_libc_has_function to
>>>>>> host-linux.c.
>>>>>>       I changed the defaults: now it is assumed that we have C99 runtime,
>>>>>> but no sincos. I updated all needed gcc/config/*.h. But 'm not sure in
>>>>>> this part,
>>>>>> cause I don't have the opportunity to test it properly...
>>>>>
>>>>> This patch seems mostly plausible, though there are various places that
>>>>> call targetm.libc_has_function with and empty string as second argument,
>>>>> that should be naming the specific function instead.  I haven't reviewed
>>>>> the details, and at this development stage I think it will need to wait
>>>>> until after 4.8 branches.
>>>>>
>>>>> --
>>>>> Joseph S. Myers
>>>>> joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-03-28 11:46             ` Alexander Ivchenko
  2013-04-23 15:00               ` Alexander Ivchenko
@ 2013-07-08 22:30               ` Joseph S. Myers
  2013-07-28  0:51                 ` Alexander Ivchenko
  1 sibling, 1 reply; 30+ messages in thread
From: Joseph S. Myers @ 2013-07-08 22:30 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: Richard Biener, gcc-patches

On Thu, 28 Mar 2013, Alexander Ivchenko wrote:

> Hi,
> 
> 4.8 is now branched, lets come back to the discussion that we had
> before. I updated the patch a little
> bit since we now have linux-protos.h and linux-android.c files.
> 
> I tried to preserve the avaiability of c99 for all targets, but it's
> pretty difficult, because we are changing
> the defaults. Passing an empty string as second argument doesn't look
> very good, but on the other hand
> the user has one clear way for checking the presence of a certain
> function. But of course we can create
> another function, that will call targetm.libc_has_function
> (function_class, "") within itself.

Observations on this patch version:

* You still shouldn't be calling with "" as function name (or 0, in 
i386.md) unless there's a good reason the relevant function can't readily 
be identified.  (Actually, the TARGET_C99_FUNCTIONS checks in i386.md seem 
wrong - the instruction patterns expand things inline and the semantics of 
an isinf insn pattern are nothing to do with whether the target library 
has C99 functions; C99 doesn't provide isinf as a function anyway, only as 
a macro.)  If you don't yet need the name in any hook implementation, feel 
free to define the hooks without the name argument and it can be added 
later if needed.

* I don't see how your change for Darwin preserves the existing semantics; 
you appear to make it use no_c99_libc_has_function, but the existing 
semantics are that it has C99 functions except for 32-bit powerpc Darwin 
versions older than 10.3.

* I don't see how your change preserves semantics for Solaris either - you 
add a definition in sol2.h (for Solaris 9) but don't override it in 
sol2-10.h (for Solaris 10, which has the C99 functions).

* I don't see anything to preserve semantics for AIX 4.3 and 5.1 (the AIX 
versions for which TARGET_C99_FUNCTIONS was not defined).

* I don't see anything to preserve semantics for alpha*-dec-*vms*.

* I don't see anything to preserve semantics for hppa*-*-hpux*.

* I don't see anything to preserve semantics for 
i[34567]86-pc-msdosdjgpp*.

* I don't see anything to preserve semantics for i[34567]86-*-cygwin*, or 
x86_64-*-cygwin*, or i[34567]86-*-mingw*, or x86_64-*-mingw*, or 
i[34567]86-*-interix[3-9]*.

* It looks rather like microblaze*-*-* don't use elfos.h, so meaning 
semantics aren't preserved for those (non-Linux) targets either.  Now, I 
don't know if there's a good reason for not using that file (ask the 
architecture maintainer), but in any case semantics should be preserved.

* I don't see anything to preserve semantics for mmix-knuth-mmixware, or 
pdp11-*-*, or picochip-* (more non-ELF targets).

* The patch is missing the poisoning of the removed target macros in 
system.h.

Now, for verifying semantics are unchanged for existing targets, you might 
want to adapt contrib/config-list.mk to show in some way the 
TARGET_C99_FUNCTIONS setting resulting from tm.h (before your patch) or 
the new hook setting (after your patch), so you can compare for all the 
targets listed there.  That's not perfect - the list of targets may not be 
complete - but if you fix all the issues listed above then 
before-and-after comparison for lots of targets using config-list.mk would 
be a good way of gaining confidence in the lack of unintended changes in 
the patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-07-08 22:30               ` Joseph S. Myers
@ 2013-07-28  0:51                 ` Alexander Ivchenko
  2013-07-28 16:37                   ` Michael Eager
                                     ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Alexander Ivchenko @ 2013-07-28  0:51 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 4349 bytes --]

Hi Joseph, thanks for your comments.

I updated the patch:

1) The function name as a second argument in libc_has_function target
hook was removed - was not usefull so far.
2) By using contrib/config-list.mk (thanks for the hint - great tool!)
and analysing tm.h files and what is included in them I have checked
197 targets. That analysis includes all issues that you raised in your
comments - everything is fixed now. I don't like that sometimes we
have to redefine the version of the hook back to the default one due
to a poisoning of including elfos.h, but I couldn't find a better
solution - I commented all those cases.

Regtesting is in progress now. I have already tested the patch before,
so I don't expect to see any new problems.

If all the tests pass, is the patch OK for trunk?

thanks,
Alexander

2013/7/9 Joseph S. Myers <joseph@codesourcery.com>:
> On Thu, 28 Mar 2013, Alexander Ivchenko wrote:
>
>> Hi,
>>
>> 4.8 is now branched, lets come back to the discussion that we had
>> before. I updated the patch a little
>> bit since we now have linux-protos.h and linux-android.c files.
>>
>> I tried to preserve the avaiability of c99 for all targets, but it's
>> pretty difficult, because we are changing
>> the defaults. Passing an empty string as second argument doesn't look
>> very good, but on the other hand
>> the user has one clear way for checking the presence of a certain
>> function. But of course we can create
>> another function, that will call targetm.libc_has_function
>> (function_class, "") within itself.
>
> Observations on this patch version:
>
> * You still shouldn't be calling with "" as function name (or 0, in
> i386.md) unless there's a good reason the relevant function can't readily
> be identified.  (Actually, the TARGET_C99_FUNCTIONS checks in i386.md seem
> wrong - the instruction patterns expand things inline and the semantics of
> an isinf insn pattern are nothing to do with whether the target library
> has C99 functions; C99 doesn't provide isinf as a function anyway, only as
> a macro.)  If you don't yet need the name in any hook implementation, feel
> free to define the hooks without the name argument and it can be added
> later if needed.
>
> * I don't see how your change for Darwin preserves the existing semantics;
> you appear to make it use no_c99_libc_has_function, but the existing
> semantics are that it has C99 functions except for 32-bit powerpc Darwin
> versions older than 10.3.
>
> * I don't see how your change preserves semantics for Solaris either - you
> add a definition in sol2.h (for Solaris 9) but don't override it in
> sol2-10.h (for Solaris 10, which has the C99 functions).
>
> * I don't see anything to preserve semantics for AIX 4.3 and 5.1 (the AIX
> versions for which TARGET_C99_FUNCTIONS was not defined).
>
> * I don't see anything to preserve semantics for alpha*-dec-*vms*.
>
> * I don't see anything to preserve semantics for hppa*-*-hpux*.
>
> * I don't see anything to preserve semantics for
> i[34567]86-pc-msdosdjgpp*.
>
> * I don't see anything to preserve semantics for i[34567]86-*-cygwin*, or
> x86_64-*-cygwin*, or i[34567]86-*-mingw*, or x86_64-*-mingw*, or
> i[34567]86-*-interix[3-9]*.
>
> * It looks rather like microblaze*-*-* don't use elfos.h, so meaning
> semantics aren't preserved for those (non-Linux) targets either.  Now, I
> don't know if there's a good reason for not using that file (ask the
> architecture maintainer), but in any case semantics should be preserved.
>
> * I don't see anything to preserve semantics for mmix-knuth-mmixware, or
> pdp11-*-*, or picochip-* (more non-ELF targets).
>
> * The patch is missing the poisoning of the removed target macros in
> system.h.
>
> Now, for verifying semantics are unchanged for existing targets, you might
> want to adapt contrib/config-list.mk to show in some way the
> TARGET_C99_FUNCTIONS setting resulting from tm.h (before your patch) or
> the new hook setting (after your patch), so you can compare for all the
> targets listed there.  That's not perfect - the list of targets may not be
> complete - but if you fix all the issues listed above then
> before-and-after comparison for lots of targets using config-list.mk would
> be a good way of gaining confidence in the lack of unintended changes in
> the patch.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com

[-- Attachment #2: libc_has_function_05.patch --]
[-- Type: application/octet-stream, Size: 54923 bytes --]

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d63ff27..70f6014 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,79 @@
+2013-07-28  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+	* target.def (TARGET_LIBC_HAS_FUNCTION): New target hook.
+	* builtins.c (default_libc_has_function): New.
+	(gnu_libc_has_function): Ditto.
+	(no_c99_libc_has_function): Ditto.
+	(expand_builtin_cexpi): Using new target hook TARGET_LIBC_HAS_FUNCTION
+	instead of TARGET_HAS_SINCOS and TARGET_C99_FUNCTIONS.
+	(fold_builtin_sincos): Likewise.
+	(fold_builtin_cexp): Likewise.
+	* builtins.def (DEF_C94_BUILTIN): Likewise.
+	(DEF_C99_BUILTIN): Likewise.
+	(DEF_C99_C90RES_BUILTIN): Likewise.
+	(DEF_C99_COMPL_BUILTIN): New define. Change all complex c99 builtin
+	definitions to using this define.
+	* config/darwin-protos.h (darwin_libc_has_function): New.
+	* config/darwin.c: (darwin_libc_has_function: Ditto.
+	* config/alpha/linux.h: Remove TARGET_C99_FUNCTIONS and
+	TARGET_HAS_SINCOS. Redefine TARGET_LIBC_HAS_FUNCTION.
+	* config/darwin.h: Ditto.
+	* config/elfos.h: Ditto.
+	* config/freebsd.h: Ditto.
+	* config/i386/cygming.h: Ditto.
+	* config/i386/djgpp.h: Ditto.
+	* config/i386/i386-interix.h: Ditto.
+	* config/microblaze/microblaze.h: Ditto.
+	* config/mmix/mmix.h: Ditto.
+	* config/gnu-user.h: Ditto.
+	* config/ia64/hpux.h: Ditto.
+	* config/pa/pa-hpux.h: Ditto.
+	* config/pdp11/pdp11.h: Ditto.
+	* config/picochip/picochip.h: Ditto.
+	* config/linux.h: Ditto.
+	* config/netbsd.h: Ditto.
+	* config/openbsd.h: Ditto.
+	* config/rs6000/aix43.h: Ditto.
+	* config/rs6000/aix51.h: Ditto.
+	* config/rs6000/aix52.h: Ditto.
+	* config/rs6000/aix53.h: Ditto.
+	* config/rs6000/aix61.h: Ditto.
+	* config/rs6000/darwin.h: Ditto.
+	* config/rs6000/linux.h: Ditto.
+	* config/rs6000/linux64.h: Ditto.
+	* config/s390/tpf.h: Ditto.
+	* config/sol2-10.h: Ditto.
+	* config/sol2.h: Ditto.
+	* config/vms/vms.h: Ditto.
+	* config/vxworks.h: Ditto.
+	* config/linux-android.c (linux_android_libc_has_function):
+	New linux-specific implementation of TARGET_LIBC_HAS_FUNCTION.
+	* config/linux-protos.h (linux_android_libc_has_function):
+	New declaration.
+	* config/i386/i386.c (ix86_libc_has_function): New.
+	* config/i386/i386-protos.h
+	(ix86_libc_has_function): New declaration.
+	* config/i386/i386.md
+	("isinfxf2"): Change condition for TARGET_LIBC_HAS_FUNCTION.
+	("isinf<mode>2): Likewise.
+	* convert.c (convert_to_integer): Using new target hook
+	TARGET_LIBC_HAS_FUNCTION istead of TARGET_HAS_SINCOS and
+	TARGET_C99_FUNCTIONS.
+	* fortran/f95-lang.c (gfc_init_builtin_functions): Ditto.
+	* tree-ssa-math-opts.c (execute_cse_sincos): Ditto.
+	* coretypes.h (function_class): New enum for different
+	classes of functions.
+	* defaults.h: Remove TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS.
+	* doc/tm.texi.in (TARGET_C99_FUNCTIONS): Remove documentation.
+	(TARGET_HAS_SINCOS): Likewise.
+	(TARGET_LIBC_HAS_FUNCTION): New.
+	* doc/tm.texi: Regenerated.
+	* targhooks.h (default_libc_has_function): New declaration.
+	(no_c99_libc_has_function): Ditto.
+	(gnu_libc_has_function): Ditto.
+	* system.h: Add the poisoning of TARGET_C99_FUNCTIONS
+	and TARGET_HAS_SINCOS.
+
 2013-07-22  Bill Schmidt  <wschmidt@vnet.linux.ibm.com>
 	    Anton Blanchard <anton@au1.ibm.com>
 
@@ -9601,21 +9677,21 @@
 
 2013-03-27  Alexander Ivchenko  <alexander.ivchenko@intel.com>
 
-	* target.def (TARGET_HAS_IFUNC_P): New target hook.
-	* doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
-	* doc/tm.texi: Regenerate.
-	* targhooks.h (default_has_ifunc_p): New.
-	* targhooks.c (default_has_ifunc_p): Ditto.
-	* config/linux-protos.h: New file.
-	* config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
+	* gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
+	* gcc/doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
+	* gcc/doc/tm.texi: Regenerate.
+	* gcc/targhooks.h (default_has_ifunc_p): New.
+	* gcc/targhooks.c (default_has_ifunc_p): Ditto.
+	* gcc/config/linux-protos.h: New file.
+	* gcc/config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
 	this hook for linux which disables support of indirect functions in
 	android.
-	* config/linux-android.c: New file.
-	* config/t-linux-android.c: Ditto.
-	* config.gcc: Added new object file linux-android.o.
-	* config/i386/i386.c (ix86_get_function_versions_dispatcher):
+	* gcc/config/linux-android.c: New file.
+	* gcc/config/t-linux-android.c: Ditto.
+	* gcc/config.gcc: Added new object file linux-android.o.
+	* gcc/config/i386/i386.c (ix86_get_function_versions_dispatcher):
 	Using TARGET_HAS_IFUNC hook instead of HAVE_GNU_INDIRECT_FUNCTION.
-	* varasm.c (do_assemble_alias): Likewise.
+	* gcc/varasm.c (do_assemble_alias): Likewise.
 	* configure.ac: Define HAVE_GNU_INDIRECT_FUNCTION as zero if the target
 	doesn't support indirect functions.
 	* configure: Regenerate.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 78b0d84..ebb79be 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -249,6 +249,30 @@ is_builtin_fn (tree decl)
   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
 }
 
+/* By default we assume that c99 functions are present at the runtime,
+   but sincos is not.  */
+bool
+default_libc_has_function (enum function_class fn_class)
+{
+  if (fn_class == function_c94
+      || fn_class == function_c99_misc
+      || fn_class == function_c99_math_complex)
+    return true;
+
+  return false;
+}
+
+bool
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+bool
+no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+{
+  return false;
+}
 
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
@@ -2548,7 +2572,7 @@ expand_builtin_cexpi (tree exp, rtx target)
       /* Compute into op1 and op2.  */
       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
     }
-  else if (TARGET_HAS_SINCOS)
+  else if (targetm.libc_has_function (function_sincos))
     {
       tree call, fn = NULL_TREE;
       tree top1, top2;
@@ -7810,7 +7834,7 @@ fold_builtin_sincos (location_t loc,
     return res;
 
   /* Canonicalize sincos to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex))
     return NULL_TREE;
   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
   if (!fn)
@@ -7850,7 +7874,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
 
   /* In case we can figure out the real part of arg0 and it is constant zero
      fold to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex))
     return NULL_TREE;
   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
   if (!ifn)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 9b55b1f..9983196 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -102,14 +102,20 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C94_BUILTIN
 #define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc94, ATTRS, targetm.libc_has_function (function_c94), true)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C99 or above.  */
 #undef DEF_C99_BUILTIN
 #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true)
+
+/* Like DEF_C99_BUILTIN, but for complex math functions.  */
+#undef DEF_C99_COMPL_BUILTIN
+#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_math_complex), true)
 
 /* Builtin that is specified by C99 and C90 reserve the name for future use.
    We can still recognize the builtin in C90 mode but we can't produce it
@@ -117,7 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef DEF_C99_C90RES_BUILTIN
 #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
-	       true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+	       true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true)
 
 /* Builtin that C99 reserve the name for future use. We can still recognize
    the builtin in C99 mode but we can't produce it implicitly.  */
@@ -463,78 +469,78 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 
 /* Category: _Complex math builtins.  */
-DEF_C99_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_GCC_BUILTIN        (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
 
 /* Category: string/memory builtins.  */
 /* bcmp, bcopy and bzero have traditionally accepted NULL pointers
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index fbf4a07..68423c5 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -63,12 +63,10 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* Determine whether the entire c99 runtime is present in the
-   runtime library.  */
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
 
 #define TARGET_POSIX_IO
 
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 70b7fb0..36d16b9 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -123,3 +123,4 @@ extern bool darwin_kextabi_p (void);
 extern void darwin_override_options (void);
 extern void darwin_patch_builtins (void);
 extern void darwin_rename_builtins (void);
+extern bool darwin_libc_has_function (enum function_class fn_class);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index e07fa4c..6c5d9c0 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -3357,6 +3357,19 @@ darwin_rename_builtins (void)
     }
 }
 
+bool
+darwin_libc_has_function (enum function_class fn_class)
+{
+  if (fn_class == function_sincos)
+    return false;
+  if (fn_class == function_c99_math_complex
+      || fn_class == function_c99_misc)
+    return (TARGET_64BIT
+	    || strverscmp (darwin_macosx_version_min, "10.3") >= 0);
+
+  return true;
+}
+
 static hashval_t
 cfstring_hash (const void *ptr)
 {
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 82a42c8..d87cd8e 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -874,10 +874,6 @@ void add_framework_path (char *);
 
 #define TARGET_POSIX_IO
 
-/* All new versions of Darwin have C99 functions.  */
-
-#define TARGET_C99_FUNCTIONS 1
-
 #define WINT_TYPE "int"
 
 /* Every program on darwin links against libSystem which contains the pthread
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 4383023..9606fe0 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -433,3 +433,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
   default_elf_asm_output_external (FILE, DECL, NAME)
 #endif
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
index 87c0acf..da66253 100644
--- a/gcc/config/freebsd.h
+++ b/gcc/config/freebsd.h
@@ -52,6 +52,9 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared}"
 #endif
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Use --as-needed -lgcc_s for eh support.  */
 #ifdef HAVE_LD_AS_NEEDED
 #define USE_LD_AS_NEEDED 1
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index bcdf0e6..757a571 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -95,8 +95,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #define TARGET_POSIX_IO
 
-#define TARGET_C99_FUNCTIONS 1
-#define TARGET_HAS_SINCOS 1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
 
 /* Link -lasan early on the command line.  For -static-libasan, don't link
    it for -shared link, the executable should be compiled with -static-libasan
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 2718764..9cb66d6 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -171,6 +171,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef MATH_LIBRARY
 #define MATH_LIBRARY ""
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 #define SIZE_TYPE (TARGET_64BIT ? "long long unsigned int" : "unsigned int")
 #define PTRDIFF_TYPE (TARGET_64BIT ? "long long int" : "int")
 
diff --git a/gcc/config/i386/djgpp.h b/gcc/config/i386/djgpp.h
index 05f9dfd..9c503ac 100644
--- a/gcc/config/i386/djgpp.h
+++ b/gcc/config/i386/djgpp.h
@@ -127,6 +127,9 @@ along with GCC; see the file COPYING3.  If not see
    in libgcc, nor call one in main().  */
 #define HAS_INIT_SECTION
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Definitions for types and sizes. Wide characters are 16-bits long so
    Win32 compiler add-ons will be wide character compatible.  */
 #undef WCHAR_TYPE_SIZE
diff --git a/gcc/config/i386/i386-interix.h b/gcc/config/i386/i386-interix.h
index c74e008..b99f4d9 100644
--- a/gcc/config/i386/i386-interix.h
+++ b/gcc/config/i386/i386-interix.h
@@ -143,6 +143,9 @@ do {									\
 #undef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* The following are needed for us to be able to use winnt.c, but are not
    otherwise meaningful to Interix.  (The functions that use these are
    never called because we don't do DLLs.) */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 0966789..3ab2f3a 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -173,6 +173,8 @@ extern int ix86_mode_after (int, int, rtx);
 extern int ix86_mode_entry (int);
 extern int ix86_mode_exit (int);
 
+extern bool ix86_libc_has_function (enum function_class fn_class);
+
 #ifdef HARD_CONST
 extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
 #endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 140c569..07ff7ed 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5651,6 +5651,14 @@ ix86_function_type_abi (const_tree fntype)
   return ix86_abi;
 }
 
+/* We add this as a workaround in order to use libc_has_function
+   hook in i386.md.  */
+bool
+ix86_libc_has_function (enum function_class fn_class)
+{
+  return targetm.libc_has_function (fn_class);
+}
+
 static bool
 ix86_function_ms_hook_prologue (const_tree fn)
 {
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c67ed31..f541c72 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14884,7 +14884,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:XF 1 "register_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS"
+   && ix86_libc_has_function (function_c99_misc)"
 {
   rtx mask = GEN_INT (0x45);
   rtx val = GEN_INT (0x05);
@@ -14910,7 +14910,7 @@
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
   "TARGET_USE_FANCY_MATH_387
-   && TARGET_C99_FUNCTIONS
+   && ix86_libc_has_function (function_c99_misc)
    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
   rtx mask = GEN_INT (0x45);
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index 22cfe9f..ca592e4 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -179,9 +179,10 @@ do {								\
 #undef  TARGET_ASM_RELOC_RW_MASK
 #define TARGET_ASM_RELOC_RW_MASK  ia64_hpux_reloc_rw_mask
 
-/* ia64 HPUX has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
+/* ia64 HPUX has the float and long double forms of math functions.
+   We redefine this hook so the version from elfos.h header won't be used.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_c99_libc_has_function
 
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
index d6e47a7..4a4b48d 100644
--- a/gcc/config/linux-android.c
+++ b/gcc/config/linux-android.c
@@ -31,3 +31,17 @@ linux_android_has_ifunc_p (void)
 {
   return TARGET_ANDROID ? false : HAVE_GNU_INDIRECT_FUNCTION;
 }
+
+bool
+linux_android_libc_has_function (enum function_class fn_class)
+{
+  if (OPTION_GLIBC)
+    return true;
+  if (OPTION_BIONIC)
+    if (fn_class == function_c94
+	|| fn_class == function_c99_misc
+	|| fn_class == function_sincos)
+	return true;
+
+  return false;
+}
diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h
index 3f926e5..d1f0f92 100644
--- a/gcc/config/linux-protos.h
+++ b/gcc/config/linux-protos.h
@@ -19,3 +19,5 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 extern bool linux_android_has_ifunc_p (void);
+
+extern bool linux_android_libc_has_function (enum function_class fn_class);
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index 2be1079..8116e69 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -95,15 +95,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
 			 BIONIC_DYNAMIC_LINKERX32)
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
-
 /* Whether we have Bionic libc runtime */
 #undef TARGET_HAS_BIONIC
 #define TARGET_HAS_BIONIC (OPTION_BIONIC)
+
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index bc4d9a1..eb8e45c 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -892,6 +892,10 @@ do {									 \
 %{pg:-start-group -lxilprofile -lgloss -lxil -lc -lm -end-group } \
 %{!pg:-start-group -lgloss -lxil -lc -lm -end-group }} "
 
+/* microblaze-unknown-elf target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 #undef  ENDFILE_SPEC
 #define ENDFILE_SPEC "crtend.o%s crtn.o%s"
 
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index c5edc57..2d5e1a8 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -813,6 +813,10 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
 
 #define NO_IMPLICIT_EXTERN_C
 
+/* mmix-knuth-mmixware target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* These are checked.  */
 #define DOLLARS_IN_IDENTIFIERS 0
 #define NO_DOLLAR_IN_LABEL
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
index 71c9183..dd50dcc 100644
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -139,6 +139,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef LIBGCC_SPEC
 #define LIBGCC_SPEC NETBSD_LIBGCC_SPEC
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* When building shared libraries, the initialization and finalization 
    functions for the library are .init and .fini respectively.  */
 
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
index 6537451..0d118b4 100644
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -145,8 +145,10 @@ while (0)
 
 #define TARGET_POSIX_IO
 
-/* All new versions of OpenBSD have C99 functions.  */
-#define TARGET_C99_FUNCTIONS 1
+/* All new versions of OpenBSD have C99 functions.  We redefine this hook
+   so the version from elfos.h header won't be used.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
 
 \f
 /* Runtime target specification.  */
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index c384824..9685bb2 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -114,3 +114,6 @@ along with GCC; see the file COPYING3.  If not see
    compatibility with the HP-UX unwind library.  */
 #undef TARGET_HPUX_UNWIND_LIBRARY
 #define TARGET_HPUX_UNWIND_LIBRARY 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index d61db4c..d4bc19a 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -666,3 +666,7 @@ extern rtx cc0_reg_rtx;
 #define COMPARE_FLAG_MODE HImode
 
 #define TARGET_HAVE_NAMED_SECTIONS false
+
+/* pdp11-unknown-aout target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h
index d43ec20..13414c6 100644
--- a/gcc/config/picochip/picochip.h
+++ b/gcc/config/picochip/picochip.h
@@ -656,4 +656,8 @@ enum picochip_builtins
    not detecting this. */
 #define HAVE_AS_LEB128 1
 
+/* picochip-unknown-none target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* The End */
diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h
index 70db7f7..b27c046 100644
--- a/gcc/config/rs6000/aix43.h
+++ b/gcc/config/rs6000/aix43.h
@@ -159,3 +159,6 @@ do {									\
 #define TARGET_USES_AIX64_OPT 1
 
 #define TARGET_AIX_VERSION 43
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/rs6000/aix51.h b/gcc/config/rs6000/aix51.h
index 669dbbe03..3837bfdc0 100644
--- a/gcc/config/rs6000/aix51.h
+++ b/gcc/config/rs6000/aix51.h
@@ -163,3 +163,6 @@ do {									\
 #define TARGET_USE_JCR_SECTION 0
 
 #define TARGET_AIX_VERSION 51
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index c57271a..5195471 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -166,10 +166,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index b1b0759..b3bd73a 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -166,10 +166,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index cd341b9..b077814 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -190,10 +190,6 @@ do {									\
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
 
-/* AIX 5.2 has the float and long double forms of math functions.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS  1
-
 #ifndef _AIX52
 extern long long int    atoll(const char *);  
 #endif
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 0cf2f4c..d5919c4 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -386,10 +386,8 @@ extern int darwin_emit_branch_islands;
 #define OFFS_ASSIGNIVAR_FAST		0xFFFEFEC0
 
 /* Old versions of Mac OS/Darwin don't have C99 functions available.  */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS					\
-  (TARGET_64BIT							\
-   || strverscmp (darwin_macosx_version_min, "10.3") >= 0)
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION darwin_libc_has_function
 
 /* When generating kernel code or kexts, we don't use Altivec by
    default, as kernel code doesn't save/restore those registers.  */
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index f7f2d80..c941942 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -32,13 +32,10 @@
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()		\
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 79f0f0b..63e656d 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -292,13 +292,10 @@ extern int dot_symbols;
 #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
 #endif
 
-/* glibc has float and long double forms of math functions.  */
-#undef  TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension.  */
-#undef  TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+   this includes full c99 runtime and sincos.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
 
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()			\
diff --git a/gcc/config/s390/tpf.h b/gcc/config/s390/tpf.h
index a2bde82..8eb1947 100644
--- a/gcc/config/s390/tpf.h
+++ b/gcc/config/s390/tpf.h
@@ -94,9 +94,6 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*} \
                   -alshd=%b.lst"
 
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
 #define ENTRY_SPEC "%{mmain:-entry=_start} \
                     %{!mmain:-entry=0}"
 
@@ -115,3 +112,7 @@ along with GCC; see the file COPYING3.  If not see
 #define MATH_LIBRARY "CLBM"
 #define LIBSTDCXX "CPP2"
 #endif /* ! _TPF_H */
+
+/* We redefine this hook so the version from elfos.h header won't be used.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
diff --git a/gcc/config/sol2-10.h b/gcc/config/sol2-10.h
index 81d0f51..262040b 100644
--- a/gcc/config/sol2-10.h
+++ b/gcc/config/sol2-10.h
@@ -18,5 +18,7 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-/* Solaris 10 has the float and long double forms of math functions.  */
-#define TARGET_C99_FUNCTIONS 1
+/* /* Solaris 10 has the float and long double forms of math functions.
+   We redefine this hook so the version from elfos.h header won't be used.  */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 4c9b334..b606595 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -285,6 +285,9 @@ along with GCC; see the file COPYING3.  If not see
 
 #define TARGET_POSIX_IO
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 extern GTY(()) tree solaris_pending_aligns;
 extern GTY(()) tree solaris_pending_inits;
 extern GTY(()) tree solaris_pending_finis;
diff --git a/gcc/config/vms/vms.h b/gcc/config/vms/vms.h
index b7689bf..5d0a5c6 100644
--- a/gcc/config/vms/vms.h
+++ b/gcc/config/vms/vms.h
@@ -87,3 +87,6 @@ extern void vms_c_register_includes (const char *, const char *, int);
 
 /* Special VMS debugger symbol to record the entry point.  */
 #define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index d91a8b1..72f344b 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -114,6 +114,9 @@ extern void vxworks_asm_out_destructor (rtx symbol, int priority);
 #undef SIZE_TYPE
 #define SIZE_TYPE "unsigned int"
 
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
 /* Both kernels and RTPs have the facilities required by this macro.  */
 #define TARGET_POSIX_IO
 
diff --git a/gcc/convert.c b/gcc/convert.c
index 9ecef42..b07f0ef 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "convert.h"
 #include "diagnostic-core.h"
+#include "target.h"
 #include "langhooks.h"
 
 /* Convert EXPR to some pointer or reference type TYPE.
@@ -386,7 +387,7 @@ convert_to_integer (tree type, tree expr)
         {
 	CASE_FLT_FN (BUILT_IN_CEIL):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -402,7 +403,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_FLOOR):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -418,7 +419,7 @@ convert_to_integer (tree type, tree expr)
 
 	CASE_FLT_FN (BUILT_IN_ROUND):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
@@ -439,7 +440,7 @@ convert_to_integer (tree type, tree expr)
 	  /* ... Fall through ...  */
 	CASE_FLT_FN (BUILT_IN_RINT):
 	  /* Only convert in ISO C99 mode.  */
-	  if (!TARGET_C99_FUNCTIONS)
+	  if (!targetm.libc_has_function (function_c99_misc))
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index edb9c8c..c16bd38 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -183,6 +183,16 @@ union _dont_use_tree_here_;
 
 #endif
 
+/* Classes of functions that compiler needs to check
+   whether they are present at the runtime or not.  */
+enum function_class {
+  function_c94,
+  function_c99_misc,
+  function_c99_math_complex,
+  function_gnu,
+  function_sincos
+};
+
 /* Memory model types for the __atomic* builtins. 
    This must match the order in libstdc++-v3/include/bits/atomic_base.h.  */
 enum memmodel
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 4f43f6f0..3fa105d 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1040,18 +1040,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #endif /* old constraint mechanism in use */
 
-/* Determine whether the entire c99 runtime
-   is present in the runtime library.  */
-#ifndef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 0
-#endif
-
-/* Determine whether the target runtime library has
-   a sincos implementation following the GNU extension.  */
-#ifndef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS 0
-#endif
-
 /* Determin whether the target runtime library is Bionic */
 #ifndef TARGET_HAS_BIONIC
 #define TARGET_HAS_BIONIC 0
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 69e7e03..5901ba4 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5358,26 +5358,10 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard.  The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}.  The
-default is zero.  The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class})
+This hook determines whether a function from a class of functions
+@var{fn_class} is present at the runtime.
+@end deftypefn
 
 @defmac NEXT_OBJC_RUNTIME
 Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index fad6d10..b51d7b3 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4221,26 +4221,7 @@ refers to the global ``variable'' @code{errno}.  (On certain systems,
 macro, a reasonable default is used.
 @end defmac
 
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard.  The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}.  The
-default is zero.  The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@hook TARGET_LIBC_HAS_FUNCTION
 
 @defmac NEXT_OBJC_RUNTIME
 Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 30cbfe59..7bb2913 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -826,7 +826,7 @@ gfc_init_builtin_functions (void)
 		      BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
 
 
-  if (TARGET_C99_FUNCTIONS)
+  if (targetm.libc_has_function (function_c99_math_complex))
     {
       gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
 			  BUILT_IN_CBRTL, "cbrtl",
@@ -848,7 +848,7 @@ gfc_init_builtin_functions (void)
 			  ATTR_CONST_NOTHROW_LEAF_LIST);
     }
 
-  if (TARGET_HAS_SINCOS)
+  if (targetm.libc_has_function (function_sincos))
     {
       gfc_define_builtin ("__builtin_sincosl",
 			  func_longdouble_longdoublep_longdoublep,
diff --git a/gcc/system.h b/gcc/system.h
index f10ba4a..b735a96 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -914,7 +914,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 	USE_COMMON_FOR_ONE_ONLY IFCVT_EXTRA_FIELDS IFCVT_INIT_EXTRA_FIELDS \
 	CASE_USE_BIT_TESTS FIXUNS_TRUNC_LIKE_FIX_TRUNC                     \
         GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE              \
-        ELIGIBLE_FOR_EPILOGUE_DELAY
+        ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS
 
 /* Hooks that are no longer used.  */
  #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE	\
diff --git a/gcc/target.def b/gcc/target.def
index 561506f..473408c 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2201,6 +2201,13 @@ set via @code{__attribute__}.",
  unsigned int, (tree decl, const char *name, int reloc),
  default_section_type_flags)
 
+DEFHOOK
+(libc_has_function,
+ "This hook determines whether a function from a class of functions\n\
+@var{fn_class} is present at the runtime.",
+ bool, (enum function_class fn_class),
+ default_libc_has_function)
+
 /* True if new jumps cannot be created, to replace existing ones or
    not, at the current point in the compilation.  */
 DEFHOOK
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 2da6fb8..aaddae9 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -166,6 +166,10 @@ extern rtx default_addr_space_convert (rtx, tree, tree);
 extern unsigned int default_case_values_threshold (void);
 extern bool default_have_conditional_execution (void);
 
+extern bool default_libc_has_function (enum function_class);
+extern bool no_c99_libc_has_function (enum function_class);
+extern bool gnu_libc_has_function (enum function_class);
+
 extern tree default_builtin_tm_load_store (tree);
 
 extern int default_memory_move_cost (enum machine_mode, reg_class_t, bool);
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index e9c32b3..b67303a 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1414,7 +1414,8 @@ execute_cse_sincos (void)
 		CASE_FLT_FN (BUILT_IN_SIN):
 		CASE_FLT_FN (BUILT_IN_CEXPI):
 		  /* Make sure we have either sincos or cexp.  */
-		  if (!TARGET_HAS_SINCOS && !TARGET_C99_FUNCTIONS)
+		  if (!targetm.libc_has_function (function_c99_math_complex)
+		      && !targetm.libc_has_function (function_sincos))
 		    break;
 
 		  arg = gimple_call_arg (stmt, 0);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-07-28  0:51                 ` Alexander Ivchenko
@ 2013-07-28 16:37                   ` Michael Eager
  2013-07-29  5:58                     ` Alexander Ivchenko
  2013-08-09 23:45                   ` Joseph S. Myers
  2013-08-21 14:30                   ` Rainer Orth
  2 siblings, 1 reply; 30+ messages in thread
From: Michael Eager @ 2013-07-28 16:37 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: Joseph S. Myers, gcc-patches

On 07/27/13 15:18, Alexander Ivchenko wrote:
> Hi Joseph, thanks for your comments.
>
> I updated the patch:

>
> 2013/7/9 Joseph S. Myers <joseph@codesourcery.com>:

>>
>> * It looks rather like microblaze*-*-* don't use elfos.h, so meaning
>> semantics aren't preserved for those (non-Linux) targets either.  Now, I
>> don't know if there's a good reason for not using that file (ask the
>> architecture maintainer), but in any case semantics should be preserved.


I don't know why microblaze does not include elfos.h.   It looks like
it should, to be consistent with other targets.  This would require some
cleanup and verification.

Your patch adds the following to microblaze.h, duplicating the change
to elfos.h:
+/* microblaze-unknown-elf target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function

I'm assuming that this means that no other change to microblaze is
needed and the question about elfos.h is moot.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-07-28 16:37                   ` Michael Eager
@ 2013-07-29  5:58                     ` Alexander Ivchenko
  2013-07-30 12:26                       ` Alexander Ivchenko
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2013-07-29  5:58 UTC (permalink / raw)
  To: Michael Eager; +Cc: Joseph S. Myers, gcc-patches

2013/7/28 Michael Eager <eager@eagerm.com>:
> On 07/27/13 15:18, Alexander Ivchenko wrote:
>>
>> Hi Joseph, thanks for your comments.
>>
>> I updated the patch:
>
>
>>
>> 2013/7/9 Joseph S. Myers <joseph@codesourcery.com>:
>
>
>>>
>>> * It looks rather like microblaze*-*-* don't use elfos.h, so meaning
>>> semantics aren't preserved for those (non-Linux) targets either.  Now, I
>>> don't know if there's a good reason for not using that file (ask the
>>> architecture maintainer), but in any case semantics should be preserved.
>
>
>
> I don't know why microblaze does not include elfos.h.   It looks like
> it should, to be consistent with other targets.  This would require some
> cleanup and verification.
>
> Your patch adds the following to microblaze.h, duplicating the change
> to elfos.h:
> +/* microblaze-unknown-elf target has no support of C99 runtime */
> +#undef TARGET_LIBC_HAS_FUNCTION
> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>
> I'm assuming that this means that no other change to microblaze is
> needed and the question about elfos.h is moot.

Yes, with this change in my patch the semantics for
microblaze-unknown-elf is preserved. As for
microblaze-unknown-linux-gnu case - the
"linux_android_libc_has_function" version of TARGET_LIBC_HAS_FUNCTION
from linux.h will be used, so the semantics is preserved as well.

--Alexander

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-07-29  5:58                     ` Alexander Ivchenko
@ 2013-07-30 12:26                       ` Alexander Ivchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Alexander Ivchenko @ 2013-07-30 12:26 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

Just to confirm that the patch successfully regtested on
x86_64-unknown-linux-gnu.


thanks,
Alexander

2013/7/29 Alexander Ivchenko <aivchenk@gmail.com>:
> 2013/7/28 Michael Eager <eager@eagerm.com>:
>> On 07/27/13 15:18, Alexander Ivchenko wrote:
>>>
>>> Hi Joseph, thanks for your comments.
>>>
>>> I updated the patch:
>>
>>
>>>
>>> 2013/7/9 Joseph S. Myers <joseph@codesourcery.com>:
>>
>>
>>>>
>>>> * It looks rather like microblaze*-*-* don't use elfos.h, so meaning
>>>> semantics aren't preserved for those (non-Linux) targets either.  Now, I
>>>> don't know if there's a good reason for not using that file (ask the
>>>> architecture maintainer), but in any case semantics should be preserved.
>>
>>
>>
>> I don't know why microblaze does not include elfos.h.   It looks like
>> it should, to be consistent with other targets.  This would require some
>> cleanup and verification.
>>
>> Your patch adds the following to microblaze.h, duplicating the change
>> to elfos.h:
>> +/* microblaze-unknown-elf target has no support of C99 runtime */
>> +#undef TARGET_LIBC_HAS_FUNCTION
>> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>>
>> I'm assuming that this means that no other change to microblaze is
>> needed and the question about elfos.h is moot.
>
> Yes, with this change in my patch the semantics for
> microblaze-unknown-elf is preserved. As for
> microblaze-unknown-linux-gnu case - the
> "linux_android_libc_has_function" version of TARGET_LIBC_HAS_FUNCTION
> from linux.h will be used, so the semantics is preserved as well.
>
> --Alexander

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-07-28  0:51                 ` Alexander Ivchenko
  2013-07-28 16:37                   ` Michael Eager
@ 2013-08-09 23:45                   ` Joseph S. Myers
  2013-08-19 12:46                     ` Kirill Yukhin
  2013-08-21 14:30                   ` Rainer Orth
  2 siblings, 1 reply; 30+ messages in thread
From: Joseph S. Myers @ 2013-08-09 23:45 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: gcc-patches

On Sun, 28 Jul 2013, Alexander Ivchenko wrote:

> Hi Joseph, thanks for your comments.
> 
> I updated the patch:
> 
> 1) The function name as a second argument in libc_has_function target
> hook was removed - was not usefull so far.
> 2) By using contrib/config-list.mk (thanks for the hint - great tool!)
> and analysing tm.h files and what is included in them I have checked
> 197 targets. That analysis includes all issues that you raised in your
> comments - everything is fixed now. I don't like that sometimes we
> have to redefine the version of the hook back to the default one due
> to a poisoning of including elfos.h, but I couldn't find a better
> solution - I commented all those cases.
> 
> Regtesting is in progress now. I have already tested the patch before,
> so I don't expect to see any new problems.
> 
> If all the tests pass, is the patch OK for trunk?

This is OK, with function_gnu removed (nothing appears to use it), if no 
OS port maintainers object to the changes for their OSes within the next 
week.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-08-09 23:45                   ` Joseph S. Myers
@ 2013-08-19 12:46                     ` Kirill Yukhin
  0 siblings, 0 replies; 30+ messages in thread
From: Kirill Yukhin @ 2013-08-19 12:46 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Alexander Ivchenko, gcc-patches

> This is OK, with function_gnu removed (nothing appears to use it), if no 
> OS port maintainers object to the changes for their OSes within the next 
> week.
Hello,
Week is over.
Comitted to MT: http://gcc.gnu.org/ml/gcc-cvs/2013-08/msg00447.html

--
Thanks, K

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-07-28  0:51                 ` Alexander Ivchenko
  2013-07-28 16:37                   ` Michael Eager
  2013-08-09 23:45                   ` Joseph S. Myers
@ 2013-08-21 14:30                   ` Rainer Orth
  2013-08-21 19:28                     ` Alexander Ivchenko
  2 siblings, 1 reply; 30+ messages in thread
From: Rainer Orth @ 2013-08-21 14:30 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: Joseph S. Myers, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1575 bytes --]

Alexander Ivchenko <aivchenk@gmail.com> writes:

> Hi Joseph, thanks for your comments.
>
> I updated the patch:
>
> 1) The function name as a second argument in libc_has_function target
> hook was removed - was not usefull so far.
> 2) By using contrib/config-list.mk (thanks for the hint - great tool!)
> and analysing tm.h files and what is included in them I have checked
> 197 targets. That analysis includes all issues that you raised in your
> comments - everything is fixed now. I don't like that sometimes we
> have to redefine the version of the hook back to the default one due
> to a poisoning of including elfos.h, but I couldn't find a better
> solution - I commented all those cases.
>
> Regtesting is in progress now. I have already tested the patch before,
> so I don't expect to see any new problems.
>
> If all the tests pass, is the patch OK for trunk?

Unfortunately, this patch broke Solaris 10+ bootstrap; it cannot have
been tested properly there:

In file included from ./tm.h:27:0,
                 from /vol/gcc/src/hg/trunk/local/gcc/gencheck.c:23:
/vol/gcc/src/hg/trunk/local/gcc/config/sol2-10.h:21:4: error: "/*" within comment [-Werror=comment]
 /* /* Solaris 10 has the float and long double forms of math functions.
 ^
cc1plus: all warnings being treated as errors
make[3]: *** [build/gencheck.o] Error 1

Fixed as follows; bootstrapped without regressions on
i386-pc-solaris2.10, installed on mainline.

	Rainer


2013-08-21  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* config/sol2-10.h (TARGET_LIBC_HAS_FUNCTION): Don't nest
	comment.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: libc.patch --]
[-- Type: text/x-patch, Size: 577 bytes --]

diff --git a/gcc/config/sol2-10.h b/gcc/config/sol2-10.h
--- a/gcc/config/sol2-10.h
+++ b/gcc/config/sol2-10.h
@@ -18,7 +18,7 @@ You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-/* /* Solaris 10 has the float and long double forms of math functions.
+/* Solaris 10 has the float and long double forms of math functions.
    We redefine this hook so the version from elfos.h header won't be used.  */
 #undef TARGET_LIBC_HAS_FUNCTION
 #define TARGET_LIBC_HAS_FUNCTION default_libc_has_function

[-- Attachment #3: Type: text/plain, Size: 143 bytes --]


-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-08-21 14:30                   ` Rainer Orth
@ 2013-08-21 19:28                     ` Alexander Ivchenko
  2013-08-22  8:56                       ` Andreas Krebbel
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2013-08-21 19:28 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Joseph S. Myers, GCC Patches

Hi, there are still a couple of problems with my patch:

The build is broken for the following targets:
1) *linux* targets that do not include config/linux.h in their tm.h
(e.g alpha-linux, ppc64-linux etc). For them we have:

../../../../gcc/gcc/config/linux-android.c: In function ‘bool
linux_android_libc_has_function(function_class)’:
../../../../gcc/gcc/config/linux-android.c:40:7: error:
‘OPTION_BIONIC’ was not declared in this scope
   if (OPTION_BIONIC)
       ^
make[2]: *** [linux-android.o] Error 1

This is adressed in the changes of config/linux-android.c: linux_libc,
LIBC_GLIBC and LIBC_BIONIC seem to be declared for all *linux*
targets.

2) *uclinux* targets that include config/linux.h. For *uclinux* we do
not use linux-protos.h, and therefore linux_android_libc_has_function
is not declared there.
I don't want to add aditional tmake_file, tm_p_file and extra_objs, so
I added explicit define of TARGET_LIBC_HAS_FUNCTION as
no_c99_libc_has_function for those targets.

I'm sorry for that. The following patch cured my build of those
targets; it is also preserving the initial presence of c99. There were
plenty of targets that were changed by my patch, I hope this time I
didn't miss anything.

Is it ok?

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e27be2..02679f3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2013-08-21  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+ * config/linux-android.c (linux_android_libc_has_function): Fix
+ checks for libc.
+ * config/bfin/uclinux.h: Define TARGET_LIBC_HAS_FUNCTION as
+ no_c99_libc_has_function.
+ * config/c6x/uclinux-elf.h: Ditto.
+ * config/lm32/uclinux-elf.h: Ditto.
+ * config/m68k/uclinux.h: Ditto.
+ * config/moxie/uclinux.h: Ditto.
+
 2013-08-21  Joern Rennecke  <joern.rennecke@embecosm.com>

  * reload.h (struct reg_equivs): Rename to ..
diff --git a/gcc/config/bfin/uclinux.h b/gcc/config/bfin/uclinux.h
index ca0f4ee..63cba99 100644
--- a/gcc/config/bfin/uclinux.h
+++ b/gcc/config/bfin/uclinux.h
@@ -44,3 +44,6 @@ see the files COPYING3 and COPYING.RUNTIME
respectively.  If not, see
 #define TARGET_SUPPORTS_SYNC_CALLS 1

 #define SUBTARGET_FDPIC_NOT_SUPPORTED
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/c6x/uclinux-elf.h b/gcc/config/c6x/uclinux-elf.h
index 5d61f4d..fa0937e 100644
--- a/gcc/config/c6x/uclinux-elf.h
+++ b/gcc/config/c6x/uclinux-elf.h
@@ -62,3 +62,5 @@
     : "0" (_beg), "b" (_end), "b" (_scno)); \
 }

+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
index 4a4b48d..e9d9e9a 100644
--- a/gcc/config/linux-android.c
+++ b/gcc/config/linux-android.c
@@ -35,9 +35,9 @@ linux_android_has_ifunc_p (void)
 bool
 linux_android_libc_has_function (enum function_class fn_class)
 {
-  if (OPTION_GLIBC)
+  if (linux_libc == LIBC_GLIBC)
     return true;
-  if (OPTION_BIONIC)
+  if (linux_libc == LIBC_BIONIC)
     if (fn_class == function_c94
  || fn_class == function_c99_misc
  || fn_class == function_sincos)
diff --git a/gcc/config/lm32/uclinux-elf.h b/gcc/config/lm32/uclinux-elf.h
index 3a556d7..a5e8163 100644
--- a/gcc/config/lm32/uclinux-elf.h
+++ b/gcc/config/lm32/uclinux-elf.h
@@ -77,3 +77,5 @@
 #undef  CC1_SPEC
 #define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}"

+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h
index 8d74312..b1af7d2 100644
--- a/gcc/config/m68k/uclinux.h
+++ b/gcc/config/m68k/uclinux.h
@@ -67,3 +67,6 @@ along with GCC; see the file COPYING3.  If not see
    sections.  */
 #undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
 #define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h
index 498037e..85c65f2 100644
--- a/gcc/config/moxie/uclinux.h
+++ b/gcc/config/moxie/uclinux.h
@@ -37,3 +37,6 @@ see the files COPYING3 and COPYING.RUNTIME
respectively.  If not, see
  --wrap=mmap --wrap=munmap --wrap=alloca\
  %{fmudflapth: --wrap=pthread_create\
 }} %{fmudflap|fmudflapth: --wrap=main}"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function

thanks,
Alexander

2013/8/21 Rainer Orth <ro@cebitec.uni-bielefeld.de>:
> Alexander Ivchenko <aivchenk@gmail.com> writes:
>
>> Hi Joseph, thanks for your comments.
>>
>> I updated the patch:
>>
>> 1) The function name as a second argument in libc_has_function target
>> hook was removed - was not usefull so far.
>> 2) By using contrib/config-list.mk (thanks for the hint - great tool!)
>> and analysing tm.h files and what is included in them I have checked
>> 197 targets. That analysis includes all issues that you raised in your
>> comments - everything is fixed now. I don't like that sometimes we
>> have to redefine the version of the hook back to the default one due
>> to a poisoning of including elfos.h, but I couldn't find a better
>> solution - I commented all those cases.
>>
>> Regtesting is in progress now. I have already tested the patch before,
>> so I don't expect to see any new problems.
>>
>> If all the tests pass, is the patch OK for trunk?
>
> Unfortunately, this patch broke Solaris 10+ bootstrap; it cannot have
> been tested properly there:
>
> In file included from ./tm.h:27:0,
>                  from /vol/gcc/src/hg/trunk/local/gcc/gencheck.c:23:
> /vol/gcc/src/hg/trunk/local/gcc/config/sol2-10.h:21:4: error: "/*" within comment [-Werror=comment]
>  /* /* Solaris 10 has the float and long double forms of math functions.
>  ^
> cc1plus: all warnings being treated as errors
> make[3]: *** [build/gencheck.o] Error 1
>
> Fixed as follows; bootstrapped without regressions on
> i386-pc-solaris2.10, installed on mainline.
>
>         Rainer
>
>
> 2013-08-21  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
>         * config/sol2-10.h (TARGET_LIBC_HAS_FUNCTION): Don't nest
>         comment.
>
>
>
> --
> -----------------------------------------------------------------------------
> Rainer Orth, Center for Biotechnology, Bielefeld University
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-08-21 19:28                     ` Alexander Ivchenko
@ 2013-08-22  8:56                       ` Andreas Krebbel
  2013-08-22 13:19                         ` Alexander Ivchenko
  0 siblings, 1 reply; 30+ messages in thread
From: Andreas Krebbel @ 2013-08-22  8:56 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: gcc-patches

On Wed, Aug 21, 2013 at 11:21:32PM +0400, Alexander Ivchenko wrote:
> I'm sorry for that. The following patch cured my build of those
> targets; it is also preserving the initial presence of c99. There were
> plenty of targets that were changed by my patch, I hope this time I
> didn't miss anything.

S/390 bootstrap still fails. The reason is that when we set
tm_file/tm_p_file in config.gcc we do not append to the existing
content so your adjustments done before are ignored and gcc complains
about unknown linux_android_libc_has_function.

However, since with s390 Linux and TPF we only target GNU Linux
systems with Glibc we can default to gnu_libc_has_functions anyway:

Index: gcc/config/s390/linux.h
===================================================================
*** gcc/config/s390/linux.h.orig        2013-01-14 07:48:06.000000000 +0000
--- gcc/config/s390/linux.h     2013-08-22 07:57:46.006014197 +0000
*************** along with GCC; see the file COPYING3.
*** 87,90 ****
--- 87,93 ----
  /* Define if long doubles should be mangled as 'g'.  */
  #define TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
  
+ #undef TARGET_LIBC_HAS_FUNCTION
+ #define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
+ 
  #endif
Index: gcc/config/s390/tpf.h
===================================================================
*** gcc/config/s390/tpf.h.orig  2013-08-22 07:01:48.000000000 +0000
--- gcc/config/s390/tpf.h       2013-08-22 07:57:27.706013534 +0000
*************** along with GCC; see the file COPYING3.
*** 111,118 ****
  /* IBM copies these libraries over with these names.  */
  #define MATH_LIBRARY "CLBM"
  #define LIBSTDCXX "CPP2"
- #endif /* ! _TPF_H */
  
- /* We redefine this hook so the version from elfos.h header won't be used.  */
  #undef TARGET_LIBC_HAS_FUNCTION
! #define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
--- 111,118 ----
  /* IBM copies these libraries over with these names.  */
  #define MATH_LIBRARY "CLBM"
  #define LIBSTDCXX "CPP2"
  
  #undef TARGET_LIBC_HAS_FUNCTION
! #define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
! 
! #endif /* ! _TPF_H */

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-08-22  8:56                       ` Andreas Krebbel
@ 2013-08-22 13:19                         ` Alexander Ivchenko
  2013-09-03 23:05                           ` Michael Meissner
  2013-09-04  5:15                           ` Maxim Kuvyrkov
  0 siblings, 2 replies; 30+ messages in thread
From: Alexander Ivchenko @ 2013-08-22 13:19 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: GCC Patches

Ugh.. thanks, you are right. That points to another problem that I
didn't see before:

3) *linux* targets that do not append to tm_p_file (s390x-*-linux* and
s390x-ibm-tpf* - your patch addresses that problem correctly) OR
tmake_file (bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux*)

(btw bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux* are
broken now anyways:

opening glibc-c.o: No such file or directory
make[1]: *** [cc1-checksum.c] Error 1
make[1]: *** Waiting for unfinished jobs...)

Sorry again for the inconvenience, here is the updated patch that now,
hopefully, fixes the issues with my initial patch.
(Andreas patch still needs to be applied)

Is it OK?

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e27be2..2d15fb1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2013-08-21  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+ * config/linux-android.c (linux_android_libc_has_function): Fix
+ checks for libc.
+ * config/bfin/uclinux.h: Define TARGET_LIBC_HAS_FUNCTION as
+ no_c99_libc_has_function.
+ * config/c6x/uclinux-elf.h: Ditto.
+ * config/lm32/uclinux-elf.h: Ditto.
+ * config/m68k/uclinux.h: Ditto.
+ * config/moxie/uclinux.h: Ditto.
+ * config.gcc (bfin*-linux-uclibc*): Add t-linux-android to tmake_file.
+ (crisv32-*-linux*, cris-*-linux*): Ditto.
+ * config/bfin/bfin.c: Include "tm_p.h".
+
 2013-08-21  Joern Rennecke  <joern.rennecke@embecosm.com>

  * reload.h (struct reg_equivs): Rename to ..
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 7e1d529..89cf30a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1018,7 +1018,7 @@ bfin*-uclinux*)
  ;;
 bfin*-linux-uclibc*)
  tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h
glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h"
- tmake_file="bfin/t-bfin-linux t-slibgcc"
+ tmake_file="bfin/t-bfin-linux t-slibgcc t-linux-android"
  use_collect2=no
  ;;
 bfin*-rtems*)
@@ -1053,7 +1053,7 @@ cris-*-elf | cris-*-none)
 crisv32-*-linux* | cris-*-linux*)
  tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h
glibc-stdint.h cris/linux.h"
  # We need to avoid using t-linux, so override default tmake_file
- tmake_file="cris/t-cris cris/t-linux t-slibgcc"
+ tmake_file="cris/t-cris cris/t-linux t-slibgcc t-linux-android"
  extra_options="${extra_options} cris/linux.opt"
  case $target in
   cris-*-*)
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 7fab975..18457f8 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -46,6 +46,7 @@
 #include "cgraph.h"
 #include "langhooks.h"
 #include "bfin-protos.h"
+#include "tm_p.h"
 #include "tm-preds.h"
 #include "tm-constrs.h"
 #include "gt-bfin.h"
diff --git a/gcc/config/bfin/uclinux.h b/gcc/config/bfin/uclinux.h
index ca0f4ee..63cba99 100644
--- a/gcc/config/bfin/uclinux.h
+++ b/gcc/config/bfin/uclinux.h
@@ -44,3 +44,6 @@ see the files COPYING3 and COPYING.RUNTIME
respectively.  If not, see
 #define TARGET_SUPPORTS_SYNC_CALLS 1

 #define SUBTARGET_FDPIC_NOT_SUPPORTED
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/c6x/uclinux-elf.h b/gcc/config/c6x/uclinux-elf.h
index 5d61f4d..fa0937e 100644
--- a/gcc/config/c6x/uclinux-elf.h
+++ b/gcc/config/c6x/uclinux-elf.h
@@ -62,3 +62,5 @@
     : "0" (_beg), "b" (_end), "b" (_scno)); \
 }

+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
index 4a4b48d..e9d9e9a 100644
--- a/gcc/config/linux-android.c
+++ b/gcc/config/linux-android.c
@@ -35,9 +35,9 @@ linux_android_has_ifunc_p (void)
 bool
 linux_android_libc_has_function (enum function_class fn_class)
 {
-  if (OPTION_GLIBC)
+  if (linux_libc == LIBC_GLIBC)
     return true;
-  if (OPTION_BIONIC)
+  if (linux_libc == LIBC_BIONIC)
     if (fn_class == function_c94
  || fn_class == function_c99_misc
  || fn_class == function_sincos)
diff --git a/gcc/config/lm32/uclinux-elf.h b/gcc/config/lm32/uclinux-elf.h
index 3a556d7..a5e8163 100644
--- a/gcc/config/lm32/uclinux-elf.h
+++ b/gcc/config/lm32/uclinux-elf.h
@@ -77,3 +77,5 @@
 #undef  CC1_SPEC
 #define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}"

+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h
index 8d74312..b1af7d2 100644
--- a/gcc/config/m68k/uclinux.h
+++ b/gcc/config/m68k/uclinux.h
@@ -67,3 +67,6 @@ along with GCC; see the file COPYING3.  If not see
    sections.  */
 #undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
 #define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h
index 498037e..85c65f2 100644
--- a/gcc/config/moxie/uclinux.h
+++ b/gcc/config/moxie/uclinux.h
@@ -37,3 +37,6 @@ see the files COPYING3 and COPYING.RUNTIME
respectively.  If not, see
  --wrap=mmap --wrap=munmap --wrap=alloca\
  %{fmudflapth: --wrap=pthread_create\
 }} %{fmudflap|fmudflapth: --wrap=main}"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function


thanks,
Alexander

2013/8/22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>:
> On Wed, Aug 21, 2013 at 11:21:32PM +0400, Alexander Ivchenko wrote:
>> I'm sorry for that. The following patch cured my build of those
>> targets; it is also preserving the initial presence of c99. There were
>> plenty of targets that were changed by my patch, I hope this time I
>> didn't miss anything.
>
> S/390 bootstrap still fails. The reason is that when we set
> tm_file/tm_p_file in config.gcc we do not append to the existing
> content so your adjustments done before are ignored and gcc complains
> about unknown linux_android_libc_has_function.
>
> However, since with s390 Linux and TPF we only target GNU Linux
> systems with Glibc we can default to gnu_libc_has_functions anyway:
>
> Index: gcc/config/s390/linux.h
> ===================================================================
> *** gcc/config/s390/linux.h.orig        2013-01-14 07:48:06.000000000 +0000
> --- gcc/config/s390/linux.h     2013-08-22 07:57:46.006014197 +0000
> *************** along with GCC; see the file COPYING3.
> *** 87,90 ****
> --- 87,93 ----
>   /* Define if long doubles should be mangled as 'g'.  */
>   #define TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
>
> + #undef TARGET_LIBC_HAS_FUNCTION
> + #define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
> +
>   #endif
> Index: gcc/config/s390/tpf.h
> ===================================================================
> *** gcc/config/s390/tpf.h.orig  2013-08-22 07:01:48.000000000 +0000
> --- gcc/config/s390/tpf.h       2013-08-22 07:57:27.706013534 +0000
> *************** along with GCC; see the file COPYING3.
> *** 111,118 ****
>   /* IBM copies these libraries over with these names.  */
>   #define MATH_LIBRARY "CLBM"
>   #define LIBSTDCXX "CPP2"
> - #endif /* ! _TPF_H */
>
> - /* We redefine this hook so the version from elfos.h header won't be used.  */
>   #undef TARGET_LIBC_HAS_FUNCTION
> ! #define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
> --- 111,118 ----
>   /* IBM copies these libraries over with these names.  */
>   #define MATH_LIBRARY "CLBM"
>   #define LIBSTDCXX "CPP2"
>
>   #undef TARGET_LIBC_HAS_FUNCTION
> ! #define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
> !
> ! #endif /* ! _TPF_H */
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-08-22 13:19                         ` Alexander Ivchenko
@ 2013-09-03 23:05                           ` Michael Meissner
  2013-09-04  5:15                           ` Maxim Kuvyrkov
  1 sibling, 0 replies; 30+ messages in thread
From: Michael Meissner @ 2013-09-03 23:05 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: Andreas Krebbel, GCC Patches

On Thu, Aug 22, 2013 at 05:04:21PM +0400, Alexander Ivchenko wrote:
> Ugh.. thanks, you are right. That points to another problem that I
> didn't see before:
> 
> 3) *linux* targets that do not append to tm_p_file (s390x-*-linux* and
> s390x-ibm-tpf* - your patch addresses that problem correctly) OR
> tmake_file (bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux*)
> 
> (btw bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux* are
> broken now anyways:
> 
> opening glibc-c.o: No such file or directory
> make[1]: *** [cc1-checksum.c] Error 1
> make[1]: *** Waiting for unfinished jobs...)
> 
> Sorry again for the inconvenience, here is the updated patch that now,
> hopefully, fixes the issues with my initial patch.
> (Andreas patch still needs to be applied)
> 
> Is it OK?
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 6e27be2..2d15fb1 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,17 @@
> +2013-08-21  Alexander Ivchenko  <alexander.ivchenko@intel.com>
> +
> + * config/linux-android.c (linux_android_libc_has_function): Fix
> + checks for libc.
> + * config/bfin/uclinux.h: Define TARGET_LIBC_HAS_FUNCTION as
> + no_c99_libc_has_function.
> + * config/c6x/uclinux-elf.h: Ditto.
> + * config/lm32/uclinux-elf.h: Ditto.
> + * config/m68k/uclinux.h: Ditto.
> + * config/moxie/uclinux.h: Ditto.
> + * config.gcc (bfin*-linux-uclibc*): Add t-linux-android to tmake_file.
> + (crisv32-*-linux*, cris-*-linux*): Ditto.
> + * config/bfin/bfin.c: Include "tm_p.h".
> +
>  2013-08-21  Joern Rennecke  <joern.rennecke@embecosm.com>
> 
>   * reload.h (struct reg_equivs): Rename to ..

Please do not put diff's of the ChangeLog file in the patch.  Instead you
should have the ChangeLog parts in the message, and if it is more than a few
lines, the patch (without the ChangeLog bits) should be a separate attachment.
That allows us to apply the patch without an error.

I just got back from vacation, and noticed the powerpc linux compiler no longer
builds, and I've been reading my old mail from the last week or so.  I suspect
we will need similar patches for the powerpc.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-08-22 13:19                         ` Alexander Ivchenko
  2013-09-03 23:05                           ` Michael Meissner
@ 2013-09-04  5:15                           ` Maxim Kuvyrkov
  2013-09-04  7:43                             ` Alexander Ivchenko
  1 sibling, 1 reply; 30+ messages in thread
From: Maxim Kuvyrkov @ 2013-09-04  5:15 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: Andreas Krebbel, GCC Patches

On 23/08/2013, at 1:04 AM, Alexander Ivchenko wrote:

> Ugh.. thanks, you are right. That points to another problem that I
> didn't see before:
> 
> 3) *linux* targets that do not append to tm_p_file (s390x-*-linux* and
> s390x-ibm-tpf* - your patch addresses that problem correctly) OR
> tmake_file (bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux*)

Could you be more verbose, please?  What some of the *linux* target do not append to tm_p_file?

It seems that there are at least two separate problems:

1. OPTION_BIONIC is not defined in linux-android.c .  I think the right fix here is to copy definitions of OPTION_BIONIC (and, optionally, OPTION_UCLIBC) from gcc/config/linux.h to rs6000/linux.h, rs6000/linux64.h and alpha/linux.h -- in other words, define OPTION_BIONIC and OPTION_UCLIBC whenever OPTION_GLIBC is defined.

2. The second problem is to do with definitions of TARGET_LIBC_HAS_FUNCTION for bfin, c6x, lm32, m68k and moxie.  What is the failure scenario here?

> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 7e1d529..89cf30a 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -1018,7 +1018,7 @@ bfin*-uclinux*)
>  ;;
> bfin*-linux-uclibc*)
>  tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h
> glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h"
> - tmake_file="bfin/t-bfin-linux t-slibgcc"
> + tmake_file="bfin/t-bfin-linux t-slibgcc t-linux-android"
>  use_collect2=no
>  ;;
> bfin*-rtems*)

Why?  Bfin has nothing to do with android.

> @@ -1053,7 +1053,7 @@ cris-*-elf | cris-*-none)
> crisv32-*-linux* | cris-*-linux*)
>  tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h
> glibc-stdint.h cris/linux.h"
>  # We need to avoid using t-linux, so override default tmake_file
> - tmake_file="cris/t-cris cris/t-linux t-slibgcc"
> + tmake_file="cris/t-cris cris/t-linux t-slibgcc t-linux-android"
>  extra_options="${extra_options} cris/linux.opt"
>  case $target in
>   cris-*-*)

Same question here.

> diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
> index 7fab975..18457f8 100644
> --- a/gcc/config/bfin/bfin.c
> +++ b/gcc/config/bfin/bfin.c
> @@ -46,6 +46,7 @@
> #include "cgraph.h"
> #include "langhooks.h"
> #include "bfin-protos.h"
> +#include "tm_p.h"
> #include "tm-preds.h"
> #include "tm-constrs.h"
> #include "gt-bfin.h"
> diff --git a/gcc/config/bfin/uclinux.h b/gcc/config/bfin/uclinux.h
> index ca0f4ee..63cba99 100644
> --- a/gcc/config/bfin/uclinux.h
> +++ b/gcc/config/bfin/uclinux.h
> @@ -44,3 +44,6 @@ see the files COPYING3 and COPYING.RUNTIME
> respectively.  If not, see
> #define TARGET_SUPPORTS_SYNC_CALLS 1
> 
> #define SUBTARGET_FDPIC_NOT_SUPPORTED
> +
> +#undef TARGET_LIBC_HAS_FUNCTION
> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
> diff --git a/gcc/config/c6x/uclinux-elf.h b/gcc/config/c6x/uclinux-elf.h
> index 5d61f4d..fa0937e 100644
> --- a/gcc/config/c6x/uclinux-elf.h
> +++ b/gcc/config/c6x/uclinux-elf.h
> @@ -62,3 +62,5 @@
>     : "0" (_beg), "b" (_end), "b" (_scno)); \
> }
> 
> +#undef TARGET_LIBC_HAS_FUNCTION
> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
> diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
> index 4a4b48d..e9d9e9a 100644
> --- a/gcc/config/linux-android.c
> +++ b/gcc/config/linux-android.c
> @@ -35,9 +35,9 @@ linux_android_has_ifunc_p (void)
> bool
> linux_android_libc_has_function (enum function_class fn_class)
> {
> -  if (OPTION_GLIBC)
> +  if (linux_libc == LIBC_GLIBC)
>     return true;
> -  if (OPTION_BIONIC)
> +  if (linux_libc == LIBC_BIONIC)
>     if (fn_class == function_c94
>  || fn_class == function_c99_misc
>  || fn_class == function_sincos)

The above hunk should not be necessary after (1).

> diff --git a/gcc/config/lm32/uclinux-elf.h b/gcc/config/lm32/uclinux-elf.h
> index 3a556d7..a5e8163 100644
> --- a/gcc/config/lm32/uclinux-elf.h
> +++ b/gcc/config/lm32/uclinux-elf.h
> @@ -77,3 +77,5 @@
> #undef  CC1_SPEC
> #define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}"
> 
> +#undef TARGET_LIBC_HAS_FUNCTION
> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
> diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h
> index 8d74312..b1af7d2 100644
> --- a/gcc/config/m68k/uclinux.h
> +++ b/gcc/config/m68k/uclinux.h
> @@ -67,3 +67,6 @@ along with GCC; see the file COPYING3.  If not see
>    sections.  */
> #undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
> #define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
> +
> +#undef TARGET_LIBC_HAS_FUNCTION
> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
> diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h
> index 498037e..85c65f2 100644
> --- a/gcc/config/moxie/uclinux.h
> +++ b/gcc/config/moxie/uclinux.h
> @@ -37,3 +37,6 @@ see the files COPYING3 and COPYING.RUNTIME
> respectively.  If not, see
>  --wrap=mmap --wrap=munmap --wrap=alloca\
>  %{fmudflapth: --wrap=pthread_create\
> }} %{fmudflap|fmudflapth: --wrap=main}"
> +
> +#undef TARGET_LIBC_HAS_FUNCTION
> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
> 
> 

Thanks,

--
Maxim Kuvyrkov
www.kugelworks.com




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-09-04  5:15                           ` Maxim Kuvyrkov
@ 2013-09-04  7:43                             ` Alexander Ivchenko
  2013-09-04  8:11                               ` Maxim Kuvyrkov
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Ivchenko @ 2013-09-04  7:43 UTC (permalink / raw)
  To: Maxim Kuvyrkov; +Cc: Andreas Krebbel, GCC Patches

Hi Maxim,

2013/9/4 Maxim Kuvyrkov <maxim@kugelworks.com>:
> On 23/08/2013, at 1:04 AM, Alexander Ivchenko wrote:
>
>> Ugh.. thanks, you are right. That points to another problem that I
>> didn't see before:
>>
>> 3) *linux* targets that do not append to tm_p_file (s390x-*-linux* and
>> s390x-ibm-tpf* - your patch addresses that problem correctly) OR
>> tmake_file (bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux*)
>
> Could you be more verbose, please?  What some of the *linux* target do not append to tm_p_file?

*linux* targets that do not append to tm_p_file are 390x-*-linux* and
s390x-ibm-tpf* and Andrew is already addressed this problem.


> It seems that there are at least two separate problems:
>
> 1. OPTION_BIONIC is not defined in linux-android.c .  I think the right fix here is to copy definitions of OPTION_BIONIC (and, optionally, OPTION_UCLIBC) from gcc/config/linux.h to rs6000/linux.h, rs6000/linux64.h and alpha/linux.h -- in other words, define OPTION_BIONIC and OPTION_UCLIBC whenever OPTION_GLIBC is defined.

Why can't we just use the checks like "if (linux_libc == LIBC_GLIBC)".
Seems that we have all infrastructure in place (linux_libc,
LIBC_GLIBC, LIBC_BIONIC, LIBC_UCLIBC are defined for all *linux*
targets). I don't see the reason to make new defines.

> 2. The second problem is to do with definitions of TARGET_LIBC_HAS_FUNCTION for bfin, c6x, lm32, m68k and moxie.  What is the failure scenario here?

"For them we have ar: linux-android.o: No such file or directory" So I
added t-linux-android rules to tmake_file.

(and for bfin additionally we have:
"../../gcc/gcc/config/bfin/bfin.c:5812:29: error:
‘linux_android_libc_has_function’ was not declared in this scope".
because
the tm_p.h is not included in bfin.c)

>
>> diff --git a/gcc/config.gcc b/gcc/config.gcc
>> index 7e1d529..89cf30a 100644
>> --- a/gcc/config.gcc
>> +++ b/gcc/config.gcc
>> @@ -1018,7 +1018,7 @@ bfin*-uclinux*)
>>  ;;
>> bfin*-linux-uclibc*)
>>  tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h
>> glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h"
>> - tmake_file="bfin/t-bfin-linux t-slibgcc"
>> + tmake_file="bfin/t-bfin-linux t-slibgcc t-linux-android"
>>  use_collect2=no
>>  ;;
>> bfin*-rtems*)
>
> Why?  Bfin has nothing to do with android.

Since ‘linux_android_libc_has_function’ handles all three libc options
for all linux targets, that's natural to use this function. May be it
should be called "linux_libc_has_function" and be located in linux.c
(we don't have this file..).

>> @@ -1053,7 +1053,7 @@ cris-*-elf | cris-*-none)
>> crisv32-*-linux* | cris-*-linux*)
>>  tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h
>> glibc-stdint.h cris/linux.h"
>>  # We need to avoid using t-linux, so override default tmake_file
>> - tmake_file="cris/t-cris cris/t-linux t-slibgcc"
>> + tmake_file="cris/t-cris cris/t-linux t-slibgcc t-linux-android"
>>  extra_options="${extra_options} cris/linux.opt"
>>  case $target in
>>   cris-*-*)
>
> Same question here.

Please, see above.

>> diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
>> index 7fab975..18457f8 100644
>> --- a/gcc/config/bfin/bfin.c
>> +++ b/gcc/config/bfin/bfin.c
>> @@ -46,6 +46,7 @@
>> #include "cgraph.h"
>> #include "langhooks.h"
>> #include "bfin-protos.h"
>> +#include "tm_p.h"
>> #include "tm-preds.h"
>> #include "tm-constrs.h"
>> #include "gt-bfin.h"
>> diff --git a/gcc/config/bfin/uclinux.h b/gcc/config/bfin/uclinux.h
>> index ca0f4ee..63cba99 100644
>> --- a/gcc/config/bfin/uclinux.h
>> +++ b/gcc/config/bfin/uclinux.h
>> @@ -44,3 +44,6 @@ see the files COPYING3 and COPYING.RUNTIME
>> respectively.  If not, see
>> #define TARGET_SUPPORTS_SYNC_CALLS 1
>>
>> #define SUBTARGET_FDPIC_NOT_SUPPORTED
>> +
>> +#undef TARGET_LIBC_HAS_FUNCTION
>> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>> diff --git a/gcc/config/c6x/uclinux-elf.h b/gcc/config/c6x/uclinux-elf.h
>> index 5d61f4d..fa0937e 100644
>> --- a/gcc/config/c6x/uclinux-elf.h
>> +++ b/gcc/config/c6x/uclinux-elf.h
>> @@ -62,3 +62,5 @@
>>     : "0" (_beg), "b" (_end), "b" (_scno)); \
>> }
>>
>> +#undef TARGET_LIBC_HAS_FUNCTION
>> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>> diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
>> index 4a4b48d..e9d9e9a 100644
>> --- a/gcc/config/linux-android.c
>> +++ b/gcc/config/linux-android.c
>> @@ -35,9 +35,9 @@ linux_android_has_ifunc_p (void)
>> bool
>> linux_android_libc_has_function (enum function_class fn_class)
>> {
>> -  if (OPTION_GLIBC)
>> +  if (linux_libc == LIBC_GLIBC)
>>     return true;
>> -  if (OPTION_BIONIC)
>> +  if (linux_libc == LIBC_BIONIC)
>>     if (fn_class == function_c94
>>  || fn_class == function_c99_misc
>>  || fn_class == function_sincos)
>
> The above hunk should not be necessary after (1).
>
>> diff --git a/gcc/config/lm32/uclinux-elf.h b/gcc/config/lm32/uclinux-elf.h
>> index 3a556d7..a5e8163 100644
>> --- a/gcc/config/lm32/uclinux-elf.h
>> +++ b/gcc/config/lm32/uclinux-elf.h
>> @@ -77,3 +77,5 @@
>> #undef  CC1_SPEC
>> #define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}"
>>
>> +#undef TARGET_LIBC_HAS_FUNCTION
>> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>> diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h
>> index 8d74312..b1af7d2 100644
>> --- a/gcc/config/m68k/uclinux.h
>> +++ b/gcc/config/m68k/uclinux.h
>> @@ -67,3 +67,6 @@ along with GCC; see the file COPYING3.  If not see
>>    sections.  */
>> #undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
>> #define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
>> +
>> +#undef TARGET_LIBC_HAS_FUNCTION
>> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>> diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h
>> index 498037e..85c65f2 100644
>> --- a/gcc/config/moxie/uclinux.h
>> +++ b/gcc/config/moxie/uclinux.h
>> @@ -37,3 +37,6 @@ see the files COPYING3 and COPYING.RUNTIME
>> respectively.  If not, see
>>  --wrap=mmap --wrap=munmap --wrap=alloca\
>>  %{fmudflapth: --wrap=pthread_create\
>> }} %{fmudflap|fmudflapth: --wrap=main}"
>> +
>> +#undef TARGET_LIBC_HAS_FUNCTION
>> +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>>
>>
>
> Thanks,
>
> --
> Maxim Kuvyrkov
> www.kugelworks.com


Thanks for the review,
Alexander

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-09-04  7:43                             ` Alexander Ivchenko
@ 2013-09-04  8:11                               ` Maxim Kuvyrkov
  2013-09-05 11:03                                 ` Kirill Yukhin
  0 siblings, 1 reply; 30+ messages in thread
From: Maxim Kuvyrkov @ 2013-09-04  8:11 UTC (permalink / raw)
  To: Alexander Ivchenko; +Cc: Andreas Krebbel, GCC Patches

On 4/09/2013, at 7:43 PM, Alexander Ivchenko wrote:

> Hi Maxim,
> 
> 2013/9/4 Maxim Kuvyrkov <maxim@kugelworks.com>:
>> On 23/08/2013, at 1:04 AM, Alexander Ivchenko wrote:
>> 
>>> Ugh.. thanks, you are right. That points to another problem that I
>>> didn't see before:
>>> 
>>> 3) *linux* targets that do not append to tm_p_file (s390x-*-linux* and
>>> s390x-ibm-tpf* - your patch addresses that problem correctly) OR
>>> tmake_file (bfin*-linux-uclibc* or crisv32-*-linux* | cris-*-linux*)
>> 
>> Could you be more verbose, please?  What some of the *linux* target do not append to tm_p_file?
> 
> *linux* targets that do not append to tm_p_file are 390x-*-linux* and
> s390x-ibm-tpf* and Andrew is already addressed this problem.

OK.

> 
> 
>> It seems that there are at least two separate problems:
>> 
>> 1. OPTION_BIONIC is not defined in linux-android.c .  I think the right fix here is to copy definitions of OPTION_BIONIC (and, optionally, OPTION_UCLIBC) from gcc/config/linux.h to rs6000/linux.h, rs6000/linux64.h and alpha/linux.h -- in other words, define OPTION_BIONIC and OPTION_UCLIBC whenever OPTION_GLIBC is defined.
> 
> Why can't we just use the checks like "if (linux_libc == LIBC_GLIBC)".
> Seems that we have all infrastructure in place (linux_libc,
> LIBC_GLIBC, LIBC_BIONIC, LIBC_UCLIBC are defined for all *linux*
> targets). I don't see the reason to make new defines.

Same reason why the existing defines are in place.  OPTION_X is not always the same as (linux_libc == LIBC_X).

> 
>> 2. The second problem is to do with definitions of TARGET_LIBC_HAS_FUNCTION for bfin, c6x, lm32, m68k and moxie.  What is the failure scenario here?
> 
> "For them we have ar: linux-android.o: No such file or directory" So I
> added t-linux-android rules to tmake_file.
> 
> (and for bfin additionally we have:
> "../../gcc/gcc/config/bfin/bfin.c:5812:29: error:
> ‘linux_android_libc_has_function’ was not declared in this scope".
> because
> the tm_p.h is not included in bfin.c)

OK.

> 
>> 
>>> diff --git a/gcc/config.gcc b/gcc/config.gcc
>>> index 7e1d529..89cf30a 100644
>>> --- a/gcc/config.gcc
>>> +++ b/gcc/config.gcc
>>> @@ -1018,7 +1018,7 @@ bfin*-uclinux*)
>>> ;;
>>> bfin*-linux-uclibc*)
>>> tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h
>>> glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h"
>>> - tmake_file="bfin/t-bfin-linux t-slibgcc"
>>> + tmake_file="bfin/t-bfin-linux t-slibgcc t-linux-android"
>>> use_collect2=no
>>> ;;
>>> bfin*-rtems*)
>> 
>> Why?  Bfin has nothing to do with android.
> 
> Since ‘linux_android_libc_has_function’ handles all three libc options
> for all linux targets, that's natural to use this function. May be it
> should be called "linux_libc_has_function" and be located in linux.c
> (we don't have this file..).

OK.

Ideally we would have linux.c with linux_libc_has_function that knows nothing about Bionic and linux-android.c with linux_android_libc_has_function.

The patch is OK with definitions of OPTION_GLIBC, OPTION_UCLIBC and OPTION_BIONIC copied verbatim from gcc/config/linux.h to rs6000 and alpha versions.

It is then on my plate to refactor handling of Bionic libc and remove it from targets that don't support it.

Thanks,

--
Maxim Kuvyrkov
www.kugelworks.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-09-04  8:11                               ` Maxim Kuvyrkov
@ 2013-09-05 11:03                                 ` Kirill Yukhin
  2013-09-05 18:57                                   ` Bernhard Reutner-Fischer
  0 siblings, 1 reply; 30+ messages in thread
From: Kirill Yukhin @ 2013-09-05 11:03 UTC (permalink / raw)
  To: Maxim Kuvyrkov; +Cc: Alexander Ivchenko, Andreas Krebbel, GCC Patches

Hello,
On 04 Sep 20:11, Maxim Kuvyrkov wrote:
> On 4/09/2013, at 7:43 PM, Alexander Ivchenko wrote:
> The patch is OK with definitions of OPTION_GLIBC, OPTION_UCLIBC and OPTION_BIONIC copied verbatim from gcc/config/l

Checked into main trunk: http://gcc.gnu.org/ml/gcc-cvs/2013-09/msg00137.html

--
Thanks, K 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-09-05 11:03                                 ` Kirill Yukhin
@ 2013-09-05 18:57                                   ` Bernhard Reutner-Fischer
  2013-09-05 19:46                                     ` Joseph S. Myers
  0 siblings, 1 reply; 30+ messages in thread
From: Bernhard Reutner-Fischer @ 2013-09-05 18:57 UTC (permalink / raw)
  To: Kirill Yukhin, Maxim Kuvyrkov
  Cc: Alexander Ivchenko, Andreas Krebbel, GCC Patches

On 5 September 2013 13:02:29 Kirill Yukhin <kirill.yukhin@gmail.com> wrote:
> Hello,
> On 04 Sep 20:11, Maxim Kuvyrkov wrote:
> > On 4/09/2013, at 7:43 PM, Alexander Ivchenko wrote:
> > The patch is OK with definitions of OPTION_GLIBC, OPTION_UCLIBC and 
> OPTION_BIONIC copied verbatim from gcc/config/l
>
> Checked into main trunk: http://gcc.gnu.org/ml/gcc-cvs/2013-09/msg00137.html


Unless i am missing something crucial I am not really convinced that this 
bionic support stuff you guys are aiming at is proper, to be defensive..

uClibc has C99 math support optionally as well as other optional, 
nonstandard feature sets. Your patch does not seem to check (in a 
cross-compilable fashion, of course) if C99 math is supported in libc or 
not, thus regressing on uClibc with C99_MATH enabled.

Please revert this patch and handle your libc in a sensible manner as 
everyone else has to since years.. I.e. either be C99 complete or fixup 
your conditions, ideally in the public port.

Thanks,
>
> --
> Thanks, K


Sent with AquaMail for Android
http://www.aqua-mail.com


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Enable non-complex math builtins from C99 for Bionic
  2013-09-05 18:57                                   ` Bernhard Reutner-Fischer
@ 2013-09-05 19:46                                     ` Joseph S. Myers
  0 siblings, 0 replies; 30+ messages in thread
From: Joseph S. Myers @ 2013-09-05 19:46 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer
  Cc: Kirill Yukhin, Maxim Kuvyrkov, Alexander Ivchenko,
	Andreas Krebbel, GCC Patches

On Thu, 5 Sep 2013, Bernhard Reutner-Fischer wrote:

> uClibc has C99 math support optionally as well as other optional, nonstandard
> feature sets. Your patch does not seem to check (in a cross-compilable
> fashion, of course) if C99 math is supported in libc or not, thus regressing
> on uClibc with C99_MATH enabled.

It is a basic principle that it should be possible to bootstrap cross 
tools by building the compiler, once, then using it to build runtime 
libraries.  We haven't got there yet, but configure-time tests for library 
features that affect how the compiler behaves are best avoided so as to 
support such bootstraps - and if present, it's best for there to be a 
corresponding configure option to override them, and a command-line option 
to control things on a per-multilib basis.  To the extent that we do have 
configure support for checking library headers if those are available when 
the compiler is configured, it only supports checking the default multilib 
and not headers for other multilibs.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2013-09-05 19:46 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-30 13:25 [PATCH] Enable non-complex math builtins from C99 for Bionic Alexander Ivchenko
2012-11-30 13:42 ` Richard Biener
2012-11-30 21:48   ` Joseph S. Myers
2012-12-13 15:30     ` Alexander Ivchenko
2012-12-19 17:57       ` Joseph S. Myers
2012-12-21 15:57         ` Alexander Ivchenko
2013-01-07 16:19           ` Joseph S. Myers
2013-03-28 11:46             ` Alexander Ivchenko
2013-04-23 15:00               ` Alexander Ivchenko
2013-05-27  9:15                 ` Alexander Ivchenko
2013-06-13  8:36                   ` Richard Biener
2013-06-19 11:32                     ` Alexander Ivchenko
2013-07-08 22:30               ` Joseph S. Myers
2013-07-28  0:51                 ` Alexander Ivchenko
2013-07-28 16:37                   ` Michael Eager
2013-07-29  5:58                     ` Alexander Ivchenko
2013-07-30 12:26                       ` Alexander Ivchenko
2013-08-09 23:45                   ` Joseph S. Myers
2013-08-19 12:46                     ` Kirill Yukhin
2013-08-21 14:30                   ` Rainer Orth
2013-08-21 19:28                     ` Alexander Ivchenko
2013-08-22  8:56                       ` Andreas Krebbel
2013-08-22 13:19                         ` Alexander Ivchenko
2013-09-03 23:05                           ` Michael Meissner
2013-09-04  5:15                           ` Maxim Kuvyrkov
2013-09-04  7:43                             ` Alexander Ivchenko
2013-09-04  8:11                               ` Maxim Kuvyrkov
2013-09-05 11:03                                 ` Kirill Yukhin
2013-09-05 18:57                                   ` Bernhard Reutner-Fischer
2013-09-05 19:46                                     ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).