Commit 3bd06df7 by Richard Sandiford Committed by Richard Sandiford

mips.h (PREDICATE_CODES): Add macc_msac_operand.

	* config/mips/mips.h (PREDICATE_CODES): Add macc_msac_operand.
	* config/mips/mips.c (macc_msac_operand): New function.
	* config/mips/mips.md (*msac): Move after *macc.
	(*msac2): New.  Generalize macc-related peepholes so that they apply
	to msac too.

From-SVN: r80790
parent 38d396e5
2004-04-17 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.h (PREDICATE_CODES): Add macc_msac_operand.
* config/mips/mips.c (macc_msac_operand): New function.
* config/mips/mips.md (*msac): Move after *macc.
(*msac2): New. Generalize macc-related peepholes so that they apply
to msac too.
2004-04-17 Paolo Bonzini <bonzini@gnu.org>
* opts.c (decode_options): Do not enable flag_rename_registers
......
......@@ -1449,6 +1449,22 @@ extend_operator (rtx op, enum machine_mode mode)
&& (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND));
}
/* Return true if X is the right hand side of a "macc" or "msac" instruction.
This predicate is intended for use in peephole optimizations. */
int
macc_msac_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (ISA_HAS_MACC && GET_CODE (x) == PLUS && REG_P (XEXP (x, 1)))
x = XEXP (x, 0);
else if (ISA_HAS_MSAC && GET_CODE (x) == MINUS && REG_P (XEXP (x, 0)))
x = XEXP (x, 1);
else
return false;
return GET_CODE (x) == MULT && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));
}
/* Return nonzero if the code of this rtx pattern is EQ or NE. */
int
......
......@@ -2742,6 +2742,7 @@ typedef struct mips_args {
CONST_DOUBLE, CONST }}, \
{"fcc_register_operand", { REG, SUBREG }}, \
{"hilo_operand", { REG }}, \
{"macc_msac_operand", { PLUS, MINUS }}, \
{"extend_operator", { ZERO_EXTEND, SIGN_EXTEND }},
/* A list of predicates that do special things with modes, and so
......
......@@ -1678,7 +1678,27 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
;; Pattern generated by define_peephole2 below
(define_insn "*msac"
[(set (match_operand:SI 0 "register_operand" "=l,d")
(minus:SI (match_operand:SI 1 "register_operand" "0,l")
(mult:SI (match_operand:SI 2 "register_operand" "d,d")
(match_operand:SI 3 "register_operand" "d,d"))))
(clobber (match_scratch:SI 4 "=h,h"))
(clobber (match_scratch:SI 5 "=X,1"))]
"ISA_HAS_MSAC"
{
if (which_alternative == 1)
return "msac\t%0,%2,%3";
else if (TARGET_MIPS5500)
return "msub\t%2,%3";
else
return "msac\t$0,%2,%3";
}
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
;; Patterns generated by the define_peephole2 below.
(define_insn "*macc2"
[(set (match_operand:SI 0 "register_operand" "=l")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
......@@ -1694,35 +1714,43 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
(define_insn "*msac2"
[(set (match_operand:SI 0 "register_operand" "=l")
(minus:SI (match_dup 0)
(mult:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d"))))
(set (match_operand:SI 3 "register_operand" "=d")
(minus:SI (match_dup 0)
(mult:SI (match_dup 1)
(match_dup 2))))
(clobber (match_scratch:SI 4 "=h"))]
"ISA_HAS_MSAC && reload_completed"
"msac\t%3,%1,%2"
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
;; Similarly msac.
;;
;; Operand 0: LO
;; Operand 1: GPR (1st multiplication operand)
;; Operand 2: GPR (2nd multiplication operand)
;; Operand 3: HI
;; Operand 4: GPR (destination)
;; Operand 1: macc/msac
;; Operand 2: HI
;; Operand 3: GPR (destination)
(define_peephole2
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" ""))
(match_dup 0)))
(clobber (match_operand:SI 3 "register_operand" ""))
(match_operand:SI 1 "macc_msac_operand" ""))
(clobber (match_operand:SI 2 "register_operand" ""))
(clobber (scratch:SI))])
(set (match_operand:SI 4 "register_operand" "")
(set (match_operand:SI 3 "register_operand" "")
(match_dup 0))]
"ISA_HAS_MACC
&& true_regnum (operands[0]) == LO_REGNUM
&& GP_REG_P (true_regnum (operands[4]))"
"true_regnum (operands[0]) == LO_REGNUM
&& GP_REG_P (true_regnum (operands[3]))"
[(parallel [(set (match_dup 0)
(plus:SI (mult:SI (match_dup 1)
(match_dup 2))
(match_dup 0)))
(set (match_dup 4)
(plus:SI (mult:SI (match_dup 1)
(match_dup 2))
(match_dup 0)))
(clobber (match_dup 3))])]
(match_dup 1))
(set (match_dup 3)
(match_dup 1))
(clobber (match_dup 2))])]
"")
;; When we have a three-address multiplication instruction, it should
......@@ -1736,9 +1764,10 @@
;; Operand 1: LO
;; Operand 2: GPR (addend)
;; Operand 3: GPR (destination)
;; Operand 4: GPR (1st multiplication operand)
;; Operand 5: GPR (2nd multiplication operand)
;; Operand 6: HI
;; Operand 4: macc/msac
;; Operand 5: HI
;; Operand 6: new multiplication
;; Operand 7: new addition/subtraction
(define_peephole2
[(match_scratch:SI 0 "d")
(set (match_operand:SI 1 "register_operand" "")
......@@ -1746,34 +1775,35 @@
(match_dup 0)
(parallel
[(set (match_operand:SI 3 "register_operand" "")
(plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
(match_operand:SI 5 "register_operand" ""))
(match_dup 1)))
(clobber (match_operand:SI 6 "register_operand" ""))
(match_operand:SI 4 "macc_msac_operand" ""))
(clobber (match_operand:SI 5 "register_operand" ""))
(clobber (match_dup 1))])]
"ISA_HAS_MACC && GENERATE_MULT3_SI
"GENERATE_MULT3_SI
&& true_regnum (operands[1]) == LO_REGNUM
&& peep2_reg_dead_p (2, operands[1])
&& GP_REG_P (true_regnum (operands[3]))"
[(parallel [(set (match_dup 0)
(mult:SI (match_dup 4)
(match_dup 5)))
(clobber (match_dup 6))
(match_dup 6))
(clobber (match_dup 5))
(clobber (match_dup 1))])
(set (match_dup 3)
(plus:SI (match_dup 0)
(match_dup 2)))]
"")
(match_dup 7))]
{
operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
operands[2], operands[0]);
})
;; Same as above, except LO is the initial target of the macc.
;;
;; Operand 0: GPR (scratch)
;; Operand 1: LO
;; Operand 2: GPR (addend)
;; Operand 3: GPR (1st multiplication operand)
;; Operand 4: GPR (2nd multiplication operand)
;; Operand 5: HI
;; Operand 6: GPR (destination)
;; Operand 3: macc/msac
;; Operand 4: HI
;; Operand 5: GPR (destination)
;; Operand 6: new multiplication
;; Operand 7: new addition/subtraction
(define_peephole2
[(match_scratch:SI 0 "d")
(set (match_operand:SI 1 "register_operand" "")
......@@ -1781,27 +1811,27 @@
(match_dup 0)
(parallel
[(set (match_dup 1)
(plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
(match_operand:SI 4 "register_operand" ""))
(match_dup 1)))
(clobber (match_operand:SI 5 "register_operand" ""))
(match_operand:SI 3 "macc_msac_operand" ""))
(clobber (match_operand:SI 4 "register_operand" ""))
(clobber (scratch:SI))])
(match_dup 0)
(set (match_operand:SI 6 "register_operand" "")
(set (match_operand:SI 5 "register_operand" "")
(match_dup 1))]
"ISA_HAS_MACC && GENERATE_MULT3_SI
"GENERATE_MULT3_SI
&& true_regnum (operands[1]) == LO_REGNUM
&& peep2_reg_dead_p (3, operands[1])
&& GP_REG_P (true_regnum (operands[6]))"
&& GP_REG_P (true_regnum (operands[5]))"
[(parallel [(set (match_dup 0)
(mult:SI (match_dup 3)
(match_dup 4)))
(clobber (match_dup 5))
(match_dup 6))
(clobber (match_dup 4))
(clobber (match_dup 1))])
(set (match_dup 6)
(plus:SI (match_dup 0)
(match_dup 2)))]
"")
(set (match_dup 5)
(match_dup 7))]
{
operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
operands[2], operands[0]);
})
(define_insn "*mul_sub_si"
[(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
......@@ -1873,25 +1903,6 @@
[(set_attr "type" "imul")
(set_attr "mode" "SI")])
(define_insn "*msac"
[(set (match_operand:SI 0 "register_operand" "=l,d")
(minus:SI (match_operand:SI 1 "register_operand" "0,l")
(mult:SI (match_operand:SI 2 "register_operand" "d,d")
(match_operand:SI 3 "register_operand" "d,d"))))
(clobber (match_scratch:SI 4 "=h,h"))
(clobber (match_scratch:SI 5 "=X,1"))]
"ISA_HAS_MSAC"
{
if (which_alternative == 1)
return "msac\t%0,%2,%3";
else if (TARGET_MIPS5500)
return "msub\t%2,%3";
else
return "msac\t$0,%2,%3";
}
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (match_operand:DI 1 "register_operand" "")
......
2004-04-17 Richard Sandiford <rsandifo@redhat.com>
* gcc.dg/vr-mult-[12].c: New tests.
2004-04-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* gcc.dg/funcorder.c: xfail hppa*64*-*-*.
......
/* Make sure that mul/addu is preferred over mtlo/macc on targets that
support both. */
/* { dg-do compile { target mips*-*-* } } */
/* { dg-options "-O2" } */
#if defined (_MIPS_ARCH_VR5400) || defined (_MIPS_ARCH_VR5500)
int f (int a, int b, int c) { return a + b * c; }
#else
void f () { asm volatile ("mul/addu"); }
#endif
/* { dg-final { scan-assembler "mul.*addu" } } */
/* Make sure that mul/subu is preferred over mtlo/msac on targets that
support both. */
/* { dg-do compile { target mips*-*-* } } */
/* { dg-options "-O2" } */
#if defined (_MIPS_ARCH_VR5400) || defined (_MIPS_ARCH_VR5500)
int f (int a, int b, int c) { return a - b * c; }
#else
void f () { asm volatile ("mul/subu"); }
#endif
/* { dg-final { scan-assembler "mul.*subu" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment