Patchwork [MIPS] NetLogic XLP scheduling

login
register
mail settings
Submitter Richard Sandiford
Date July 15, 2012, 4:28 p.m.
Message ID <87k3y53s6h.fsf@talisman.home>
Download mbox | patch
Permalink /patch/171077/
State New
Headers show

Comments

Richard Sandiford - July 15, 2012, 4:28 p.m.
Chung-Lin Tang <cltang@codesourcery.com> writes:
> This patch adds scheduling support for the NetLogic XLP, including a new
> pipeline description, and associated changes.
>
> Asides from the new xlp.md description file, there are also some sync
> primitive attribute modifications, for better scheduling of sync loops
> (Maxim should be able to better explain this).

Rather than add a "type" attribute to each sync loop, please just add:

	  (not (eq_attr "sync_mem" "none"))
	  (symbol_ref "syncloop")

to the default value of the "type" attribute.  You'll probably need
to swap the order of the sync* attributes with the "type" attribute
in order for this to compile.

The patch is effectively changing the type of the sync loops from
"unknown" to "syncloop".  That's certainly OK, but you'll need to
add "syncloop" to the "unknown" reservations of all other schedulers
(except for generic.md, where what you've done instead is fine).
It might be easier if you split out the addition of syncloop
as a separate patch.

> Other generic changes include a new "hilo" insn attribute, to mark which
> of HI/LO does a m[ft]hilo insn access.

The way other schedulers handle this is with things like:

(define_insn_reservation "ir_sb1_mfhi" 1
  (and (eq_attr "cpu" "sb1,sb1a")
       (and (eq_attr "type" "mfhilo")
	    (not (match_operand 1 "lo_operand"))))
  "sb1_ex1")

which seems simpler.  mfhilo and mthilo are required to read operand 1
and write to operand 0 (respectively) in order to support this kind of
construct.

That said, even the above is a hold-over from when we tried to allow
high registers to store independent values.  These days we can be a bit
more precise, as with the patch below.  (As the comment says:

	 ;; If a doubleword move uses these expensive instructions,
	 ;; it is usually better to schedule them in the same way
	 ;; as the singleword form, rather than as "multi".

I'm continuing to assume that mflo and mtlo are the best type choices
for unsplit double-register moves.  That path should be very rarely
outside of MIPS16 anyway -- just by sched1 if hi and lo are exposed
directly -- and no current scheduler tries to model a doubleword hi/lo
move separately from single-register ones.  The information is available
via the dword_mode attribute if required.)

Tested on mips64-elf, and by making sure that there were no changes in
-O2 output for a recent set of cc1 .ii files.  Applied.

I'm probably punishing you for being honest here, but the only other
thing is that you've listed NetLogic Microsystems Inc. as one of the
authors.  I think that means they'll need to sign a copyright assignment.
Have they already done that?

Thanks,
Richard


gcc/
	* config/mips/mips.md (move_type): Replace mfhilo and mthilo
	with mflo and mtlo.
	(type): Split mfhilo into mfhi and mflo.  Split mthilo into mthi
	and mtlo.  Adjust move_type->type mapping.
	(may_clobber_hilo): Split mthilo into mthi and mtlo.
	(*movdi_32bit, *movdi_32bit_mips16, *movdi_64bit, *movdi_64bit_mips16)
	(*mov<mode>_internal, *mov<mode>_mips16, *movhi_internal)
	(*movhi_mips16, *movqi_internal, *movqi_mips16): Use mtlo and mflo
	instead of mthilo and mfhilo.
	(mfhi<GPR:mode>_<HILO:mode>): Use mfhi instead of mfhilo.
	(mthi<GPR:mode>_<HILO:mode>): Use mthi instead of mthilo.
	* config/mips/mips-dsp.md (mips_extr_w, mips_extr_r_w, mips_extr_rs_w)
	(mips_extr_s_h, mips_extp, mips_extpdp, mips_shilo, mips_mthlip):
	Use mflo instead of mfhilo.
	* config/mips/10000.md (r10k_arith): Split mthilo.
	(r10k_mfhi, r10k_mflo): Use mfhi and mflo directly.
	* config/mips/sb1.md (ir_sb1_mfhi, ir_sb1_mflo): Likewise.
	(ir_sb1_mthilo): Split mthilo into mthi and mtlo.
	* config/mips/20kc.md (r20kc_imthilo, r20kc_imfhilo): Split
	mthilo and mfhilo.
	* config/mips/24k.md (r24k_int_mfhilo, r24k_int_mthilo): Likewise.
	* config/mips/4130.md (vr4130_class, vr4130_mfhilo, vr4130_mthilo):
	Likewise.
	* config/mips/4k.md (r4k_int_mthilo, r4k_int_mfhilo): Likewise.
	* config/mips/5400.md (ir_vr54_hilo): Likewise.
	* config/mips/5500.md (ir_vr55_mthilo, ir_vr55_mfhilo): Likewise.
	* config/mips/5k.md (r5k_int_mthilo, r5k_int_mfhilo): Likewise.
	* config/mips/7000.md (rm7_mthilo, rm7_mfhilo): Likewise.
	* config/mips/74k.md (r74k_int_mfhilo, r74k_int_mthilo): Likewise.
	* config/mips/9000.md (rm9k_mfhilo, rm9k_mthilo): Likewise.
	* config/mips/generic.md (generic_hilo): Likewise.
	* config/mips/loongson2ef.md (ls2_alu): Likewise.
	* config/mips/loongson3a.md (ls3a_mfhilo): Likewise.
	* config/mips/octeon.md (octeon_imul_o1, octeon_imul_o2)
	(octeon_mfhilo_o1, octeon_mfhilo_o2): Likewise.
	* config/mips/sr71k.md (ir_sr70_hilo): Likewise.
	* config/mips/xlr.md (xlr_hilo): Likewise.
Chung-Lin Tang - July 16, 2012, 6:37 a.m.
On 2012/7/16 12:28 AM, Richard Sandiford wrote:
> Chung-Lin Tang <cltang@codesourcery.com> writes:
>> This patch adds scheduling support for the NetLogic XLP, including a new
>> pipeline description, and associated changes.
>>
>> Asides from the new xlp.md description file, there are also some sync
>> primitive attribute modifications, for better scheduling of sync loops
>> (Maxim should be able to better explain this).
> 
> Rather than add a "type" attribute to each sync loop, please just add:
> 
> 	  (not (eq_attr "sync_mem" "none"))
> 	  (symbol_ref "syncloop")
> 
> to the default value of the "type" attribute.  You'll probably need
> to swap the order of the sync* attributes with the "type" attribute
> in order for this to compile.
> 
> The patch is effectively changing the type of the sync loops from
> "unknown" to "syncloop".  That's certainly OK, but you'll need to
> add "syncloop" to the "unknown" reservations of all other schedulers
> (except for generic.md, where what you've done instead is fine).
> It might be easier if you split out the addition of syncloop
> as a separate patch.

I'll leave it to Maxim to respond to the sync parts.

>> Other generic changes include a new "hilo" insn attribute, to mark which
>> of HI/LO does a m[ft]hilo insn access.
> 
> The way other schedulers handle this is with things like:
> 
> (define_insn_reservation "ir_sb1_mfhi" 1
>   (and (eq_attr "cpu" "sb1,sb1a")
>        (and (eq_attr "type" "mfhilo")
> 	    (not (match_operand 1 "lo_operand"))))
>   "sb1_ex1")
> 
> which seems simpler.  mfhilo and mthilo are required to read operand 1
> and write to operand 0 (respectively) in order to support this kind of
> construct.
> 
> That said, even the above is a hold-over from when we tried to allow
> high registers to store independent values.  These days we can be a bit
> more precise, as with the patch below.  (As the comment says:
> 
> 	 ;; If a doubleword move uses these expensive instructions,
> 	 ;; it is usually better to schedule them in the same way
> 	 ;; as the singleword form, rather than as "multi".
> 
> I'm continuing to assume that mflo and mtlo are the best type choices
> for unsplit double-register moves.  That path should be very rarely
> outside of MIPS16 anyway -- just by sched1 if hi and lo are exposed
> directly -- and no current scheduler tries to model a doubleword hi/lo
> move separately from single-register ones.  The information is available
> via the dword_mode attribute if required.)

I suppose this means that actual generation of moves as mfhi/mthi should
almost never happen out of normal conditions?

> Tested on mips64-elf, and by making sure that there were no changes in
> -O2 output for a recent set of cc1 .ii files.  Applied.
> 
> I'm probably punishing you for being honest here, but the only other
> thing is that you've listed NetLogic Microsystems Inc. as one of the
> authors.  I think that means they'll need to sign a copyright assignment.
> Have they already done that?

They have assigned the copyright to Mentor Graphics, so it should mean
the code can be contributed by us.

Thanks,
Chung-Lin
Maxim Kuvyrkov - July 16, 2012, 6:56 a.m.
On 16/07/2012, at 6:37 PM, Chung-Lin Tang wrote:

> On 2012/7/16 12:28 AM, Richard Sandiford wrote:
>> Chung-Lin Tang <cltang@codesourcery.com> writes:
>>> This patch adds scheduling support for the NetLogic XLP, including a new
>>> pipeline description, and associated changes.
>>> 
>>> Asides from the new xlp.md description file, there are also some sync
>>> primitive attribute modifications, for better scheduling of sync loops
>>> (Maxim should be able to better explain this).
>> 
>> Rather than add a "type" attribute to each sync loop, please just add:
>> 
>> 	  (not (eq_attr "sync_mem" "none"))
>> 	  (symbol_ref "syncloop")
>> 
>> to the default value of the "type" attribute.  You'll probably need
>> to swap the order of the sync* attributes with the "type" attribute
>> in order for this to compile.
>> 
>> The patch is effectively changing the type of the sync loops from
>> "unknown" to "syncloop".  That's certainly OK, but you'll need to
>> add "syncloop" to the "unknown" reservations of all other schedulers
>> (except for generic.md, where what you've done instead is fine).
>> It might be easier if you split out the addition of syncloop
>> as a separate patch.
> 
> I'll leave it to Maxim to respond to the sync parts.

Richard, that's indeed simpler, thanks.

Chung-Lin, I'll try to make a patch for the patch in the next couple of days and will send it to you.  Let me know if you'd rather fixed this yourself.

...

>> Tested on mips64-elf, and by making sure that there were no changes in
>> -O2 output for a recent set of cc1 .ii files.  Applied.
>> 
>> I'm probably punishing you for being honest here, but the only other
>> thing is that you've listed NetLogic Microsystems Inc. as one of the
>> authors.  I think that means they'll need to sign a copyright assignment.
>> Have they already done that?
> 
> They have assigned the copyright to Mentor Graphics, so it should mean
> the code can be contributed by us.

That is correct.  NetLogic developed the original xlp.md description, which Chung-Lin essentially rewrote.  In any case, Mentor has copyright assignment for the original xlp.md specifically so that we can contribute this upstream.

Thank you,

--
Maxim Kuvyrkov
CodeSourcery / Mentor Graphics
Richard Sandiford - July 16, 2012, 9:05 a.m.
Chung-Lin Tang <cltang@codesourcery.com> writes:
>>> Other generic changes include a new "hilo" insn attribute, to mark which
>>> of HI/LO does a m[ft]hilo insn access.
>> 
>> The way other schedulers handle this is with things like:
>> 
>> (define_insn_reservation "ir_sb1_mfhi" 1
>>   (and (eq_attr "cpu" "sb1,sb1a")
>>        (and (eq_attr "type" "mfhilo")
>> 	    (not (match_operand 1 "lo_operand"))))
>>   "sb1_ex1")
>> 
>> which seems simpler.  mfhilo and mthilo are required to read operand 1
>> and write to operand 0 (respectively) in order to support this kind of
>> construct.
>> 
>> That said, even the above is a hold-over from when we tried to allow
>> high registers to store independent values.  These days we can be a bit
>> more precise, as with the patch below.  (As the comment says:
>> 
>> 	 ;; If a doubleword move uses these expensive instructions,
>> 	 ;; it is usually better to schedule them in the same way
>> 	 ;; as the singleword form, rather than as "multi".
>> 
>> I'm continuing to assume that mflo and mtlo are the best type choices
>> for unsplit double-register moves.  That path should be very rarely
>> outside of MIPS16 anyway -- just by sched1 if hi and lo are exposed
>> directly -- and no current scheduler tries to model a doubleword hi/lo
>> move separately from single-register ones.  The information is available
>> via the dword_mode attribute if required.)
>
> I suppose this means that actual generation of moves as mfhi/mthi should
> almost never happen out of normal conditions?

Yeah, the move patterns themselves never generate mfhi or mthi in isolation.
They either generate mflo, mtlo, mfhi+mflo, or mthi+mtlo.  mfhi and mthi
have special patterns that are generated by post-reload splits.

Richard
Richard Sandiford - July 16, 2012, 9:07 a.m.
Maxim Kuvyrkov <maxim@codesourcery.com> writes:
> On 16/07/2012, at 6:37 PM, Chung-Lin Tang wrote:
>> On 2012/7/16 12:28 AM, Richard Sandiford wrote:
>>> Chung-Lin Tang <cltang@codesourcery.com> writes:
>>> Tested on mips64-elf, and by making sure that there were no changes in
>>> -O2 output for a recent set of cc1 .ii files.  Applied.
>>> 
>>> I'm probably punishing you for being honest here, but the only other
>>> thing is that you've listed NetLogic Microsystems Inc. as one of the
>>> authors.  I think that means they'll need to sign a copyright assignment.
>>> Have they already done that?
>> 
>> They have assigned the copyright to Mentor Graphics, so it should mean
>> the code can be contributed by us.
>
> That is correct.  NetLogic developed the original xlp.md description, which Chung-Lin essentially rewrote.  In any case, Mentor has copyright assignment for the original xlp.md specifically so that we can contribute this upstream.

Ah, excellent, thanks.

Richard
Maxim Kuvyrkov - July 20, 2012, 4:27 a.m.
On 16/07/2012, at 6:56 PM, Maxim Kuvyrkov wrote:

> On 16/07/2012, at 6:37 PM, Chung-Lin Tang wrote:
> 
>> On 2012/7/16 12:28 AM, Richard Sandiford wrote:
>>> Chung-Lin Tang <cltang@codesourcery.com> writes:
>>>> This patch adds scheduling support for the NetLogic XLP, including a new
>>>> pipeline description, and associated changes.
>>>> 
>>>> Asides from the new xlp.md description file, there are also some sync
>>>> primitive attribute modifications, for better scheduling of sync loops
>>>> (Maxim should be able to better explain this).
>>> 
>>> Rather than add a "type" attribute to each sync loop, please just add:
>>> 
>>> 	  (not (eq_attr "sync_mem" "none"))
>>> 	  (symbol_ref "syncloop")
>>> 
>>> to the default value of the "type" attribute.  You'll probably need
>>> to swap the order of the sync* attributes with the "type" attribute
>>> in order for this to compile.
>>> 
>>> The patch is effectively changing the type of the sync loops from
>>> "unknown" to "syncloop".  That's certainly OK, but you'll need to
>>> add "syncloop" to the "unknown" reservations of all other schedulers
>>> (except for generic.md, where what you've done instead is fine).
>>> It might be easier if you split out the addition of syncloop
>>> as a separate patch.
>> 
>> I'll leave it to Maxim to respond to the sync parts.
> 
> Richard, that's indeed simpler, thanks.

Attached is a stand-alone patch that adds handling of "syncloop" and "atomic" type attributes.

Tested by building cross-toolchain mips64-linux-gnu including GLIBC.  OK to apply?

--
Maxim Kuvyrkov
CodeSourcery / Mentor Graphics
Richard Sandiford - July 20, 2012, 8:26 a.m.
Maxim Kuvyrkov <maxim@codesourcery.com> writes:
> 2012-07-13  Maxim Kuvyrkov  <maxim@codesourcery.com>
>
> 	* config/mips/mips.md (define_attr sync_*): Move before "type".
> 	(define_attr "type"): New values "atomic" and "syncloop".
> 	* config/mips/sync.md (atomic_exchange<mode>, atomic_fetch_add<mode>):
> 	Set "type" attribute.
> 	* config/mips/generic.md (generic_atomic, generic_syncloop):
> 	New reservations.
> 	* gcc/config/mips/10000.md, gcc/config/mips/20kc.md,
> 	* gcc/config/mips/24k.md, gcc/config/mips/4130.md,
>         * gcc/config/mips/4k.md, gcc/config/mips/5400.md,
> 	* gcc/config/mips/5500.md, gcc/config/mips/5k.md,
>         * gcc/config/mips/7000.md, gcc/config/mips/74k.md,
> 	* gcc/config/mips/9000.md, gcc/config/mips/loongson2ef.md,
> 	* gcc/config/mips/loongson3a.md, gcc/config/mips/octeon.md,
> 	* gcc/config/mips/sb1.md, gcc/config/mips/sr71k.md,
> 	* gcc/config/mips/xlr.md: Handle "atomic" and "syncloop" types.

OK, thanks.

Richard

Patch

Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2012-06-23 08:30:36.000000000 +0100
+++ gcc/config/mips/mips.md	2012-07-14 13:26:35.795953795 +0100
@@ -201,7 +201,7 @@  (define_attr "jal_macro" "no,yes"
 ;; the split instructions; in some cases, it is more appropriate for the
 ;; scheduling type to be "multi" instead.
 (define_attr "move_type"
-  "unknown,load,fpload,store,fpstore,mtc,mfc,mthilo,mfhilo,move,fmove,
+  "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,move,fmove,
    const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
    shift_shift,lui_movf"
   (const_string "unknown"))
@@ -239,8 +239,10 @@  (define_attr "dword_mode" "no,yes"
 ;; condmove	conditional moves
 ;; mtc		transfer to coprocessor
 ;; mfc		transfer from coprocessor
-;; mthilo	transfer to hi/lo registers
-;; mfhilo	transfer from hi/lo registers
+;; mthi		transfer to a hi register
+;; mtlo		transfer to a lo register
+;; mfhi		transfer from a hi register
+;; mflo		transfer from a lo register
 ;; const	load constant
 ;; arith	integer arithmetic instructions
 ;; logical      integer logical instructions
@@ -278,7 +280,7 @@  (define_attr "dword_mode" "no,yes"
 ;; ghost	an instruction that produces no real code
 (define_attr "type"
   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
-   prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical,
+   prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
    shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
    fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
    frsqrt,frsqrt1,frsqrt2,multi,nop,ghost"
@@ -298,8 +300,8 @@  (define_attr "type"
 	 (eq_attr "move_type" "fpstore") (const_string "fpstore")
 	 (eq_attr "move_type" "mtc") (const_string "mtc")
 	 (eq_attr "move_type" "mfc") (const_string "mfc")
-	 (eq_attr "move_type" "mthilo") (const_string "mthilo")
-	 (eq_attr "move_type" "mfhilo") (const_string "mfhilo")
+	 (eq_attr "move_type" "mtlo") (const_string "mtlo")
+	 (eq_attr "move_type" "mflo") (const_string "mflo")
 
 	 ;; These types of move are always single insns.
 	 (eq_attr "move_type" "fmove") (const_string "fmove")
@@ -475,7 +477,7 @@  (define_attr "length" ""
 
 	  ;; Check for doubleword moves that are decomposed into two
 	  ;; instructions.
-	  (and (eq_attr "move_type" "mtc,mfc,mthilo,mfhilo,move")
+	  (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
 	       (eq_attr "dword_mode" "yes"))
 	  (const_int 8)
 
@@ -557,7 +559,7 @@  (define_attr "hazard" "none,delay,hilo"
 	      (match_test "TARGET_FIX_R4000"))
 	 (const_string "hilo")
 
-	 (and (eq_attr "type" "mfhilo")
+	 (and (eq_attr "type" "mfhi,mflo")
 	      (not (match_test "ISA_HAS_HILO_INTERLOCKS")))
 	 (const_string "hilo")]
 	(const_string "none")))
@@ -585,7 +587,7 @@  (define_attr "branch_likely" "no,yes"
 ;; True if an instruction might assign to hi or lo when reloaded.
 ;; This is used by the TUNE_MACC_CHAINS code.
 (define_attr "may_clobber_hilo" "no,yes"
-  (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
+  (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthi,mtlo")
 		(const_string "yes")
 		(const_string "no")))
 
@@ -4115,7 +4117,7 @@  (define_insn "*movdi_32bit"
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
+  [(set_attr "move_type" "move,const,load,store,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
    (set_attr "mode" "DI")])
 
 (define_insn "*movdi_32bit_mips16"
@@ -4125,7 +4127,7 @@  (define_insn "*movdi_32bit_mips16"
    && (register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo")
+  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
    (set_attr "mode" "DI")])
 
 (define_insn "*movdi_64bit"
@@ -4135,7 +4137,7 @@  (define_insn "*movdi_64bit"
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mthilo,mfhilo,mtc,fpload,mfc,fpstore")
+  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore")
    (set_attr "mode" "DI")])
 
 (define_insn "*movdi_64bit_mips16"
@@ -4145,7 +4147,7 @@  (define_insn "*movdi_64bit_mips16"
    && (register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mfhilo")
+  [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
    (set_attr "mode" "DI")])
 
 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
@@ -4213,7 +4215,7 @@  (define_insn "*mov<mode>_internal"
    && (register_operand (operands[0], <MODE>mode)
        || reg_or_0_operand (operands[1], <MODE>mode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,fpload,mfc,fpstore")
+  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore")
    (set_attr "mode" "SI")])
 
 (define_insn "*mov<mode>_mips16"
@@ -4223,7 +4225,7 @@  (define_insn "*mov<mode>_mips16"
    && (register_operand (operands[0], <MODE>mode)
        || register_operand (operands[1], <MODE>mode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mfhilo")
+  [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
    (set_attr "mode" "SI")])
 
 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
@@ -4400,7 +4402,7 @@  (define_insn "*movhi_internal"
    && (register_operand (operands[0], HImode)
        || reg_or_0_operand (operands[1], HImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo")
+  [(set_attr "move_type" "move,const,load,store,mtlo,mflo")
    (set_attr "mode" "HI")])
 
 (define_insn "*movhi_mips16"
@@ -4410,7 +4412,7 @@  (define_insn "*movhi_mips16"
    && (register_operand (operands[0], HImode)
        || register_operand (operands[1], HImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo")
+  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
    (set_attr "mode" "HI")])
 
 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
@@ -4475,7 +4477,7 @@  (define_insn "*movqi_internal"
    && (register_operand (operands[0], QImode)
        || reg_or_0_operand (operands[1], QImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo")
+  [(set_attr "move_type" "move,const,load,store,mtlo,mflo")
    (set_attr "mode" "QI")])
 
 (define_insn "*movqi_mips16"
@@ -4485,7 +4487,7 @@  (define_insn "*movqi_mips16"
    && (register_operand (operands[0], QImode)
        || register_operand (operands[1], QImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo")
+  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
    (set_attr "mode" "QI")])
 
 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
@@ -4616,7 +4618,7 @@  (define_insn "*movti"
    && (register_operand (operands[0], TImode)
        || reg_or_0_operand (operands[1], TImode))"
   "#"
-  [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo")
+  [(set_attr "move_type" "move,const,load,store,mtlo,mflo")
    (set_attr "mode" "TI")])
 
 (define_insn "*movti_mips16"
@@ -4627,7 +4629,7 @@  (define_insn "*movti_mips16"
    && (register_operand (operands[0], TImode)
        || register_operand (operands[1], TImode))"
   "#"
-  [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo")
+  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
    (set_attr "mode" "TI")])
 
 ;; 128-bit floating point moves
@@ -4734,7 +4736,7 @@  (define_insn "mfhi<GPR:mode>_<HILO:mode>
 		    UNSPEC_MFHI))]
   ""
   { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; }
-  [(set_attr "move_type" "mfhilo")
+  [(set_attr "type" "mfhi")
    (set_attr "mode" "<GPR:MODE>")])
 
 ;; Set the high part of a HI/LO value, given that the low part has
@@ -4747,7 +4749,7 @@  (define_insn "mthi<GPR:mode>_<HILO:mode>
 		     UNSPEC_MTHI))]
   ""
   "mthi\t%z1"
-  [(set_attr "move_type" "mthilo")
+  [(set_attr "type" "mthi")
    (set_attr "mode" "SI")])
 
 ;; Emit a doubleword move in which exactly one of the operands is
Index: gcc/config/mips/mips-dsp.md
===================================================================
--- gcc/config/mips/mips-dsp.md	2012-01-04 19:04:48.000000000 +0000
+++ gcc/config/mips/mips-dsp.md	2012-07-14 09:55:30.923984782 +0100
@@ -909,7 +909,7 @@  (define_insn "mips_extr_w"
     }
   return "extrv.w\t%0,%q1,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 (define_insn "mips_extr_r_w"
@@ -930,7 +930,7 @@  (define_insn "mips_extr_r_w"
     }
   return "extrv_r.w\t%0,%q1,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 (define_insn "mips_extr_rs_w"
@@ -951,7 +951,7 @@  (define_insn "mips_extr_rs_w"
     }
   return "extrv_rs.w\t%0,%q1,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 ;; EXTR*_S.H
@@ -973,7 +973,7 @@  (define_insn "mips_extr_s_h"
     }
   return "extrv_s.h\t%0,%q1,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 ;; EXTP*
@@ -996,7 +996,7 @@  (define_insn "mips_extp"
     }
   return "extpv\t%0,%q1,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 (define_insn "mips_extpdp"
@@ -1021,7 +1021,7 @@  (define_insn "mips_extpdp"
     }
   return "extpdpv\t%0,%q1,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 ;; SHILO*
@@ -1040,7 +1040,7 @@  (define_insn "mips_shilo"
     }
   return "shilov\t%q0,%2";
 }
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 ;; MTHLIP*
@@ -1056,7 +1056,7 @@  (define_insn "mips_mthlip"
 			 (reg:CCDSP CCDSP_PO_REGNUM)] UNSPEC_MTHLIP))])]
   "ISA_HAS_DSP && !TARGET_64BIT"
   "mthlip\t%2,%q0"
-  [(set_attr "type"	"mfhilo")
+  [(set_attr "type"	"mflo")
    (set_attr "mode"	"SI")])
 
 ;; WRDSP
Index: gcc/config/mips/10000.md
===================================================================
--- gcc/config/mips/10000.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/10000.md	2012-07-14 09:03:32.058992414 +0100
@@ -68,21 +68,19 @@  (define_insn_reservation "r10k_fpload" 3
 ;; Miscellaneous arith goes here too (this is a guess).
 (define_insn_reservation "r10k_arith" 1
   (and (eq_attr "cpu" "r10000")
-       (eq_attr "type" "arith,mthilo,slt,clz,const,nop,trap,logical"))
+       (eq_attr "type" "arith,mthi,mtlo,slt,clz,const,nop,trap,logical"))
   "r10k_alu1 | r10k_alu2")
 
 ;; We treat mfhilo differently, because we need to know when
 ;; it's HI and when it's LO.
 (define_insn_reservation "r10k_mfhi" 1
   (and (eq_attr "cpu" "r10000")
-       (and (eq_attr "type" "mfhilo")
-            (not (match_operand 1 "lo_operand"))))
+       (eq_attr "type" "mfhi"))
   "r10k_alu1 | r10k_alu2")
 
 (define_insn_reservation "r10k_mflo" 1
   (and (eq_attr "cpu" "r10000")
-       (and (eq_attr "type" "mfhilo")
-            (match_operand 1 "lo_operand")))
+       (eq_attr "type" "mflo"))
   "r10k_alu1 | r10k_alu2")
 
 
Index: gcc/config/mips/sb1.md
===================================================================
--- gcc/config/mips/sb1.md	2011-09-11 18:19:40.000000000 +0100
+++ gcc/config/mips/sb1.md	2012-07-14 09:59:09.174984249 +0100
@@ -295,21 +295,19 @@  (define_bypass 5
 
 (define_insn_reservation "ir_sb1_mfhi" 1
   (and (eq_attr "cpu" "sb1,sb1a")
-       (and (eq_attr "type" "mfhilo")
-	    (not (match_operand 1 "lo_operand"))))
+       (eq_attr "type" "mfhi"))
   "sb1_ex1")
 
 (define_insn_reservation "ir_sb1_mflo" 1
   (and (eq_attr "cpu" "sb1,sb1a")
-       (and (eq_attr "type" "mfhilo")
-	    (match_operand 1 "lo_operand")))
+       (eq_attr "type" "mflo"))
   "sb1_ex1")
 
 ;; mt{hi,lo} to mul/div is 4 cycles.
 
 (define_insn_reservation "ir_sb1_mthilo" 4
   (and (eq_attr "cpu" "sb1,sb1a")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "sb1_ex1")
 
 ;; mt{hi,lo} to mf{hi,lo} is 3 cycles.
Index: gcc/config/mips/20kc.md
===================================================================
--- gcc/config/mips/20kc.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/20kc.md	2012-07-14 09:00:05.818992918 +0100
@@ -195,12 +195,12 @@  (define_insn_reservation "r20kc_impy_di"
 ;; cycle latency.  Repeat rate is 3 for both.
 (define_insn_reservation "r20kc_imthilo" 3 
 			 (and (eq_attr "cpu" "20kc")
-			      (eq_attr "type" "mthilo"))
+			      (eq_attr "type" "mthi,mtlo"))
 			 "r20kc_impydiv+(r20kc_impydiv_iter*3)")
 
 (define_insn_reservation "r20kc_imfhilo" 1
 			 (and (eq_attr "cpu" "20kc")
-			      (eq_attr "type" "mfhilo"))
+			      (eq_attr "type" "mfhi,mflo"))
 			 "r20kc_impydiv+(r20kc_impydiv_iter*3)")
 
 ;; Move to fp coprocessor.
Index: gcc/config/mips/24k.md
===================================================================
--- gcc/config/mips/24k.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/24k.md	2012-07-14 09:00:05.822992916 +0100
@@ -94,13 +94,13 @@  (define_insn_reservation "r24k_int_mul3"
 ;; mfhi, mflo, mflhxu - deliver result to gpr in 5 cycles
 (define_insn_reservation "r24k_int_mfhilo" 5
   (and (eq_attr "cpu" "24kc,24kf2_1,24kf1_1")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)")
 
 ;; mthi, mtlo, mtlhx - deliver result to hi/lo, thence madd, handled as bypass
 (define_insn_reservation "r24k_int_mthilo" 1
   (and (eq_attr "cpu" "24kc,24kf2_1,24kf1_1")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)")
 
 ;; div - default to 36 cycles for 32bit operands.  Faster for 24bit, 16bit and
Index: gcc/config/mips/4130.md
===================================================================
--- gcc/config/mips/4130.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/4130.md	2012-07-14 09:00:05.824992918 +0100
@@ -72,7 +72,7 @@  (define_attr "vr4130_class" "mul,mem,alu
   (cond [(eq_attr "type" "load,store")
 	 (const_string "mem")
 
-	 (eq_attr "type" "mfhilo,mthilo,imul,imul3,imadd,idiv")
+	 (eq_attr "type" "mfhi,mflo,mthi,mtlo,imul,imul3,imadd,idiv")
 	 (const_string "mul")]
 	(const_string "alu")))
 
@@ -98,12 +98,12 @@  (define_insn_reservation "vr4130_store"
 
 (define_insn_reservation "vr4130_mfhilo" 3
   (and (eq_attr "cpu" "r4130")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "vr4130_muldiv")
 
 (define_insn_reservation "vr4130_mthilo" 1
   (and (eq_attr "cpu" "r4130")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "vr4130_muldiv")
 
 ;; The product is available in LO & HI after one cycle.  Moving the result
Index: gcc/config/mips/4k.md
===================================================================
--- gcc/config/mips/4k.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/4k.md	2012-07-14 09:00:05.825992918 +0100
@@ -114,13 +114,13 @@  (define_insn_reservation "r4k_madd_4kp"
 ;; Move to HI/LO -> MADD/MSUB,MFHI/MFLO has a 1 cycle latency.
 (define_insn_reservation "r4k_int_mthilo" 1
   (and (eq_attr "cpu" "4kc,4kp")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "r4k_ixu_arith+r4k_ixu_mpydiv")
 
 ;; Move from HI/LO -> integer operation has a 2 cycle latency.
 (define_insn_reservation "r4k_int_mfhilo" 2
   (and (eq_attr "cpu" "4kc,4kp")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "r4k_ixu_arith+r4k_ixu_mpydiv")
 
 ;; All other integer insns.
Index: gcc/config/mips/5400.md
===================================================================
--- gcc/config/mips/5400.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/5400.md	2012-07-14 09:00:05.826992918 +0100
@@ -73,7 +73,7 @@  (define_insn_reservation "ir_vr54_xfer"
 
 (define_insn_reservation "ir_vr54_hilo" 1
   (and (eq_attr "cpu" "r5400")
-       (eq_attr "type" "mthilo,mfhilo"))
+       (eq_attr "type" "mthi,mtlo,mfhi,mflo"))
   "vr54_dp0|vr54_dp1")
 
 (define_insn_reservation "ir_vr54_arith" 1
Index: gcc/config/mips/5500.md
===================================================================
--- gcc/config/mips/5500.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/5500.md	2012-07-14 09:00:05.826992918 +0100
@@ -84,12 +84,12 @@  (define_bypass 2
 
 (define_insn_reservation "ir_vr55_mthilo" 1
   (and (eq_attr "cpu" "r5500")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "vr55_mac")
 
 (define_insn_reservation "ir_vr55_mfhilo" 5
   (and (eq_attr "cpu" "r5500")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "vr55_mac")
 
 ;; The default latency is for the GPR result of a mul.  Bypasses handle the
Index: gcc/config/mips/5k.md
===================================================================
--- gcc/config/mips/5k.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/5k.md	2012-07-14 09:00:05.827992918 +0100
@@ -88,13 +88,13 @@  (define_insn_reservation "r5k_int_mul" 4
 ;; Move to HI/LO -> MADD/MSUB,MFHI/MFLO has a 1 cycle latency.
 (define_insn_reservation "r5k_int_mthilo" 1
   (and (eq_attr "cpu" "5kc,5kf")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "r5k_ixu_arith+r5k_ixu_mpydiv")
 
 ;; Move from HI/LO -> integer operation has a 2 cycle latency.
 (define_insn_reservation "r5k_int_mfhilo" 2
   (and (eq_attr "cpu" "5kc,5kf")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "r5k_ixu_arith+r5k_ixu_mpydiv")
 
 ;; All other integer insns.
Index: gcc/config/mips/7000.md
===================================================================
--- gcc/config/mips/7000.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/7000.md	2012-07-14 09:00:05.828992918 +0100
@@ -134,12 +134,12 @@  (define_insn_reservation "rm7_impy_di" 9
 ;; Move to/from HI/LO.
 (define_insn_reservation "rm7_mthilo" 3
   (and (eq_attr "cpu" "r7000")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "rm7_impydiv")
 
 (define_insn_reservation "rm7_mfhilo" 1
   (and (eq_attr "cpu" "r7000")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "rm7_impydiv")
 
 ;; Move to/from fp coprocessor.
Index: gcc/config/mips/74k.md
===================================================================
--- gcc/config/mips/74k.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/74k.md	2012-07-14 09:00:05.829992918 +0100
@@ -80,13 +80,13 @@  (define_insn_reservation "r74k_int_mul3"
 ;; mfhi, mflo, mflhxu - deliver result to gpr in 7 cycles
 (define_insn_reservation "r74k_int_mfhilo" 7
   (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "r74k_alu+r74k_mul")
 
 ;; mthi, mtlo, mtlhx - deliver result to hi/lo, thence madd, handled as bypass
 (define_insn_reservation "r74k_int_mthilo" 7
   (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "r74k_alu+r74k_mul")
 
 ;; div - default to 50 cycles for 32bit operands.  Faster for 8 bit,
Index: gcc/config/mips/9000.md
===================================================================
--- gcc/config/mips/9000.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/9000.md	2012-07-14 09:00:05.829992918 +0100
@@ -87,12 +87,12 @@  (define_insn_reservation "rm9k_divdi" 70
 
 (define_insn_reservation "rm9k_mfhilo" 1
   (and (eq_attr "cpu" "r9000")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "rm9k_f_int")
 
 (define_insn_reservation "rm9k_mthilo" 5
   (and (eq_attr "cpu" "r9000")
-       (eq_attr "type" "mthilo"))
+       (eq_attr "type" "mthi,mtlo"))
   "rm9k_f_int")
 
 (define_insn_reservation "rm9k_xfer" 2
Index: gcc/config/mips/generic.md
===================================================================
--- gcc/config/mips/generic.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/generic.md	2012-07-14 09:00:05.832992918 +0100
@@ -43,7 +43,7 @@  (define_insn_reservation "generic_branch
   "alu")
 
 (define_insn_reservation "generic_hilo" 1
-  (eq_attr "type" "mfhilo,mthilo")
+  (eq_attr "type" "mfhi,mflo,mthi,mtlo")
   "imuldiv*3")
 
 (define_insn_reservation "generic_imul" 17
Index: gcc/config/mips/loongson2ef.md
===================================================================
--- gcc/config/mips/loongson2ef.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/loongson2ef.md	2012-07-14 10:00:13.085984090 +0100
@@ -154,8 +154,8 @@  (define_query_cpu_unit "ls2_mem" "ls2_me
 ;; Reservation for integer instructions.
 (define_insn_reservation "ls2_alu" 2
   (and (eq_attr "cpu" "loongson_2e,loongson_2f")
-       (eq_attr "type" "arith,condmove,const,logical,mfhilo,move,
-                        mthilo,nop,shift,signext,slt"))
+       (eq_attr "type" "arith,condmove,const,logical,mfhi,mflo,move,
+                        mthi,mtlo,nop,shift,signext,slt"))
   "ls2_alu")
 
 ;; Reservation for branch instructions.
Index: gcc/config/mips/loongson3a.md
===================================================================
--- gcc/config/mips/loongson3a.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/loongson3a.md	2012-07-14 09:00:05.834992918 +0100
@@ -53,7 +53,7 @@  (define_insn_reservation "ls3a_branch" 1
 
 (define_insn_reservation "ls3a_mfhilo" 1
   (and (eq_attr "cpu" "loongson_3a")
-       (eq_attr "type" "mfhilo,mthilo"))
+       (eq_attr "type" "mfhi,mflo,mthi,mtlo"))
   "ls3a_alu2")
 
 ;; Operation imul3nc is fully pipelined.
Index: gcc/config/mips/octeon.md
===================================================================
--- gcc/config/mips/octeon.md	2011-12-14 19:37:20.000000000 +0000
+++ gcc/config/mips/octeon.md	2012-07-14 09:00:05.903992918 +0100
@@ -83,22 +83,22 @@  (define_insn_reservation "octeon_imul3_o
 
 (define_insn_reservation "octeon_imul_o1" 2
   (and (eq_attr "cpu" "octeon")
-       (eq_attr "type" "imul,mthilo"))
+       (eq_attr "type" "imul,mthi,mtlo"))
   "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult")
 
 (define_insn_reservation "octeon_imul_o2" 1
   (and (eq_attr "cpu" "octeon2")
-       (eq_attr "type" "imul,mthilo"))
+       (eq_attr "type" "imul,mthi,mtlo"))
   "octeon_pipe1 + octeon_mult")
 
 (define_insn_reservation "octeon_mfhilo_o1" 5
   (and (eq_attr "cpu" "octeon")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "(octeon_pipe0 | octeon_pipe1) + octeon_mult")
 
 (define_insn_reservation "octeon_mfhilo_o2" 6
   (and (eq_attr "cpu" "octeon2")
-       (eq_attr "type" "mfhilo"))
+       (eq_attr "type" "mfhi,mflo"))
   "octeon_pipe1 + octeon_mult")
 
 (define_insn_reservation "octeon_imadd_o1" 4
Index: gcc/config/mips/sr71k.md
===================================================================
--- gcc/config/mips/sr71k.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/sr71k.md	2012-07-14 09:00:05.907992918 +0100
@@ -201,7 +201,7 @@  (define_insn_reservation "ir_sr70_xfer_t
 
 (define_insn_reservation "ir_sr70_hilo" 1
   (and (eq_attr "cpu" "sr71000")
-       (eq_attr "type" "mthilo,mfhilo"))
+       (eq_attr "type" "mthi,mtlo,mfhi,mflo"))
   "ri_insns")
 
 (define_insn_reservation "ir_sr70_arith" 1
Index: gcc/config/mips/xlr.md
===================================================================
--- gcc/config/mips/xlr.md	2011-09-03 10:05:51.000000000 +0100
+++ gcc/config/mips/xlr.md	2012-07-14 09:00:05.913992918 +0100
@@ -85,5 +85,5 @@  (define_insn_reservation "ir_xlr_div" 68
 
 (define_insn_reservation "xlr_hilo" 2
   (and (eq_attr "cpu" "xlr") 
-       (eq_attr "type" "mfhilo,mthilo"))
+       (eq_attr "type" "mfhi,mflo,mthi,mtlo"))
   "xlr_imuldiv_nopipe")