aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-01-19 11:13:24 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-01-19 11:13:24 +0000
commitb54c5497e582ab4ee818b7f4fa50c1ac42d42f42 (patch)
tree8aa7960fa2ab0a9fc31dedc803da21172038a158 /gcc/builtins.c
parent006339cde4079778a003f75127e5bc7fbcde256d (diff)
downloadgcc-b54c5497e582ab4ee818b7f4fa50c1ac42d42f42.zip
gcc-b54c5497e582ab4ee818b7f4fa50c1ac42d42f42.tar.gz
gcc-b54c5497e582ab4ee818b7f4fa50c1ac42d42f42.tar.bz2
builtins.c (expand_builtin_cexpi): Fall back to expanding via cexp in case sincos is not available.
2007-01-19 Richard Guenther <rguenther@suse.de> * builtins.c (expand_builtin_cexpi): Fall back to expanding via cexp in case sincos is not available. From-SVN: r120953
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index a823c6a..82e5a1e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2240,8 +2240,8 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
mode = TYPE_MODE (TREE_TYPE (arg));
/* Try expanding via a sincos optab, fall back to emitting a libcall
- to sincos. We are sure we have sincos either way because cexpi
- is only generated from sincos. */
+ to sincos or cexp. We are sure we have sincos or cexp because cexpi
+ is only generated from sincos, cexp or if we have either of them. */
if (sincos_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
op1 = gen_reg_rtx (mode);
@@ -2252,7 +2252,7 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
/* Compute into op1 and op2. */
expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
}
- else
+ else if (TARGET_HAS_SINCOS)
{
tree call, narglist, fn = NULL_TREE;
tree top1, top2;
@@ -2264,7 +2264,6 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
fn = built_in_decls[BUILT_IN_SINCOS];
else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
fn = built_in_decls[BUILT_IN_SINCOSL];
- gcc_assert (fn);
op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
@@ -2282,6 +2281,24 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
expand_normal (build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
call, narglist, NULL_TREE));
}
+ else
+ {
+ tree call, fn, narg;
+ tree ctype = build_complex_type (type);
+
+ /* We can expand via the C99 cexp function. */
+ gcc_assert (TARGET_C99_FUNCTIONS);
+
+ fn = mathfn_built_in (ctype, BUILT_IN_CEXP);
+ narg = fold_build2 (COMPLEX_EXPR, ctype,
+ build_real (type, dconst0), arg);
+
+ /* Make sure not to fold the cexp call again. */
+ call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
+ return expand_expr (build3 (CALL_EXPR, ctype, call,
+ build_tree_list (NULL_TREE, narg),
+ NULL_TREE), target, VOIDmode, 0);
+ }
/* Now build the proper return type. */
return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),