From 47bac44b58d233131d21f747fbef69bd389c8387 Mon Sep 17 00:00:00 2001 From: rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Sat, 17 Apr 2004 07:02:32 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80790 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++ gcc/config/mips/mips.c | 16 ++++ gcc/config/mips/mips.h | 1 + gcc/config/mips/mips.md | 155 +++++++++++++++++-------------- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/vr-mult-1.c | 10 ++ gcc/testsuite/gcc.dg/vr-mult-2.c | 10 ++ 7 files changed, 132 insertions(+), 72 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vr-mult-1.c create mode 100644 gcc/testsuite/gcc.dg/vr-mult-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a29202d65b8..e8f9213e7c05 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +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 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index b8d27a3c39f4..16a1ab252986 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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 diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index c4b7769db515..8bd9fb710de6 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -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 diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index fdf3f96fef06..0ac944419ec4 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -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" "") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e3fd06ac1b4a..a8a7364ad26c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +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*-*-*. diff --git a/gcc/testsuite/gcc.dg/vr-mult-1.c b/gcc/testsuite/gcc.dg/vr-mult-1.c new file mode 100644 index 000000000000..a208067fb7db --- /dev/null +++ b/gcc/testsuite/gcc.dg/vr-mult-1.c @@ -0,0 +1,10 @@ +/* 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" } } */ diff --git a/gcc/testsuite/gcc.dg/vr-mult-2.c b/gcc/testsuite/gcc.dg/vr-mult-2.c new file mode 100644 index 000000000000..4a3ad98cc2a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vr-mult-2.c @@ -0,0 +1,10 @@ +/* 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" } } */ -- GitLab