/* Compute into op1 and op2. */
expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
}
- else if (targetm.libc_has_function (function_sincos))
+ else if (targetm.libc_has_function (function_sincos, type))
{
tree call, fn = NULL_TREE;
tree top1, top2;
}
if (!call)
{
- if (!targetm.libc_has_function (function_c99_math_complex)
+ if (!targetm.libc_has_function (function_c99_math_complex, type)
|| !builtin_decl_implicit_p (fn))
return NULL_TREE;
fndecl = builtin_decl_explicit (fn);
#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, targetm.libc_has_function (function_c94), true)
+ true, true, !flag_isoc94, ATTRS, \
+ targetm.libc_has_function (function_c94, NULL_TREE), 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, targetm.libc_has_function (function_c99_misc), true)
+ true, true, !flag_isoc99, ATTRS, \
+ targetm.libc_has_function (function_c99_misc, NULL_TREE), true)
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
the standard in C11 or above. */
#undef DEF_C11_BUILTIN
#define DEF_C11_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, !flag_isoc11, ATTRS, targetm.libc_has_function (function_c11_misc), true)
+ true, true, !flag_isoc11, ATTRS, \
+ targetm.libc_has_function (function_c11_misc, NULL_TREE), true)
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
the standard in C2x or above. */
#undef DEF_C2X_BUILTIN
#define DEF_C2X_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, !flag_isoc2x, ATTRS, targetm.libc_has_function (function_c2x_misc), true)
+ true, true, !flag_isoc2x, ATTRS, \
+ targetm.libc_has_function (function_c2x_misc, NULL_TREE), 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)
+ true, true, !flag_isoc99, ATTRS, \
+ targetm.libc_has_function (function_c99_math_complex, \
+ NULL_TREE), \
+ 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
#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, targetm.libc_has_function (function_c99_misc), true)
+ true, true, !flag_isoc99, ATTRS, \
+ targetm.libc_has_function (function_c99_misc, NULL_TREE), 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. */
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);
+extern bool darwin_libc_has_function (enum function_class fn_class, tree);
#endif /* CONFIG_DARWIN_PROTOS_H */
}
bool
-darwin_libc_has_function (enum function_class fn_class)
+darwin_libc_has_function (enum function_class fn_class,
+ tree type ATTRIBUTE_UNUSED)
{
if (fn_class == function_sincos)
return (strverscmp (darwin_macosx_version_min, "10.9") >= 0);
bool
ix86_libc_has_function (enum function_class fn_class)
{
- return targetm.libc_has_function (fn_class);
+ return targetm.libc_has_function (fn_class, NULL_TREE);
}
/* Returns value SYSV_ABI, MS_ABI dependent on fntype,
extern bool linux_has_ifunc_p (void);
-extern bool linux_libc_has_function (enum function_class fn_class);
+extern bool linux_libc_has_function (enum function_class fn_class, tree);
#include "linux-protos.h"
bool
-linux_libc_has_function (enum function_class fn_class)
+linux_libc_has_function (enum function_class fn_class,
+ tree type ATTRIBUTE_UNUSED)
{
if (OPTION_GLIBC || OPTION_MUSL)
return true;
oacc_bcast_partition = 0;
}
+/* Implement TARGET_LIBC_HAS_FUNCTION. */
+
+bool
+nvptx_libc_has_function (enum function_class fn_class, tree type)
+{
+ if (fn_class == function_sincos)
+ {
+ if (type != NULL_TREE)
+ /* Currently, newlib does not support sincosl. */
+ return type == float_type_node || type == double_type_node;
+ else
+ return true;
+ }
+
+ return default_libc_has_function (fn_class, type);
+}
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE nvptx_option_override
#undef TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION nvptx_set_current_function
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION nvptx_libc_has_function
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-nvptx.h"
CASE_FLT_FN (BUILT_IN_CEIL):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
/* Only convert in ISO C99 mode. */
- if (!targetm.libc_has_function (function_c99_misc))
+ if (!targetm.libc_has_function (function_c99_misc, intype))
break;
if (outprec < TYPE_PRECISION (integer_type_node)
|| (outprec == TYPE_PRECISION (integer_type_node)
CASE_FLT_FN (BUILT_IN_FLOOR):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
/* Only convert in ISO C99 mode. */
- if (!targetm.libc_has_function (function_c99_misc))
+ if (!targetm.libc_has_function (function_c99_misc, intype))
break;
if (outprec < TYPE_PRECISION (integer_type_node)
|| (outprec == TYPE_PRECISION (integer_type_node)
CASE_FLT_FN (BUILT_IN_ROUND):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
/* Only convert in ISO C99 mode and with -fno-math-errno. */
- if (!targetm.libc_has_function (function_c99_misc)
+ if (!targetm.libc_has_function (function_c99_misc, intype)
|| flag_errno_math)
break;
if (outprec < TYPE_PRECISION (integer_type_node)
CASE_FLT_FN (BUILT_IN_RINT):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
/* Only convert in ISO C99 mode and with -fno-math-errno. */
- if (!targetm.libc_has_function (function_c99_misc)
+ if (!targetm.libc_has_function (function_c99_misc, intype)
|| flag_errno_math)
break;
if (outprec < TYPE_PRECISION (integer_type_node)
macro, a reasonable default is used.
@end defmac
-@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class})
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class}, tree @var{type})
This hook determines whether a function from a class of functions
-@var{fn_class} is present in the target C library.
+@var{fn_class} is present in the target C library. If @var{type} is NULL,
+the caller asks for support for all standard (float, double, long double)
+types. If @var{type} is non-NULL, the caller asks for support for a
+specific type.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FAST_FUNCTION (int @var{fcode})
BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
- if (targetm.libc_has_function (function_c99_math_complex))
+ if (targetm.libc_has_function (function_c99_math_complex, NULL_TREE))
{
gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
BUILT_IN_CBRTL, "cbrtl",
ATTR_CONST_NOTHROW_LEAF_LIST);
}
- if (targetm.libc_has_function (function_sincos))
+ if (targetm.libc_has_function (function_sincos, NULL_TREE))
{
gfc_define_builtin ("__builtin_sincosl",
func_longdouble_longdoublep_longdoublep,
(with {
const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (@0);
bool use_exp2 = false;
- if (targetm.libc_has_function (function_c99_misc)
+ if (targetm.libc_has_function (function_c99_misc, TREE_TYPE (@0))
&& value->cl == rvc_normal)
{
REAL_VALUE_TYPE frac_rvt = *value;
cexpis (CEXPI)
(simplify
(cexps compositional_complex@0)
- (if (targetm.libc_has_function (function_c99_math_complex))
+ (if (targetm.libc_has_function (function_c99_math_complex, TREE_TYPE (@0)))
(complex
(mult (exps@1 (realpart @0)) (realpart (cexpis:type@2 (imagpart @0))))
(mult @1 (imagpart @2)))))))
/* truncl(extend(x)) and trunc(extend(x)) -> extend(truncf(x)), etc.,
if x is a float. */
(if (optimize && canonicalize_math_p ()
- && targetm.libc_has_function (function_c99_misc))
+ && targetm.libc_has_function (function_c99_misc, NULL_TREE))
(simplify
(froms (convert float_value_p@0))
(convert (tos @0)))))
DEFHOOK
(libc_has_function,
"This hook determines whether a function from a class of functions\n\
-@var{fn_class} is present in the target C library.",
- bool, (enum function_class fn_class),
+@var{fn_class} is present in the target C library. If @var{type} is NULL,\n\
+the caller asks for support for all standard (float, double, long double)\n\
+types. If @var{type} is non-NULL, the caller asks for support for a\n\
+specific type.",
+ bool, (enum function_class fn_class, tree type),
default_libc_has_function)
DEFHOOK
/* 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)
+default_libc_has_function (enum function_class fn_class,
+ tree type ATTRIBUTE_UNUSED)
{
if (fn_class == function_c94
|| fn_class == function_c99_misc
}
bool
-gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED)
{
return true;
}
bool
-no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED)
{
return false;
}
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 default_libc_has_function (enum function_class, tree);
extern bool default_libc_has_fast_function (int fcode);
-extern bool no_c99_libc_has_function (enum function_class);
-extern bool gnu_libc_has_function (enum function_class);
+extern bool no_c99_libc_has_function (enum function_class, tree);
+extern bool gnu_libc_has_function (enum function_class, tree);
extern tree default_builtin_tm_load_store (tree);
CASE_CFN_COS:
CASE_CFN_SIN:
CASE_CFN_CEXPI:
+ arg = gimple_call_arg (stmt, 0);
/* Make sure we have either sincos or cexp. */
- if (!targetm.libc_has_function (function_c99_math_complex)
- && !targetm.libc_has_function (function_sincos))
+ if (!targetm.libc_has_function (function_c99_math_complex,
+ TREE_TYPE (arg))
+ && !targetm.libc_has_function (function_sincos,
+ TREE_TYPE (arg)))
break;
- arg = gimple_call_arg (stmt, 0);
if (TREE_CODE (arg) == SSA_NAME)
cfg_changed |= execute_cse_sincos_1 (arg);
break;