diff options
author | Richard Guenther <rguenther@suse.de> | 2006-01-13 11:31:49 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2006-01-13 11:31:49 +0000 |
commit | 403e54f013d0186db61adbc5cfee6ed08f35bfe6 (patch) | |
tree | b8b96c69d5797b33eed925faa0af9382e3fc6fb3 /gcc/builtins.c | |
parent | 90922b2d107a5f1c32b5c34f3b36aefe02c33a01 (diff) | |
download | gcc-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.c | 65 |
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 (); |