aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-01-13 11:31:49 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-01-13 11:31:49 +0000
commit403e54f013d0186db61adbc5cfee6ed08f35bfe6 (patch)
treeb8b96c69d5797b33eed925faa0af9382e3fc6fb3 /gcc/builtins.c
parent90922b2d107a5f1c32b5c34f3b36aefe02c33a01 (diff)
downloadgcc-403e54f013d0186db61adbc5cfee6ed08f35bfe6.zip
gcc-403e54f013d0186db61adbc5cfee6ed08f35bfe6.tar.gz
gcc-403e54f013d0186db61adbc5cfee6ed08f35bfe6.tar.bz2
builtins.c (expand_builtin_sincos): New function.
2006-01-13 Richard Guenther <rguenther@suse.de> * builtins.c (expand_builtin_sincos): New function. (expand_builtin_mathfn_3): Remove dead code, sin and cos do not set errno. (expand_builtin): Expand sincos using expand_builtin_sincos. * gcc.target/i386/387-9.c: New testcase. From-SVN: r109664
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c65
1 files changed, 58 insertions, 7 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 01d16dd..657f38b 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -95,6 +95,7 @@ static void expand_errno_check (tree, rtx);
static rtx expand_builtin_mathfn (tree, rtx, rtx);
static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
+static rtx expand_builtin_sincos (tree);
static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
static rtx expand_builtin_args_info (tree);
static rtx expand_builtin_next_arg (void);
@@ -2064,7 +2065,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
enum machine_mode mode;
- bool errno_set = false;
tree arg, narg;
if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
@@ -2084,9 +2084,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
/* Make a suitable register to place result in. */
mode = TYPE_MODE (TREE_TYPE (exp));
- if (! flag_errno_math || ! HONOR_NANS (mode))
- errno_set = false;
-
/* Check if sincos insn is available, otherwise fallback
to sin or cos insn. */
if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
@@ -2147,9 +2144,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
if (target != 0)
{
- if (errno_set)
- expand_errno_check (exp, target);
-
/* Output the entire sequence. */
insns = get_insns ();
end_sequence ();
@@ -2168,6 +2162,55 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
return target;
}
+/* Expand a call to the builtin sincos math function.
+ Return 0 if a normal call should be emitted rather than expanding the
+ function in-line. EXP is the expression that is a call to the builtin
+ function. */
+
+static rtx
+expand_builtin_sincos (tree exp)
+{
+ rtx op0, op1, op2, target1, target2;
+ tree arglist = TREE_OPERAND (exp, 1);
+ enum machine_mode mode;
+ tree arg, sinp, cosp;
+ int result;
+
+ if (!validate_arglist (arglist, REAL_TYPE,
+ POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg = TREE_VALUE (arglist);
+ sinp = TREE_VALUE (TREE_CHAIN (arglist));
+ cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* Make a suitable register to place result in. */
+ mode = TYPE_MODE (TREE_TYPE (arg));
+
+ /* Check if sincos insn is available, otherwise emit the call. */
+ if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ target1 = gen_reg_rtx (mode);
+ target2 = gen_reg_rtx (mode);
+
+ op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (build_fold_indirect_ref (sinp), NULL_RTX, VOIDmode, 0);
+ op2 = expand_expr (build_fold_indirect_ref (cosp), NULL_RTX, VOIDmode, 0);
+
+ /* Compute into target1 and target2.
+ Set TARGET to wherever the result comes back. */
+ result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
+ gcc_assert (result);
+
+ /* Move target1 and target2 to the memory locations indicated
+ by op1 and op2. */
+ emit_move_insn (op1, target1);
+ emit_move_insn (op2, target2);
+
+ return const0_rtx;
+}
+
/* Expand a call to one of the builtin rounding functions (lfloor).
If expanding via optab fails, lower expression to (int)(floor(x)).
EXP is the expression that is a call to the builtin function;
@@ -5649,6 +5692,14 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
return target;
break;
+ CASE_FLT_FN (BUILT_IN_SINCOS):
+ if (! flag_unsafe_math_optimizations)
+ break;
+ target = expand_builtin_sincos (exp);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_APPLY_ARGS:
return expand_builtin_apply_args ();