aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/mips/mips-protos.h5
-rw-r--r--gcc/config/mips/mips.c33
-rw-r--r--gcc/config/mips/mips.md24
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/mips/mult-1.c4
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-dmul-3.c19
7 files changed, 90 insertions, 11 deletions
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 <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.
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 <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;
+ }
+}
/* 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 (<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;
})
@@ -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<u>_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 <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.
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;
+}