Commit 403e54f0 by Richard Guenther Committed by Richard Biener

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
parent 90922b2d
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> 2006-01-12 DJ Delorie <dj@redhat.com>
* config/m32c/shift.md: Rewrite: Allow arbitrary operands for * config/m32c/shift.md: Rewrite: Allow arbitrary operands for
......
...@@ -95,6 +95,7 @@ static void expand_errno_check (tree, rtx); ...@@ -95,6 +95,7 @@ static void expand_errno_check (tree, rtx);
static rtx expand_builtin_mathfn (tree, rtx, rtx); static rtx expand_builtin_mathfn (tree, rtx, rtx);
static rtx expand_builtin_mathfn_2 (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_mathfn_3 (tree, rtx, rtx);
static rtx expand_builtin_sincos (tree);
static rtx expand_builtin_int_roundingfn (tree, rtx, rtx); static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
static rtx expand_builtin_args_info (tree); static rtx expand_builtin_args_info (tree);
static rtx expand_builtin_next_arg (void); static rtx expand_builtin_next_arg (void);
...@@ -2064,7 +2065,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) ...@@ -2064,7 +2065,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
tree fndecl = get_callee_fndecl (exp); tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1); tree arglist = TREE_OPERAND (exp, 1);
enum machine_mode mode; enum machine_mode mode;
bool errno_set = false;
tree arg, narg; tree arg, narg;
if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
...@@ -2084,9 +2084,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) ...@@ -2084,9 +2084,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
/* Make a suitable register to place result in. */ /* Make a suitable register to place result in. */
mode = TYPE_MODE (TREE_TYPE (exp)); mode = TYPE_MODE (TREE_TYPE (exp));
if (! flag_errno_math || ! HONOR_NANS (mode))
errno_set = false;
/* Check if sincos insn is available, otherwise fallback /* Check if sincos insn is available, otherwise fallback
to sin or cos insn. */ to sin or cos insn. */
if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) { 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) ...@@ -2147,9 +2144,6 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
if (target != 0) if (target != 0)
{ {
if (errno_set)
expand_errno_check (exp, target);
/* Output the entire sequence. */ /* Output the entire sequence. */
insns = get_insns (); insns = get_insns ();
end_sequence (); end_sequence ();
...@@ -2168,6 +2162,55 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) ...@@ -2168,6 +2162,55 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
return target; 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). /* Expand a call to one of the builtin rounding functions (lfloor).
If expanding via optab fails, lower expression to (int)(floor(x)). If expanding via optab fails, lower expression to (int)(floor(x)).
EXP is the expression that is a call to the builtin function; 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, ...@@ -5649,6 +5692,14 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
return target; return target;
break; 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: case BUILT_IN_APPLY_ARGS:
return expand_builtin_apply_args (); return expand_builtin_apply_args ();
......
2006-01-13 Richard Guenther <rguenther@suse.de>
* gcc.target/i386/387-9.c: New testcase.
2006-01-12 Nathan Sidwell <nathan@codesourcery.com> 2006-01-12 Nathan Sidwell <nathan@codesourcery.com>
PR c++/24824 PR c++/24824
/* 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment