From 8b0045f2b6b696d2808466662f3eb9f79669e689 Mon Sep 17 00:00:00 2001 From: nemet Date: Sat, 21 Nov 2009 19:25:35 +0000 Subject: [PATCH] * config/mips/mips-protos.h (mulsidi3_gen_fn): New typedef. (mips_mulsidi3_gen_fn): Declare new function. * config/mips/mips.c (mips_mulsidi3_gen_fn): New function. * config/mips/mips.md (mulsidi3): Change condition to use mips_mulsidi3_gen_fn. Use mips_mulsidi3_gen_fn to generate the insn. (mulsidi3_64bit): Don't match for ISA_HAS_DMUL3. (mulsidi3_64bit_dmul): New define_insn. testsuite/ * gcc.target/mips/mult-1.c: Forbid octeon. * gcc.target/mips/octeon-dmul-3.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154410 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++ gcc/config/mips/mips-protos.h | 5 ++++ gcc/config/mips/mips.c | 33 +++++++++++++++++++++++++++ gcc/config/mips/mips.md | 24 +++++++++++-------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/mips/mult-1.c | 4 ++-- gcc/testsuite/gcc.target/mips/octeon-dmul-3.c | 19 +++++++++++++++ 7 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/octeon-dmul-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fee1494..20a2d09 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-11-21 Adam Nemet + + * config/mips/mips-protos.h (mulsidi3_gen_fn): New typedef. + (mips_mulsidi3_gen_fn): Declare new function. + * config/mips/mips.c (mips_mulsidi3_gen_fn): New function. + * config/mips/mips.md (mulsidi3): Change condition to use + mips_mulsidi3_gen_fn. Use mips_mulsidi3_gen_fn to generate the + insn. + (mulsidi3_64bit): Don't match for ISA_HAS_DMUL3. + (mulsidi3_64bit_dmul): New define_insn. + 2009-11-21 Ben Elliston * gengtype-lex.l: Enable noinput flex option. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 716b7ac..e4fbb32 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -346,4 +346,9 @@ extern void mips_final_prescan_insn (rtx, rtx *, int); extern int mips_trampoline_code_size (void); extern void mips_function_profiler (FILE *); +typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx); +#ifdef RTX_CODE +extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code); +#endif + #endif /* ! GCC_MIPS_PROTOS_H */ diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index c8c1dca..eeff72d 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -15982,6 +15982,39 @@ mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx insn, if (mips_need_noat_wrapper_p (insn, opvec, noperands)) mips_pop_asm_switch (&mips_noat); } + +/* Return the function that is used to expand the mulsidi3 pattern. + EXT_CODE is the code of the extension used. Return NULL if widening + multiplication shouldn't be used. */ + +mulsidi3_gen_fn +mips_mulsidi3_gen_fn (enum rtx_code ext_code) +{ + bool signed_p; + + signed_p = ext_code == SIGN_EXTEND; + if (TARGET_64BIT) + { + /* Don't use widening multiplication with MULT when we have DMUL. Even + with the extension of its input operands DMUL is faster. Note that + the extension is not needed for signed multiplication. In order to + ensure that we always remove the redundant sign-extension in this + case we still expand mulsidi3 for DMUL. */ + if (ISA_HAS_DMUL3) + return signed_p ? gen_mulsidi3_64bit_dmul : NULL; + if (TARGET_FIX_R4000) + return NULL; + return signed_p ? gen_mulsidi3_64bit : gen_umulsidi3_64bit; + } + else + { + if (TARGET_FIX_R4000) + return signed_p ? gen_mulsidi3_32bit_r4000 : gen_umulsidi3_32bit_r4000; + if (ISA_HAS_DSPR2) + return signed_p ? gen_mips_mult : gen_mips_multu; + return signed_p ? gen_mulsidi3_32bit : gen_umulsidi3_32bit; + } +} /* Return the size in bytes of the trampoline code, padded to TRAMPOLINE_ALIGNMENT bits. The static chain pointer and target diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 76fc37b..2179b8a 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1847,15 +1847,10 @@ [(set (match_operand:DI 0 "register_operand") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) (any_extend:DI (match_operand:SI 2 "register_operand"))))] - "!TARGET_64BIT || !TARGET_FIX_R4000" + "mips_mulsidi3_gen_fn () != NULL" { - if (TARGET_64BIT) - emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2])); - else if (TARGET_FIX_R4000) - emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1], - operands[2])); - else - emit_insn (gen_mulsidi3_32bit (operands[0], operands[1], operands[2])); + mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (); + emit_insn (fn (operands[0], operands[1], operands[2])); DONE; }) @@ -1885,7 +1880,7 @@ (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:TI 3 "=x")) (clobber (match_scratch:DI 4 "=d"))] - "TARGET_64BIT && !TARGET_FIX_R4000" + "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3" "#" [(set_attr "type" "imul") (set_attr "mode" "SI") @@ -1961,6 +1956,17 @@ [(set_attr "type" "imul") (set_attr "mode" "SI")]) +;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn. +(define_insn "mulsidi3_64bit_dmul" + [(set (match_operand:DI 0 "register_operand" "=d") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) + (clobber (match_scratch:DI 3 "=l"))] + "TARGET_64BIT && ISA_HAS_DMUL3" + "dmul\t%0,%1,%2" + [(set_attr "type" "imul3") + (set_attr "mode" "DI")]) + ;; Widening multiply with negation. (define_insn "*muls_di" [(set (match_operand:DI 0 "register_operand" "=x") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 009b3335..445691a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-11-21 Adam Nemet + + * gcc.target/mips/mult-1.c: Forbid octeon. + * gcc.target/mips/octeon-dmul-3.c: New test. + 2009-11-21 Andreas Krebbel * gcc.dg/tree-ssa/vrp47.c: Fix target check. diff --git a/gcc/testsuite/gcc.target/mips/mult-1.c b/gcc/testsuite/gcc.target/mips/mult-1.c index d82a477..43dd08c 100644 --- a/gcc/testsuite/gcc.target/mips/mult-1.c +++ b/gcc/testsuite/gcc.target/mips/mult-1.c @@ -1,6 +1,6 @@ /* For SI->DI widening multiplication we should use DINS to combine the two - halves. */ -/* { dg-options "-O -mgp64 isa_rev>=2" } */ + halves. For Octeon use DMUL with explicit widening. */ +/* { dg-options "-O -mgp64 isa_rev>=2 forbid_cpu=octeon" } */ /* { dg-final { scan-assembler "\tdins\t" } } */ /* { dg-final { scan-assembler-not "\tdsll\t" } } */ /* { dg-final { scan-assembler-not "\tdsrl\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/octeon-dmul-3.c b/gcc/testsuite/gcc.target/mips/octeon-dmul-3.c new file mode 100644 index 0000000..01f0eef --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon-dmul-3.c @@ -0,0 +1,19 @@ +/* Use DMUL for widening multiplication too. */ +/* { dg-options "-O -march=octeon -mgp64" } */ +/* { dg-final { scan-assembler-times "\tdmul\t" 2 } } */ +/* { dg-final { scan-assembler-not "\td?mult\t" } } */ +/* { dg-final { scan-assembler-times "\tdext\t" 2 } } */ + +NOMIPS16 long long +f (int i, int j) +{ + i++; + return (long long) i * j; +} + +NOMIPS16 unsigned long long +g (unsigned int i, unsigned int j) +{ + i++; + return (unsigned long long) i * j; +} -- 2.7.4