OSDN Git Service

2006-01-13 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jan 2006 11:31:49 +0000 (11:31 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jan 2006 11:31:49 +0000 (11:31 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109664 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/387-9.c [new file with mode: 0644]

index 4da37fd..2951055 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2006-01-12  DJ Delorie  <dj@redhat.com>
 
        * config/m32c/shift.md: Rewrite: Allow arbitrary operands for
index 01d16dd..657f38b 100644 (file)
@@ -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 ();
 
index 1df5757..e1cbca6 100644 (file)
@@ -1,3 +1,7 @@
+2006-01-13  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.target/i386/387-9.c: New testcase.
+
 2006-01-12  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/24824
diff --git a/gcc/testsuite/gcc.target/i386/387-9.c b/gcc/testsuite/gcc.target/i386/387-9.c
new file mode 100644 (file)
index 0000000..f04faa5
--- /dev/null
@@ -0,0 +1,36 @@
+/* Verify that 387 fsincos instruction is generated.  */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O -funsafe-math-optimizations -march=i686" } */
+
+extern double sin (double);
+extern double cos (double);
+extern void sincos (double, double *, double *);
+
+double f1(double x)
+{
+  double s, c;
+  sincos (x, &s, &c);
+  return s + c;
+}
+
+double f2(double x)
+{
+  double s, c, tmp;
+  sincos (x, &s, &tmp);
+  c = cos (x);
+  return s + c;
+}
+
+double f3(double x)
+{
+  double s, c, tmp;
+  sincos (x, &tmp, &c);
+  s = sin (x);
+  return s + c;
+}
+
+/* { dg-final { scan-assembler "fsincos" } } */
+/* { dg-final { scan-assembler-not "fsin " } } */
+/* { dg-final { scan-assembler-not "fcos" } } */
+/* { dg-final { scan-assembler-not "call" } } */