* config/mips/mips-protos.h (mulsidi3_gen_fn): New typedef.
authornemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Nov 2009 19:25:35 +0000 (19:25 +0000)
committernemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Nov 2009 19:25:35 +0000 (19:25 +0000)
(mips_mulsidi3_gen_fn): Declare new function.
* config/mips/mips.c (mips_mulsidi3_gen_fn): New function.
* config/mips/mips.md (<u>mulsidi3): Change condition to use
mips_mulsidi3_gen_fn.  Use mips_mulsidi3_gen_fn to generate the
insn.
(<u>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
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/mult-1.c
gcc/testsuite/gcc.target/mips/octeon-dmul-3.c [new file with mode: 0644]

index fee1494..20a2d09 100644 (file)
@@ -1,3 +1,14 @@
+2009-11-21  Adam Nemet  <adambnemet@gmail.com>
+
+       * 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 (<u>mulsidi3): Change condition to use
+       mips_mulsidi3_gen_fn.  Use mips_mulsidi3_gen_fn to generate the
+       insn.
+       (<u>mulsidi3_64bit): Don't match for ISA_HAS_DMUL3.
+       (mulsidi3_64bit_dmul): New define_insn.
+
 2009-11-21  Ben Elliston  <bje@au.ibm.com>
 
        * gengtype-lex.l: Enable noinput flex option.
index 716b7ac..e4fbb32 100644 (file)
@@ -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 */
index c8c1dca..eeff72d 100644 (file)
@@ -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 <u>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;
+    }
+}
 \f
 /* Return the size in bytes of the trampoline code, padded to
    TRAMPOLINE_ALIGNMENT bits.  The static chain pointer and target
index 76fc37b..2179b8a 100644 (file)
   [(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 (<CODE>) != NULL"
 {
-  if (TARGET_64BIT)
-    emit_insn (gen_<u>mulsidi3_64bit (operands[0], operands[1], operands[2]));
-  else if (TARGET_FIX_R4000)
-    emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
-                                           operands[2]));
-  else
-    emit_insn (gen_<u>mulsidi3_32bit (operands[0], operands[1], operands[2]));
+  mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>);
+  emit_insn (fn (operands[0], operands[1], operands[2]));
   DONE;
 })
 
                 (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")
   [(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<u>_di"
   [(set (match_operand:DI 0 "register_operand" "=x")
index 009b333..445691a 100644 (file)
@@ -1,3 +1,8 @@
+2009-11-21  Adam Nemet  <adambnemet@gmail.com>
+
+       * gcc.target/mips/mult-1.c: Forbid octeon.
+       * gcc.target/mips/octeon-dmul-3.c: New test.
+
 2009-11-21  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * gcc.dg/tree-ssa/vrp47.c: Fix target check.
index d82a477..43dd08c 100644 (file)
@@ -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 (file)
index 0000000..01f0eef
--- /dev/null
@@ -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;
+}