diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4dcbbf12802c034bb54aa8d0c56fec37d744ee80..0ecbe423d55d96f6b428d732d0c71a3e207d62f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2006-05-31 Roger Sayle <roger@eyesopen.com> + + * config/i386/i386.c (ix86_expand_fp_absneg_operator): When SSE + isn't available, directly generate the simpler x87 patterns without + the (use (const_int 0)). + * config/i386/i386.md (*negsf2_1): Enable pre-reload if the SSE + implementation isn't available. + (*negdf2_1): Likewise. + (*negxf2_1): XF mode negation is always done using the x87. + (*abssf2_1, *absdf2_1, *absxf2_1): Likewise^3 for fabs. + 2006-05-31 Roger Sayle <roger@eyesopen.com> * builtins.c (fold_builtin_cabs): Delete prototype. Require an diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8c33150bd783389f0bb60055773cbbc641d82efe..145fc2e523e1b0ed21175621e762026955c6aa74 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9288,22 +9288,17 @@ ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode, if (use_sse) mask = ix86_build_signbit_mask (elt_mode, vector_mode, code == ABS); else - { - /* When not using SSE, we don't use the mask, but prefer to keep the - same general form of the insn pattern to reduce duplication when - it comes time to split. */ - mask = const0_rtx; - } + mask = NULL_RTX; dst = operands[0]; src = operands[1]; /* If the destination is memory, and we don't have matching source - operands, do things in registers. */ + operands or we're using the x87, do things in registers. */ matching_memory = false; if (MEM_P (dst)) { - if (rtx_equal_p (dst, src)) + if (use_sse && rtx_equal_p (dst, src)) matching_memory = true; else dst = gen_reg_rtx (mode); @@ -9321,9 +9316,15 @@ ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode, { set = gen_rtx_fmt_e (code, mode, src); set = gen_rtx_SET (VOIDmode, dst, set); - use = gen_rtx_USE (VOIDmode, mask); - clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); - emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, set, use, clob))); + if (mask) + { + use = gen_rtx_USE (VOIDmode, mask); + clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (3, set, use, clob))); + } + else + emit_insn (set); } if (dst != operands[0]) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a298e1b4aa751192050de26e200f7faa84fec7f4..8380561b58d18f172202ffc8512fb1731ac2172a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -9905,7 +9905,7 @@ (define_insn "*negsf2_1" [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "register_operand" "0")))] - "TARGET_80387 && reload_completed" + "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" "fchs" [(set_attr "type" "fsgn") (set_attr "mode" "SF")]) @@ -9913,7 +9913,7 @@ (define_insn "*negdf2_1" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (match_operand:DF 1 "register_operand" "0")))] - "TARGET_80387 && reload_completed" + "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" "fchs" [(set_attr "type" "fsgn") (set_attr "mode" "DF")]) @@ -9921,7 +9921,7 @@ (define_insn "*negxf2_1" [(set (match_operand:XF 0 "register_operand" "=f") (neg:XF (match_operand:XF 1 "register_operand" "0")))] - "TARGET_80387 && reload_completed" + "TARGET_80387" "fchs" [(set_attr "type" "fsgn") (set_attr "mode" "XF")]) @@ -9929,7 +9929,7 @@ (define_insn "*abssf2_1" [(set (match_operand:SF 0 "register_operand" "=f") (abs:SF (match_operand:SF 1 "register_operand" "0")))] - "TARGET_80387 && reload_completed" + "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" "fabs" [(set_attr "type" "fsgn") (set_attr "mode" "SF")]) @@ -9937,7 +9937,7 @@ (define_insn "*absdf2_1" [(set (match_operand:DF 0 "register_operand" "=f") (abs:DF (match_operand:DF 1 "register_operand" "0")))] - "TARGET_80387 && reload_completed" + "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" "fabs" [(set_attr "type" "fsgn") (set_attr "mode" "DF")]) @@ -9945,7 +9945,7 @@ (define_insn "*absxf2_1" [(set (match_operand:XF 0 "register_operand" "=f") (abs:XF (match_operand:XF 1 "register_operand" "0")))] - "TARGET_80387 && reload_completed" + "TARGET_80387" "fabs" [(set_attr "type" "fsgn") (set_attr "mode" "DF")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7277f60936cf9e9ddba2a97a46d30653a622fecf..c1f6dec91d1e74f8760d0bc978245878aca28d1e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-05-31 Roger Sayle <roger@eyesopen.com> + + * gcc.target/i386/387-11.c: New test case. + 2006-05-31 Mark Mitchell <mark@codesourcery.com> PR c++/27801 diff --git a/gcc/testsuite/gcc.target/i386/387-11.c b/gcc/testsuite/gcc.target/i386/387-11.c new file mode 100644 index 0000000000000000000000000000000000000000..cb55a9337c32311112adec196cb9678be9af19de --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/387-11.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2 -mfpmath=387" } */ + +double foo(double x, double y) +{ + double t = -x * y; + return -t; +} + +/* { dg-final { scan-assembler-not "fchs" } } */