diff options
author | Richard Sandiford <rsandifo@redhat.com> | 2002-10-16 08:13:28 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@redhat.com> | 2002-10-16 08:13:28 +0000 |
commit | 4a191e81564cd86de24d4b47e22e7efe46914c16 (patch) | |
tree | 394413dc6dc5765ddf2f4ccff6d39f873adacbb0 | |
parent | 98d78f5cd5a93de24a57290701d13b01b62e603b (diff) |
* config/mips/mips.h (ISA_HAS_MACC): True for normal-mode vr4120 code.
* config/mips/mips.md (mulsi3_mult3): Add a define_peephole2 to
mop up unnecessarly moves through LO.
(*mul_acc_si): Remove vr5400 and vr5500 handling from here.
(*macc): New pattern for ISA_HAS_MACC. Add define_peephole2s to
change mtlo/macc sequences into mul/add sequences when a three-
address mul is available.
(*macc2): New pattern. Add a define_peephole2 to generate it.
(*mul_sub_si): Fix contraint for operand 5.
(*muls): Use in 32-bit code as well.
(*msac): Likewise. Use msub instead of msac in vr5500 code
if the destination is LO. Remove duplicate define_split.
(*muls_di): Use only in 32-bit code. Adjust rtl accordingly.
(*msac_di): Likewise. Fix formatting.
(smulsi3_highpart, umulsi3_highpart): Use mulhi in 32-bit code too.
(*xmulsi3_highpart_internal): Use only if !ISA_HAS_MULHI.
(*xmulsi3_highpart_mulhi): Use even if !TARGET_64BIT.
(*xmulsi3_neg_highpart_mulhi): Likewise.
(*mul_acc_64bit_di): Remove.
(*mul_acc_di): Use only in 32-bit code. Handle ISA_HAS_MACC as well.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/mips-3_4-rewrite-branch@58195 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 3 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 344 |
3 files changed, 260 insertions, 111 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f294fa699c7..32a509d088d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2002-10-16 Richard Sandiford <rsandifo@redhat.com> + Michael Meissner <meissner@redhat.com> + + * config/mips/mips.h (ISA_HAS_MACC): True for normal-mode vr4120 code. + * config/mips/mips.md (mulsi3_mult3): Add a define_peephole2 to + mop up unnecessarly moves through LO. + (*mul_acc_si): Remove vr5400 and vr5500 handling from here. + (*macc): New pattern for ISA_HAS_MACC. Add define_peephole2s to + change mtlo/macc sequences into mul/add sequences when a three- + address mul is available. + (*macc2): New pattern. Add a define_peephole2 to generate it. + (*mul_sub_si): Fix contraint for operand 5. + (*muls): Use in 32-bit code as well. + (*msac): Likewise. Use msub instead of msac in vr5500 code + if the destination is LO. Remove duplicate define_split. + (*muls_di): Use only in 32-bit code. Adjust rtl accordingly. + (*msac_di): Likewise. Fix formatting. + (smulsi3_highpart, umulsi3_highpart): Use mulhi in 32-bit code too. + (*xmulsi3_highpart_internal): Use only if !ISA_HAS_MULHI. + (*xmulsi3_highpart_mulhi): Use even if !TARGET_64BIT. + (*xmulsi3_neg_highpart_mulhi): Likewise. + (*mul_acc_64bit_di): Remove. + (*mul_acc_di): Use only in 32-bit code. Handle ISA_HAS_MACC as well. + 2002-10-14 Richard Sandiford <rsandifo@redhat.com> * config/mips/vr.h (DRIVER_SELF_SPECS): Define. diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 114712b45e6..231ea02ee20 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -873,7 +873,8 @@ extern void sbss_section PARAMS ((void)); ) /* ISA has three operand multiply instructions that the result from a 4th operand and puts the result in an accumulator. */ -#define ISA_HAS_MACC (TARGET_MIPS5400 \ +#define ISA_HAS_MACC ((TARGET_MIPS4120 && !TARGET_MIPS16) \ + || TARGET_MIPS5400 \ || TARGET_MIPS5500 \ || TARGET_SR71K \ ) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 3855cb99c76..90bccf420ed 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1812,6 +1812,38 @@ [(set_attr "type" "imul") (set_attr "mode" "SI")]) +;; If a register gets allocated to LO, and we spill to memory, the reload +;; will include a move from LO to a GPR. Merge it into the multiplication +;; if it can set the GPR directly. +;; +;; Operand 0: LO +;; Operand 1: GPR (1st multiplication operand) +;; Operand 2: GPR (2nd multiplication operand) +;; Operand 3: HI +;; Operand 4: HILO +;; Operand 5: GPR (destination) +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand" "") + (mult:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" ""))) + (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (scratch:SI)) + (clobber (match_operand:SI 4 "register_operand" ""))]) + (set (match_operand:SI 5 "register_operand" "") + (match_dup 0))] + "GENERATE_MULT3_SI + && true_regnum (operands[0]) == LO_REGNUM + && GP_REG_P (true_regnum (operands[5])) + && peep2_reg_dead_p (2, operands[0])" + [(parallel + [(set (match_dup 5) + (mult:SI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 3)) + (clobber (match_dup 0)) + (clobber (match_dup 4))])]) + (define_insn "mulsi3_internal" [(set (match_operand:SI 0 "register_operand" "=l") (mult:SI (match_operand:SI 1 "register_operand" "d") @@ -1868,30 +1900,15 @@ (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] "(TARGET_MIPS3900 - || TARGET_MIPS5400 - || TARGET_MIPS5500 || ISA_HAS_MADD_MSUB) && !TARGET_MIPS16" "* { static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" }; - static const char *const macc[] = { \"macc\\t$0,%1,%2\", \"macc\\t%0,%1,%2\" }; if (which_alternative == 2) return \"#\"; if (ISA_HAS_MADD_MSUB && which_alternative != 0) return \"#\"; - - if (TARGET_MIPS5400) - return macc[which_alternative]; - - if (TARGET_MIPS5500) - { - if (which_alternative == 0) - return madd[0]; - else - return macc[which_alternative]; - } - return madd[which_alternative]; }" [(set_attr "type" "imadd,imadd,multi") @@ -1942,13 +1959,169 @@ (set (match_dup 0) (match_dup 3))] "") +(define_insn "*macc" + [(set (match_operand:SI 0 "register_operand" "=l,d") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "register_operand" "d,d")) + (match_operand:SI 3 "register_operand" "0,l"))) + (clobber (match_scratch:SI 4 "=h,h")) + (clobber (match_scratch:SI 5 "=X,3")) + (clobber (match_scratch:SI 6 "=a,a"))] + "ISA_HAS_MACC" + "* +{ + if (which_alternative == 1) + return \"macc\\t%0,%1,%2\"; + else if (TARGET_MIPS5500) + return \"madd\\t%1,%2\"; + else + return \"macc\\t%.,%1,%2\"; +}" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) + +;; Pattern generated by 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") + (match_operand:SI 2 "register_operand" "d")) + (match_dup 0))) + (set (match_operand:SI 3 "register_operand" "=d") + (plus:SI (mult:SI (match_dup 1) + (match_dup 2)) + (match_dup 0))) + (clobber (match_scratch:SI 4 "=h")) + (clobber (match_scratch:SI 5 "=a"))] + "ISA_HAS_MACC && reload_completed" + "macc\\t%3,%1,%2" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) + +;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2> +;; +;; Operand 0: LO +;; Operand 1: GPR (1st multiplication operand) +;; Operand 2: GPR (2nd multiplication operand) +;; Operand 3: HI +;; Operand 4: HILO +;; Operand 5: 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" "")) + (clobber (scratch:SI)) + (clobber (match_operand:SI 4 "register_operand" ""))]) + (set (match_operand:SI 5 "register_operand" "") + (match_dup 0))] + "ISA_HAS_MACC + && true_regnum (operands[0]) == LO_REGNUM + && GP_REG_P (true_regnum (operands[5]))" + [(parallel [(set (match_dup 0) + (plus:SI (mult:SI (match_dup 1) + (match_dup 2)) + (match_dup 0))) + (set (match_dup 5) + (plus:SI (mult:SI (match_dup 1) + (match_dup 2)) + (match_dup 0))) + (clobber (match_dup 3)) + (clobber (match_dup 4))])] + "") + +;; When we have a three-address multiplication instruction, it should +;; be faster to do a separate multiply and add, rather than moving +;; something into LO in order to use a macc instruction. +;; +;; This peephole needs a scratch register to cater for the case when one +;; of the multiplication operands is the same as the destination. +;; +;; Operand 0: GPR (scratch) +;; 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 7: HILO +(define_peephole2 + [(match_scratch:SI 0 "d") + (set (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" "")) + (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" "")) + (clobber (match_dup 1)) + (clobber (match_operand:SI 7 "register_operand" ""))])] + "ISA_HAS_MACC && 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)) + (clobber (match_dup 1)) + (clobber (match_dup 7))]) + (set (match_dup 3) + (plus:SI (match_dup 0) + (match_dup 2)))] + "") + +;; 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: HILO +;; Operand 7: GPR (destination) +(define_peephole2 + [(match_scratch:SI 0 "d") + (set (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" "")) + (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" "")) + (clobber (scratch:SI)) + (clobber (match_operand:SI 6 "register_operand" ""))]) + (match_dup 0) + (set (match_operand:SI 7 "register_operand" "") + (match_dup 1))] + "ISA_HAS_MACC && GENERATE_MULT3_SI + && true_regnum (operands[1]) == LO_REGNUM + && peep2_reg_dead_p (3, operands[1]) + && GP_REG_P (true_regnum (operands[7]))" + [(parallel [(set (match_dup 0) + (mult:SI (match_dup 3) + (match_dup 4))) + (clobber (match_dup 5)) + (clobber (match_dup 1)) + (clobber (match_dup 6))]) + (set (match_dup 7) + (plus:SI (match_dup 0) + (match_dup 2)))] + "") + (define_insn "*mul_sub_si" [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") (match_operand:SI 3 "register_operand" "d,d,d")))) (clobber (match_scratch:SI 4 "=h,h,h")) - (clobber (match_scratch:SI 5 "=X,3,l")) + (clobber (match_scratch:SI 5 "=X,1,l")) (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] "ISA_HAS_MADD_MSUB" @@ -2013,7 +2186,7 @@ (clobber (match_scratch:SI 3 "=h,h")) (clobber (match_scratch:SI 4 "=a,a")) (clobber (match_scratch:SI 5 "=X,l"))] - "ISA_HAS_MULS && TARGET_64BIT" + "ISA_HAS_MULS" "@ muls\\t$0,%1,%2 muls\\t%0,%1,%2" @@ -2030,35 +2203,20 @@ (clobber (match_scratch:SI 5 "=X,1,l")) (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] - "ISA_HAS_MSAC && TARGET_64BIT" - "@ - msac\\t$0,%2,%3 - msac\\t%0,%2,%3 - #" + "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,imadd,multi") (set_attr "mode" "SI") (set_attr "length" "4,4,8")]) -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "register_operand" "") - (mult:SI (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "register_operand" "")))) - (clobber (match_scratch:SI 4 "")) - (clobber (match_scratch:SI 5 "")) - (clobber (match_scratch:SI 6 "")) - (clobber (match_scratch:SI 7 ""))] - "reload_completed && !TARGET_DEBUG_D_MODE - && GP_REG_P (true_regnum (operands[0])) - && GP_REG_P (true_regnum (operands[1]))" - [(parallel [(set (match_dup 7) - (mult:SI (match_dup 2) (match_dup 3))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6))]) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))] - "") - (define_expand "muldi3" [(set (match_operand:DI 0 "register_operand" "=l") (mult:DI (match_operand:DI 1 "se_register_operand" "d") @@ -2194,22 +2352,17 @@ [(set_attr "type" "imul") (set_attr "mode" "SI")]) -;; widening multiply with accumulator and/or negation -;; These don't match yet for zero-extending; too complex for combine? -;; Possible additions we should have: -;; "=x" variants for when !TARGET_64BIT ? -;; all-d alternatives with splits like pure SImode versions +;; Widening multiply with negation. It isn't worth using this pattern +;; for 64-bit code since the reload sequence for HILO_REGNUM is so long. (define_insn "*muls_di" - [(set (match_operand:DI 0 "register_operand" "=a") + [(set (match_operand:DI 0 "register_operand" "=x") (neg:DI (mult:DI (match_operator:DI 3 "extend_operator" [(match_operand:SI 1 "register_operand" "d")]) (match_operator:DI 4 "extend_operator" [(match_operand:SI 2 "register_operand" "d")])))) - (clobber (match_scratch:SI 5 "=h")) - (clobber (match_scratch:SI 6 "=l"))] - "TARGET_64BIT - && ISA_HAS_MULS + (clobber (match_scratch:SI 5 "=a"))] + "!TARGET_64BIT && ISA_HAS_MULS && GET_CODE (operands[3]) == GET_CODE (operands[4])" "* { @@ -2222,33 +2375,32 @@ (set_attr "length" "4") (set_attr "mode" "SI")]) +;; Not used for 64-bit code: see comment for *muls_di. (define_insn "*msac_di" - [(set (match_operand:DI 0 "register_operand" "=a") + [(set (match_operand:DI 0 "register_operand" "=x") (minus:DI (match_operand:DI 3 "register_operand" "0") (mult:DI (match_operator:DI 4 "extend_operator" [(match_operand:SI 1 "register_operand" "d")]) (match_operator:DI 5 "extend_operator" [(match_operand:SI 2 "register_operand" "d")])))) - (clobber (match_scratch:SI 6 "=h")) - (clobber (match_scratch:SI 7 "=l"))] - "TARGET_64BIT - && ISA_HAS_MSAC + (clobber (match_scratch:SI 6 "=a"))] + "!TARGET_64BIT && ISA_HAS_MSAC && GET_CODE (operands[4]) == GET_CODE (operands[5])" "* { if (GET_CODE (operands[4]) == SIGN_EXTEND) - { - if (TARGET_MIPS5500) - return \"msub\\t%1,%2\"; - else - return \"msac\\t$0,%1,%2\"; + { + if (TARGET_MIPS5500) + return \"msub\\t%1,%2\"; + else + return \"msac\\t$0,%1,%2\"; } else - { - if (TARGET_MIPS5500) - return \"msubu\\t%1,%2\"; - else - return \"msacu\\t$0,%1,%2\"; + { + if (TARGET_MIPS5500) + return \"msubu\\t%1,%2\"; + else + return \"msacu\\t$0,%1,%2\"; } }" [(set_attr "type" "imadd") @@ -2272,9 +2424,9 @@ #else rtx (*genfn) (); #endif - if (ISA_HAS_MULHI && TARGET_64BIT) + if (ISA_HAS_MULHI) genfn = gen_xmulsi3_highpart_mulhi; - else + else genfn = gen_xmulsi3_highpart_internal; emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy, dummy, dummy2)); @@ -2297,7 +2449,7 @@ #else rtx (*genfn) (); #endif - if (ISA_HAS_MULHI && TARGET_64BIT) + if (ISA_HAS_MULHI) genfn = gen_xmulsi3_highpart_mulhi; else genfn = gen_xmulsi3_highpart_internal; @@ -2317,7 +2469,7 @@ (const_int 32)]))) (clobber (match_scratch:SI 6 "=l")) (clobber (match_scratch:SI 7 "=a"))] - "GET_CODE (operands[3]) == GET_CODE (operands[4])" + "!ISA_HAS_MULHI && GET_CODE (operands[3]) == GET_CODE (operands[4])" "* { if (GET_CODE (operands[3]) == SIGN_EXTEND) @@ -2340,9 +2492,7 @@ (clobber (match_scratch:SI 6 "=l,l")) (clobber (match_scratch:SI 7 "=a,a")) (clobber (match_scratch:SI 8 "=X,h"))] - "ISA_HAS_MULHI - && TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" + "ISA_HAS_MULHI && GET_CODE (operands[3]) == GET_CODE (operands[4])" "* { static char const *const sign[] = { \"mult\\t%1,%2\", \"mulhi\\t%0,%1,%2\" }; @@ -2369,9 +2519,7 @@ (clobber (match_scratch:SI 6 "=l,l")) (clobber (match_scratch:SI 7 "=a,a")) (clobber (match_scratch:SI 8 "=X,h"))] - "ISA_HAS_MULHI - && TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" + "ISA_HAS_MULHI && GET_CODE (operands[3]) == GET_CODE (operands[4])" "* { static char const *const sign[] = { \"mulshi\\t$0,%1,%2\", \"mulshi\\t%0,%1,%2\" }; @@ -2427,38 +2575,17 @@ [(set_attr "type" "imadd") (set_attr "mode" "SI")]) +;; Only use this pattern in 32-bit code: see *muls_di. (define_insn "*mul_acc_di" - [(set (match_operand:DI 0 "register_operand" "+x") - (plus:DI (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")])) - (match_dup 0))) - (clobber (match_scratch:SI 5 "=a"))] - "TARGET_MAD - && ! TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" - "* -{ - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"mad\\t%1,%2\"; - else - return \"madu\\t%1,%2\"; -}" - [(set_attr "type" "imadd") - (set_attr "mode" "SI")]) - -(define_insn "*mul_acc_64bit_di" - [(set (match_operand:DI 0 "register_operand" "+a") + [(set (match_operand:DI 0 "register_operand" "=x") (plus:DI (mult:DI (match_operator:DI 3 "extend_operator" [(match_operand:SI 1 "register_operand" "d")]) (match_operator:DI 4 "extend_operator" [(match_operand:SI 2 "register_operand" "d")])) - (match_dup 0))) - (clobber (match_scratch:SI 5 "=h")) - (clobber (match_scratch:SI 6 "=l"))] - "TARGET_MAD - && TARGET_64BIT + (match_operand:DI 5 "register_operand" "0"))) + (clobber (match_scratch:SI 6 "=a"))] + "(TARGET_MAD || ISA_HAS_MACC) + && !TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])" "* { @@ -2469,26 +2596,23 @@ else return \"madu\\t%1,%2\"; } - else if (ISA_HAS_MACC) + else { if (GET_CODE (operands[3]) == SIGN_EXTEND) { if (TARGET_MIPS5500) return \"madd\\t%1,%2\"; else - return \"macc\\t$0,%1,%2\"; + return \"macc\\t$0,%1,%2\"; } else { if (TARGET_MIPS5500) return \"maddu\\t%1,%2\"; else - return \"maccu\\t$0,%1,%2\"; + return \"maccu\\t$0,%1,%2\"; } } - else - abort (); - }" [(set_attr "type" "imadd") (set_attr "mode" "SI")]) |