mips-protos.h (mulsidi3_gen_fn): New typedef.

* 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.

testsuite/
	* gcc.target/mips/mult-1.c: Forbid octeon.
	* gcc.target/mips/octeon-dmul-3.c: New test.

From-SVN: r154410
This commit is contained in:
Adam Nemet 2009-11-21 19:25:35 +00:00 committed by Adam Nemet
parent 36fd5b872b
commit a3c7bb26ea
7 changed files with 90 additions and 11 deletions

View 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.

View 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 */

View 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;
}
}
/* Return the size in bytes of the trampoline code, padded to
TRAMPOLINE_ALIGNMENT bits. The static chain pointer and target

View File

@ -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")

View 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.

View 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" } } */

View File

@ -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;
}