* optabs.c (expand_twoval_unop): Reorder function arguments.
* builtins.c (expand_builtin_mathfn_3): Update calls to
expand_twoval_unop.
* reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_TAN_ONE
and UNSPEC_TAN_TAN. Add missing comment.
* config/i386/i386.md (*tandf3_1, *tansf3_1, *tanxf3_1): New
patterns to implement fptan x87 instruction.
(tandf2, tansf2, tanxf2): New expanders to implement tan, tanf
and tanl built-ins as inline x87 intrinsics. Define corresponding
peephole2 optimizers for 'fptan; fstp %st(0); fld1' sequence.
(UNSPEC_TAN_ONE, UNSPEC_TAN_TAN): New unspecs to represent
x87's fptan insn.
* gcc.dg/i386-387-1.c: Add new test for __builtin_tan.
* gcc.dg/i386-387-2.c: Likewise.
* gcc.dg/i386-387-7.c: New test.
* gcc.dg/i386-387-8.c: New test.
* gcc.dg/builtins-37.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80677
138bc75d-0d04-0410-961f-
82ee72b054a4
+2004-04-13 Uros Bizjak <uros@kss-loka.si>:
+
+ * optabs.c (expand_twoval_unop): Reorder function arguments.
+ * builtins.c (expand_builtin_mathfn_3): Update calls to
+ expand_twoval_unop.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_TAN_ONE
+ and UNSPEC_TAN_TAN. Add missing comment.
+
+ * config/i386/i386.md (*tandf3_1, *tansf3_1, *tanxf3_1): New
+ patterns to implement fptan x87 instruction.
+ (tandf2, tansf2, tanxf2): New expanders to implement tan, tanf
+ and tanl built-ins as inline x87 intrinsics. Define corresponding
+ peephole2 optimizers for 'fptan; fstp %st(0); fld1' sequence.
+ (UNSPEC_TAN_ONE, UNSPEC_TAN_TAN): New unspecs to represent
+ x87's fptan insn.
+
2004-03-13 Richard Henderson <rth@redhat.com>
* bb-reorder.c (fix_crossing_unconditional_branches): Use Pmode
(sindf2, sinsf2, sinxf2): Rename to *sindf2, *sinsf2, *sinxf2.
(cosdf2, cossf2, cosxf2): Rename to *cosdf2, *cossf2, *cosxf2.
- (UNSPEC_SINCOS_SIN, UNPEC_SINCOS_COS): New unspecs to represent
- x87's unspec insn.
+ (UNSPEC_SINCOS_SIN, UNSPEC_SINCOS_COS): New unspecs to represent
+ x87's fsincos insn.
2004-04-06 Devang Patel <dpatel@apple.com>
case BUILT_IN_SIN:
case BUILT_IN_SINF:
case BUILT_IN_SINL:
- if (! expand_twoval_unop(builtin_optab, 0, target, op0, 0))
+ if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
abort();
break;
case BUILT_IN_COS:
case BUILT_IN_COSF:
case BUILT_IN_COSL:
- if (! expand_twoval_unop(builtin_optab, target, 0, op0, 0))
+ if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
abort();
break;
default:
(UNSPEC_FRNDINT 68)
(UNSPEC_F2XM1 69)
+ ; x87 Double output FP
(UNSPEC_SINCOS_COS 80)
(UNSPEC_SINCOS_SIN 81)
+ (UNSPEC_TAN_ONE 82)
+ (UNSPEC_TAN_TAN 83)
; REP instruction
(UNSPEC_REP 75)
[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
"")
+(define_insn "*tandf3_1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:DF 1 "register_operand" "=u")
+ (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fptan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "DF")])
+
+;; optimize sequence: fptan
+;; fstp %st(0)
+;; fld1
+;; into fptan insn.
+
+(define_peephole2
+ [(parallel[(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:DF 1 "register_operand" "")
+ (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
+ (set (match_dup 0)
+ (match_operand:DF 3 "immediate_operand" ""))]
+ "standard_80387_constant_p (operands[3]) == 2"
+ [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
+ (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
+ "")
+
+(define_expand "tandf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+})
+
+(define_insn "*tansf3_1"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:SF 1 "register_operand" "=u")
+ (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fptan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "SF")])
+
+;; optimize sequence: fptan
+;; fstp %st(0)
+;; fld1
+;; into fptan insn.
+
+(define_peephole2
+ [(parallel[(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:SF 1 "register_operand" "")
+ (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
+ (set (match_dup 0)
+ (match_operand:SF 3 "immediate_operand" ""))]
+ "standard_80387_constant_p (operands[3]) == 2"
+ [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
+ (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
+ "")
+
+(define_expand "tansf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (SFmode);
+})
+
+(define_insn "*tanxf3_1"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fptan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+;; optimize sequence: fptan
+;; fstp %st(0)
+;; fld1
+;; into fptan insn.
+
+(define_peephole2
+ [(parallel[(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:XF 1 "register_operand" "")
+ (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
+ (set (match_dup 0)
+ (match_operand:XF 3 "immediate_operand" ""))]
+ "standard_80387_constant_p (operands[3]) == 2"
+ [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
+ (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
+ "")
+
+(define_expand "tanxf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+})
+
(define_insn "atan2df3_1"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 2 "register_operand" "0")
Returns 1 if this operation can be performed; 0 if not. */
int
-expand_twoval_unop (optab unoptab, rtx targ0, rtx targ1, rtx op0,
+expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
int unsignedp)
{
enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
rtx t1 = gen_reg_rtx (wider_mode);
rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
- if (expand_twoval_unop (unoptab, t0, t1, cop0, unsignedp))
+ if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
{
convert_move (targ0, t0, unsignedp);
convert_move (targ1, t1, unsignedp);
break;
case UNSPEC_SINCOS_COS:
+ case UNSPEC_TAN_ONE:
/* These insns operate on the top two stack slots,
first part of one input, double output insn. */
break;
case UNSPEC_SINCOS_SIN:
+ case UNSPEC_TAN_TAN:
+ /* These insns operate on the top two stack slots,
+ second part of one input, double output insn. */
+
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
emit_swap_insn (insn, regstack, *src1);
+2004-04-13 Uros Bizjak <uros@kss-loka.si>:
+
+ * gcc.dg/i386-387-1.c: Add new test for __builtin_tan.
+ * gcc.dg/i386-387-2.c: Likewise.
+
+ * gcc.dg/i386-387-7.c: New test.
+ * gcc.dg/i386-387-8.c: New test.
+
+ * gcc.dg/builtins-37.c: New test.
+
2004-04-13 Geoffrey Keating <geoffk@apple.com>
* g++.dg/pch/externc-1.C: Add missing semicolon.
--- /dev/null
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check tan, tanf and tanl built-in functions.
+
+ Written by Uros Bizjak, 7th April 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double tan(double);
+extern float tanf(float);
+extern long double tanl(long double);
+
+
+double test1(double x)
+{
+ return tan(x);
+}
+
+float test1f(float x)
+{
+ return tanf(x);
+}
+
+long double test1l(long double x)
+{
+ return tanl(x);
+}
+
/* { dg-final { scan-assembler "call\t_?atan2" } } */
/* { dg-final { scan-assembler "call\t_?log" } } */
/* { dg-final { scan-assembler "call\t_?exp" } } */
+/* { dg-final { scan-assembler "call\t_?tan" } } */
double f1(double x) { return __builtin_sin(x); }
double f2(double x) { return __builtin_cos(x); }
double f4(double x, double y) { return __builtin_atan2(x,y); }
double f5(double x) { return __builtin_log(x); }
double f6(double x) { return __builtin_exp(x); }
+double f7(double x) { return __builtin_tan(x); }
/* { dg-final { scan-assembler "fpatan" } } */
/* { dg-final { scan-assembler "fyl2x" } } */
/* { dg-final { scan-assembler "f2xm1" } } */
+/* { dg-final { scan-assembler "fptan" } } */
double f1(double x) { return __builtin_sin(x); }
double f2(double x) { return __builtin_cos(x); }
double f4(double x, double y) { return __builtin_atan2(x,y); }
double f5(double x) { return __builtin_log(x); }
double f6(double x) { return __builtin_exp(x); }
+double f7(double x) { return __builtin_tan(x); }
--- /dev/null
+/* Verify that 387 fsincos instruction is generated. */
+/* { dg-do compile { target "i?86-*-*" } } */
+/* { dg-options "-O -ffast-math -march=i686" } */
+/* { dg-final { scan-assembler "fsincos" } } */
+
+double f1(double x)
+{
+ return sin(x) + cos (x);
+}
+
--- /dev/null
+/* Verify that 387 fptan instruction is generated. Also check fptan
+ peephole2 optimizer. */
+/* { dg-do compile { target "i?86-*-*" } } */
+/* { dg-options "-O2 -ffast-math -march=i686" } */
+/* { dg-final { scan-assembler "fptan" } } */
+/* { dg-final { scan-assembler-not "fld1" } } */
+
+double f1(double x)
+{
+ return 1.0 / tan(x);
+}
+