public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
@ 2011-07-14  9:02 Xinyu Qi
  2011-08-18  9:14 ` Ramana Radhakrishnan
  0 siblings, 1 reply; 15+ messages in thread
From: Xinyu Qi @ 2011-07-14  9:02 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2063 bytes --]

> Hi,
> 
> It is the fourth part of iWMMXt maintenance.
> 

Since "*cond_iwmmxt_movsi_insn" would be got rid of soon, I keep it unchanged.

*config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
 (arm_output_iwmmxt_tinsr): Ditto.
*config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): New prototype.
 (arm_output_iwmmxt_tinsr): Ditto.
*config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
 (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
 (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi, *iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Rename...
 (tbcstv8qi, tbcstv4hi, tbsctv2si, iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): ...New pattern.
 (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt, rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt, ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr, iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2, iwmmxt_walignr3, iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2, iwmmxt_setwcgr3, iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2, iwmmxt_getwcgr3): New pattern.
(All instruction patterns): Add wtype attribute.
 (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3, iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3, gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb, iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh, iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh, iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh, iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Revise.
 (iwmmxt2.md): Include.
*config/arm/iwmmxt2.md: New file.
*config/arm/iterators.md (VMMX2): New mode_iterator.
*config/arm/arm.md (wtype): New attribute.
*config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.

Thanks,
Xinyu

[-- Attachment #2: 4_wmmx_md.diff.gz --]
[-- Type: application/x-gzip, Size: 13061 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-07-14  9:02 [PATCH, ARM, iWMMXt][4/5]: WMMX machine description Xinyu Qi
@ 2011-08-18  9:14 ` Ramana Radhakrishnan
  2011-09-05  9:57   ` Xinyu Qi
                     ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Ramana Radhakrishnan @ 2011-08-18  9:14 UTC (permalink / raw)
  To: Xinyu Qi; +Cc: gcc-patches

On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
>> Hi,
>>
>> It is the fourth part of iWMMXt maintenance.
>>

Can this be broken down further. ? I'll have to do this again but
there are some initial comments below for some discussion.

>
> Since "*cond_iwmmxt_movsi_insn" would be got rid of soon, I keep it unchanged.
>
> *config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
>  (arm_output_iwmmxt_tinsr): Ditto.

s/Ditto/Likewise

> *config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): New prototype.
s/New prototype/Declare.

>  (arm_output_iwmmxt_tinsr): Ditto.
> *config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
>  (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.


>  (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi, *iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Rename...



>  (tbcstv8qi, tbcstv4hi, tbsctv2si, iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): ...New pattern.
s/...//

>  (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt, rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt, ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr, iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2, iwmmxt_walignr3, iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2, iwmmxt_setwcgr3, iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2, iwmmxt_getwcgr3): New pattern.

Break this up into multiple lines. Each line should only have upto 80
characters. Put this on one line and say New and add the others in a
row afterwards and use Likewise.

Look at other patches in the near past which set up Changelogs.


>  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3, iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3, gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb, iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh, iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh, iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh, iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Revise.

Revise to do what ?

> (define_insn "*iwmmxt_movsi_insn"
> -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk, m,z,r,?z,Uy,z")
>-	(match_operand:SI 1 "general_operand"      "rk, I,K,mi,rk,r,z,Uy,z, z"))]
>+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk, m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
>+	(match_operand:SI 1 "general_operand"      " rk,I,K,N,mi,rk,r,z,Uy,  z, z,r,t, z, t,t"))]
>   "TARGET_REALLY_IWMMXT
>-   && (   register_operand (operands[0], SImode)
>-       || register_operand (operands[1], SImode))"
>-  "*
>-   switch (which_alternative)
>+   && ((register_operand (operands[0], SImode)
>+	&& (!reload_completed
>+	    || REGNO_REG_CLASS (REGNO (operands[0])) == IWMMXT_GR_REGS))
>+       || (register_operand (operands[1], SImode)
>+	   && (!reload_completed



>  (iwmmxt2.md): Include.
> *config/arm/iwmmxt2.md: New file.
> *config/arm/iterators.md (VMMX2): New mode_iterator.
> *config/arm/arm.md (wtype): New attribute.
> *config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
>
> Thanks,
> Xinyu
>


>+	       || REGNO_REG_CLASS (REGNO (operands[1])) == IWMMXT_GR_REGS)))"

I don't like this at all - what you are doing is assuming that after
reg-alloc you are going to be able to rely on whether something has a
particular register class and then turn on and off it's matching. So
this matches before reload and doesn't do so after reload for the
cases where *iwmmxt_movsi_insn is really in a core register. I don't
think you can do it this way. If you really want to do this properly -
have an arch field for iwmmxt as well in the arch attribute and then
add these alternatives to existing patterns.


The documentation states with respect to conditions for a define_insn :

`For nameless patterns, the condition is applied only when matching an
individual insn, and only after the insn has matched the pattern's
recognition template.  The insn's operands may be found in the vector
@code{operands}.  For an insn where the condition has once matched, it
can't be used to control register allocation, for example by excluding
certain hard registers or hard register combinations.'

If I understand what you are trying to do here - you are trying to use
*arm_movsi_insn and other patterns in the rest of the backend and let
things like "predicable" kick in right after reload for all cases
other than the ones you enumerate. In which case get rid of all the
other constaints in this pattern other than the constraints that are
valid for registers of class IWMMXT_REGS

Also the definition of output_move_double has changed now and hence
this needs some rework.

Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
user visible option ?

Just in case it wasn't clear please don't commit any patch in this
series until all the patches have been completely reviewed.

cheers
Ramana

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-08-18  9:14 ` Ramana Radhakrishnan
@ 2011-09-05  9:57   ` Xinyu Qi
  2011-09-26  5:42   ` PING: " Xinyu Qi
  2011-10-20  8:12   ` Xinyu Qi
  2 siblings, 0 replies; 15+ messages in thread
From: Xinyu Qi @ 2011-09-05  9:57 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 7669 bytes --]

At 2011-08-18 10:21:01,"Ramana Radhakrishnan" <ramana.radhakrishnan@linaro.org> wrote:
> On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
> >> Hi,
> >>
> >> It is the fourth part of iWMMXt maintenance.
> >>
> 
> Can this be broken down further. ? I'll have to do this again but
> there are some initial comments below for some discussion.

> 
> >  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3,
> iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3, iwmmxt_tinsrb,
> iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3, gtuv4hi3,
> gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb, iwmmxt_wunpckihh,
> iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh, iwmmxt_wunpckilw,
> iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw, iwmmxt_wunpckehsb,
> iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh,
> iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh, iwmmxt_wunpckelsw,
> iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
> iwmmxt_wsadhz): Revise.
> 
> Revise to do what ?

Sorry for late response.

Some of them have incorrect RTL templates. For example, see iwmmxt_uavgv8qi3
Its old RTL template is:
  [(set (match_operand:V8QI                 0 "register_operand" "=y")
        (ashiftrt:V8QI (plus:V8QI
	                    (match_operand:V8QI 1 "register_operand" "y")
			           (match_operand:V8QI 2 "register_operand" "y"))
		              (const_int 1)))]

According to the assembly behavior of wavg2b, the correct one should be:
  [(set (match_operand:V8QI  0 "register_operand" "=y")
        (truncate:V8QI
	     (lshiftrt:V8HI
	       (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
	                  (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y")))
	     (const_int 1))))]

Consider the case:
The Operation on element 0x01 and 0xff: gcc with old RTL template would optimize to the result 0x00.That is:
0x01 + 0xff => 0x00. 0x00 > 1 => 0x00
While the correct result should be 0x80. 
0x01 => 0x0001, 0xff => 0x00ff. 0x0001 + 0x00ff => 0x0100. 0x0100 > 1 => 0x0080, 0x0080 => 0x80

iwmmxt_wmadds and iwmmxt_wmaddu are modified to use detailed RTL template instead of unspec.

For some of the wunpck patterns, change the order of zero_extend and vec_select in order to avoid a vec_select optimization internal error in old version gcc. Maybe this internal bug has been fixed, but such modification is harmless.

Rests of them are only revised for their format.

> 
> > (define_insn "*iwmmxt_movsi_insn"
> > -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk,
> m,z,r,?z,Uy,z")
> >-	(match_operand:SI 1 "general_operand"      "rk, I,K,mi,rk,r,z,Uy,z,
> z"))]
> >+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,
> m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
> >+	(match_operand:SI 1 "general_operand"      " rk,I,K,N,mi,rk,r,z,Uy,  z,
> z,r,t, z, t,t"))]
> >   "TARGET_REALLY_IWMMXT
> >-   && (   register_operand (operands[0], SImode)
> >-       || register_operand (operands[1], SImode))"
> >-  "*
> >-   switch (which_alternative)
> >+   && ((register_operand (operands[0], SImode)
> >+	&& (!reload_completed
> >+	    || REGNO_REG_CLASS (REGNO (operands[0])) == IWMMXT_GR_REGS))
> >+       || (register_operand (operands[1], SImode)
> >+	   && (!reload_completed
> 
> 
> 
> >+	       || REGNO_REG_CLASS (REGNO (operands[1])) == IWMMXT_GR_REGS)))"
> 
> I don't like this at all - what you are doing is assuming that after
> reg-alloc you are going to be able to rely on whether something has a
> particular register class and then turn on and off it's matching. So
> this matches before reload and doesn't do so after reload for the
> cases where *iwmmxt_movsi_insn is really in a core register. I don't
> think you can do it this way. If you really want to do this properly -
> have an arch field for iwmmxt as well in the arch attribute and then
> add these alternatives to existing patterns.
> 
> If I understand what you are trying to do here - you are trying to use
> *arm_movsi_insn and other patterns in the rest of the backend and let
> things like "predicable" kick in right after reload for all cases
> other than the ones you enumerate. In which case get rid of all the
> other constaints in this pattern other than the constraints that are
> valid for registers of class IWMMXT_REGS

This piece of code is added to make iwmmxt coexist with vfp when iwmmxt and vfp are enabled together. Agree, I don't think it is a good fix. 
Add adequate constrains to *iwmmxt_movsi_insn and *iwmmxt_arm_movdi so that don't need to change their conditions.

> 
> Also the definition of output_move_double has changed now and hence
> this needs some rework.

Done.

> Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
> user visible option ?

I don't think users need to know the distinction between iwmmxt and iwmmxt2 though there are two options "-mcpu=iwmmxt" and "-mcpu=iwmmxt2". It seems if "-mcpu=iwmmxt" is specified in gcc, the assembler cannot recognize the wmmx2 insns.


> 
> Just in case it wasn't clear please don't commit any patch in this
> series until all the patches have been completely reviewed.
> 
> cheers
> Ramana


The new diff attached. New ChangLog:

* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
  (arm_output_iwmmxt_tinsr): Likewise.
* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
  (arm_output_iwmmxt_tinsr): Likewise.
* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
  (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
  (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
  (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
  (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
  (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
  (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
  (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt): Likewise.
  (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
  (iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
  (iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
  (iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
  (All instruction patterns): Add wtype attribute.
  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp. 
  (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
  (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
  (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
  (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
  (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
  (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
  (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
  (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
  (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
  (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
  (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
  (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
  (iwmmxt2.md): Include.
* config/arm/iwmmxt2.md: New file.
* config/arm/iterators.md (VMMX2): New mode_iterator.
* config/arm/arm.md (wtype): New attribute.
  (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
  (UNSPEC_WALIGNI): New unspec.
* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.

Thanks,
Xinyu

[-- Attachment #2: 4_wmmx_md.diff.gz --]
[-- Type: application/x-gzip, Size: 13186 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-08-18  9:14 ` Ramana Radhakrishnan
  2011-09-05  9:57   ` Xinyu Qi
@ 2011-09-26  5:42   ` Xinyu Qi
  2011-11-19  2:43     ` Ramana Radhakrishnan
  2011-10-20  8:12   ` Xinyu Qi
  2 siblings, 1 reply; 15+ messages in thread
From: Xinyu Qi @ 2011-09-26  5:42 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches

Ping.

http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00279.html

	* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
	(rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt): Likewise.
	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
	(All instruction patterns): Add wtype attribute.
	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp. 
	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
	(iwmmxt2.md): Include.
	* config/arm/iwmmxt2.md: New file.
	* config/arm/iterators.md (VMMX2): New mode_iterator.
	* config/arm/arm.md (wtype): New attribute.
	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
	(UNSPEC_WALIGNI): New unspec.
	* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.

At 2011-09-05 17:55:34,"Xinyu Qi" <xyqi@marvell.com> wrote: 
> At 2011-08-18 10:21:01,"Ramana Radhakrishnan"
> <ramana.radhakrishnan@linaro.org> wrote:
> > On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
> > >> Hi,
> > >>
> > >> It is the fourth part of iWMMXt maintenance.
> > >>
> >
> > Can this be broken down further. ? I'll have to do this again but
> > there are some initial comments below for some discussion.
> 
> >
> > >  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3,
> > iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3, iwmmxt_tinsrb,
> > iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3,
> gtuv4hi3,
> > gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb, iwmmxt_wunpckihh,
> > iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh, iwmmxt_wunpckilw,
> > iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw,
> iwmmxt_wunpckehsb,
> > iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
> iwmmxt_wunpckeluh,
> > iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh,
> iwmmxt_wunpckelsw,
> > iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
> > iwmmxt_wsadhz): Revise.
> >
> > Revise to do what ?
> 
> Sorry for late response.
> 
> Some of them have incorrect RTL templates. For example, see iwmmxt_uavgv8qi3
> Its old RTL template is:
>   [(set (match_operand:V8QI                 0 "register_operand" "=y")
>         (ashiftrt:V8QI (plus:V8QI
> 	                    (match_operand:V8QI 1 "register_operand" "y")
> 			           (match_operand:V8QI 2 "register_operand" "y"))
> 		              (const_int 1)))]
> 
> According to the assembly behavior of wavg2b, the correct one should be:
>   [(set (match_operand:V8QI  0 "register_operand" "=y")
>         (truncate:V8QI
> 	     (lshiftrt:V8HI
> 	       (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1
> "register_operand" "y"))
> 	                  (zero_extend:V8HI (match_operand:V8QI 2
> "register_operand" "y")))
> 	     (const_int 1))))]
> 
> Consider the case:
> The Operation on element 0x01 and 0xff: gcc with old RTL template would optimize
> to the result 0x00.That is:
> 0x01 + 0xff => 0x00. 0x00 > 1 => 0x00
> While the correct result should be 0x80.
> 0x01 => 0x0001, 0xff => 0x00ff. 0x0001 + 0x00ff => 0x0100. 0x0100 > 1 => 0x0080,
> 0x0080 => 0x80
> 
> iwmmxt_wmadds and iwmmxt_wmaddu are modified to use detailed RTL template
> instead of unspec.
> 
> For some of the wunpck patterns, change the order of zero_extend and vec_select
> in order to avoid a vec_select optimization internal error in old version gcc.
> Maybe this internal bug has been fixed, but such modification is harmless.
> 
> Rests of them are only revised for their format.
> 
> >
> > > (define_insn "*iwmmxt_movsi_insn"
> > > -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk,
> > m,z,r,?z,Uy,z")
> > >-	(match_operand:SI 1 "general_operand"      "rk, I,K,mi,rk,r,z,Uy,z,
> > z"))]
> > >+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,
> > m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
> > >+	(match_operand:SI 1 "general_operand"      " rk,I,K,N,mi,rk,r,z,Uy,
> z,
> > z,r,t, z, t,t"))]
> > >   "TARGET_REALLY_IWMMXT
> > >-   && (   register_operand (operands[0], SImode)
> > >-       || register_operand (operands[1], SImode))"
> > >-  "*
> > >-   switch (which_alternative)
> > >+   && ((register_operand (operands[0], SImode)
> > >+	&& (!reload_completed
> > >+	    || REGNO_REG_CLASS (REGNO (operands[0])) == IWMMXT_GR_REGS))
> > >+       || (register_operand (operands[1], SImode)
> > >+	   && (!reload_completed
> >
> >
> >
> > >+	       || REGNO_REG_CLASS (REGNO (operands[1])) == IWMMXT_GR_REGS)))"
> >
> > I don't like this at all - what you are doing is assuming that after
> > reg-alloc you are going to be able to rely on whether something has a
> > particular register class and then turn on and off it's matching. So
> > this matches before reload and doesn't do so after reload for the
> > cases where *iwmmxt_movsi_insn is really in a core register. I don't
> > think you can do it this way. If you really want to do this properly -
> > have an arch field for iwmmxt as well in the arch attribute and then
> > add these alternatives to existing patterns.
> >
> > If I understand what you are trying to do here - you are trying to use
> > *arm_movsi_insn and other patterns in the rest of the backend and let
> > things like "predicable" kick in right after reload for all cases
> > other than the ones you enumerate. In which case get rid of all the
> > other constaints in this pattern other than the constraints that are
> > valid for registers of class IWMMXT_REGS
> 
> This piece of code is added to make iwmmxt coexist with vfp when iwmmxt and
> vfp are enabled together. Agree, I don't think it is a good fix.
> Add adequate constrains to *iwmmxt_movsi_insn and *iwmmxt_arm_movdi so that
> don't need to change their conditions.
> 
> >
> > Also the definition of output_move_double has changed now and hence
> > this needs some rework.
> 
> Done.
> 
> > Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
> > user visible option ?
> 
> I don't think users need to know the distinction between iwmmxt and iwmmxt2
> though there are two options "-mcpu=iwmmxt" and "-mcpu=iwmmxt2". It seems if
> "-mcpu=iwmmxt" is specified in gcc, the assembler cannot recognize the wmmx2
> insns.
> 
> 
> >
> > Just in case it wasn't clear please don't commit any patch in this
> > series until all the patches have been completely reviewed.
> >
> > cheers
> > Ramana
> 
> 
> The new diff attached. New ChangLog:
> 
> * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
>   (arm_output_iwmmxt_tinsr): Likewise.
> * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
>   (arm_output_iwmmxt_tinsr): Likewise.
> * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
>   (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
>   (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
>   (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
>   (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
>   (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
>   (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
>   (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt): Likewise.
>   (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
>   (iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2, iwmmxt_walignr3):
> Likewise.
>   (iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2, iwmmxt_setwcgr3):
> Likewise.
>   (iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2, iwmmxt_getwcgr3):
> Likewise.
>   (All instruction patterns): Add wtype attribute.
>   (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
>   (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
>   (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
>   (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
>   (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
>   (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
>   (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
>   (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
>   (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
>   (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
>   (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
>   (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
>   (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
>   (iwmmxt2.md): Include.
> * config/arm/iwmmxt2.md: New file.
> * config/arm/iterators.md (VMMX2): New mode_iterator.
> * config/arm/arm.md (wtype): New attribute.
>   (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
>   (UNSPEC_WALIGNI): New unspec.
> * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> 
> Thanks,
> Xinyu

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-08-18  9:14 ` Ramana Radhakrishnan
  2011-09-05  9:57   ` Xinyu Qi
  2011-09-26  5:42   ` PING: " Xinyu Qi
@ 2011-10-20  8:12   ` Xinyu Qi
  2 siblings, 0 replies; 15+ messages in thread
From: Xinyu Qi @ 2011-10-20  8:12 UTC (permalink / raw)
  To: Ramana Radhakrishnan, gcc-patches

Ping

http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00279.html

	* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
	(rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt): Likewise.
	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
	(All instruction patterns): Add wtype attribute.
	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp. 
	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
	(iwmmxt2.md): Include.
	* config/arm/iwmmxt2.md: New file.
	* config/arm/iterators.md (VMMX2): New mode_iterator.
	* config/arm/arm.md (wtype): New attribute.
	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
	(UNSPEC_WALIGNI): New unspec.
	* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-09-26  5:42   ` PING: " Xinyu Qi
@ 2011-11-19  2:43     ` Ramana Radhakrishnan
  2011-11-24  9:56       ` Xinyu Qi
  0 siblings, 1 reply; 15+ messages in thread
From: Ramana Radhakrishnan @ 2011-11-19  2:43 UTC (permalink / raw)
  To: Xinyu Qi; +Cc: gcc-patches

Hi Xinyu,

This doesn't apply cleanly currently on trunk and the reject appears
to come from iwmmxt.md and I've not yet investigated why.

Can you have a look ?

cheers
Ramana

On 26 September 2011 04:22, Xinyu Qi <xyqi@marvell.com> wrote:
> Ping.
>
> http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00279.html
>
>        * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
>        (arm_output_iwmmxt_tinsr): Likewise.
>        * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
>        (arm_output_iwmmxt_tinsr): Likewise.
>        * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
>        (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
>        (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
>        (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
>        (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
>        (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
>        (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
>        (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt): Likewise.
>        (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
>        (iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
>        (iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
>        (iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
>        (iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
>        (iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
>        (iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
>        (All instruction patterns): Add wtype attribute.
>        (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
>        (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
>        (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
>        (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
>        (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
>        (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
>        (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
>        (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
>        (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
>        (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
>        (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
>        (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
>        (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
>        (iwmmxt2.md): Include.
>        * config/arm/iwmmxt2.md: New file.
>        * config/arm/iterators.md (VMMX2): New mode_iterator.
>        * config/arm/arm.md (wtype): New attribute.
>        (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
>        (UNSPEC_WALIGNI): New unspec.
>        * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
>
> At 2011-09-05 17:55:34,"Xinyu Qi" <xyqi@marvell.com> wrote:
>> At 2011-08-18 10:21:01,"Ramana Radhakrishnan"
>> <ramana.radhakrishnan@linaro.org> wrote:
>> > On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
>> > >> Hi,
>> > >>
>> > >> It is the fourth part of iWMMXt maintenance.
>> > >>
>> >
>> > Can this be broken down further. ? I'll have to do this again but
>> > there are some initial comments below for some discussion.
>>
>> >
>> > >  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3,
>> > iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3, iwmmxt_tinsrb,
>> > iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3,
>> gtuv4hi3,
>> > gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb, iwmmxt_wunpckihh,
>> > iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh, iwmmxt_wunpckilw,
>> > iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw,
>> iwmmxt_wunpckehsb,
>> > iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
>> iwmmxt_wunpckeluh,
>> > iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh,
>> iwmmxt_wunpckelsw,
>> > iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
>> > iwmmxt_wsadhz): Revise.
>> >
>> > Revise to do what ?
>>
>> Sorry for late response.
>>
>> Some of them have incorrect RTL templates. For example, see iwmmxt_uavgv8qi3
>> Its old RTL template is:
>>   [(set (match_operand:V8QI                 0 "register_operand" "=y")
>>         (ashiftrt:V8QI (plus:V8QI
>>                           (match_operand:V8QI 1 "register_operand" "y")
>>                                  (match_operand:V8QI 2 "register_operand" "y"))
>>                             (const_int 1)))]
>>
>> According to the assembly behavior of wavg2b, the correct one should be:
>>   [(set (match_operand:V8QI  0 "register_operand" "=y")
>>         (truncate:V8QI
>>            (lshiftrt:V8HI
>>              (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1
>> "register_operand" "y"))
>>                         (zero_extend:V8HI (match_operand:V8QI 2
>> "register_operand" "y")))
>>            (const_int 1))))]
>>
>> Consider the case:
>> The Operation on element 0x01 and 0xff: gcc with old RTL template would optimize
>> to the result 0x00.That is:
>> 0x01 + 0xff => 0x00. 0x00 > 1 => 0x00
>> While the correct result should be 0x80.
>> 0x01 => 0x0001, 0xff => 0x00ff. 0x0001 + 0x00ff => 0x0100. 0x0100 > 1 => 0x0080,
>> 0x0080 => 0x80
>>
>> iwmmxt_wmadds and iwmmxt_wmaddu are modified to use detailed RTL template
>> instead of unspec.
>>
>> For some of the wunpck patterns, change the order of zero_extend and vec_select
>> in order to avoid a vec_select optimization internal error in old version gcc.
>> Maybe this internal bug has been fixed, but such modification is harmless.
>>
>> Rests of them are only revised for their format.
>>
>> >
>> > > (define_insn "*iwmmxt_movsi_insn"
>> > > -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk,
>> > m,z,r,?z,Uy,z")
>> > >-  (match_operand:SI 1 "general_operand"      "rk, I,K,mi,rk,r,z,Uy,z,
>> > z"))]
>> > >+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,
>> > m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
>> > >+  (match_operand:SI 1 "general_operand"      " rk,I,K,N,mi,rk,r,z,Uy,
>> z,
>> > z,r,t, z, t,t"))]
>> > >   "TARGET_REALLY_IWMMXT
>> > >-   && (   register_operand (operands[0], SImode)
>> > >-       || register_operand (operands[1], SImode))"
>> > >-  "*
>> > >-   switch (which_alternative)
>> > >+   && ((register_operand (operands[0], SImode)
>> > >+  && (!reload_completed
>> > >+      || REGNO_REG_CLASS (REGNO (operands[0])) == IWMMXT_GR_REGS))
>> > >+       || (register_operand (operands[1], SImode)
>> > >+     && (!reload_completed
>> >
>> >
>> >
>> > >+         || REGNO_REG_CLASS (REGNO (operands[1])) == IWMMXT_GR_REGS)))"
>> >
>> > I don't like this at all - what you are doing is assuming that after
>> > reg-alloc you are going to be able to rely on whether something has a
>> > particular register class and then turn on and off it's matching. So
>> > this matches before reload and doesn't do so after reload for the
>> > cases where *iwmmxt_movsi_insn is really in a core register. I don't
>> > think you can do it this way. If you really want to do this properly -
>> > have an arch field for iwmmxt as well in the arch attribute and then
>> > add these alternatives to existing patterns.
>> >
>> > If I understand what you are trying to do here - you are trying to use
>> > *arm_movsi_insn and other patterns in the rest of the backend and let
>> > things like "predicable" kick in right after reload for all cases
>> > other than the ones you enumerate. In which case get rid of all the
>> > other constaints in this pattern other than the constraints that are
>> > valid for registers of class IWMMXT_REGS
>>
>> This piece of code is added to make iwmmxt coexist with vfp when iwmmxt and
>> vfp are enabled together. Agree, I don't think it is a good fix.
>> Add adequate constrains to *iwmmxt_movsi_insn and *iwmmxt_arm_movdi so that
>> don't need to change their conditions.
>>
>> >
>> > Also the definition of output_move_double has changed now and hence
>> > this needs some rework.
>>
>> Done.
>>
>> > Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
>> > user visible option ?
>>
>> I don't think users need to know the distinction between iwmmxt and iwmmxt2
>> though there are two options "-mcpu=iwmmxt" and "-mcpu=iwmmxt2". It seems if
>> "-mcpu=iwmmxt" is specified in gcc, the assembler cannot recognize the wmmx2
>> insns.
>>
>>
>> >
>> > Just in case it wasn't clear please don't commit any patch in this
>> > series until all the patches have been completely reviewed.
>> >
>> > cheers
>> > Ramana
>>
>>
>> The new diff attached. New ChangLog:
>>
>> * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
>>   (arm_output_iwmmxt_tinsr): Likewise.
>> * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
>>   (arm_output_iwmmxt_tinsr): Likewise.
>> * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
>>   (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
>>   (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
>>   (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
>>   (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
>>   (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
>>   (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
>>   (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt): Likewise.
>>   (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
>>   (iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2, iwmmxt_walignr3):
>> Likewise.
>>   (iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2, iwmmxt_setwcgr3):
>> Likewise.
>>   (iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2, iwmmxt_getwcgr3):
>> Likewise.
>>   (All instruction patterns): Add wtype attribute.
>>   (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
>>   (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
>>   (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
>>   (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
>>   (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
>>   (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
>>   (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
>>   (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
>>   (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
>>   (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
>>   (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
>>   (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
>>   (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
>>   (iwmmxt2.md): Include.
>> * config/arm/iwmmxt2.md: New file.
>> * config/arm/iterators.md (VMMX2): New mode_iterator.
>> * config/arm/arm.md (wtype): New attribute.
>>   (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
>>   (UNSPEC_WALIGNI): New unspec.
>> * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
>>
>> Thanks,
>> Xinyu
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-11-19  2:43     ` Ramana Radhakrishnan
@ 2011-11-24  9:56       ` Xinyu Qi
  2011-12-14 17:48         ` Richard Earnshaw
  0 siblings, 1 reply; 15+ messages in thread
From: Xinyu Qi @ 2011-11-24  9:56 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 12078 bytes --]

Hi Ramana,

I solve the conflict, please try again. The new diff is attached.

Thanks,
Xinyu

At 2011-11-19 07:36:15,"Ramana Radhakrishnan" <ramana.radhakrishnan@linaro.org> wrote:
> 
> Hi Xinyu,
> 
> This doesn't apply cleanly currently on trunk and the reject appears
> to come from iwmmxt.md and I've not yet investigated why.
> 
> Can you have a look ?
> 
> cheers
> Ramana
> 
> On 26 September 2011 04:22, Xinyu Qi <xyqi@marvell.com> wrote:
> > Ping.
> >
> > http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00279.html
> >
> >        * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New
> function.
> >        (arm_output_iwmmxt_tinsr): Likewise.
> >        * config/arm/arm-protos.h
> (arm_output_iwmmxt_shift_immediate): Declare.
> >        (arm_output_iwmmxt_tinsr): Likewise.
> >        * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3):
> New constant.
> >        (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
> Delete.
> >        (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
> >        (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
> >        (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
> >        (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
> >        (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt,
> *xor<mode>3_iwmmxt): Likewise.
> >        (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt):
> Likewise.
> >        (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr):
> Likewise.
> >        (iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
> >        (iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
> >        (iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
> >        (iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
> >        (iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
> >        (iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
> >        (All instruction patterns): Add wtype attribute.
> >        (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist
> with vfp.
> >        (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the
> pattern.
> >        (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
> >        (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
> >        (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
> >        (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
> >        (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh):
> Likewise.
> >        (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
> Likewise.
> >        (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb,
> iwmmxt_wunpckehsh): Likewise.
> >        (iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
> iwmmxt_wunpckeluh): Likewise.
> >        (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
> Likewise.
> >        (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu):
> Likewise.
> >        (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
> iwmmxt_wsadhz): Likewise.
> >        (iwmmxt2.md): Include.
> >        * config/arm/iwmmxt2.md: New file.
> >        * config/arm/iterators.md (VMMX2): New mode_iterator.
> >        * config/arm/arm.md (wtype): New attribute.
> >        (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
> >        (UNSPEC_WALIGNI): New unspec.
> >        * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> >
> > At 2011-09-05 17:55:34,"Xinyu Qi" <xyqi@marvell.com> wrote:
> >> At 2011-08-18 10:21:01,"Ramana Radhakrishnan"
> >> <ramana.radhakrishnan@linaro.org> wrote:
> >> > On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
> >> > >> Hi,
> >> > >>
> >> > >> It is the fourth part of iWMMXt maintenance.
> >> > >>
> >> >
> >> > Can this be broken down further. ? I'll have to do this again but
> >> > there are some initial comments below for some discussion.
> >>
> >> >
> >> > >  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3,
> >> > iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3,
> iwmmxt_tinsrb,
> >> > iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3,
> >> gtuv4hi3,
> >> > gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb,
> iwmmxt_wunpckihh,
> >> > iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh,
> iwmmxt_wunpckilw,
> >> > iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw,
> >> iwmmxt_wunpckehsb,
> >> > iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
> >> iwmmxt_wunpckeluh,
> >> > iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh,
> >> iwmmxt_wunpckelsw,
> >> > iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh,
> iwmmxt_wsadbz,
> >> > iwmmxt_wsadhz): Revise.
> >> >
> >> > Revise to do what ?
> >>
> >> Sorry for late response.
> >>
> >> Some of them have incorrect RTL templates. For example, see
> iwmmxt_uavgv8qi3
> >> Its old RTL template is:
> >>   [(set (match_operand:V8QI                 0 "register_operand"
> "=y")
> >>         (ashiftrt:V8QI (plus:V8QI
> >>                           (match_operand:V8QI 1
> "register_operand" "y")
> >>                                  (match_operand:V8QI 2
> "register_operand" "y"))
> >>                             (const_int 1)))]
> >>
> >> According to the assembly behavior of wavg2b, the correct one should be:
> >>   [(set (match_operand:V8QI  0 "register_operand" "=y")
> >>         (truncate:V8QI
> >>            (lshiftrt:V8HI
> >>              (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1
> >> "register_operand" "y"))
> >>                         (zero_extend:V8HI (match_operand:V8QI 2
> >> "register_operand" "y")))
> >>            (const_int 1))))]
> >>
> >> Consider the case:
> >> The Operation on element 0x01 and 0xff: gcc with old RTL template would
> optimize
> >> to the result 0x00.That is:
> >> 0x01 + 0xff => 0x00. 0x00 > 1 => 0x00
> >> While the correct result should be 0x80.
> >> 0x01 => 0x0001, 0xff => 0x00ff. 0x0001 + 0x00ff => 0x0100. 0x0100 > 1 =>
> 0x0080,
> >> 0x0080 => 0x80
> >>
> >> iwmmxt_wmadds and iwmmxt_wmaddu are modified to use detailed RTL
> template
> >> instead of unspec.
> >>
> >> For some of the wunpck patterns, change the order of zero_extend and
> vec_select
> >> in order to avoid a vec_select optimization internal error in old version gcc.
> >> Maybe this internal bug has been fixed, but such modification is harmless.
> >>
> >> Rests of them are only revised for their format.
> >>
> >> >
> >> > > (define_insn "*iwmmxt_movsi_insn"
> >> > > -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk,
> >> > m,z,r,?z,Uy,z")
> >> > >-  (match_operand:SI 1 "general_operand"      "rk,
> I,K,mi,rk,r,z,Uy,z,
> >> > z"))]
> >> > >+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,
> >> > m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
> >> > >+  (match_operand:SI 1 "general_operand"      "
> rk,I,K,N,mi,rk,r,z,Uy,
> >> z,
> >> > z,r,t, z, t,t"))]
> >> > >   "TARGET_REALLY_IWMMXT
> >> > >-   && (   register_operand (operands[0], SImode)
> >> > >-       || register_operand (operands[1], SImode))"
> >> > >-  "*
> >> > >-   switch (which_alternative)
> >> > >+   && ((register_operand (operands[0], SImode)
> >> > >+  && (!reload_completed
> >> > >+      || REGNO_REG_CLASS (REGNO (operands[0])) ==
> IWMMXT_GR_REGS))
> >> > >+       || (register_operand (operands[1], SImode)
> >> > >+     && (!reload_completed
> >> >
> >> >
> >> >
> >> > >+         || REGNO_REG_CLASS (REGNO (operands[1])) ==
> IWMMXT_GR_REGS)))"
> >> >
> >> > I don't like this at all - what you are doing is assuming that after
> >> > reg-alloc you are going to be able to rely on whether something has a
> >> > particular register class and then turn on and off it's matching. So
> >> > this matches before reload and doesn't do so after reload for the
> >> > cases where *iwmmxt_movsi_insn is really in a core register. I don't
> >> > think you can do it this way. If you really want to do this properly -
> >> > have an arch field for iwmmxt as well in the arch attribute and then
> >> > add these alternatives to existing patterns.
> >> >
> >> > If I understand what you are trying to do here - you are trying to use
> >> > *arm_movsi_insn and other patterns in the rest of the backend and let
> >> > things like "predicable" kick in right after reload for all cases
> >> > other than the ones you enumerate. In which case get rid of all the
> >> > other constaints in this pattern other than the constraints that are
> >> > valid for registers of class IWMMXT_REGS
> >>
> >> This piece of code is added to make iwmmxt coexist with vfp when iwmmxt
> and
> >> vfp are enabled together. Agree, I don't think it is a good fix.
> >> Add adequate constrains to *iwmmxt_movsi_insn and
> *iwmmxt_arm_movdi so that
> >> don't need to change their conditions.
> >>
> >> >
> >> > Also the definition of output_move_double has changed now and hence
> >> > this needs some rework.
> >>
> >> Done.
> >>
> >> > Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
> >> > user visible option ?
> >>
> >> I don't think users need to know the distinction between iwmmxt and
> iwmmxt2
> >> though there are two options "-mcpu=iwmmxt" and "-mcpu=iwmmxt2". It
> seems if
> >> "-mcpu=iwmmxt" is specified in gcc, the assembler cannot recognize the
> wmmx2
> >> insns.
> >>
> >>
> >> >
> >> > Just in case it wasn't clear please don't commit any patch in this
> >> > series until all the patches have been completely reviewed.
> >> >
> >> > cheers
> >> > Ramana
> >>
> >>
> >> The new diff attached. New ChangLog:
> >>
> >> * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
> >>   (arm_output_iwmmxt_tinsr): Likewise.
> >> * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate):
> Declare.
> >>   (arm_output_iwmmxt_tinsr): Likewise.
> >> * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New
> constant.
> >>   (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
> Delete.
> >>   (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
> >>   (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
> >>   (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
> >>   (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
> >>   (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt,
> *xor<mode>3_iwmmxt): Likewise.
> >>   (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt):
> Likewise.
> >>   (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
> >>   (iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2,
> iwmmxt_walignr3):
> >> Likewise.
> >>   (iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2,
> iwmmxt_setwcgr3):
> >> Likewise.
> >>   (iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2,
> iwmmxt_getwcgr3):
> >> Likewise.
> >>   (All instruction patterns): Add wtype attribute.
> >>   (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with
> vfp.
> >>   (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
> >>   (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
> >>   (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
> >>   (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
> >>   (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
> >>   (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh):
> Likewise.
> >>   (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
> Likewise.
> >>   (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh):
> Likewise.
> >>   (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh):
> Likewise.
> >>   (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
> Likewise.
> >>   (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
> >>   (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz):
> Likewise.
> >>   (iwmmxt2.md): Include.
> >> * config/arm/iwmmxt2.md: New file.
> >> * config/arm/iterators.md (VMMX2): New mode_iterator.
> >> * config/arm/arm.md (wtype): New attribute.
> >>   (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
> >>   (UNSPEC_WALIGNI): New unspec.
> >> * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> >>
> >> Thanks,
> >> Xinyu
> >

[-- Attachment #2: 4_wmmx_md.diff.gz --]
[-- Type: application/x-gzip, Size: 13183 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-11-24  9:56       ` Xinyu Qi
@ 2011-12-14 17:48         ` Richard Earnshaw
  2011-12-22  6:50           ` Xinyu Qi
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Earnshaw @ 2011-12-14 17:48 UTC (permalink / raw)
  To: Xinyu Qi; +Cc: Ramana Radhakrishnan, gcc-patches

On 24/11/11 01:33, Xinyu Qi wrote:
> Hi Ramana,
> 
> I solve the conflict, please try again. The new diff is attached.
> 
> Thanks,
> Xinyu
> 
> At 2011-11-19 07:36:15,"Ramana Radhakrishnan" <ramana.radhakrishnan@linaro.org> wrote:
>>
>> Hi Xinyu,
>>
>> This doesn't apply cleanly currently on trunk and the reject appears
>> to come from iwmmxt.md and I've not yet investigated why.
>>
>> Can you have a look ?
>>

This patch is NOT ok.

You're adding features that were new in iWMMXt2 (ie not in the original
implementation) but you've provided no means by which the compiler can
detect which operations are only available on the new cores.

Further, I don't like the way you have separate patterns for the rotates
with immediate.  Please investigate using the alternative enable feature
to reduce these down to single patterns.  Once you've done all this,
some of your tricky builtin expand code in patch 3/5 should then
simplify significantly as you won't need separate expand codes for those
alternatives.

R.

>> cheers
>> Ramana
>>
>> On 26 September 2011 04:22, Xinyu Qi <xyqi@marvell.com> wrote:
>>> Ping.
>>>
>>> http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00279.html
>>>
>>>        * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New
>> function.
>>>        (arm_output_iwmmxt_tinsr): Likewise.
>>>        * config/arm/arm-protos.h
>> (arm_output_iwmmxt_shift_immediate): Declare.
>>>        (arm_output_iwmmxt_tinsr): Likewise.
>>>        * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3):
>> New constant.
>>>        (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
>> Delete.
>>>        (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
>>>        (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
>>>        (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
>>>        (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
>>>        (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt,
>> *xor<mode>3_iwmmxt): Likewise.
>>>        (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt):
>> Likewise.
>>>        (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr):
>> Likewise.
>>>        (iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
>>>        (iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
>>>        (iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
>>>        (iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
>>>        (iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
>>>        (iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
>>>        (All instruction patterns): Add wtype attribute.
>>>        (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist
>> with vfp.
>>>        (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the
>> pattern.
>>>        (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
>>>        (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
>>>        (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
>>>        (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
>>>        (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh):
>> Likewise.
>>>        (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
>> Likewise.
>>>        (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb,
>> iwmmxt_wunpckehsh): Likewise.
>>>        (iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
>> iwmmxt_wunpckeluh): Likewise.
>>>        (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
>> Likewise.
>>>        (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu):
>> Likewise.
>>>        (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
>> iwmmxt_wsadhz): Likewise.
>>>        (iwmmxt2.md): Include.
>>>        * config/arm/iwmmxt2.md: New file.
>>>        * config/arm/iterators.md (VMMX2): New mode_iterator.
>>>        * config/arm/arm.md (wtype): New attribute.
>>>        (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
>>>        (UNSPEC_WALIGNI): New unspec.
>>>        * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
>>>
>>> At 2011-09-05 17:55:34,"Xinyu Qi" <xyqi@marvell.com> wrote:
>>>> At 2011-08-18 10:21:01,"Ramana Radhakrishnan"
>>>> <ramana.radhakrishnan@linaro.org> wrote:
>>>>> On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> It is the fourth part of iWMMXt maintenance.
>>>>>>>
>>>>>
>>>>> Can this be broken down further. ? I'll have to do this again but
>>>>> there are some initial comments below for some discussion.
>>>>
>>>>>
>>>>>>  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn, iwmmxt_uavgrndv8qi3,
>>>>> iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3,
>> iwmmxt_tinsrb,
>>>>> iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3,
>>>> gtuv4hi3,
>>>>> gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb,
>> iwmmxt_wunpckihh,
>>>>> iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh,
>> iwmmxt_wunpckilw,
>>>>> iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw,
>>>> iwmmxt_wunpckehsb,
>>>>> iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
>>>> iwmmxt_wunpckeluh,
>>>>> iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh,
>>>> iwmmxt_wunpckelsw,
>>>>> iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh,
>> iwmmxt_wsadbz,
>>>>> iwmmxt_wsadhz): Revise.
>>>>>
>>>>> Revise to do what ?
>>>>
>>>> Sorry for late response.
>>>>
>>>> Some of them have incorrect RTL templates. For example, see
>> iwmmxt_uavgv8qi3
>>>> Its old RTL template is:
>>>>   [(set (match_operand:V8QI                 0 "register_operand"
>> "=y")
>>>>         (ashiftrt:V8QI (plus:V8QI
>>>>                           (match_operand:V8QI 1
>> "register_operand" "y")
>>>>                                  (match_operand:V8QI 2
>> "register_operand" "y"))
>>>>                             (const_int 1)))]
>>>>
>>>> According to the assembly behavior of wavg2b, the correct one should be:
>>>>   [(set (match_operand:V8QI  0 "register_operand" "=y")
>>>>         (truncate:V8QI
>>>>            (lshiftrt:V8HI
>>>>              (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1
>>>> "register_operand" "y"))
>>>>                         (zero_extend:V8HI (match_operand:V8QI 2
>>>> "register_operand" "y")))
>>>>            (const_int 1))))]
>>>>
>>>> Consider the case:
>>>> The Operation on element 0x01 and 0xff: gcc with old RTL template would
>> optimize
>>>> to the result 0x00.That is:
>>>> 0x01 + 0xff => 0x00. 0x00 > 1 => 0x00
>>>> While the correct result should be 0x80.
>>>> 0x01 => 0x0001, 0xff => 0x00ff. 0x0001 + 0x00ff => 0x0100. 0x0100 > 1 =>
>> 0x0080,
>>>> 0x0080 => 0x80
>>>>
>>>> iwmmxt_wmadds and iwmmxt_wmaddu are modified to use detailed RTL
>> template
>>>> instead of unspec.
>>>>
>>>> For some of the wunpck patterns, change the order of zero_extend and
>> vec_select
>>>> in order to avoid a vec_select optimization internal error in old version gcc.
>>>> Maybe this internal bug has been fixed, but such modification is harmless.
>>>>
>>>> Rests of them are only revised for their format.
>>>>
>>>>>
>>>>>> (define_insn "*iwmmxt_movsi_insn"
>>>>>> -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk,
>>>>> m,z,r,?z,Uy,z")
>>>>>> -  (match_operand:SI 1 "general_operand"      "rk,
>> I,K,mi,rk,r,z,Uy,z,
>>>>> z"))]
>>>>>> +  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,
>>>>> m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
>>>>>> +  (match_operand:SI 1 "general_operand"      "
>> rk,I,K,N,mi,rk,r,z,Uy,
>>>> z,
>>>>> z,r,t, z, t,t"))]
>>>>>>   "TARGET_REALLY_IWMMXT
>>>>>> -   && (   register_operand (operands[0], SImode)
>>>>>> -       || register_operand (operands[1], SImode))"
>>>>>> -  "*
>>>>>> -   switch (which_alternative)
>>>>>> +   && ((register_operand (operands[0], SImode)
>>>>>> +  && (!reload_completed
>>>>>> +      || REGNO_REG_CLASS (REGNO (operands[0])) ==
>> IWMMXT_GR_REGS))
>>>>>> +       || (register_operand (operands[1], SImode)
>>>>>> +     && (!reload_completed
>>>>>
>>>>>
>>>>>
>>>>>> +         || REGNO_REG_CLASS (REGNO (operands[1])) ==
>> IWMMXT_GR_REGS)))"
>>>>>
>>>>> I don't like this at all - what you are doing is assuming that after
>>>>> reg-alloc you are going to be able to rely on whether something has a
>>>>> particular register class and then turn on and off it's matching. So
>>>>> this matches before reload and doesn't do so after reload for the
>>>>> cases where *iwmmxt_movsi_insn is really in a core register. I don't
>>>>> think you can do it this way. If you really want to do this properly -
>>>>> have an arch field for iwmmxt as well in the arch attribute and then
>>>>> add these alternatives to existing patterns.
>>>>>
>>>>> If I understand what you are trying to do here - you are trying to use
>>>>> *arm_movsi_insn and other patterns in the rest of the backend and let
>>>>> things like "predicable" kick in right after reload for all cases
>>>>> other than the ones you enumerate. In which case get rid of all the
>>>>> other constaints in this pattern other than the constraints that are
>>>>> valid for registers of class IWMMXT_REGS
>>>>
>>>> This piece of code is added to make iwmmxt coexist with vfp when iwmmxt
>> and
>>>> vfp are enabled together. Agree, I don't think it is a good fix.
>>>> Add adequate constrains to *iwmmxt_movsi_insn and
>> *iwmmxt_arm_movdi so that
>>>> don't need to change their conditions.
>>>>
>>>>>
>>>>> Also the definition of output_move_double has changed now and hence
>>>>> this needs some rework.
>>>>
>>>> Done.
>>>>
>>>>> Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
>>>>> user visible option ?
>>>>
>>>> I don't think users need to know the distinction between iwmmxt and
>> iwmmxt2
>>>> though there are two options "-mcpu=iwmmxt" and "-mcpu=iwmmxt2". It
>> seems if
>>>> "-mcpu=iwmmxt" is specified in gcc, the assembler cannot recognize the
>> wmmx2
>>>> insns.
>>>>
>>>>
>>>>>
>>>>> Just in case it wasn't clear please don't commit any patch in this
>>>>> series until all the patches have been completely reviewed.
>>>>>
>>>>> cheers
>>>>> Ramana
>>>>
>>>>
>>>> The new diff attached. New ChangLog:
>>>>
>>>> * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
>>>>   (arm_output_iwmmxt_tinsr): Likewise.
>>>> * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate):
>> Declare.
>>>>   (arm_output_iwmmxt_tinsr): Likewise.
>>>> * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New
>> constant.
>>>>   (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
>> Delete.
>>>>   (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
>>>>   (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
>>>>   (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
>>>>   (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
>>>>   (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt,
>> *xor<mode>3_iwmmxt): Likewise.
>>>>   (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt):
>> Likewise.
>>>>   (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
>>>>   (iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2,
>> iwmmxt_walignr3):
>>>> Likewise.
>>>>   (iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2,
>> iwmmxt_setwcgr3):
>>>> Likewise.
>>>>   (iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2,
>> iwmmxt_getwcgr3):
>>>> Likewise.
>>>>   (All instruction patterns): Add wtype attribute.
>>>>   (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with
>> vfp.
>>>>   (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
>>>>   (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
>>>>   (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
>>>>   (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
>>>>   (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
>>>>   (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh):
>> Likewise.
>>>>   (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
>> Likewise.
>>>>   (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh):
>> Likewise.
>>>>   (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh):
>> Likewise.
>>>>   (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
>> Likewise.
>>>>   (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
>>>>   (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz):
>> Likewise.
>>>>   (iwmmxt2.md): Include.
>>>> * config/arm/iwmmxt2.md: New file.
>>>> * config/arm/iterators.md (VMMX2): New mode_iterator.
>>>> * config/arm/arm.md (wtype): New attribute.
>>>>   (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
>>>>   (UNSPEC_WALIGNI): New unspec.
>>>> * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
>>>>
>>>> Thanks,
>>>> Xinyu
>> >


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-12-14 17:48         ` Richard Earnshaw
@ 2011-12-22  6:50           ` Xinyu Qi
  2011-12-22 10:12             ` Richard Earnshaw
  0 siblings, 1 reply; 15+ messages in thread
From: Xinyu Qi @ 2011-12-22  6:50 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: Ramana Radhakrishnan, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 16950 bytes --]

At 2011-12-15 01:32:13,"Richard Earnshaw" <rearnsha@arm.com> wrote:
> On 24/11/11 01:33, Xinyu Qi wrote:
> > Hi Ramana,
> >
> > I solve the conflict, please try again. The new diff is attached.
> >
> > Thanks,
> > Xinyu
> >
> > At 2011-11-19 07:36:15,"Ramana Radhakrishnan"
> <ramana.radhakrishnan@linaro.org> wrote:
> >>
> >> Hi Xinyu,
> >>
> >> This doesn't apply cleanly currently on trunk and the reject appears
> >> to come from iwmmxt.md and I've not yet investigated why.
> >>
> >> Can you have a look ?
> >>
>
> This patch is NOT ok.
>
> You're adding features that were new in iWMMXt2 (ie not in the original
> implementation) but you've provided no means by which the compiler can
> detect which operations are only available on the new cores.

Hi Richard,

All of the WMMX chips support WMMX2 instructions.
What I do is to complement the WMMX2 intrinsic support in GCC.
I don't think it is necessary for users to consider whether one WMMX insn is a WMMX2 insn or not.

> Further, I don't like the way you have separate patterns for the rotates
> with immediate.  Please investigate using the alternative enable feature
> to reduce these down to single patterns.  Once you've done all this,
> some of your tricky builtin expand code in patch 3/5 should then
> simplify significantly as you won't need separate expand codes for those
> alternatives.

Done. Combine immediate and register alternative into one pattern for all shift patterns.
Also update the part three. Send it in another mail.
The new diff is attached. The new Changlog:

        * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
        (arm_output_iwmmxt_tinsr): Likewise.
        * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
        (arm_output_iwmmxt_tinsr): Likewise.
        * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
        (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
        (rorv4hi3, rorv2si3, rordi3): Likewise.
        (rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
        (ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
        (lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
        (ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
        (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
        (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
        (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
        (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
        (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
        (ror<mode>3, ror<mode>3_di): Likewise.
        (ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
        (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
        (iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
        (iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
        (iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
        (iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
        (iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
        (iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
        (All instruction patterns): Add wtype attribute.
        (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
        (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
        (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
        (ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt): Likewise.
        (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
        (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
        (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
        (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
        (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
        (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
        (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
        (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
        (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
        (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
        (iwmmxt2.md): Include.
        * config/arm/iwmmxt2.md: New file.
        * config/arm/iterators.md (VMMX2): New mode_iterator.
        * config/arm/arm.md (wtype): New attribute.
        (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
        (UNSPEC_WALIGNI): New unspec.
        * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
        * config/arm/predicates.md (imm_or_reg_operand): New predicate.

Thanks,
Xinyu

> R.
>
> >> cheers
> >> Ramana
> >>
> >> On 26 September 2011 04:22, Xinyu Qi <xyqi@marvell.com> wrote:
> >>> Ping.
> >>>
> >>> http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00279.html
> >>>
> >>>        * config/arm/arm.c (arm_output_iwmmxt_shift_immediate):
> New
> >> function.
> >>>        (arm_output_iwmmxt_tinsr): Likewise.
> >>>        * config/arm/arm-protos.h
> >> (arm_output_iwmmxt_shift_immediate): Declare.
> >>>        (arm_output_iwmmxt_tinsr): Likewise.
> >>>        * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3):
> >> New constant.
> >>>        (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc,
> iwmmxt_tmcr):
> >> Delete.
> >>>        (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
> >>>        (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
> >>>        (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
> >>>        (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
> >>>        (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt,
> >> *xor<mode>3_iwmmxt): Likewise.
> >>>        (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt):
> >> Likewise.
> >>>        (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr):
> >> Likewise.
> >>>        (iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
> >>>        (iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
> >>>        (iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
> >>>        (iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
> >>>        (iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
> >>>        (iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
> >>>        (All instruction patterns): Add wtype attribute.
> >>>        (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist
> >> with vfp.
> >>>        (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the
> >> pattern.
> >>>        (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
> >>>        (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
> >>>        (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
> >>>        (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
> >>>        (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh):
> >> Likewise.
> >>>        (iwmmxt_wunpckilw, iwmmxt_wunpckehub,
> iwmmxt_wunpckehuh):
> >> Likewise.
> >>>        (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb,
> >> iwmmxt_wunpckehsh): Likewise.
> >>>        (iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
> >> iwmmxt_wunpckeluh): Likewise.
> >>>        (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb,
> iwmmxt_wunpckelsh):
> >> Likewise.
> >>>        (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu):
> >> Likewise.
> >>>        (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
> >> iwmmxt_wsadhz): Likewise.
> >>>        (iwmmxt2.md): Include.
> >>>        * config/arm/iwmmxt2.md: New file.
> >>>        * config/arm/iterators.md (VMMX2): New mode_iterator.
> >>>        * config/arm/arm.md (wtype): New attribute.
> >>>        (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
> >>>        (UNSPEC_WALIGNI): New unspec.
> >>>        * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> >>>
> >>> At 2011-09-05 17:55:34,"Xinyu Qi" <xyqi@marvell.com> wrote:
> >>>> At 2011-08-18 10:21:01,"Ramana Radhakrishnan"
> >>>> <ramana.radhakrishnan@linaro.org> wrote:
> >>>>> On 14 July 2011 08:45, Xinyu Qi <xyqi@marvell.com> wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> It is the fourth part of iWMMXt maintenance.
> >>>>>>>
> >>>>>
> >>>>> Can this be broken down further. ? I'll have to do this again but
> >>>>> there are some initial comments below for some discussion.
> >>>>
> >>>>>
> >>>>>>  (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn,
> iwmmxt_uavgrndv8qi3,
> >>>>> iwmmxt_uavgrndv4hi3, iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3,
> >> iwmmxt_tinsrb,
> >>>>> iwmmxt_tinsrh, iwmmxt_tinsrw, eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3,
> >>>> gtuv4hi3,
> >>>>> gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3, iwmmxt_wunpckihb,
> >> iwmmxt_wunpckihh,
> >>>>> iwmmxt_wunpckihw, iwmmxt_wunpckilb, iwmmxt_wunpckilh,
> >> iwmmxt_wunpckilw,
> >>>>> iwmmxt_wunpckehub, iwmmxt_wunpckehuh, iwmmxt_wunpckehuw,
> >>>> iwmmxt_wunpckehsb,
> >>>>> iwmmxt_wunpckehsh, iwmmxt_wunpckehsw, iwmmxt_wunpckelub,
> >>>> iwmmxt_wunpckeluh,
> >>>>> iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh,
> >>>> iwmmxt_wunpckelsw,
> >>>>> iwmmxt_wmadds, iwmmxt_wmaddu, iwmmxt_wsadb, iwmmxt_wsadh,
> >> iwmmxt_wsadbz,
> >>>>> iwmmxt_wsadhz): Revise.
> >>>>>
> >>>>> Revise to do what ?
> >>>>
> >>>> Sorry for late response.
> >>>>
> >>>> Some of them have incorrect RTL templates. For example, see
> >> iwmmxt_uavgv8qi3
> >>>> Its old RTL template is:
> >>>>   [(set (match_operand:V8QI                 0 "register_operand"
> >> "=y")
> >>>>         (ashiftrt:V8QI (plus:V8QI
> >>>>                           (match_operand:V8QI 1
> >> "register_operand" "y")
> >>>>                                  (match_operand:V8QI 2
> >> "register_operand" "y"))
> >>>>                             (const_int 1)))]
> >>>>
> >>>> According to the assembly behavior of wavg2b, the correct one should be:
> >>>>   [(set (match_operand:V8QI  0 "register_operand" "=y")
> >>>>         (truncate:V8QI
> >>>>            (lshiftrt:V8HI
> >>>>              (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1
> >>>> "register_operand" "y"))
> >>>>                         (zero_extend:V8HI (match_operand:V8QI 2
> >>>> "register_operand" "y")))
> >>>>            (const_int 1))))]
> >>>>
> >>>> Consider the case:
> >>>> The Operation on element 0x01 and 0xff: gcc with old RTL template would
> >> optimize
> >>>> to the result 0x00.That is:
> >>>> 0x01 + 0xff => 0x00. 0x00 > 1 => 0x00
> >>>> While the correct result should be 0x80.
> >>>> 0x01 => 0x0001, 0xff => 0x00ff. 0x0001 + 0x00ff => 0x0100. 0x0100 > 1 =>
> >> 0x0080,
> >>>> 0x0080 => 0x80
> >>>>
> >>>> iwmmxt_wmadds and iwmmxt_wmaddu are modified to use detailed RTL
> >> template
> >>>> instead of unspec.
> >>>>
> >>>> For some of the wunpck patterns, change the order of zero_extend and
> >> vec_select
> >>>> in order to avoid a vec_select optimization internal error in old version
> gcc.
> >>>> Maybe this internal bug has been fixed, but such modification is harmless.
> >>>>
> >>>> Rests of them are only revised for their format.
> >>>>
> >>>>>
> >>>>>> (define_insn "*iwmmxt_movsi_insn"
> >>>>>> -  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk,
> >>>>> m,z,r,?z,Uy,z")
> >>>>>> -  (match_operand:SI 1 "general_operand"      "rk,
> >> I,K,mi,rk,r,z,Uy,z,
> >>>>> z"))]
> >>>>>> +  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,
> >>>>> m,z,r,?z,?Uy,?z,t,r,?t,?z,t")
> >>>>>> +  (match_operand:SI 1 "general_operand"      "
> >> rk,I,K,N,mi,rk,r,z,Uy,
> >>>> z,
> >>>>> z,r,t, z, t,t"))]
> >>>>>>   "TARGET_REALLY_IWMMXT
> >>>>>> -   && (   register_operand (operands[0], SImode)
> >>>>>> -       || register_operand (operands[1], SImode))"
> >>>>>> -  "*
> >>>>>> -   switch (which_alternative)
> >>>>>> +   && ((register_operand (operands[0], SImode)
> >>>>>> +  && (!reload_completed
> >>>>>> +      || REGNO_REG_CLASS (REGNO (operands[0])) ==
> >> IWMMXT_GR_REGS))
> >>>>>> +       || (register_operand (operands[1], SImode)
> >>>>>> +     && (!reload_completed
> >>>>>
> >>>>>
> >>>>>
> >>>>>> +         || REGNO_REG_CLASS (REGNO (operands[1])) ==
> >> IWMMXT_GR_REGS)))"
> >>>>>
> >>>>> I don't like this at all - what you are doing is assuming that after
> >>>>> reg-alloc you are going to be able to rely on whether something has a
> >>>>> particular register class and then turn on and off it's matching. So
> >>>>> this matches before reload and doesn't do so after reload for the
> >>>>> cases where *iwmmxt_movsi_insn is really in a core register. I don't
> >>>>> think you can do it this way. If you really want to do this properly -
> >>>>> have an arch field for iwmmxt as well in the arch attribute and then
> >>>>> add these alternatives to existing patterns.
> >>>>>
> >>>>> If I understand what you are trying to do here - you are trying to use
> >>>>> *arm_movsi_insn and other patterns in the rest of the backend and let
> >>>>> things like "predicable" kick in right after reload for all cases
> >>>>> other than the ones you enumerate. In which case get rid of all the
> >>>>> other constaints in this pattern other than the constraints that are
> >>>>> valid for registers of class IWMMXT_REGS
> >>>>
> >>>> This piece of code is added to make iwmmxt coexist with vfp when
> iwmmxt
> >> and
> >>>> vfp are enabled together. Agree, I don't think it is a good fix.
> >>>> Add adequate constrains to *iwmmxt_movsi_insn and
> >> *iwmmxt_arm_movdi so that
> >>>> don't need to change their conditions.
> >>>>
> >>>>>
> >>>>> Also the definition of output_move_double has changed now and hence
> >>>>> this needs some rework.
> >>>>
> >>>> Done.
> >>>>
> >>>>> Should there be a distinction between iwmmxt and iwmmxt2 ? Is it a
> >>>>> user visible option ?
> >>>>
> >>>> I don't think users need to know the distinction between iwmmxt and
> >> iwmmxt2
> >>>> though there are two options "-mcpu=iwmmxt" and "-mcpu=iwmmxt2".
> It
> >> seems if
> >>>> "-mcpu=iwmmxt" is specified in gcc, the assembler cannot recognize the
> >> wmmx2
> >>>> insns.
> >>>>
> >>>>
> >>>>>
> >>>>> Just in case it wasn't clear please don't commit any patch in this
> >>>>> series until all the patches have been completely reviewed.
> >>>>>
> >>>>> cheers
> >>>>> Ramana
> >>>>
> >>>>
> >>>> The new diff attached. New ChangLog:
> >>>>
> >>>> * config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New
> function.
> >>>>   (arm_output_iwmmxt_tinsr): Likewise.
> >>>> * config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate):
> >> Declare.
> >>>>   (arm_output_iwmmxt_tinsr): Likewise.
> >>>> * config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New
> >> constant.
> >>>>   (iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
> >> Delete.
> >>>>   (iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
> >>>>   (*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
> >>>>   (tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
> >>>>   (iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
> >>>>   (*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt,
> >> *xor<mode>3_iwmmxt): Likewise.
> >>>>   (rori<mode>3, ashri<mode>3_iwmmxt, lshri<mode>3_iwmmxt):
> >> Likewise.
> >>>>   (ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr):
> Likewise.
> >>>>   (iwmmxt_walignr0, iwmmxt_walignr1, iwmmxt_walignr2,
> >> iwmmxt_walignr3):
> >>>> Likewise.
> >>>>   (iwmmxt_setwcgr0, iwmmxt_setwcgr1, iwmmxt_setwcgr2,
> >> iwmmxt_setwcgr3):
> >>>> Likewise.
> >>>>   (iwmmxt_getwcgr0, iwmmxt_getwcgr1, iwmmxt_getwcgr2,
> >> iwmmxt_getwcgr3):
> >>>> Likewise.
> >>>>   (All instruction patterns): Add wtype attribute.
> >>>>   (*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with
> >> vfp.
> >>>>   (iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
> >>>>   (iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
> >>>>   (iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
> >>>>   (eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
> >>>>   (gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
> >>>>   (iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh):
> >> Likewise.
> >>>>   (iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
> >> Likewise.
> >>>>   (iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh):
> >> Likewise.
> >>>>   (iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh):
> >> Likewise.
> >>>>   (iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
> >> Likewise.
> >>>>   (iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu):
> Likewise.
> >>>>   (iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz,
> iwmmxt_wsadhz):
> >> Likewise.
> >>>>   (iwmmxt2.md): Include.
> >>>> * config/arm/iwmmxt2.md: New file.
> >>>> * config/arm/iterators.md (VMMX2): New mode_iterator.
> >>>> * config/arm/arm.md (wtype): New attribute.
> >>>>   (UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
> >>>>   (UNSPEC_WALIGNI): New unspec.
> >>>> * config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> >>>>
> >>>> Thanks,
> >>>> Xinyu
> >> >
>


[-- Attachment #2: 4_wmmx_md.diff.gz --]
[-- Type: application/x-gzip, Size: 13077 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-12-22  6:50           ` Xinyu Qi
@ 2011-12-22 10:12             ` Richard Earnshaw
  2011-12-29  6:24               ` Xinyu Qi
                                 ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Richard Earnshaw @ 2011-12-22 10:12 UTC (permalink / raw)
  To: Xinyu Qi; +Cc: Ramana Radhakrishnan, gcc-patches

On 22/12/11 06:38, Xinyu Qi wrote:
> At 2011-12-15 01:32:13,"Richard Earnshaw" <rearnsha@arm.com> wrote:
>> On 24/11/11 01:33, Xinyu Qi wrote:
>>> Hi Ramana,
>>>
>>> I solve the conflict, please try again. The new diff is attached.
>>>
>>> Thanks,
>>> Xinyu
>>>
>>> At 2011-11-19 07:36:15,"Ramana Radhakrishnan"
>> <ramana.radhakrishnan@linaro.org> wrote:
>>>>
>>>> Hi Xinyu,
>>>>
>>>> This doesn't apply cleanly currently on trunk and the reject appears
>>>> to come from iwmmxt.md and I've not yet investigated why.
>>>>
>>>> Can you have a look ?
>>>>
>>
>> This patch is NOT ok.
>>
>> You're adding features that were new in iWMMXt2 (ie not in the original
>> implementation) but you've provided no means by which the compiler can
>> detect which operations are only available on the new cores.
> 
> Hi Richard,
> 
> All of the WMMX chips support WMMX2 instructions.

This may be true for Marvell's current range of processors, but I find
it hard to reconcile with the assembler support in GAS, which clearly
distinguishes between iWMMXT and iWMMXT2 instruction sets.  Are you
telling me that no cores were ever manufactured (even by Intel) that
only supported iWMMXT?

I'm concerned that this patch will break support for existing users who
have older chips (for GCC we have to go through a deprecation cycle if
we want to drop support for something we now believe is no-longer worth
maintaining).

> What I do is to complement the WMMX2 intrinsic support in GCC.

I understand that, and I'm not saying the patch can never go in; just
that it needs to separate out the support for the different architecture
variants.

> I don't think it is necessary for users to consider whether one WMMX insn is a WMMX2 insn or not.

Users don't (unless they want their code to run on legacy processors
that only support the original instruction set), but the compiler surely
must know what it is targeting.  Remember that the instruction patterns
are not entirely black boxes, the compiler can do optimizations on
intrinsics (it's one of the reasons why they are better than inline
assembly).  Unless the compiler knows exactly what instructions are
legal, it could end up optimizing something that started as a WMMX insn
into something that's a WMMX2 insn (for example, propagating a constant
into a vector shift expression).

R.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-12-22 10:12             ` Richard Earnshaw
@ 2011-12-29  6:24               ` Xinyu Qi
  2012-02-03  2:11               ` Xinyu Qi
  2012-03-13  8:57               ` Xinyu Qi
  2 siblings, 0 replies; 15+ messages in thread
From: Xinyu Qi @ 2011-12-29  6:24 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: Ramana Radhakrishnan, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 6481 bytes --]

At 2011-12-22 17:53:45,"Richard Earnshaw" <rearnsha@arm.com> wrote: 
> On 22/12/11 06:38, Xinyu Qi wrote:
> > At 2011-12-15 01:32:13,"Richard Earnshaw" <rearnsha@arm.com> wrote:
> >> On 24/11/11 01:33, Xinyu Qi wrote:
> >>> Hi Ramana,
> >>>
> >>> I solve the conflict, please try again. The new diff is attached.
> >>>
> >>> Thanks,
> >>> Xinyu
> >>>
> >>> At 2011-11-19 07:36:15,"Ramana Radhakrishnan"
> >> <ramana.radhakrishnan@linaro.org> wrote:
> >>>>
> >>>> Hi Xinyu,
> >>>>
> >>>> This doesn't apply cleanly currently on trunk and the reject appears
> >>>> to come from iwmmxt.md and I've not yet investigated why.
> >>>>
> >>>> Can you have a look ?
> >>>>
> >>
> >> This patch is NOT ok.
> >>
> >> You're adding features that were new in iWMMXt2 (ie not in the original
> >> implementation) but you've provided no means by which the compiler can
> >> detect which operations are only available on the new cores.
> >
> > Hi Richard,
> >
> > All of the WMMX chips support WMMX2 instructions.
> 
> This may be true for Marvell's current range of processors, but I find
> it hard to reconcile with the assembler support in GAS, which clearly
> distinguishes between iWMMXT and iWMMXT2 instruction sets.  Are you
> telling me that no cores were ever manufactured (even by Intel) that
> only supported iWMMXT?
> 
> I'm concerned that this patch will break support for existing users who
> have older chips (for GCC we have to go through a deprecation cycle if
> we want to drop support for something we now believe is no-longer worth
> maintaining).
> 
> > What I do is to complement the WMMX2 intrinsic support in GCC.
> 
> I understand that, and I'm not saying the patch can never go in; just
> that it needs to separate out the support for the different architecture
> variants.
> 
> > I don't think it is necessary for users to consider whether one WMMX insn is a
> WMMX2 insn or not.
> 
> Users don't (unless they want their code to run on legacy processors
> that only support the original instruction set), but the compiler surely
> must know what it is targeting.  Remember that the instruction patterns
> are not entirely black boxes, the compiler can do optimizations on
> intrinsics (it's one of the reasons why they are better than inline
> assembly).  Unless the compiler knows exactly what instructions are
> legal, it could end up optimizing something that started as a WMMX insn
> into something that's a WMMX2 insn (for example, propagating a constant
> into a vector shift expression).
> 
> R.

Hi, Richard,

You are right. There exist the chips that only support WMMX instructions in the history.
I distinguish the iWMMXt and iWMMXt2 in the patch update this time.

In current GCC, -march=iwmmxt and -march=iwmmxt2 (or -mcpu=iwmmxt and -mcpu=iwmmxt2) are almost no difference in the compiling stage.
I take advantage of them to do the work, that is, make -march=iwmmxt (or -mcpu=iwmmxt) only support iWMMXt intrinsic iWMMXt built in and WMMX instructions,
and make -march=iwmmxt2 (or -mcpu=iwmmxt2) support fully iWMMXt2.

Define a new flag FL_IWMMXT2 to represent the chip support iWMMXt2 extension, which directly controls the iWMMXt2 built in initialization and the followed defines.
Define __IWMMXT2__ in TARGET_CPU_CPP_BUILTINS to control the access of iWMMXt2 intrinsics.
Define TARGET_REALLY_IWMMXT2 to control the access of WMMX2 instructions' machine description.
In arm.md, define iwmmxt2 in "arch" attr to control the access of the alternative in shift patterns. 

The updated patch 4/5 is attached here. 1/5, 2/5 and 3/5 are updated accordingly. Attach them in related mails.
Please take a look if such modification is proper.

Changelog:

	* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
	(rorv4hi3, rorv2si3, rordi3): Likewise.
	(rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
	(ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
	(lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
	(ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
	(ror<mode>3, ror<mode>3_di): Likewise.
	(ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
	(All instruction patterns): Add wtype attribute.
	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
	(ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt): Likewise.
	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
	(iwmmxt2.md): Include.
	* config/arm/iwmmxt2.md: New file.
	* config/arm/iterators.md (VMMX2): New mode_iterator.
	* config/arm/arm.md (wtype): New attribute.
	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
	(UNSPEC_WALIGNI): New unspec.
	* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
	* config/arm/predicates.md (imm_or_reg_operand): New predicate.

Thanks,
Xinyu

[-- Attachment #2: 4_wmmx_md.diff.gz --]
[-- Type: application/x-gzip, Size: 13102 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-12-22 10:12             ` Richard Earnshaw
  2011-12-29  6:24               ` Xinyu Qi
@ 2012-02-03  2:11               ` Xinyu Qi
  2012-03-13  8:57               ` Xinyu Qi
  2 siblings, 0 replies; 15+ messages in thread
From: Xinyu Qi @ 2012-02-03  2:11 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: Ramana Radhakrishnan, gcc-patches

PING

http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01786.html

At 2011-12-29 14:12:44,"Xinyu Qi" <xyqi@marvell.com> wrote:
> At 2011-12-22 17:53:45,"Richard Earnshaw" <rearnsha@arm.com> wrote:
> > On 22/12/11 06:38, Xinyu Qi wrote:
> > > At 2011-12-15 01:32:13,"Richard Earnshaw" <rearnsha@arm.com> wrote:
> > >> On 24/11/11 01:33, Xinyu Qi wrote:
> > >>> Hi Ramana,
> > >>>
> > >>> I solve the conflict, please try again. The new diff is attached.
> > >>>
> > >>> Thanks,
> > >>> Xinyu
> > >>>
> > >>> At 2011-11-19 07:36:15,"Ramana Radhakrishnan"
> > >> <ramana.radhakrishnan@linaro.org> wrote:
> > >>>>
> > >>>> Hi Xinyu,
> > >>>>
> > >>>> This doesn't apply cleanly currently on trunk and the reject
> > >>>> appears to come from iwmmxt.md and I've not yet investigated why.
> > >>>>
> > >>>> Can you have a look ?
> > >>>>
> > >>
> > >> This patch is NOT ok.
> > >>
> > >> You're adding features that were new in iWMMXt2 (ie not in the
> > >> original
> > >> implementation) but you've provided no means by which the compiler
> > >> can detect which operations are only available on the new cores.
> > >
> > > Hi Richard,
> > >
> > > All of the WMMX chips support WMMX2 instructions.
> >
> > This may be true for Marvell's current range of processors, but I find
> > it hard to reconcile with the assembler support in GAS, which clearly
> > distinguishes between iWMMXT and iWMMXT2 instruction sets.  Are you
> > telling me that no cores were ever manufactured (even by Intel) that
> > only supported iWMMXT?
> >
> > I'm concerned that this patch will break support for existing users
> > who have older chips (for GCC we have to go through a deprecation
> > cycle if we want to drop support for something we now believe is
> > no-longer worth maintaining).
> >
> > > What I do is to complement the WMMX2 intrinsic support in GCC.
> >
> > I understand that, and I'm not saying the patch can never go in; just
> > that it needs to separate out the support for the different
> > architecture variants.
> >
> > > I don't think it is necessary for users to consider whether one WMMX
> > > insn is a
> > WMMX2 insn or not.
> >
> > Users don't (unless they want their code to run on legacy processors
> > that only support the original instruction set), but the compiler
> > surely must know what it is targeting.  Remember that the instruction
> > patterns are not entirely black boxes, the compiler can do
> > optimizations on intrinsics (it's one of the reasons why they are
> > better than inline assembly).  Unless the compiler knows exactly what
> > instructions are legal, it could end up optimizing something that
> > started as a WMMX insn into something that's a WMMX2 insn (for
> > example, propagating a constant into a vector shift expression).
> >
> > R.
> 
> Hi, Richard,
> 
> You are right. There exist the chips that only support WMMX instructions in the
> history.
> I distinguish the iWMMXt and iWMMXt2 in the patch update this time.
> 
> In current GCC, -march=iwmmxt and -march=iwmmxt2 (or -mcpu=iwmmxt and
> -mcpu=iwmmxt2) are almost no difference in the compiling stage.
> I take advantage of them to do the work, that is, make -march=iwmmxt (or
> -mcpu=iwmmxt) only support iWMMXt intrinsic iWMMXt built in and WMMX
> instructions, and make -march=iwmmxt2 (or -mcpu=iwmmxt2) support fully
> iWMMXt2.
> 
> Define a new flag FL_IWMMXT2 to represent the chip support iWMMXt2
> extension, which directly controls the iWMMXt2 built in initialization and the
> followed defines.
> Define __IWMMXT2__ in TARGET_CPU_CPP_BUILTINS to control the access of
> iWMMXt2 intrinsics.
> Define TARGET_REALLY_IWMMXT2 to control the access of WMMX2
> instructions' machine description.
> In arm.md, define iwmmxt2 in "arch" attr to control the access of the
> alternative in shift patterns.
> 
> The updated patch 4/5 is attached here. 1/5, 2/5 and 3/5 are updated
> accordingly. Attach them in related mails.
> Please take a look if such modification is proper.
> 
> Changelog:
> 
> 	* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New
> function.
> 	(arm_output_iwmmxt_tinsr): Likewise.
> 	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate):
> Declare.
> 	(arm_output_iwmmxt_tinsr): Likewise.
> 	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New
> constant.
> 	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
> Delete.
> 	(rorv4hi3, rorv2si3, rordi3): Likewise.
> 	(rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
> 	(ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
> 	(lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
> 	(ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
> 	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
> 	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
> 	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
> 	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
> 	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt):
> Likewise.
> 	(ror<mode>3, ror<mode>3_di): Likewise.
> 	(ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
> 	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
> 	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
> 	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
> 	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
> 	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
> 	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
> 	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
> 	(All instruction patterns): Add wtype attribute.
> 	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
> 	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
> 	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
> 	(ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt):
> Likewise.
> 	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
> 	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
> 	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
> 	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
> 	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
> Likewise.
> 	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh):
> Likewise.
> 	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh):
> Likewise.
> 	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
> Likewise.
> 	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
> 	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz):
> Likewise.
> 	(iwmmxt2.md): Include.
> 	* config/arm/iwmmxt2.md: New file.
> 	* config/arm/iterators.md (VMMX2): New mode_iterator.
> 	* config/arm/arm.md (wtype): New attribute.
> 	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
> 	(UNSPEC_WALIGNI): New unspec.
> 	* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> 	* config/arm/predicates.md (imm_or_reg_operand): New predicate.
> 
> Thanks,
> Xinyu

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PING: [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
  2011-12-22 10:12             ` Richard Earnshaw
  2011-12-29  6:24               ` Xinyu Qi
  2012-02-03  2:11               ` Xinyu Qi
@ 2012-03-13  8:57               ` Xinyu Qi
  2 siblings, 0 replies; 15+ messages in thread
From: Xinyu Qi @ 2012-03-13  8:57 UTC (permalink / raw)
  To: Xinyu Qi, Richard Earnshaw; +Cc: Ramana Radhakrishnan, gcc-patches

PING

At 2012-02-03 10:09:55,"Xinyu Qi" <xyqi@marvell.com> wrote:
> PING
> 
> http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01786.html
> 
> At 2011-12-29 14:12:44,"Xinyu Qi" <xyqi@marvell.com> wrote:
> > At 2011-12-22 17:53:45,"Richard Earnshaw" <rearnsha@arm.com> wrote:
> > > On 22/12/11 06:38, Xinyu Qi wrote:
> > > > At 2011-12-15 01:32:13,"Richard Earnshaw" <rearnsha@arm.com>
> wrote:
> > > >> On 24/11/11 01:33, Xinyu Qi wrote:
> > > >>> Hi Ramana,
> > > >>>
> > > >>> I solve the conflict, please try again. The new diff is attached.
> > > >>>
> > > >>> Thanks,
> > > >>> Xinyu
> > > >>>
> > > >>> At 2011-11-19 07:36:15,"Ramana Radhakrishnan"
> > > >> <ramana.radhakrishnan@linaro.org> wrote:
> > > >>>>
> > > >>>> Hi Xinyu,
> > > >>>>
> > > >>>> This doesn't apply cleanly currently on trunk and the reject
> > > >>>> appears to come from iwmmxt.md and I've not yet investigated why.
> > > >>>>
> > > >>>> Can you have a look ?
> > > >>>>
> > > >>
> > > >> This patch is NOT ok.
> > > >>
> > > >> You're adding features that were new in iWMMXt2 (ie not in the
> > > >> original
> > > >> implementation) but you've provided no means by which the compiler
> > > >> can detect which operations are only available on the new cores.
> > > >
> > > > Hi Richard,
> > > >
> > > > All of the WMMX chips support WMMX2 instructions.
> > >
> > > This may be true for Marvell's current range of processors, but I find
> > > it hard to reconcile with the assembler support in GAS, which clearly
> > > distinguishes between iWMMXT and iWMMXT2 instruction sets.  Are you
> > > telling me that no cores were ever manufactured (even by Intel) that
> > > only supported iWMMXT?
> > >
> > > I'm concerned that this patch will break support for existing users
> > > who have older chips (for GCC we have to go through a deprecation
> > > cycle if we want to drop support for something we now believe is
> > > no-longer worth maintaining).
> > >
> > > > What I do is to complement the WMMX2 intrinsic support in GCC.
> > >
> > > I understand that, and I'm not saying the patch can never go in; just
> > > that it needs to separate out the support for the different
> > > architecture variants.
> > >
> > > > I don't think it is necessary for users to consider whether one WMMX
> > > > insn is a
> > > WMMX2 insn or not.
> > >
> > > Users don't (unless they want their code to run on legacy processors
> > > that only support the original instruction set), but the compiler
> > > surely must know what it is targeting.  Remember that the instruction
> > > patterns are not entirely black boxes, the compiler can do
> > > optimizations on intrinsics (it's one of the reasons why they are
> > > better than inline assembly).  Unless the compiler knows exactly what
> > > instructions are legal, it could end up optimizing something that
> > > started as a WMMX insn into something that's a WMMX2 insn (for
> > > example, propagating a constant into a vector shift expression).
> > >
> > > R.
> >
> > Hi, Richard,
> >
> > You are right. There exist the chips that only support WMMX instructions in
> the
> > history.
> > I distinguish the iWMMXt and iWMMXt2 in the patch update this time.
> >
> > In current GCC, -march=iwmmxt and -march=iwmmxt2 (or -mcpu=iwmmxt
> and
> > -mcpu=iwmmxt2) are almost no difference in the compiling stage.
> > I take advantage of them to do the work, that is, make -march=iwmmxt (or
> > -mcpu=iwmmxt) only support iWMMXt intrinsic iWMMXt built in and WMMX
> > instructions, and make -march=iwmmxt2 (or -mcpu=iwmmxt2) support fully
> > iWMMXt2.
> >
> > Define a new flag FL_IWMMXT2 to represent the chip support iWMMXt2
> > extension, which directly controls the iWMMXt2 built in initialization and the
> > followed defines.
> > Define __IWMMXT2__ in TARGET_CPU_CPP_BUILTINS to control the access
> of
> > iWMMXt2 intrinsics.
> > Define TARGET_REALLY_IWMMXT2 to control the access of WMMX2
> > instructions' machine description.
> > In arm.md, define iwmmxt2 in "arch" attr to control the access of the
> > alternative in shift patterns.
> >
> > The updated patch 4/5 is attached here. 1/5, 2/5 and 3/5 are updated
> > accordingly. Attach them in related mails.
> > Please take a look if such modification is proper.
> >
> > Changelog:
> >
> > 	* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New
> > function.
> > 	(arm_output_iwmmxt_tinsr): Likewise.
> > 	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate):
> > Declare.
> > 	(arm_output_iwmmxt_tinsr): Likewise.
> > 	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New
> > constant.
> > 	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr):
> > Delete.
> > 	(rorv4hi3, rorv2si3, rordi3): Likewise.
> > 	(rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
> > 	(ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
> > 	(lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
> > 	(ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
> > 	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
> > 	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
> > 	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
> > 	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
> > 	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt):
> > Likewise.
> > 	(ror<mode>3, ror<mode>3_di): Likewise.
> > 	(ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
> > 	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
> > 	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
> > 	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
> > 	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
> > 	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
> > 	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
> > 	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
> > 	(All instruction patterns): Add wtype attribute.
> > 	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
> > 	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
> > 	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
> > 	(ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt):
> > Likewise.
> > 	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
> > 	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
> > 	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
> > 	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
> > 	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh):
> > Likewise.
> > 	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh):
> > Likewise.
> > 	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh):
> > Likewise.
> > 	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh):
> > Likewise.
> > 	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
> > 	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz):
> > Likewise.
> > 	(iwmmxt2.md): Include.
> > 	* config/arm/iwmmxt2.md: New file.
> > 	* config/arm/iterators.md (VMMX2): New mode_iterator.
> > 	* config/arm/arm.md (wtype): New attribute.
> > 	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
> > 	(UNSPEC_WALIGNI): New unspec.
> > 	* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
> > 	* config/arm/predicates.md (imm_or_reg_operand): New predicate.
> >
> > Thanks,
> > Xinyu

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH ARM iWMMXt 4/5] WMMX machine description
  2012-05-29  4:13 [PATCH ARM iWMMXt 0/5] Improve iWMMXt support Matt Turner
@ 2012-05-29  4:15 ` Matt Turner
  0 siblings, 0 replies; 15+ messages in thread
From: Matt Turner @ 2012-05-29  4:15 UTC (permalink / raw)
  To: gcc-patches
  Cc: Ramana Radhakrishnan, Richard Earnshaw, Nick Clifton, Paul Brook,
	Xinyu Qi

From: Xinyu Qi <xyqi@marvell.com>

	gcc/
	* config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
	(rorv4hi3, rorv2si3, rordi3): Likewise.
	(rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
	(ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
	(lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
	(ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
	(ror<mode>3, ror<mode>3_di): Likewise.
	(ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
	(All instruction patterns): Add wtype attribute.
	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
	(ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt): Likewise.
	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
	(iwmmxt2.md): Include.
	* config/arm/iwmmxt2.md: New file.
	* config/arm/iterators.md (VMMX2): New mode_iterator.
	* config/arm/arm.md (wtype): New attribute.
	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
	(UNSPEC_WALIGNI): New unspec.
	* config/arm/t-arm (MD_INCLUDES): Add iwmmxt2.md.
	* config/arm/predicates.md (imm_or_reg_operand): New predicate.
---
 gcc/config/arm/arm-protos.h  |    2 +
 gcc/config/arm/arm.c         |   89 +++
 gcc/config/arm/arm.md        |    8 +-
 gcc/config/arm/iterators.md  |    2 +
 gcc/config/arm/iwmmxt.md     | 1753 ++++++++++++++++++++++++++----------------
 gcc/config/arm/iwmmxt2.md    |  918 ++++++++++++++++++++++
 gcc/config/arm/predicates.md |    5 +
 gcc/config/arm/t-arm         |    1 +
 8 files changed, 2122 insertions(+), 656 deletions(-)
 create mode 100644 gcc/config/arm/iwmmxt2.md

diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 4e6d7bb..955f324 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -159,6 +159,8 @@ extern const char *vfp_output_fstmd (rtx *);
 extern void arm_set_return_address (rtx, rtx);
 extern int arm_eliminable_register (rtx);
 extern const char *arm_output_shift(rtx *, int);
+extern const char *arm_output_iwmmxt_shift_immediate (const char *, rtx *, bool);
+extern const char *arm_output_iwmmxt_tinsr (rtx *);
 extern unsigned int arm_sync_loop_insns (rtx , rtx *);
 extern int arm_attr_length_push_multi(rtx, rtx);
 extern void arm_expand_compare_and_swap (rtx op[]);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 51eed40..a709f2f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -25149,6 +25149,95 @@ arm_output_shift(rtx * operands, int set_flags)
   return "";
 }
 
+/* Output assembly for a WMMX immediate shift instruction.  */
+const char *
+arm_output_iwmmxt_shift_immediate (const char *insn_name, rtx *operands, bool wror_or_wsra)
+{
+  int shift = INTVAL (operands[2]);
+  char templ[50];
+  enum machine_mode opmode = GET_MODE (operands[0]);
+
+  gcc_assert (shift >= 0);
+
+  /* If the shift value in the register versions is > 63 (for D qualifier),
+     31 (for W qualifier) or 15 (for H qualifier).  */
+  if (((opmode == V4HImode) && (shift > 15))
+	|| ((opmode == V2SImode) && (shift > 31))
+	|| ((opmode == DImode) && (shift > 63)))
+  {
+    if (wror_or_wsra)
+      {
+        sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, 32);
+        output_asm_insn (templ, operands);
+        if (opmode == DImode)
+          {
+	    sprintf (templ, "%s\t%%0, %%0, #%d", insn_name, 32);
+	    output_asm_insn (templ, operands);
+          }
+      }
+    else
+      {
+        /* The destination register will contain all zeros.  */
+        sprintf (templ, "wzero\t%%0");
+        output_asm_insn (templ, operands);
+      }
+    return "";
+  }
+
+  if ((opmode == DImode) && (shift > 32))
+    {
+      sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, 32);
+      output_asm_insn (templ, operands);
+      sprintf (templ, "%s\t%%0, %%0, #%d", insn_name, shift - 32);
+      output_asm_insn (templ, operands);
+    }
+  else
+    {
+      sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, shift);
+      output_asm_insn (templ, operands);
+    }
+  return "";
+}
+
+/* Output assembly for a WMMX tinsr instruction.  */
+const char *
+arm_output_iwmmxt_tinsr (rtx *operands)
+{
+  int mask = INTVAL (operands[3]);
+  int i;
+  char templ[50];
+  int units = mode_nunits[GET_MODE (operands[0])];
+  gcc_assert ((mask & (mask - 1)) == 0);
+  for (i = 0; i < units; ++i)
+    {
+      if ((mask & 0x01) == 1)
+        {
+          break;
+        }
+      mask >>= 1;
+    }
+  gcc_assert (i < units);
+  {
+    switch (GET_MODE (operands[0]))
+      {
+      case V8QImode:
+	sprintf (templ, "tinsrb%%?\t%%0, %%2, #%d", i);
+	break;
+      case V4HImode:
+	sprintf (templ, "tinsrh%%?\t%%0, %%2, #%d", i);
+	break;
+      case V2SImode:
+	sprintf (templ, "tinsrw%%?\t%%0, %%2, #%d", i);
+	break;
+      default:
+	gcc_unreachable ();
+	break;
+      }
+    output_asm_insn (templ, operands);
+  }
+  return "";
+}
+
 /* Output a Thumb-1 casesi dispatch sequence.  */
 const char *
 thumb1_output_casesi (rtx *operands)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index ad9d948..b0333c2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -62,6 +62,7 @@
 ;; UNSPEC Usage:
 ;; Note: sin and cos are no-longer used.
 ;; Unspec enumerators for Neon are defined in neon.md.
+;; Unspec enumerators for iwmmxt2 are defined in iwmmxt2.md
 
 (define_c_enum "unspec" [
   UNSPEC_SIN            ; `sin' operation (MODE_FLOAT):
@@ -98,8 +99,7 @@
   UNSPEC_WMACSZ         ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
   UNSPEC_WMACUZ         ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
   UNSPEC_CLRDI          ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
-  UNSPEC_WMADDS         ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
-  UNSPEC_WMADDU         ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
+  UNSPEC_WALIGNI        ; Used by the intrinsic form of the iWMMXt WALIGN instruction.
   UNSPEC_TLS            ; A symbol that has been treated properly for TLS usage.
   UNSPEC_PIC_LABEL      ; A label used for PIC access that does not appear in the
                         ; instruction stream.
@@ -366,6 +366,10 @@
 	       (const_string "yes")
 	       (const_string "no")))
 
+; wtype for WMMX insn scheduling purposes.
+(define_attr "wtype"
+        "none,wor,wxor,wand,wandn,wmov,tmcrr,tmrrc,wldr,wstr,tmcr,tmrc,wadd,wsub,wmul,wmac,wavg2,tinsr,textrm,wshufh,wcmpeq,wcmpgt,wmax,wmin,wpack,wunpckih,wunpckil,wunpckeh,wunpckel,wror,wsra,wsrl,wsll,wmadd,tmia,tmiaph,tmiaxy,tbcst,tmovmsk,wacc,waligni,walignr,tandc,textrc,torc,torvsc,wsad,wabs,wabsdiff,waddsubhx,wsubaddhx,wavg4,wmulw,wqmulm,wqmulwm,waddbhus,wqmiaxy,wmiaxy,wmiawxy,wmerge" (const_string "none"))
+
 ; Load scheduling, set from the arm_ld_sched variable
 ; initialized by arm_option_override()
 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 1567264..916444c 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -45,6 +45,8 @@
 ;; Integer element sizes implemented by IWMMXT.
 (define_mode_iterator VMMX [V2SI V4HI V8QI])
 
+(define_mode_iterator VMMX2 [V4HI V2SI])
+
 ;; Integer element sizes for shifts.
 (define_mode_iterator VSHFT [V4HI V2SI DI])
 
diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index bc0b80d..12f4179 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -1,4 +1,3 @@
-;; ??? This file needs auditing for thumb2
 ;; Patterns for the Intel Wireless MMX technology architecture.
 ;; Copyright (C) 2003, 2004, 2005, 2007, 2008, 2010
 ;; Free Software Foundation, Inc.
@@ -20,6 +19,41 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+;; Register numbers
+(define_constants
+  [(WCGR0           43)
+   (WCGR1           44)
+   (WCGR2           45)
+   (WCGR3           46)
+  ]
+)
+
+(define_insn "tbcstv8qi"
+  [(set (match_operand:V8QI                   0 "register_operand" "=y")
+        (vec_duplicate:V8QI (match_operand:QI 1 "s_register_operand" "r")))]
+  "TARGET_REALLY_IWMMXT"
+  "tbcstb%?\\t%0, %1"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tbcst")]
+)
+
+(define_insn "tbcstv4hi"
+  [(set (match_operand:V4HI                   0 "register_operand" "=y")
+        (vec_duplicate:V4HI (match_operand:HI 1 "s_register_operand" "r")))]
+  "TARGET_REALLY_IWMMXT"
+  "tbcsth%?\\t%0, %1"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tbcst")]
+)
+
+(define_insn "tbcstv2si"
+  [(set (match_operand:V2SI                   0 "register_operand" "=y")
+        (vec_duplicate:V2SI (match_operand:SI 1 "s_register_operand" "r")))]
+  "TARGET_REALLY_IWMMXT"
+  "tbcstw%?\\t%0, %1"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tbcst")]
+)
 
 (define_insn "iwmmxt_iordi3"
   [(set (match_operand:DI         0 "register_operand" "=y,?&r,?&r")
@@ -31,7 +65,9 @@
    #
    #"
   [(set_attr "predicable" "yes")
-   (set_attr "length" "4,8,8")])
+   (set_attr "length" "4,8,8")
+   (set_attr "wtype" "wor,none,none")]
+)
 
 (define_insn "iwmmxt_xordi3"
   [(set (match_operand:DI         0 "register_operand" "=y,?&r,?&r")
@@ -43,7 +79,9 @@
    #
    #"
   [(set_attr "predicable" "yes")
-   (set_attr "length" "4,8,8")])
+   (set_attr "length" "4,8,8")
+   (set_attr "wtype" "wxor,none,none")]
+)
 
 (define_insn "iwmmxt_anddi3"
   [(set (match_operand:DI         0 "register_operand" "=y,?&r,?&r")
@@ -55,7 +93,9 @@
    #
    #"
   [(set_attr "predicable" "yes")
-   (set_attr "length" "4,8,8")])
+   (set_attr "length" "4,8,8")
+   (set_attr "wtype" "wand,none,none")]
+)
 
 (define_insn "iwmmxt_nanddi3"
   [(set (match_operand:DI                 0 "register_operand" "=y")
@@ -63,64 +103,96 @@
 		(not:DI (match_operand:DI 2 "register_operand"  "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wandn%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wandn")]
+)
 
 (define_insn "*iwmmxt_arm_movdi"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, m,y,y,yr,y,yrUy")
-	(match_operand:DI 1 "di_operand"              "rIK,mi,r,y,yr,y,yrUy,y"))]
+  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m,y,y,yr,y,yrUy,*w, r,*w,*w, *Uv")
+        (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,r,y,yr,y,yrUy,y, r,*w,*w,*Uvi,*w"))]
   "TARGET_REALLY_IWMMXT
    && (   register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode))"
   "*
-{
   switch (which_alternative)
     {
-    default:
-      return output_move_double (operands, true, NULL);
     case 0:
+    case 1:
+    case 2:
       return \"#\";
-    case 3:
+    case 3: case 4:
+      return output_move_double (operands, true, NULL);
+    case 5:
       return \"wmov%?\\t%0,%1\";
-    case 4:
+    case 6:
       return \"tmcrr%?\\t%0,%Q1,%R1\";
-    case 5:
+    case 7:
       return \"tmrrc%?\\t%Q0,%R0,%1\";
-    case 6:
+    case 8:
       return \"wldrd%?\\t%0,%1\";
-    case 7:
+    case 9:
       return \"wstrd%?\\t%1,%0\";
+    case 10:
+      return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
+    case 11:
+      return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
+    case 12:
+      if (TARGET_VFP_SINGLE)
+	return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
+      else
+	return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
+    case 13: case 14:
+      return output_move_vfp (operands);
+    default:
+      gcc_unreachable ();
     }
-}"
-  [(set_attr "length"         "8,8,8,4,4,4,4,4")
-   (set_attr "type"           "*,load1,store2,*,*,*,*,*")
-   (set_attr "pool_range"     "*,1020,*,*,*,*,*,*")
-   (set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")]
+  "
+  [(set (attr "length") (cond [(eq_attr "alternative" "0,3,4") (const_int 8)
+                              (eq_attr "alternative" "1") (const_int 12)
+                              (eq_attr "alternative" "2") (const_int 16)
+                              (eq_attr "alternative" "12")
+                               (if_then_else
+                                 (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
+                                 (const_int 8)
+                                 (const_int 4))]
+                              (const_int 4)))
+   (set_attr "type" "*,*,*,load2,store2,*,*,*,*,*,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
+   (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,*,*,*,*,*,*,1020,*")
+   (set_attr "arm_neg_pool_range" "*,*,*,1008,*,*,*,*,*,*,*,*,*,1008,*")
+   (set_attr "wtype" "*,*,*,*,*,wmov,tmcrr,tmrrc,wldr,wstr,*,*,*,*,*")]
 )
 
 (define_insn "*iwmmxt_movsi_insn"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk, m,z,r,?z,Uy,z")
-	(match_operand:SI 1 "general_operand"      "rk, I,K,mi,rk,r,z,Uy,z, z"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk, m,z,r,?z,?Uy,*t, r,*t,*t  ,*Uv")
+	(match_operand:SI 1 "general_operand"      " rk,I,K,j,mi,rk,r,z,Uy,  z, r,*t,*t,*Uvi, *t"))]
   "TARGET_REALLY_IWMMXT
    && (   register_operand (operands[0], SImode)
        || register_operand (operands[1], SImode))"
   "*
    switch (which_alternative)
-   {
-   case 0: return \"mov\\t%0, %1\";
-   case 1: return \"mov\\t%0, %1\";
-   case 2: return \"mvn\\t%0, #%B1\";
-   case 3: return \"ldr\\t%0, %1\";
-   case 4: return \"str\\t%1, %0\";
-   case 5: return \"tmcr\\t%0, %1\";
-   case 6: return \"tmrc\\t%0, %1\";
-   case 7: return arm_output_load_gr (operands);
-   case 8: return \"wstrw\\t%1, %0\";
-   default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\";
-  }"
-  [(set_attr "type"           "*,*,*,load1,store1,*,*,load1,store1,*")
-   (set_attr "length"         "*,*,*,*,        *,*,*,  16,     *,8")
-   (set_attr "pool_range"     "*,*,*,4096,     *,*,*,1024,     *,*")
-   (set_attr "neg_pool_range" "*,*,*,4084,     *,*,*,   *,  1012,*")
+     {
+     case 0: return \"mov\\t%0, %1\";
+     case 1: return \"mov\\t%0, %1\";
+     case 2: return \"mvn\\t%0, #%B1\";
+     case 3: return \"movw\\t%0, %1\";
+     case 4: return \"ldr\\t%0, %1\";
+     case 5: return \"str\\t%1, %0\";
+     case 6: return \"tmcr\\t%0, %1\";
+     case 7: return \"tmrc\\t%0, %1\";
+     case 8: return arm_output_load_gr (operands);
+     case 9: return \"wstrw\\t%1, %0\";
+     case 10:return \"fmsr\\t%0, %1\";
+     case 11:return \"fmrs\\t%0, %1\";
+     case 12:return \"fcpys\\t%0, %1\\t%@ int\";
+     case 13: case 14:
+       return output_move_vfp (operands);
+     default:
+       gcc_unreachable ();
+     }"
+  [(set_attr "type"           "*,*,*,*,load1,store1,*,*,*,*,r_2_f,f_2_r,fcpys,f_loads,f_stores")
+   (set_attr "length"         "*,*,*,*,*,        *,*,*,  16,     *,*,*,*,*,*")
+   (set_attr "pool_range"     "*,*,*,*,4096,     *,*,*,1024,     *,*,*,*,1020,*")
+   (set_attr "neg_pool_range" "*,*,*,*,4084,     *,*,*,   *,  1012,*,*,*,1008,*")
    ;; Note - the "predicable" attribute is not allowed to have alternatives.
    ;; Since the wSTRw wCx instruction is not predicable, we cannot support
    ;; predicating any of the alternatives in this template.  Instead,
@@ -129,7 +201,8 @@
    ;; Also - we have to pretend that these insns clobber the condition code
    ;; bits as otherwise arm_final_prescan_insn() will try to conditionalize
    ;; them.
-   (set_attr "conds" "clob")]
+   (set_attr "conds" "clob")
+   (set_attr "wtype" "*,*,*,*,*,*,tmcr,tmrc,wldr,wstr,*,*,*,*,*")]
 )
 
 ;; Because iwmmxt_movsi_insn is not predicable, we provide the
@@ -177,19 +250,110 @@
    }"
   [(set_attr "predicable" "yes")
    (set_attr "length"         "4,     4,   4,4,4,8,   8,8")
-   (set_attr "type"           "*,store1,load1,*,*,*,load1,store1")
+   (set_attr "type"           "*,*,*,*,*,*,load1,store1")
    (set_attr "pool_range"     "*,     *, 256,*,*,*, 256,*")
-   (set_attr "neg_pool_range" "*,     *, 244,*,*,*, 244,*")])
+   (set_attr "neg_pool_range" "*,     *, 244,*,*,*, 244,*")
+   (set_attr "wtype"          "wmov,wstr,wldr,tmrrc,tmcrr,*,*,*")]
+)
+
+(define_expand "iwmmxt_setwcgr0"
+  [(set (reg:SI WCGR0)
+	(match_operand:SI 0 "register_operand"  ""))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_setwcgr1"
+  [(set (reg:SI WCGR1)
+	(match_operand:SI 0 "register_operand"  ""))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_setwcgr2"
+  [(set (reg:SI WCGR2)
+	(match_operand:SI 0 "register_operand"  ""))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_setwcgr3"
+  [(set (reg:SI WCGR3)
+	(match_operand:SI 0 "register_operand"  ""))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_getwcgr0"
+  [(set (match_operand:SI 0 "register_operand"  "")
+        (reg:SI WCGR0))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_getwcgr1"
+  [(set (match_operand:SI 0 "register_operand"  "")
+        (reg:SI WCGR1))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_getwcgr2"
+  [(set (match_operand:SI 0 "register_operand"  "")
+        (reg:SI WCGR2))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_expand "iwmmxt_getwcgr3"
+  [(set (match_operand:SI 0 "register_operand"  "")
+        (reg:SI WCGR3))]
+  "TARGET_REALLY_IWMMXT"
+  {}
+)
+
+(define_insn "*and<mode>3_iwmmxt"
+  [(set (match_operand:VMMX           0 "register_operand" "=y")
+        (and:VMMX (match_operand:VMMX 1 "register_operand"  "y")
+	          (match_operand:VMMX 2 "register_operand"  "y")))]
+  "TARGET_REALLY_IWMMXT"
+  "wand\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wand")]
+)
+
+(define_insn "*ior<mode>3_iwmmxt"
+  [(set (match_operand:VMMX           0 "register_operand" "=y")
+        (ior:VMMX (match_operand:VMMX 1 "register_operand"  "y")
+	          (match_operand:VMMX 2 "register_operand"  "y")))]
+  "TARGET_REALLY_IWMMXT"
+  "wor\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wor")]
+)
+
+(define_insn "*xor<mode>3_iwmmxt"
+  [(set (match_operand:VMMX           0 "register_operand" "=y")
+        (xor:VMMX (match_operand:VMMX 1 "register_operand"  "y")
+	          (match_operand:VMMX 2 "register_operand"  "y")))]
+  "TARGET_REALLY_IWMMXT"
+  "wxor\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wxor")]
+)
+
 
 ;; Vector add/subtract
 
 (define_insn "*add<mode>3_iwmmxt"
   [(set (match_operand:VMMX            0 "register_operand" "=y")
-        (plus:VMMX (match_operand:VMMX 1 "register_operand"  "y")
-	           (match_operand:VMMX 2 "register_operand"  "y")))]
+        (plus:VMMX (match_operand:VMMX 1 "register_operand" "y")
+	           (match_operand:VMMX 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wadd<MMX_char>%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "ssaddv8qi3"
   [(set (match_operand:V8QI               0 "register_operand" "=y")
@@ -197,7 +361,9 @@
 		      (match_operand:V8QI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "waddbss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "ssaddv4hi3"
   [(set (match_operand:V4HI               0 "register_operand" "=y")
@@ -205,7 +371,9 @@
 		      (match_operand:V4HI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "waddhss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "ssaddv2si3"
   [(set (match_operand:V2SI               0 "register_operand" "=y")
@@ -213,7 +381,9 @@
 		      (match_operand:V2SI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "waddwss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "usaddv8qi3"
   [(set (match_operand:V8QI               0 "register_operand" "=y")
@@ -221,7 +391,9 @@
 		      (match_operand:V8QI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "waddbus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "usaddv4hi3"
   [(set (match_operand:V4HI               0 "register_operand" "=y")
@@ -229,7 +401,9 @@
 		      (match_operand:V4HI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "waddhus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "usaddv2si3"
   [(set (match_operand:V2SI               0 "register_operand" "=y")
@@ -237,7 +411,9 @@
 		      (match_operand:V2SI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "waddwus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
 
 (define_insn "*sub<mode>3_iwmmxt"
   [(set (match_operand:VMMX             0 "register_operand" "=y")
@@ -245,7 +421,9 @@
 		    (match_operand:VMMX 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsub<MMX_char>%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "sssubv8qi3"
   [(set (match_operand:V8QI                0 "register_operand" "=y")
@@ -253,7 +431,9 @@
 		       (match_operand:V8QI 2 "register_operand"  "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsubbss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "sssubv4hi3"
   [(set (match_operand:V4HI                0 "register_operand" "=y")
@@ -261,7 +441,9 @@
 		       (match_operand:V4HI 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsubhss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "sssubv2si3"
   [(set (match_operand:V2SI                0 "register_operand" "=y")
@@ -269,7 +451,9 @@
 		       (match_operand:V2SI 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsubwss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "ussubv8qi3"
   [(set (match_operand:V8QI                0 "register_operand" "=y")
@@ -277,7 +461,9 @@
 		       (match_operand:V8QI 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsubbus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "ussubv4hi3"
   [(set (match_operand:V4HI                0 "register_operand" "=y")
@@ -285,7 +471,9 @@
 		       (match_operand:V4HI 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsubhus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "ussubv2si3"
   [(set (match_operand:V2SI                0 "register_operand" "=y")
@@ -293,7 +481,9 @@
 		       (match_operand:V2SI 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wsubwus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsub")]
+)
 
 (define_insn "*mulv4hi3_iwmmxt"
   [(set (match_operand:V4HI            0 "register_operand" "=y")
@@ -301,63 +491,77 @@
 		   (match_operand:V4HI 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wmulul%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmul")]
+)
 
 (define_insn "smulv4hi3_highpart"
-  [(set (match_operand:V4HI                                0 "register_operand" "=y")
-	(truncate:V4HI
-	 (lshiftrt:V4SI
-	  (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
-		     (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
-	  (const_int 16))))]
+  [(set (match_operand:V4HI 0 "register_operand" "=y")
+	  (truncate:V4HI
+	    (lshiftrt:V4SI
+	      (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                 (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+	      (const_int 16))))]
   "TARGET_REALLY_IWMMXT"
   "wmulsm%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmul")]
+)
 
 (define_insn "umulv4hi3_highpart"
-  [(set (match_operand:V4HI                                0 "register_operand" "=y")
-	(truncate:V4HI
-	 (lshiftrt:V4SI
-	  (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
-		     (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
-	  (const_int 16))))]
+  [(set (match_operand:V4HI 0 "register_operand" "=y")
+	  (truncate:V4HI
+	    (lshiftrt:V4SI
+	      (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                 (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+	      (const_int 16))))]
   "TARGET_REALLY_IWMMXT"
   "wmulum%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmul")]
+)
 
 (define_insn "iwmmxt_wmacs"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:DI   1 "register_operand" "0")
-		    (match_operand:V4HI 2 "register_operand" "y")
-		    (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACS))]
+	            (match_operand:V4HI 2 "register_operand" "y")
+	            (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACS))]
   "TARGET_REALLY_IWMMXT"
   "wmacs%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmac")]
+)
 
 (define_insn "iwmmxt_wmacsz"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:V4HI 1 "register_operand" "y")
-		    (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACSZ))]
+	            (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACSZ))]
   "TARGET_REALLY_IWMMXT"
   "wmacsz%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmac")]
+)
 
 (define_insn "iwmmxt_wmacu"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:DI   1 "register_operand" "0")
-		    (match_operand:V4HI 2 "register_operand" "y")
-		    (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACU))]
+	            (match_operand:V4HI 2 "register_operand" "y")
+	            (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACU))]
   "TARGET_REALLY_IWMMXT"
   "wmacu%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmac")]
+)
 
 (define_insn "iwmmxt_wmacuz"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:V4HI 1 "register_operand" "y")
-		    (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACUZ))]
+	            (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACUZ))]
   "TARGET_REALLY_IWMMXT"
   "wmacuz%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmac")]
+)
 
 ;; Same as xordi3, but don't show input operands so that we don't think
 ;; they are live.
@@ -366,168 +570,207 @@
         (unspec:DI [(const_int 0)] UNSPEC_CLRDI))]
   "TARGET_REALLY_IWMMXT"
   "wxor%?\\t%0, %0, %0"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wxor")]
+)
 
 ;; Seems like cse likes to generate these, so we have to support them.
 
-(define_insn "*iwmmxt_clrv8qi"
-  [(set (match_operand:V8QI 0 "register_operand" "=y")
+(define_insn "iwmmxt_clrv8qi"
+  [(set (match_operand:V8QI 0 "s_register_operand" "=y")
         (const_vector:V8QI [(const_int 0) (const_int 0)
 			    (const_int 0) (const_int 0)
 			    (const_int 0) (const_int 0)
 			    (const_int 0) (const_int 0)]))]
   "TARGET_REALLY_IWMMXT"
   "wxor%?\\t%0, %0, %0"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wxor")]
+)
 
-(define_insn "*iwmmxt_clrv4hi"
-  [(set (match_operand:V4HI 0 "register_operand" "=y")
+(define_insn "iwmmxt_clrv4hi"
+  [(set (match_operand:V4HI 0 "s_register_operand" "=y")
         (const_vector:V4HI [(const_int 0) (const_int 0)
 			    (const_int 0) (const_int 0)]))]
   "TARGET_REALLY_IWMMXT"
   "wxor%?\\t%0, %0, %0"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wxor")]
+)
 
-(define_insn "*iwmmxt_clrv2si"
+(define_insn "iwmmxt_clrv2si"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
         (const_vector:V2SI [(const_int 0) (const_int 0)]))]
   "TARGET_REALLY_IWMMXT"
   "wxor%?\\t%0, %0, %0"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wxor")]
+)
 
 ;; Unsigned averages/sum of absolute differences
 
 (define_insn "iwmmxt_uavgrndv8qi3"
-  [(set (match_operand:V8QI              0 "register_operand" "=y")
-        (ashiftrt:V8QI
-	 (plus:V8QI (plus:V8QI
-		     (match_operand:V8QI 1 "register_operand" "y")
-		     (match_operand:V8QI 2 "register_operand" "y"))
-		    (const_vector:V8QI [(const_int 1)
-					(const_int 1)
-					(const_int 1)
-					(const_int 1)
-					(const_int 1)
-					(const_int 1)
-					(const_int 1)
-					(const_int 1)]))
-	 (const_int 1)))]
+  [(set (match_operand:V8QI                                    0 "register_operand" "=y")
+        (truncate:V8QI
+	  (lshiftrt:V8HI
+	    (plus:V8HI
+	      (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+	                 (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y")))
+	      (const_vector:V8HI [(const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)]))
+	    (const_int 1))))]
   "TARGET_REALLY_IWMMXT"
   "wavg2br%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wavg2")]
+)
 
 (define_insn "iwmmxt_uavgrndv4hi3"
-  [(set (match_operand:V4HI              0 "register_operand" "=y")
-        (ashiftrt:V4HI
-	 (plus:V4HI (plus:V4HI
-		     (match_operand:V4HI 1 "register_operand" "y")
-		     (match_operand:V4HI 2 "register_operand" "y"))
-		    (const_vector:V4HI [(const_int 1)
-					(const_int 1)
-					(const_int 1)
-					(const_int 1)]))
-	 (const_int 1)))]
+  [(set (match_operand:V4HI                                    0 "register_operand" "=y")
+        (truncate:V4HI
+	  (lshiftrt:V4SI
+            (plus:V4SI
+	      (plus:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                 (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+	      (const_vector:V4SI [(const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)
+	                          (const_int 1)]))
+	    (const_int 1))))]
   "TARGET_REALLY_IWMMXT"
   "wavg2hr%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wavg2")]
+)
 
 (define_insn "iwmmxt_uavgv8qi3"
-  [(set (match_operand:V8QI                 0 "register_operand" "=y")
-        (ashiftrt:V8QI (plus:V8QI
-			(match_operand:V8QI 1 "register_operand" "y")
-			(match_operand:V8QI 2 "register_operand" "y"))
-		       (const_int 1)))]
+  [(set (match_operand:V8QI                                  0 "register_operand" "=y")
+        (truncate:V8QI
+	  (lshiftrt:V8HI
+	    (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+	               (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y")))
+	    (const_int 1))))]
   "TARGET_REALLY_IWMMXT"
   "wavg2b%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wavg2")]
+)
 
 (define_insn "iwmmxt_uavgv4hi3"
-  [(set (match_operand:V4HI                 0 "register_operand" "=y")
-        (ashiftrt:V4HI (plus:V4HI
-			(match_operand:V4HI 1 "register_operand" "y")
-			(match_operand:V4HI 2 "register_operand" "y"))
-		       (const_int 1)))]
+  [(set (match_operand:V4HI                                  0 "register_operand" "=y")
+        (truncate:V4HI
+	  (lshiftrt:V4SI
+	    (plus:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	               (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+	    (const_int 1))))]
   "TARGET_REALLY_IWMMXT"
   "wavg2h%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "iwmmxt_psadbw"
-  [(set (match_operand:V8QI                       0 "register_operand" "=y")
-        (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
-			      (match_operand:V8QI 2 "register_operand" "y"))))]
-  "TARGET_REALLY_IWMMXT"
-  "psadbw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wavg2")]
+)
 
 ;; Insert/extract/shuffle
 
 (define_insn "iwmmxt_tinsrb"
-  [(set (match_operand:V8QI                             0 "register_operand"    "=y")
-        (vec_merge:V8QI (match_operand:V8QI             1 "register_operand"     "0")
-			(vec_duplicate:V8QI
-			 (truncate:QI (match_operand:SI 2 "nonimmediate_operand" "r")))
-			(match_operand:SI               3 "immediate_operand"    "i")))]
+  [(set (match_operand:V8QI                0 "register_operand" "=y")
+        (vec_merge:V8QI
+	  (vec_duplicate:V8QI
+	    (truncate:QI (match_operand:SI 2 "nonimmediate_operand" "r")))
+	  (match_operand:V8QI              1 "register_operand"     "0")
+	  (match_operand:SI                3 "immediate_operand"    "i")))]
   "TARGET_REALLY_IWMMXT"
-  "tinsrb%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  "*
+   {
+     return arm_output_iwmmxt_tinsr (operands);
+   }
+   "
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tinsr")]
+)
 
 (define_insn "iwmmxt_tinsrh"
-  [(set (match_operand:V4HI                             0 "register_operand"    "=y")
-        (vec_merge:V4HI (match_operand:V4HI             1 "register_operand"     "0")
-			(vec_duplicate:V4HI
-			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "r")))
-			(match_operand:SI               3 "immediate_operand"    "i")))]
+  [(set (match_operand:V4HI                0 "register_operand"    "=y")
+        (vec_merge:V4HI
+          (vec_duplicate:V4HI
+            (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "r")))
+	  (match_operand:V4HI              1 "register_operand"     "0")
+	  (match_operand:SI                3 "immediate_operand"    "i")))]
   "TARGET_REALLY_IWMMXT"
-  "tinsrh%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  "*
+   {
+     return arm_output_iwmmxt_tinsr (operands);
+   }
+   "
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tinsr")]
+)
 
 (define_insn "iwmmxt_tinsrw"
-  [(set (match_operand:V2SI                 0 "register_operand"    "=y")
-        (vec_merge:V2SI (match_operand:V2SI 1 "register_operand"     "0")
-			(vec_duplicate:V2SI
-			 (match_operand:SI  2 "nonimmediate_operand" "r"))
-			(match_operand:SI   3 "immediate_operand"    "i")))]
+  [(set (match_operand:V2SI   0 "register_operand"    "=y")
+        (vec_merge:V2SI
+          (vec_duplicate:V2SI
+            (match_operand:SI 2 "nonimmediate_operand" "r"))
+          (match_operand:V2SI 1 "register_operand"     "0")
+          (match_operand:SI   3 "immediate_operand"    "i")))]
   "TARGET_REALLY_IWMMXT"
-  "tinsrw%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  "*
+   {
+     return arm_output_iwmmxt_tinsr (operands);
+   }
+   "
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tinsr")]
+)
 
 (define_insn "iwmmxt_textrmub"
-  [(set (match_operand:SI                                  0 "register_operand" "=r")
-        (zero_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y")
-				       (parallel
-					[(match_operand:SI 2 "immediate_operand" "i")]))))]
+  [(set (match_operand:SI                                   0 "register_operand" "=r")
+        (zero_extend:SI (vec_select:QI (match_operand:V8QI  1 "register_operand" "y")
+		                       (parallel
+				         [(match_operand:SI 2 "immediate_operand" "i")]))))]
   "TARGET_REALLY_IWMMXT"
   "textrmub%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "textrm")]
+)
 
 (define_insn "iwmmxt_textrmsb"
-  [(set (match_operand:SI                                  0 "register_operand" "=r")
-        (sign_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y")
+  [(set (match_operand:SI                                   0 "register_operand" "=r")
+        (sign_extend:SI (vec_select:QI (match_operand:V8QI  1 "register_operand" "y")
 				       (parallel
-					[(match_operand:SI 2 "immediate_operand" "i")]))))]
+				         [(match_operand:SI 2 "immediate_operand" "i")]))))]
   "TARGET_REALLY_IWMMXT"
   "textrmsb%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "textrm")]
+)
 
 (define_insn "iwmmxt_textrmuh"
-  [(set (match_operand:SI                                  0 "register_operand" "=r")
-        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
+  [(set (match_operand:SI                                   0 "register_operand" "=r")
+        (zero_extend:SI (vec_select:HI (match_operand:V4HI  1 "register_operand" "y")
 				       (parallel
-					[(match_operand:SI 2 "immediate_operand" "i")]))))]
+				         [(match_operand:SI 2 "immediate_operand" "i")]))))]
   "TARGET_REALLY_IWMMXT"
   "textrmuh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "textrm")]
+)
 
 (define_insn "iwmmxt_textrmsh"
-  [(set (match_operand:SI                                  0 "register_operand" "=r")
-        (sign_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
+  [(set (match_operand:SI                                   0 "register_operand" "=r")
+        (sign_extend:SI (vec_select:HI (match_operand:V4HI  1 "register_operand" "y")
 				       (parallel
-					[(match_operand:SI 2 "immediate_operand" "i")]))))]
+				         [(match_operand:SI 2 "immediate_operand" "i")]))))]
   "TARGET_REALLY_IWMMXT"
   "textrmsh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "textrm")]
+)
 
 ;; There are signed/unsigned variants of this instruction, but they are
 ;; pointless.
@@ -537,7 +780,9 @@
 		       (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
   "TARGET_REALLY_IWMMXT"
   "textrmsw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "textrm")]
+)
 
 (define_insn "iwmmxt_wshufh"
   [(set (match_operand:V4HI               0 "register_operand" "=y")
@@ -545,7 +790,9 @@
 		      (match_operand:SI   2 "immediate_operand" "i")] UNSPEC_WSHUFH))]
   "TARGET_REALLY_IWMMXT"
   "wshufh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wshufh")]
+)
 
 ;; Mask-generating comparisons
 ;;
@@ -557,92 +804,106 @@
 ;; into the entire destination vector, (with the '1' going into the least
 ;; significant element of the vector).  This is not how these instructions
 ;; behave.
-;;
-;; Unfortunately the current patterns are illegal.  They are SET insns
-;; without a SET in them.  They work in most cases for ordinary code
-;; generation, but there are circumstances where they can cause gcc to fail.
-;; XXX - FIXME.
 
 (define_insn "eqv8qi3"
-  [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
-		     (match_operand:V8QI 1 "register_operand"  "y")
-		     (match_operand:V8QI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_EQ)]
+  [(set (match_operand:V8QI                        0 "register_operand" "=y")
+	(unspec_volatile:V8QI [(match_operand:V8QI 1 "register_operand"  "y")
+	                       (match_operand:V8QI 2 "register_operand"  "y")]
+	                      VUNSPEC_WCMP_EQ))]
   "TARGET_REALLY_IWMMXT"
   "wcmpeqb%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpeq")]
+)
 
 (define_insn "eqv4hi3"
-  [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
-		     (match_operand:V4HI 1 "register_operand"  "y")
-		     (match_operand:V4HI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_EQ)]
+  [(set (match_operand:V4HI                        0 "register_operand" "=y")
+	(unspec_volatile:V4HI [(match_operand:V4HI 1 "register_operand"  "y")
+		               (match_operand:V4HI 2 "register_operand"  "y")]
+	                       VUNSPEC_WCMP_EQ))]
   "TARGET_REALLY_IWMMXT"
   "wcmpeqh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpeq")]
+)
 
 (define_insn "eqv2si3"
-  [(unspec_volatile:V2SI [(match_operand:V2SI 0 "register_operand" "=y")
-			  (match_operand:V2SI 1 "register_operand"  "y")
-			  (match_operand:V2SI 2 "register_operand"  "y")]
-			 VUNSPEC_WCMP_EQ)]
+  [(set (match_operand:V2SI    0 "register_operand" "=y")
+	(unspec_volatile:V2SI
+	  [(match_operand:V2SI 1 "register_operand"  "y")
+	   (match_operand:V2SI 2 "register_operand"  "y")]
+           VUNSPEC_WCMP_EQ))]
   "TARGET_REALLY_IWMMXT"
   "wcmpeqw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpeq")]
+)
 
 (define_insn "gtuv8qi3"
-  [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
-		     (match_operand:V8QI 1 "register_operand"  "y")
-		     (match_operand:V8QI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_GTU)]
+  [(set (match_operand:V8QI                        0 "register_operand" "=y")
+	(unspec_volatile:V8QI [(match_operand:V8QI 1 "register_operand"  "y")
+	                       (match_operand:V8QI 2 "register_operand"  "y")]
+	                       VUNSPEC_WCMP_GTU))]
   "TARGET_REALLY_IWMMXT"
   "wcmpgtub%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpgt")]
+)
 
 (define_insn "gtuv4hi3"
-  [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
-		     (match_operand:V4HI 1 "register_operand"  "y")
-		     (match_operand:V4HI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_GTU)]
+  [(set (match_operand:V4HI                        0 "register_operand" "=y")
+        (unspec_volatile:V4HI [(match_operand:V4HI 1 "register_operand"  "y")
+                               (match_operand:V4HI 2 "register_operand"  "y")]
+                               VUNSPEC_WCMP_GTU))]
   "TARGET_REALLY_IWMMXT"
   "wcmpgtuh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpgt")]
+)
 
 (define_insn "gtuv2si3"
-  [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y")
-		     (match_operand:V2SI 1 "register_operand"  "y")
-		     (match_operand:V2SI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_GTU)]
+  [(set (match_operand:V2SI                        0 "register_operand" "=y")
+	(unspec_volatile:V2SI [(match_operand:V2SI 1 "register_operand"  "y")
+	                       (match_operand:V2SI 2 "register_operand"  "y")]
+	                       VUNSPEC_WCMP_GTU))]
   "TARGET_REALLY_IWMMXT"
   "wcmpgtuw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpgt")]
+)
 
 (define_insn "gtv8qi3"
-  [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
-		     (match_operand:V8QI 1 "register_operand"  "y")
-		     (match_operand:V8QI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_GT)]
+  [(set (match_operand:V8QI                        0 "register_operand" "=y")
+	(unspec_volatile:V8QI [(match_operand:V8QI 1 "register_operand"  "y")
+	                       (match_operand:V8QI 2 "register_operand"  "y")]
+	                       VUNSPEC_WCMP_GT))]
   "TARGET_REALLY_IWMMXT"
   "wcmpgtsb%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpgt")]
+)
 
 (define_insn "gtv4hi3"
-  [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
-		     (match_operand:V4HI 1 "register_operand"  "y")
-		     (match_operand:V4HI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_GT)]
+  [(set (match_operand:V4HI                        0 "register_operand" "=y")
+	(unspec_volatile:V4HI [(match_operand:V4HI 1 "register_operand"  "y")
+	                       (match_operand:V4HI 2 "register_operand"  "y")]
+	                       VUNSPEC_WCMP_GT))]
   "TARGET_REALLY_IWMMXT"
   "wcmpgtsh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpgt")]
+)
 
 (define_insn "gtv2si3"
-  [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y")
-		     (match_operand:V2SI 1 "register_operand"  "y")
-		     (match_operand:V2SI 2 "register_operand"  "y")]
-		    VUNSPEC_WCMP_GT)]
+  [(set (match_operand:V2SI                        0 "register_operand" "=y")
+	(unspec_volatile:V2SI [(match_operand:V2SI 1 "register_operand"  "y")
+	                       (match_operand:V2SI 2 "register_operand"  "y")]
+	                       VUNSPEC_WCMP_GT))]
   "TARGET_REALLY_IWMMXT"
   "wcmpgtsw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wcmpgt")]
+)
 
 ;; Max/min insns
 
@@ -652,7 +913,9 @@
 		   (match_operand:VMMX 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wmaxs<MMX_char>%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmax")]
+)
 
 (define_insn "*umax<mode>3_iwmmxt"
   [(set (match_operand:VMMX            0 "register_operand" "=y")
@@ -660,7 +923,9 @@
 		   (match_operand:VMMX 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wmaxu<MMX_char>%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmax")]
+)
 
 (define_insn "*smin<mode>3_iwmmxt"
   [(set (match_operand:VMMX            0 "register_operand" "=y")
@@ -668,7 +933,9 @@
 		   (match_operand:VMMX 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wmins<MMX_char>%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmin")]
+)
 
 (define_insn "*umin<mode>3_iwmmxt"
   [(set (match_operand:VMMX            0 "register_operand" "=y")
@@ -676,657 +943,835 @@
 		   (match_operand:VMMX 2 "register_operand" "y")))]
   "TARGET_REALLY_IWMMXT"
   "wminu<MMX_char>%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmin")]
+)
 
 ;; Pack/unpack insns.
 
 (define_insn "iwmmxt_wpackhss"
-  [(set (match_operand:V8QI                    0 "register_operand" "=y")
+  [(set (match_operand:V8QI                     0 "register_operand" "=y")
 	(vec_concat:V8QI
-	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
-	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
+	  (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
+	  (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wpackhss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wpack")]
+)
 
 (define_insn "iwmmxt_wpackwss"
-  [(set (match_operand:V4HI                    0 "register_operand" "=y")
-	(vec_concat:V4HI
-	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
-	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
+  [(set (match_operand:V4HI                     0 "register_operand" "=y")
+        (vec_concat:V4HI
+	  (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
+	  (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wpackwss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wpack")]
+)
 
 (define_insn "iwmmxt_wpackdss"
-  [(set (match_operand:V2SI                0 "register_operand" "=y")
+  [(set (match_operand:V2SI                 0 "register_operand" "=y")
 	(vec_concat:V2SI
-	 (ss_truncate:SI (match_operand:DI 1 "register_operand" "y"))
-	 (ss_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
+	  (ss_truncate:SI (match_operand:DI 1 "register_operand" "y"))
+	  (ss_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wpackdss%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wpack")]
+)
 
 (define_insn "iwmmxt_wpackhus"
-  [(set (match_operand:V8QI                    0 "register_operand" "=y")
+  [(set (match_operand:V8QI                     0 "register_operand" "=y")
 	(vec_concat:V8QI
-	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
-	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
+	  (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
+	  (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wpackhus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wpack")]
+)
 
 (define_insn "iwmmxt_wpackwus"
-  [(set (match_operand:V4HI                    0 "register_operand" "=y")
+  [(set (match_operand:V4HI                     0 "register_operand" "=y")
 	(vec_concat:V4HI
-	 (us_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
-	 (us_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
+	  (us_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
+	  (us_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wpackwus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wpack")]
+)
 
 (define_insn "iwmmxt_wpackdus"
-  [(set (match_operand:V2SI                0 "register_operand" "=y")
+  [(set (match_operand:V2SI                 0 "register_operand" "=y")
 	(vec_concat:V2SI
-	 (us_truncate:SI (match_operand:DI 1 "register_operand" "y"))
-	 (us_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
+	  (us_truncate:SI (match_operand:DI 1 "register_operand" "y"))
+	  (us_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
   "TARGET_REALLY_IWMMXT"
   "wpackdus%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wpack")]
+)
 
 (define_insn "iwmmxt_wunpckihb"
-  [(set (match_operand:V8QI                   0 "register_operand" "=y")
+  [(set (match_operand:V8QI                                      0 "register_operand" "=y")
 	(vec_merge:V8QI
-	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
-			  (parallel [(const_int 4)
-				     (const_int 0)
-				     (const_int 5)
-				     (const_int 1)
-				     (const_int 6)
-				     (const_int 2)
-				     (const_int 7)
-				     (const_int 3)]))
-	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
-			  (parallel [(const_int 0)
-				     (const_int 4)
-				     (const_int 1)
-				     (const_int 5)
-				     (const_int 2)
-				     (const_int 6)
-				     (const_int 3)
-				     (const_int 7)]))
-	 (const_int 85)))]
+	  (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
+		           (parallel [(const_int 4)
+			              (const_int 0)
+			              (const_int 5)
+			              (const_int 1)
+			              (const_int 6)
+			              (const_int 2)
+			              (const_int 7)
+			              (const_int 3)]))
+          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
+			   (parallel [(const_int 0)
+			              (const_int 4)
+			              (const_int 1)
+			              (const_int 5)
+			              (const_int 2)
+			              (const_int 6)
+			              (const_int 3)
+			              (const_int 7)]))
+          (const_int 85)))]
   "TARGET_REALLY_IWMMXT"
   "wunpckihb%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckih")]
+)
 
 (define_insn "iwmmxt_wunpckihh"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
+  [(set (match_operand:V4HI                                      0 "register_operand" "=y")
 	(vec_merge:V4HI
-	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
-			  (parallel [(const_int 0)
-				     (const_int 2)
-				     (const_int 1)
-				     (const_int 3)]))
-	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
-			  (parallel [(const_int 2)
-				     (const_int 0)
-				     (const_int 3)
-				     (const_int 1)]))
-	 (const_int 5)))]
+	  (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
+		           (parallel [(const_int 2)
+			              (const_int 0)
+			              (const_int 3)
+			              (const_int 1)]))
+	  (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+		           (parallel [(const_int 0)
+			              (const_int 2)
+			              (const_int 1)
+			              (const_int 3)]))
+          (const_int 5)))]
   "TARGET_REALLY_IWMMXT"
   "wunpckihh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckih")]
+)
 
 (define_insn "iwmmxt_wunpckihw"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
+  [(set (match_operand:V2SI                    0 "register_operand" "=y")
 	(vec_merge:V2SI
-	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
-			  (parallel [(const_int 0)
-				     (const_int 1)]))
-	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
-			  (parallel [(const_int 1)
-				     (const_int 0)]))
-	 (const_int 1)))]
+	  (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
+		           (parallel [(const_int 1)
+		                      (const_int 0)]))
+          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
+		           (parallel [(const_int 0)
+			              (const_int 1)]))
+          (const_int 1)))]
   "TARGET_REALLY_IWMMXT"
   "wunpckihw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckih")]
+)
 
 (define_insn "iwmmxt_wunpckilb"
-  [(set (match_operand:V8QI                   0 "register_operand" "=y")
+  [(set (match_operand:V8QI                                      0 "register_operand" "=y")
 	(vec_merge:V8QI
-	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
-			  (parallel [(const_int 0)
-				     (const_int 4)
-				     (const_int 1)
-				     (const_int 5)
-				     (const_int 2)
-				     (const_int 6)
-				     (const_int 3)
-				     (const_int 7)]))
-	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
-			  (parallel [(const_int 4)
-				     (const_int 0)
-				     (const_int 5)
-				     (const_int 1)
-				     (const_int 6)
-				     (const_int 2)
-				     (const_int 7)
-				     (const_int 3)]))
-	 (const_int 85)))]
+	  (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
+		           (parallel [(const_int 0)
+			              (const_int 4)
+			              (const_int 1)
+			              (const_int 5)
+		                      (const_int 2)
+				      (const_int 6)
+				      (const_int 3)
+				      (const_int 7)]))
+	  (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
+		           (parallel [(const_int 4)
+			              (const_int 0)
+			              (const_int 5)
+			              (const_int 1)
+			              (const_int 6)
+			              (const_int 2)
+			              (const_int 7)
+			              (const_int 3)]))
+	  (const_int 85)))]
   "TARGET_REALLY_IWMMXT"
   "wunpckilb%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckil")]
+)
 
 (define_insn "iwmmxt_wunpckilh"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
+  [(set (match_operand:V4HI                                      0 "register_operand" "=y")
 	(vec_merge:V4HI
-	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
-			  (parallel [(const_int 2)
-				     (const_int 0)
-				     (const_int 3)
-				     (const_int 1)]))
-	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
-			  (parallel [(const_int 0)
-				     (const_int 2)
-				     (const_int 1)
-				     (const_int 3)]))
-	 (const_int 5)))]
+	  (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
+		           (parallel [(const_int 0)
+			              (const_int 2)
+			              (const_int 1)
+			              (const_int 3)]))
+	  (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+			   (parallel [(const_int 2)
+			              (const_int 0)
+			              (const_int 3)
+			              (const_int 1)]))
+	  (const_int 5)))]
   "TARGET_REALLY_IWMMXT"
   "wunpckilh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckil")]
+)
 
 (define_insn "iwmmxt_wunpckilw"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
+  [(set (match_operand:V2SI                    0 "register_operand" "=y")
 	(vec_merge:V2SI
-	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
-			   (parallel [(const_int 1)
-				      (const_int 0)]))
-	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
-			  (parallel [(const_int 0)
-				     (const_int 1)]))
-	 (const_int 1)))]
+	  (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
+		           (parallel [(const_int 0)
+				      (const_int 1)]))
+	  (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
+		           (parallel [(const_int 1)
+			              (const_int 0)]))
+	  (const_int 1)))]
   "TARGET_REALLY_IWMMXT"
   "wunpckilw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckil")]
+)
 
 (define_insn "iwmmxt_wunpckehub"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
-	(zero_extend:V4HI
-	 (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
-			  (parallel [(const_int 4) (const_int 5)
-				     (const_int 6) (const_int 7)]))))]
+  [(set (match_operand:V4HI                     0 "register_operand" "=y")
+	(vec_select:V4HI
+	  (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+	  (parallel [(const_int 4) (const_int 5)
+	             (const_int 6) (const_int 7)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckehub%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckeh")]
+)
 
 (define_insn "iwmmxt_wunpckehuh"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
-	(zero_extend:V2SI
-	 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
-			  (parallel [(const_int 2) (const_int 3)]))))]
+  [(set (match_operand:V2SI                     0 "register_operand" "=y")
+	(vec_select:V2SI
+	  (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	  (parallel [(const_int 2) (const_int 3)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckehuh%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckeh")]
+)
 
 (define_insn "iwmmxt_wunpckehuw"
-  [(set (match_operand:DI                   0 "register_operand" "=y")
-	(zero_extend:DI
-	 (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
-			(parallel [(const_int 1)]))))]
+  [(set (match_operand:DI                       0 "register_operand" "=y")
+	(vec_select:DI
+	  (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+	  (parallel [(const_int 1)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckehuw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckeh")]
+)
 
 (define_insn "iwmmxt_wunpckehsb"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
-	(sign_extend:V4HI
-	 (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
-			  (parallel [(const_int 4) (const_int 5)
-				     (const_int 6) (const_int 7)]))))]
+  [(set (match_operand:V4HI                     0 "register_operand" "=y")
+        (vec_select:V4HI
+	  (sign_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+	  (parallel [(const_int 4) (const_int 5)
+	             (const_int 6) (const_int 7)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckehsb%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckeh")]
+)
 
 (define_insn "iwmmxt_wunpckehsh"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
-	(sign_extend:V2SI
-	 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
-			  (parallel [(const_int 2) (const_int 3)]))))]
+  [(set (match_operand:V2SI                     0 "register_operand" "=y")
+	(vec_select:V2SI
+	  (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	  (parallel [(const_int 2) (const_int 3)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckehsh%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckeh")]
+)
 
 (define_insn "iwmmxt_wunpckehsw"
-  [(set (match_operand:DI                   0 "register_operand" "=y")
-	(sign_extend:DI
-	 (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
-			(parallel [(const_int 1)]))))]
+  [(set (match_operand:DI                       0 "register_operand" "=y")
+	(vec_select:DI
+	  (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+	  (parallel [(const_int 1)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckehsw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckeh")]
+)
 
 (define_insn "iwmmxt_wunpckelub"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
-	(zero_extend:V4HI
-	 (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
-			  (parallel [(const_int 0) (const_int 1)
-				     (const_int 2) (const_int 3)]))))]
+  [(set (match_operand:V4HI                     0 "register_operand" "=y")
+	(vec_select:V4HI
+	  (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+	  (parallel [(const_int 0) (const_int 1)
+		     (const_int 2) (const_int 3)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckelub%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckel")]
+)
 
 (define_insn "iwmmxt_wunpckeluh"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
-	(zero_extend:V2SI
-	 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
-			  (parallel [(const_int 0) (const_int 1)]))))]
+  [(set (match_operand:V2SI                     0 "register_operand" "=y")
+	(vec_select:V2SI
+	  (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	  (parallel [(const_int 0) (const_int 1)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckeluh%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckel")]
+)
 
 (define_insn "iwmmxt_wunpckeluw"
-  [(set (match_operand:DI                   0 "register_operand" "=y")
-	(zero_extend:DI
-	 (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
-			(parallel [(const_int 0)]))))]
+  [(set (match_operand:DI                       0 "register_operand" "=y")
+	(vec_select:DI
+	  (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+	  (parallel [(const_int 0)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckeluw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckel")]
+)
 
 (define_insn "iwmmxt_wunpckelsb"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
-	(sign_extend:V4HI
-	 (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
-			  (parallel [(const_int 0) (const_int 1)
-				     (const_int 2) (const_int 3)]))))]
+  [(set (match_operand:V4HI                     0 "register_operand" "=y")
+	(vec_select:V4HI
+	  (sign_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+	  (parallel [(const_int 0) (const_int 1)
+		     (const_int 2) (const_int 3)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckelsb%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckel")]
+)
 
 (define_insn "iwmmxt_wunpckelsh"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
-	(sign_extend:V2SI
-	 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
-			  (parallel [(const_int 0) (const_int 1)]))))]
+  [(set (match_operand:V2SI                     0 "register_operand" "=y")
+	(vec_select:V2SI
+	  (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	  (parallel [(const_int 0) (const_int 1)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckelsh%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckel")]
+)
 
 (define_insn "iwmmxt_wunpckelsw"
-  [(set (match_operand:DI                   0 "register_operand" "=y")
-	(sign_extend:DI
-	 (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
-			(parallel [(const_int 0)]))))]
+  [(set (match_operand:DI                       0 "register_operand" "=y")
+        (vec_select:DI
+	  (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+	  (parallel [(const_int 0)])))]
   "TARGET_REALLY_IWMMXT"
   "wunpckelsw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wunpckel")]
+)
 
 ;; Shifts
 
-(define_insn "rorv4hi3"
-  [(set (match_operand:V4HI                0 "register_operand" "=y")
-        (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y")
-		       (match_operand:SI   2 "register_operand" "z")))]
-  "TARGET_REALLY_IWMMXT"
-  "wrorhg%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "rorv2si3"
-  [(set (match_operand:V2SI                0 "register_operand" "=y")
-        (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y")
-		       (match_operand:SI   2 "register_operand" "z")))]
-  "TARGET_REALLY_IWMMXT"
-  "wrorwg%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "rordi3"
-  [(set (match_operand:DI              0 "register_operand" "=y")
-	(rotatert:DI (match_operand:DI 1 "register_operand" "y")
-		   (match_operand:SI   2 "register_operand" "z")))]
+(define_insn "ror<mode>3"
+  [(set (match_operand:VSHFT                 0 "register_operand" "=y,y")
+        (rotatert:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+		        (match_operand:SI    2 "imm_or_reg_operand" "z,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wrordg%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch  (which_alternative)
+    {
+    case 0:
+      return \"wror<MMX_char>g%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wror<MMX_char>\", operands, true);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wror, wror")]
+)
 
 (define_insn "ashr<mode>3_iwmmxt"
-  [(set (match_operand:VSHFT                 0 "register_operand" "=y")
-        (ashiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y")
-			(match_operand:SI    2 "register_operand" "z")))]
+  [(set (match_operand:VSHFT                 0 "register_operand" "=y,y")
+        (ashiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+			(match_operand:SI    2 "imm_or_reg_operand" "z,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wsra<MMX_char>g%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch  (which_alternative)
+    {
+    case 0:
+      return \"wsra<MMX_char>g%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wsra<MMX_char>\", operands, true);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wsra, wsra")]
+)
 
 (define_insn "lshr<mode>3_iwmmxt"
-  [(set (match_operand:VSHFT                 0 "register_operand" "=y")
-        (lshiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y")
-			(match_operand:SI    2 "register_operand" "z")))]
+  [(set (match_operand:VSHFT                 0 "register_operand" "=y,y")
+        (lshiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+			(match_operand:SI    2 "imm_or_reg_operand" "z,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wsrl<MMX_char>g%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch  (which_alternative)
+    {
+    case 0:
+      return \"wsrl<MMX_char>g%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wsrl<MMX_char>\", operands, false);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wsrl, wsrl")]
+)
 
 (define_insn "ashl<mode>3_iwmmxt"
-  [(set (match_operand:VSHFT               0 "register_operand" "=y")
-        (ashift:VSHFT (match_operand:VSHFT 1 "register_operand" "y")
-		      (match_operand:SI    2 "register_operand" "z")))]
-  "TARGET_REALLY_IWMMXT"
-  "wsll<MMX_char>g%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "rorv4hi3_di"
-  [(set (match_operand:V4HI                0 "register_operand" "=y")
-        (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y")
-		       (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wrorh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "rorv2si3_di"
-  [(set (match_operand:V2SI                0 "register_operand" "=y")
-        (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y")
-		       (match_operand:DI   2 "register_operand" "y")))]
+  [(set (match_operand:VSHFT               0 "register_operand" "=y,y")
+        (ashift:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+		      (match_operand:SI    2 "imm_or_reg_operand" "z,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wrorw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "rordi3_di"
-  [(set (match_operand:DI              0 "register_operand" "=y")
-	(rotatert:DI (match_operand:DI 1 "register_operand" "y")
-		   (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wrord%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "ashrv4hi3_di"
-  [(set (match_operand:V4HI                0 "register_operand" "=y")
-        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
-		       (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wsrah%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "ashrv2si3_di"
-  [(set (match_operand:V2SI                0 "register_operand" "=y")
-        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
-		       (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wsraw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "ashrdi3_di"
-  [(set (match_operand:DI              0 "register_operand" "=y")
-	(ashiftrt:DI (match_operand:DI 1 "register_operand" "y")
-		   (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wsrad%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "lshrv4hi3_di"
-  [(set (match_operand:V4HI                0 "register_operand" "=y")
-        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
-		       (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wsrlh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "lshrv2si3_di"
-  [(set (match_operand:V2SI                0 "register_operand" "=y")
-        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
-		       (match_operand:DI   2 "register_operand" "y")))]
-  "TARGET_REALLY_IWMMXT"
-  "wsrlw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch  (which_alternative)
+    {
+    case 0:
+      return \"wsll<MMX_char>g%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wsll<MMX_char>\", operands, false);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wsll, wsll")]
+)
 
-(define_insn "lshrdi3_di"
-  [(set (match_operand:DI              0 "register_operand" "=y")
-	(lshiftrt:DI (match_operand:DI 1 "register_operand" "y")
-		     (match_operand:DI 2 "register_operand" "y")))]
+(define_insn "ror<mode>3_di"
+  [(set (match_operand:VSHFT                 0 "register_operand" "=y,y")
+        (rotatert:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+		        (match_operand:DI    2 "imm_or_reg_operand" "y,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wsrld%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch (which_alternative)
+    {
+    case 0:
+      return \"wror<MMX_char>%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wror<MMX_char>\", operands, true);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wror, wror")]
+)
 
-(define_insn "ashlv4hi3_di"
-  [(set (match_operand:V4HI              0 "register_operand" "=y")
-        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "y")
-		     (match_operand:DI   2 "register_operand" "y")))]
+(define_insn "ashr<mode>3_di"
+  [(set (match_operand:VSHFT                 0 "register_operand" "=y,y")
+        (ashiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+		        (match_operand:DI    2 "imm_or_reg_operand" "y,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wsllh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch (which_alternative)
+    {
+    case 0:
+      return \"wsra<MMX_char>%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wsra<MMX_char>\", operands, true);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wsra, wsra")]
+)
 
-(define_insn "ashlv2si3_di"
-  [(set (match_operand:V2SI              0 "register_operand" "=y")
-        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "y")
-		       (match_operand:DI 2 "register_operand" "y")))]
+(define_insn "lshr<mode>3_di"
+  [(set (match_operand:VSHFT                 0 "register_operand" "=y,y")
+        (lshiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+		        (match_operand:DI    2 "register_operand" "y,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wsllw%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch (which_alternative)
+    {
+    case 0:
+      return \"wsrl<MMX_char>%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wsrl<MMX_char>\", operands, false);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wsrl, wsrl")]
+)
 
-(define_insn "ashldi3_di"
-  [(set (match_operand:DI            0 "register_operand" "=y")
-	(ashift:DI (match_operand:DI 1 "register_operand" "y")
-		   (match_operand:DI 2 "register_operand" "y")))]
+(define_insn "ashl<mode>3_di"
+  [(set (match_operand:VSHFT               0 "register_operand" "=y,y")
+        (ashift:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y")
+		      (match_operand:DI    2 "imm_or_reg_operand" "y,i")))]
   "TARGET_REALLY_IWMMXT"
-  "wslld%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "*
+  switch (which_alternative)
+    {
+    case 0:
+      return \"wsll<MMX_char>%?\\t%0, %1, %2\";
+    case 1:
+      return arm_output_iwmmxt_shift_immediate (\"wsll<MMX_char>\", operands, false);
+    default:
+      gcc_unreachable ();
+    }
+  "
+  [(set_attr "predicable" "yes")
+   (set_attr "arch" "*, iwmmxt2")
+   (set_attr "wtype" "wsll, wsll")]
+)
 
 (define_insn "iwmmxt_wmadds"
-  [(set (match_operand:V4HI               0 "register_operand" "=y")
-        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
-		      (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDS))]
+  [(set (match_operand:V2SI                                        0 "register_operand" "=y")
+	(plus:V2SI
+	  (mult:V2SI
+	    (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                     (parallel [(const_int 1) (const_int 3)]))
+	    (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))
+	                     (parallel [(const_int 1) (const_int 3)])))
+	  (mult:V2SI
+	    (vec_select:V2SI (sign_extend:V4SI (match_dup 1))
+	                     (parallel [(const_int 0) (const_int 2)]))
+	    (vec_select:V2SI (sign_extend:V4SI (match_dup 2))
+	                     (parallel [(const_int 0) (const_int 2)])))))]
   "TARGET_REALLY_IWMMXT"
   "wmadds%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmadd")]
+)
 
 (define_insn "iwmmxt_wmaddu"
-  [(set (match_operand:V4HI               0 "register_operand" "=y")
-        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
-		      (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDU))]
+  [(set (match_operand:V2SI               0 "register_operand" "=y")
+	(plus:V2SI
+	  (mult:V2SI
+	    (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                     (parallel [(const_int 1) (const_int 3)]))
+	    (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))
+	                     (parallel [(const_int 1) (const_int 3)])))
+	  (mult:V2SI
+	    (vec_select:V2SI (zero_extend:V4SI (match_dup 1))
+	                     (parallel [(const_int 0) (const_int 2)]))
+	    (vec_select:V2SI (zero_extend:V4SI (match_dup 2))
+	                     (parallel [(const_int 0) (const_int 2)])))))]
   "TARGET_REALLY_IWMMXT"
   "wmaddu%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmadd")]
+)
 
 (define_insn "iwmmxt_tmia"
-  [(set (match_operand:DI                    0 "register_operand" "=y")
-	(plus:DI (match_operand:DI           1 "register_operand" "0")
+  [(set (match_operand:DI                     0 "register_operand" "=y")
+	(plus:DI (match_operand:DI            1 "register_operand" "0")
 		 (mult:DI (sign_extend:DI
-			   (match_operand:SI 2 "register_operand" "r"))
+			    (match_operand:SI 2 "register_operand" "r"))
 			  (sign_extend:DI
-			   (match_operand:SI 3 "register_operand" "r")))))]
+			    (match_operand:SI 3 "register_operand" "r")))))]
   "TARGET_REALLY_IWMMXT"
   "tmia%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmia")]
+)
 
 (define_insn "iwmmxt_tmiaph"
-  [(set (match_operand:DI          0 "register_operand" "=y")
-	(plus:DI (match_operand:DI 1 "register_operand" "0")
+  [(set (match_operand:DI                                    0 "register_operand" "=y")
+	(plus:DI (match_operand:DI                           1 "register_operand" "0")
 		 (plus:DI
-		  (mult:DI (sign_extend:DI
-			    (truncate:HI (match_operand:SI 2 "register_operand" "r")))
-			   (sign_extend:DI
-			    (truncate:HI (match_operand:SI 3 "register_operand" "r"))))
-		  (mult:DI (sign_extend:DI
-			    (truncate:HI (ashiftrt:SI (match_dup 2) (const_int 16))))
-			   (sign_extend:DI
-			    (truncate:HI (ashiftrt:SI (match_dup 3) (const_int 16))))))))]
+		   (mult:DI (sign_extend:DI
+			      (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+			    (sign_extend:DI
+			      (truncate:HI (match_operand:SI 3 "register_operand" "r"))))
+		   (mult:DI (sign_extend:DI
+			      (truncate:HI (ashiftrt:SI (match_dup 2) (const_int 16))))
+			    (sign_extend:DI
+			      (truncate:HI (ashiftrt:SI (match_dup 3) (const_int 16))))))))]
   "TARGET_REALLY_IWMMXT"
   "tmiaph%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmiaph")]
+)
 
 (define_insn "iwmmxt_tmiabb"
-  [(set (match_operand:DI          0 "register_operand" "=y")
-	(plus:DI (match_operand:DI 1 "register_operand" "0")
+  [(set (match_operand:DI                                  0 "register_operand" "=y")
+	(plus:DI (match_operand:DI                         1 "register_operand" "0")
 		 (mult:DI (sign_extend:DI
-			   (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+			    (truncate:HI (match_operand:SI 2 "register_operand" "r")))
 			  (sign_extend:DI
-			   (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
+			    (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
   "TARGET_REALLY_IWMMXT"
   "tmiabb%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmiaxy")]
+)
 
 (define_insn "iwmmxt_tmiatb"
-  [(set (match_operand:DI          0 "register_operand" "=y")
-	(plus:DI (match_operand:DI 1 "register_operand" "0")
+  [(set (match_operand:DI                         0 "register_operand" "=y")
+	(plus:DI (match_operand:DI                1 "register_operand" "0")
 		 (mult:DI (sign_extend:DI
-			   (truncate:HI (ashiftrt:SI
-					 (match_operand:SI 2 "register_operand" "r")
-					 (const_int 16))))
+			    (truncate:HI
+			      (ashiftrt:SI
+				(match_operand:SI 2 "register_operand" "r")
+				(const_int 16))))
 			  (sign_extend:DI
-			   (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
+			    (truncate:HI
+			      (match_operand:SI   3 "register_operand" "r"))))))]
   "TARGET_REALLY_IWMMXT"
   "tmiatb%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmiaxy")]
+)
 
 (define_insn "iwmmxt_tmiabt"
-  [(set (match_operand:DI          0 "register_operand" "=y")
-	(plus:DI (match_operand:DI 1 "register_operand" "0")
+  [(set (match_operand:DI                         0 "register_operand" "=y")
+	(plus:DI (match_operand:DI                1 "register_operand" "0")
 		 (mult:DI (sign_extend:DI
-			   (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+			    (truncate:HI
+			      (match_operand:SI   2 "register_operand" "r")))
 			  (sign_extend:DI
-			   (truncate:HI (ashiftrt:SI
-					 (match_operand:SI 3 "register_operand" "r")
-					 (const_int 16)))))))]
+			    (truncate:HI
+			      (ashiftrt:SI
+				(match_operand:SI 3 "register_operand" "r")
+				(const_int 16)))))))]
   "TARGET_REALLY_IWMMXT"
   "tmiabt%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmiaxy")]
+)
 
 (define_insn "iwmmxt_tmiatt"
   [(set (match_operand:DI          0 "register_operand" "=y")
 	(plus:DI (match_operand:DI 1 "register_operand" "0")
 		 (mult:DI (sign_extend:DI
-			   (truncate:HI (ashiftrt:SI
-					 (match_operand:SI 2 "register_operand" "r")
-					 (const_int 16))))
+			    (truncate:HI
+			      (ashiftrt:SI
+				(match_operand:SI 2 "register_operand" "r")
+				(const_int 16))))
 			  (sign_extend:DI
-			   (truncate:HI (ashiftrt:SI
-					 (match_operand:SI 3 "register_operand" "r")
-					 (const_int 16)))))))]
+			    (truncate:HI
+			      (ashiftrt:SI
+				(match_operand:SI 3 "register_operand" "r")
+				(const_int 16)))))))]
   "TARGET_REALLY_IWMMXT"
   "tmiatt%?\\t%0, %2, %3"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "iwmmxt_tbcstqi"
-  [(set (match_operand:V8QI                   0 "register_operand" "=y")
-	(vec_duplicate:V8QI (match_operand:QI 1 "register_operand" "r")))]
-  "TARGET_REALLY_IWMMXT"
-  "tbcstb%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "iwmmxt_tbcsthi"
-  [(set (match_operand:V4HI                   0 "register_operand" "=y")
-	(vec_duplicate:V4HI (match_operand:HI 1 "register_operand" "r")))]
-  "TARGET_REALLY_IWMMXT"
-  "tbcsth%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
-
-(define_insn "iwmmxt_tbcstsi"
-  [(set (match_operand:V2SI                   0 "register_operand" "=y")
-	(vec_duplicate:V2SI (match_operand:SI 1 "register_operand" "r")))]
-  "TARGET_REALLY_IWMMXT"
-  "tbcstw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmiaxy")]
+)
 
 (define_insn "iwmmxt_tmovmskb"
   [(set (match_operand:SI               0 "register_operand" "=r")
 	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
   "TARGET_REALLY_IWMMXT"
   "tmovmskb%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmovmsk")]
+)
 
 (define_insn "iwmmxt_tmovmskh"
   [(set (match_operand:SI               0 "register_operand" "=r")
 	(unspec:SI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
   "TARGET_REALLY_IWMMXT"
   "tmovmskh%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmovmsk")]
+)
 
 (define_insn "iwmmxt_tmovmskw"
   [(set (match_operand:SI               0 "register_operand" "=r")
 	(unspec:SI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
   "TARGET_REALLY_IWMMXT"
   "tmovmskw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tmovmsk")]
+)
 
 (define_insn "iwmmxt_waccb"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_WACC))]
   "TARGET_REALLY_IWMMXT"
   "waccb%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wacc")]
+)
 
 (define_insn "iwmmxt_wacch"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_WACC))]
   "TARGET_REALLY_IWMMXT"
   "wacch%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wacc")]
+)
 
 (define_insn "iwmmxt_waccw"
   [(set (match_operand:DI               0 "register_operand" "=y")
 	(unspec:DI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_WACC))]
   "TARGET_REALLY_IWMMXT"
   "waccw%?\\t%0, %1"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wacc")]
+)
 
-(define_insn "iwmmxt_walign"
-  [(set (match_operand:V8QI                           0 "register_operand" "=y,y")
+;; use unspec here to prevent 8 * imm to be optimized by cse
+(define_insn "iwmmxt_waligni"
+  [(set (match_operand:V8QI                                0 "register_operand" "=y")
+	(unspec:V8QI [(subreg:V8QI
+		        (ashiftrt:TI
+		          (subreg:TI (vec_concat:V16QI
+				       (match_operand:V8QI 1 "register_operand" "y")
+				       (match_operand:V8QI 2 "register_operand" "y")) 0)
+		          (mult:SI
+		            (match_operand:SI              3 "immediate_operand" "i")
+		            (const_int 8))) 0)] UNSPEC_WALIGNI))]
+  "TARGET_REALLY_IWMMXT"
+  "waligni%?\\t%0, %1, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "waligni")]
+)
+
+(define_insn "iwmmxt_walignr"
+  [(set (match_operand:V8QI                           0 "register_operand" "=y")
 	(subreg:V8QI (ashiftrt:TI
-		      (subreg:TI (vec_concat:V16QI
-				  (match_operand:V8QI 1 "register_operand" "y,y")
-				  (match_operand:V8QI 2 "register_operand" "y,y")) 0)
-		      (mult:SI
-		       (match_operand:SI              3 "nonmemory_operand" "i,z")
-		       (const_int 8))) 0))]
-  "TARGET_REALLY_IWMMXT"
-  "@
-   waligni%?\\t%0, %1, %2, %3
-   walignr%U3%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+		       (subreg:TI (vec_concat:V16QI
+				    (match_operand:V8QI 1 "register_operand" "y")
+				    (match_operand:V8QI 2 "register_operand" "y")) 0)
+		       (mult:SI
+		         (zero_extract:SI (match_operand:SI 3 "register_operand" "z") (const_int 3) (const_int 0))
+		         (const_int 8))) 0))]
+  "TARGET_REALLY_IWMMXT"
+  "walignr%U3%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "walignr")]
+)
 
-(define_insn "iwmmxt_tmrc"
-  [(set (match_operand:SI                      0 "register_operand" "=r")
-	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")]
-			    VUNSPEC_TMRC))]
-  "TARGET_REALLY_IWMMXT"
-  "tmrc%?\\t%0, %w1"
-  [(set_attr "predicable" "yes")])
+(define_insn "iwmmxt_walignr0"
+  [(set (match_operand:V8QI                           0 "register_operand" "=y")
+	(subreg:V8QI (ashiftrt:TI
+		       (subreg:TI (vec_concat:V16QI
+				    (match_operand:V8QI 1 "register_operand" "y")
+				    (match_operand:V8QI 2 "register_operand" "y")) 0)
+		       (mult:SI
+		         (zero_extract:SI (reg:SI WCGR0) (const_int 3) (const_int 0))
+		         (const_int 8))) 0))]
+  "TARGET_REALLY_IWMMXT"
+  "walignr0%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "walignr")]
+)
 
-(define_insn "iwmmxt_tmcr"
-  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
-			(match_operand:SI 1 "register_operand"  "r")]
-		       VUNSPEC_TMCR)]
-  "TARGET_REALLY_IWMMXT"
-  "tmcr%?\\t%w0, %1"
-  [(set_attr "predicable" "yes")])
+(define_insn "iwmmxt_walignr1"
+  [(set (match_operand:V8QI                           0 "register_operand" "=y")
+	(subreg:V8QI (ashiftrt:TI
+		       (subreg:TI (vec_concat:V16QI
+				    (match_operand:V8QI 1 "register_operand" "y")
+				    (match_operand:V8QI 2 "register_operand" "y")) 0)
+		       (mult:SI
+		         (zero_extract:SI (reg:SI WCGR1) (const_int 3) (const_int 0))
+		         (const_int 8))) 0))]
+  "TARGET_REALLY_IWMMXT"
+  "walignr1%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "walignr")]
+)
+
+(define_insn "iwmmxt_walignr2"
+  [(set (match_operand:V8QI                           0 "register_operand" "=y")
+	(subreg:V8QI (ashiftrt:TI
+		       (subreg:TI (vec_concat:V16QI
+				    (match_operand:V8QI 1 "register_operand" "y")
+				    (match_operand:V8QI 2 "register_operand" "y")) 0)
+		       (mult:SI
+		         (zero_extract:SI (reg:SI WCGR2) (const_int 3) (const_int 0))
+		         (const_int 8))) 0))]
+  "TARGET_REALLY_IWMMXT"
+  "walignr2%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "walignr")]
+)
+
+(define_insn "iwmmxt_walignr3"
+  [(set (match_operand:V8QI                           0 "register_operand" "=y")
+	(subreg:V8QI (ashiftrt:TI
+		       (subreg:TI (vec_concat:V16QI
+				    (match_operand:V8QI 1 "register_operand" "y")
+				    (match_operand:V8QI 2 "register_operand" "y")) 0)
+		       (mult:SI
+		         (zero_extract:SI (reg:SI WCGR3) (const_int 3) (const_int 0))
+		         (const_int 8))) 0))]
+  "TARGET_REALLY_IWMMXT"
+  "walignr3%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "walignr")]
+)
 
 (define_insn "iwmmxt_wsadb"
-  [(set (match_operand:V8QI               0 "register_operand" "=y")
-        (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
-		      (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSAD))]
+  [(set (match_operand:V2SI               0 "register_operand" "=y")
+        (unspec:V2SI [
+		      (match_operand:V2SI 1 "register_operand" "0")
+		      (match_operand:V8QI 2 "register_operand" "y")
+		      (match_operand:V8QI 3 "register_operand" "y")] UNSPEC_WSAD))]
   "TARGET_REALLY_IWMMXT"
-  "wsadb%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "wsadb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsad")]
+)
 
 (define_insn "iwmmxt_wsadh"
-  [(set (match_operand:V4HI               0 "register_operand" "=y")
-        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
-		      (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSAD))]
+  [(set (match_operand:V2SI               0 "register_operand" "=y")
+        (unspec:V2SI [
+		      (match_operand:V2SI 1 "register_operand" "0")
+		      (match_operand:V4HI 2 "register_operand" "y")
+		      (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WSAD))]
   "TARGET_REALLY_IWMMXT"
-  "wsadh%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  "wsadh%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsad")]
+)
 
 (define_insn "iwmmxt_wsadbz"
-  [(set (match_operand:V8QI               0 "register_operand" "=y")
-        (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
+  [(set (match_operand:V2SI               0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V8QI 1 "register_operand" "y")
 		      (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSADZ))]
   "TARGET_REALLY_IWMMXT"
   "wsadbz%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsad")]
+)
 
 (define_insn "iwmmxt_wsadhz"
-  [(set (match_operand:V4HI               0 "register_operand" "=y")
-        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+  [(set (match_operand:V2SI               0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V4HI 1 "register_operand" "y")
 		      (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSADZ))]
   "TARGET_REALLY_IWMMXT"
   "wsadhz%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")])
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsad")]
+)
 
+(include "iwmmxt2.md")
diff --git a/gcc/config/arm/iwmmxt2.md b/gcc/config/arm/iwmmxt2.md
new file mode 100644
index 0000000..78fcb7f
--- /dev/null
+++ b/gcc/config/arm/iwmmxt2.md
@@ -0,0 +1,918 @@
+;; Patterns for the Intel Wireless MMX technology architecture.
+;; Copyright (C) 2011 Free Software Foundation, Inc.
+;; Written by Marvell, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_c_enum "unspec" [
+  UNSPEC_WADDC		; Used by the intrinsic form of the iWMMXt WADDC instruction.
+  UNSPEC_WABS		; Used by the intrinsic form of the iWMMXt WABS instruction.
+  UNSPEC_WQMULWMR	; Used by the intrinsic form of the iWMMXt WQMULWMR instruction.
+  UNSPEC_WQMULMR	; Used by the intrinsic form of the iWMMXt WQMULMR instruction.
+  UNSPEC_WQMULWM	; Used by the intrinsic form of the iWMMXt WQMULWM instruction.
+  UNSPEC_WQMULM		; Used by the intrinsic form of the iWMMXt WQMULM instruction.
+  UNSPEC_WQMIAxyn	; Used by the intrinsic form of the iWMMXt WMIAxyn instruction.
+  UNSPEC_WQMIAxy	; Used by the intrinsic form of the iWMMXt WMIAxy instruction.
+  UNSPEC_TANDC		; Used by the intrinsic form of the iWMMXt TANDC instruction.
+  UNSPEC_TORC		; Used by the intrinsic form of the iWMMXt TORC instruction.
+  UNSPEC_TORVSC		; Used by the intrinsic form of the iWMMXt TORVSC instruction.
+  UNSPEC_TEXTRC		; Used by the intrinsic form of the iWMMXt TEXTRC instruction.
+])
+
+(define_insn "iwmmxt_wabs<mode>3"
+  [(set (match_operand:VMMX               0 "register_operand" "=y")
+        (unspec:VMMX [(match_operand:VMMX 1 "register_operand"  "y")] UNSPEC_WABS))]
+  "TARGET_REALLY_IWMMXT"
+  "wabs<MMX_char>%?\\t%0, %1"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wabs")]
+)
+
+(define_insn "iwmmxt_wabsdiffb"
+  [(set (match_operand:V8QI                          0 "register_operand" "=y")
+	(truncate:V8QI
+	  (abs:V8HI
+	    (minus:V8HI
+	      (zero_extend:V8HI (match_operand:V8QI  1 "register_operand"  "y"))
+	      (zero_extend:V8HI (match_operand:V8QI  2 "register_operand"  "y"))))))]
+ "TARGET_REALLY_IWMMXT"
+ "wabsdiffb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+  (set_attr "wtype" "wabsdiff")]
+)
+
+(define_insn "iwmmxt_wabsdiffh"
+  [(set (match_operand:V4HI                          0 "register_operand" "=y")
+        (truncate: V4HI
+          (abs:V4SI
+            (minus:V4SI
+              (zero_extend:V4SI (match_operand:V4HI  1 "register_operand"  "y"))
+	      (zero_extend:V4SI (match_operand:V4HI  2 "register_operand"  "y"))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wabsdiffh%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wabsdiff")]
+)
+
+(define_insn "iwmmxt_wabsdiffw"
+  [(set (match_operand:V2SI                          0 "register_operand" "=y")
+        (truncate: V2SI
+	  (abs:V2DI
+	    (minus:V2DI
+	      (zero_extend:V2DI (match_operand:V2SI  1 "register_operand"  "y"))
+	      (zero_extend:V2DI (match_operand:V2SI  2 "register_operand"  "y"))))))]
+ "TARGET_REALLY_IWMMXT"
+ "wabsdiffw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+  (set_attr "wtype" "wabsdiff")]
+)
+
+(define_insn "iwmmxt_waddsubhx"
+  [(set (match_operand:V4HI                                        0 "register_operand" "=y")
+	(vec_merge:V4HI
+	  (ss_minus:V4HI
+	    (match_operand:V4HI                                    1 "register_operand" "y")
+	    (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+	                     (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))
+	  (ss_plus:V4HI
+	    (match_dup 1)
+	    (vec_select:V4HI (match_dup 2)
+	                     (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))
+	  (const_int 10)))]
+  "TARGET_REALLY_IWMMXT"
+  "waddsubhx%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "waddsubhx")]
+)
+
+(define_insn "iwmmxt_wsubaddhx"
+  [(set (match_operand:V4HI                                        0 "register_operand" "=y")
+	(vec_merge:V4HI
+	  (ss_plus:V4HI
+	    (match_operand:V4HI                                    1 "register_operand" "y")
+	    (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+	                     (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))
+	  (ss_minus:V4HI
+	    (match_dup 1)
+	    (vec_select:V4HI (match_dup 2)
+	                     (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))
+	  (const_int 10)))]
+  "TARGET_REALLY_IWMMXT"
+  "wsubaddhx%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wsubaddhx")]
+)
+
+(define_insn "addc<mode>3"
+  [(set (match_operand:VMMX2      0 "register_operand" "=y")
+	(unspec:VMMX2
+          [(plus:VMMX2
+             (match_operand:VMMX2 1 "register_operand"  "y")
+	     (match_operand:VMMX2 2 "register_operand"  "y"))] UNSPEC_WADDC))]
+  "TARGET_REALLY_IWMMXT"
+  "wadd<MMX_char>c%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wadd")]
+)
+
+(define_insn "iwmmxt_avg4"
+[(set (match_operand:V8QI                                 0 "register_operand" "=y")
+      (truncate:V8QI
+        (vec_select:V8HI
+	  (vec_merge:V8HI
+	    (lshiftrt:V8HI
+	      (plus:V8HI
+	        (plus:V8HI
+		  (plus:V8HI
+	            (plus:V8HI
+		      (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+		      (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y")))
+		    (vec_select:V8HI (zero_extend:V8HI (match_dup 1))
+		                     (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2)
+				                (const_int 3) (const_int 4) (const_int 5) (const_int 6)])))
+		  (vec_select:V8HI (zero_extend:V8HI (match_dup 2))
+		                   (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2)
+				              (const_int 3) (const_int 4) (const_int 5) (const_int 6)])))
+	        (const_vector:V8HI [(const_int 1) (const_int 1) (const_int 1) (const_int 1)
+	                            (const_int 1) (const_int 1) (const_int 1) (const_int 1)]))
+	      (const_int 2))
+	    (const_vector:V8HI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)
+	                        (const_int 0) (const_int 0) (const_int 0) (const_int 0)])
+	    (const_int 254))
+	  (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 4)
+	             (const_int 5) (const_int 6) (const_int 7) (const_int 0)]))))]
+  "TARGET_REALLY_IWMMXT"
+  "wavg4%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wavg4")]
+)
+
+(define_insn "iwmmxt_avg4r"
+  [(set (match_operand:V8QI                                   0 "register_operand" "=y")
+	(truncate:V8QI
+	  (vec_select:V8HI
+	    (vec_merge:V8HI
+	      (lshiftrt:V8HI
+	        (plus:V8HI
+		  (plus:V8HI
+		    (plus:V8HI
+		      (plus:V8HI
+		        (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y"))
+		        (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y")))
+		      (vec_select:V8HI (zero_extend:V8HI (match_dup 1))
+		                       (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2)
+				                  (const_int 3) (const_int 4) (const_int 5) (const_int 6)])))
+		    (vec_select:V8HI (zero_extend:V8HI (match_dup 2))
+		                     (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2)
+				                (const_int 3) (const_int 4) (const_int 5) (const_int 6)])))
+		  (const_vector:V8HI [(const_int 2) (const_int 2) (const_int 2) (const_int 2)
+		                      (const_int 2) (const_int 2) (const_int 2) (const_int 2)]))
+	        (const_int 2))
+	      (const_vector:V8HI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)
+	                          (const_int 0) (const_int 0) (const_int 0) (const_int 0)])
+	      (const_int 254))
+	    (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 4)
+	               (const_int 5) (const_int 6) (const_int 7) (const_int 0)]))))]
+  "TARGET_REALLY_IWMMXT"
+  "wavg4r%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wavg4")]
+)
+
+(define_insn "iwmmxt_wmaddsx"
+  [(set (match_operand:V2SI                                        0 "register_operand" "=y")
+	(plus:V2SI
+	  (mult:V2SI
+	    (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                     (parallel [(const_int 1) (const_int 3)]))
+	    (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))
+	                     (parallel [(const_int 0) (const_int 2)])))
+	  (mult:V2SI
+	    (vec_select:V2SI (sign_extend:V4SI (match_dup 1))
+	                     (parallel [(const_int 0) (const_int 2)]))
+	    (vec_select:V2SI (sign_extend:V4SI (match_dup 2))
+	                     (parallel [(const_int 1) (const_int 3)])))))]
+ "TARGET_REALLY_IWMMXT"
+  "wmaddsx%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+	(set_attr "wtype" "wmadd")]
+)
+
+(define_insn "iwmmxt_wmaddux"
+  [(set (match_operand:V2SI                                        0 "register_operand" "=y")
+	(plus:V2SI
+	  (mult:V2SI
+	    (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                     (parallel [(const_int 1) (const_int 3)]))
+	    (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))
+	                     (parallel [(const_int 0) (const_int 2)])))
+	  (mult:V2SI
+	    (vec_select:V2SI (zero_extend:V4SI (match_dup 1))
+	                     (parallel [(const_int 0) (const_int 2)]))
+	    (vec_select:V2SI (zero_extend:V4SI (match_dup 2))
+	                     (parallel [(const_int 1) (const_int 3)])))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmaddux%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmadd")]
+)
+
+(define_insn "iwmmxt_wmaddsn"
+ [(set (match_operand:V2SI                                     0 "register_operand" "=y")
+    (minus:V2SI
+      (mult:V2SI
+        (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                 (parallel [(const_int 0) (const_int 2)]))
+        (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))
+	                 (parallel [(const_int 0) (const_int 2)])))
+      (mult:V2SI
+        (vec_select:V2SI (sign_extend:V4SI (match_dup 1))
+	                 (parallel [(const_int 1) (const_int 3)]))
+        (vec_select:V2SI (sign_extend:V4SI (match_dup 2))
+	                 (parallel [(const_int 1) (const_int 3)])))))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaddsn%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+  (set_attr "wtype" "wmadd")]
+)
+
+(define_insn "iwmmxt_wmaddun"
+  [(set (match_operand:V2SI                                        0 "register_operand" "=y")
+	(minus:V2SI
+	  (mult:V2SI
+	    (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+	                     (parallel [(const_int 0) (const_int 2)]))
+	    (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))
+	                     (parallel [(const_int 0) (const_int 2)])))
+	  (mult:V2SI
+	    (vec_select:V2SI (zero_extend:V4SI (match_dup 1))
+	                     (parallel [(const_int 1) (const_int 3)]))
+	    (vec_select:V2SI (zero_extend:V4SI (match_dup 2))
+	                     (parallel [(const_int 1) (const_int 3)])))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmaddun%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmadd")]
+)
+
+(define_insn "iwmmxt_wmulwsm"
+  [(set (match_operand:V2SI                         0 "register_operand" "=y")
+	(truncate:V2SI
+	  (ashiftrt:V2DI
+	    (mult:V2DI
+	      (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+	      (sign_extend:V2DI (match_operand:V2SI 2 "register_operand" "y")))
+	    (const_int 32))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulwsm%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmulw")]
+)
+
+(define_insn "iwmmxt_wmulwum"
+  [(set (match_operand:V2SI                         0 "register_operand" "=y")
+	(truncate:V2SI
+          (lshiftrt:V2DI
+	    (mult:V2DI
+	      (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+	      (zero_extend:V2DI (match_operand:V2SI 2 "register_operand" "y")))
+	    (const_int 32))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulwum%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmulw")]
+)
+
+(define_insn "iwmmxt_wmulsmr"
+  [(set (match_operand:V4HI                           0 "register_operand" "=y")
+	(truncate:V4HI
+	  (ashiftrt:V4SI
+	    (plus:V4SI
+	      (mult:V4SI
+	        (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+		(sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+	      (const_vector:V4SI [(const_int 32768)
+	                          (const_int 32768)
+				  (const_int 32768)]))
+	    (const_int 16))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulsmr%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmul")]
+)
+
+(define_insn "iwmmxt_wmulumr"
+  [(set (match_operand:V4HI                           0 "register_operand" "=y")
+	(truncate:V4HI
+	  (lshiftrt:V4SI
+	    (plus:V4SI
+	      (mult:V4SI
+	        (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+		(zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+	      (const_vector:V4SI [(const_int 32768)
+				  (const_int 32768)
+				  (const_int 32768)
+				  (const_int 32768)]))
+	  (const_int 16))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulumr%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmul")]
+)
+
+(define_insn "iwmmxt_wmulwsmr"
+  [(set (match_operand:V2SI                           0 "register_operand" "=y")
+	(truncate:V2SI
+	  (ashiftrt:V2DI
+	    (plus:V2DI
+	      (mult:V2DI
+	        (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+		(sign_extend:V2DI (match_operand:V2SI 2 "register_operand" "y")))
+	      (const_vector:V2DI [(const_int 2147483648)
+				  (const_int 2147483648)]))
+	    (const_int 32))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulwsmr%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmul")]
+)
+
+(define_insn "iwmmxt_wmulwumr"
+  [(set (match_operand:V2SI                           0 "register_operand" "=y")
+	(truncate:V2SI
+	  (lshiftrt:V2DI
+	    (plus:V2DI
+	      (mult:V2DI
+	        (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y"))
+		(zero_extend:V2DI (match_operand:V2SI 2 "register_operand" "y")))
+	      (const_vector:V2DI [(const_int 2147483648)
+			          (const_int 2147483648)]))
+	    (const_int 32))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulwumr%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmulw")]
+)
+
+(define_insn "iwmmxt_wmulwl"
+  [(set (match_operand:V2SI   0 "register_operand" "=y")
+        (mult:V2SI
+          (match_operand:V2SI 1 "register_operand" "y")
+	  (match_operand:V2SI 2 "register_operand" "y")))]
+  "TARGET_REALLY_IWMMXT"
+  "wmulwl%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmulw")]
+)
+
+(define_insn "iwmmxt_wqmulm"
+  [(set (match_operand:V4HI            0 "register_operand" "=y")
+        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+		      (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WQMULM))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmulm%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmulm")]
+)
+
+(define_insn "iwmmxt_wqmulwm"
+  [(set (match_operand:V2SI               0 "register_operand" "=y")
+	(unspec:V2SI [(match_operand:V2SI 1 "register_operand" "y")
+		      (match_operand:V2SI 2 "register_operand" "y")] UNSPEC_WQMULWM))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmulwm%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmulwm")]
+)
+
+(define_insn "iwmmxt_wqmulmr"
+  [(set (match_operand:V4HI               0 "register_operand" "=y")
+	(unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+		      (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WQMULMR))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmulmr%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmulm")]
+)
+
+(define_insn "iwmmxt_wqmulwmr"
+  [(set (match_operand:V2SI            0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "y")
+		      (match_operand:V2SI 2 "register_operand" "y")] UNSPEC_WQMULWMR))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmulwmr%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmulwm")]
+)
+
+(define_insn "iwmmxt_waddbhusm"
+  [(set (match_operand:V8QI                          0 "register_operand" "=y")
+	(vec_concat:V8QI
+	  (const_vector:V4QI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)])
+	  (us_truncate:V4QI
+	    (ss_plus:V4HI
+	      (match_operand:V4HI                    1 "register_operand" "y")
+	      (zero_extend:V4HI
+	        (vec_select:V4QI (match_operand:V8QI 2 "register_operand" "y")
+	                         (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "waddbhusm%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "waddbhus")]
+)
+
+(define_insn "iwmmxt_waddbhusl"
+  [(set (match_operand:V8QI                          0 "register_operand" "=y")
+	(vec_concat:V8QI
+	  (us_truncate:V4QI
+	    (ss_plus:V4HI
+	      (match_operand:V4HI                    1 "register_operand" "y")
+	      (zero_extend:V4HI
+		(vec_select:V4QI (match_operand:V8QI 2 "register_operand" "y")
+		                 (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)])))))
+	  (const_vector:V4QI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)])))]
+  "TARGET_REALLY_IWMMXT"
+  "waddbhusl%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "waddbhus")]
+)
+
+(define_insn "iwmmxt_wqmiabb"
+  [(set (match_operand:V2SI	                             0 "register_operand" "=y")
+	(unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+		      (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0))
+		      (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32))
+		      (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0))
+		      (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxy))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiabb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiabt"
+  [(set (match_operand:V2SI	                             0 "register_operand" "=y")
+	(unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+	              (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0))
+		      (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32))
+		      (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16))
+		      (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxy))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiabt%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiatb"
+  [(set (match_operand:V2SI                                  0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+	              (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16))
+	              (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48))
+	              (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0))
+	              (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxy))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiatb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiatt"
+  [(set (match_operand:V2SI                                  0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+	              (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16))
+	              (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48))
+	              (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16))
+	              (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxy))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiatt%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiabbn"
+  [(set (match_operand:V2SI                                  0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+                      (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0))
+	              (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32))
+	              (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0))
+	              (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxyn))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiabbn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiabtn"
+  [(set (match_operand:V2SI                                  0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+                      (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0))
+	              (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32))
+	              (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16))
+	              (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxyn))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiabtn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiatbn"
+  [(set (match_operand:V2SI                                  0 "register_operand" "=y")
+        (unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+                      (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16))
+	              (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48))
+	              (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0))
+	              (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxyn))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiatbn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wqmiattn"
+ [(set (match_operand:V2SI                                  0 "register_operand" "=y")
+       (unspec:V2SI [(match_operand:V2SI                    1 "register_operand" "0")
+                     (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16))
+	             (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48))
+	             (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16))
+	             (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxyn))]
+  "TARGET_REALLY_IWMMXT"
+  "wqmiattn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wqmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiabb"
+  [(set	(match_operand:DI	                          0 "register_operand" "=y")
+	(plus:DI (match_operand:DI	                  1 "register_operand" "0")
+		 (plus:DI
+		   (mult:DI
+		     (sign_extend:DI
+		       (vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				      (parallel [(const_int 0)])))
+		     (sign_extend:DI
+		       (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				      (parallel [(const_int 0)]))))
+		   (mult:DI
+		     (sign_extend:DI
+		       (vec_select:HI (match_dup 2)
+			              (parallel [(const_int 2)])))
+		     (sign_extend:DI
+		       (vec_select:HI (match_dup 3)
+				      (parallel [(const_int 2)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiabb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiabt"
+  [(set	(match_operand:DI	                          0 "register_operand" "=y")
+	(plus:DI (match_operand:DI	                  1 "register_operand" "0")
+		 (plus:DI
+		   (mult:DI
+		     (sign_extend:DI
+		       (vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				      (parallel [(const_int 0)])))
+		     (sign_extend:DI
+		       (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				      (parallel [(const_int 1)]))))
+		   (mult:DI
+		     (sign_extend:DI
+		       (vec_select:HI (match_dup 2)
+				      (parallel [(const_int 2)])))
+		     (sign_extend:DI
+		       (vec_select:HI (match_dup 3)
+				      (parallel [(const_int 3)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiabt%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiatb"
+  [(set	(match_operand:DI	                          0 "register_operand" "=y")
+	(plus:DI (match_operand:DI	                  1 "register_operand" "0")
+		 (plus:DI
+		   (mult:DI
+		     (sign_extend:DI
+		       (vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				      (parallel [(const_int 1)])))
+		     (sign_extend:DI
+		       (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				      (parallel [(const_int 0)]))))
+		   (mult:DI
+		     (sign_extend:DI
+		       (vec_select:HI (match_dup 2)
+				      (parallel [(const_int 3)])))
+		     (sign_extend:DI
+		       (vec_select:HI (match_dup 3)
+				      (parallel [(const_int 2)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiatb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiatt"
+  [(set	(match_operand:DI	                   0 "register_operand" "=y")
+        (plus:DI (match_operand:DI	           1 "register_operand" "0")
+          (plus:DI
+            (mult:DI
+              (sign_extend:DI
+                (vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+	                       (parallel [(const_int 1)])))
+	      (sign_extend:DI
+	        (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+	                       (parallel [(const_int 1)]))))
+            (mult:DI
+	      (sign_extend:DI
+                (vec_select:HI (match_dup 2)
+	                       (parallel [(const_int 3)])))
+              (sign_extend:DI
+                (vec_select:HI (match_dup 3)
+	                       (parallel [(const_int 3)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiatt%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiabbn"
+  [(set	(match_operand:DI	                           0 "register_operand" "=y")
+	(minus:DI (match_operand:DI	                   1 "register_operand" "0")
+		  (plus:DI
+		    (mult:DI
+		      (sign_extend:DI
+			(vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				       (parallel [(const_int 0)])))
+		      (sign_extend:DI
+		        (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				       (parallel [(const_int 0)]))))
+		    (mult:DI
+		      (sign_extend:DI
+			(vec_select:HI (match_dup 2)
+				       (parallel [(const_int 2)])))
+		      (sign_extend:DI
+		        (vec_select:HI (match_dup 3)
+				       (parallel [(const_int 2)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiabbn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiabtn"
+  [(set	(match_operand:DI	                           0 "register_operand" "=y")
+	(minus:DI (match_operand:DI	                   1 "register_operand" "0")
+		  (plus:DI
+		    (mult:DI
+		      (sign_extend:DI
+			(vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				       (parallel [(const_int 0)])))
+		      (sign_extend:DI
+		        (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				       (parallel [(const_int 1)]))))
+		    (mult:DI
+		      (sign_extend:DI
+		        (vec_select:HI (match_dup 2)
+				       (parallel [(const_int 2)])))
+		      (sign_extend:DI
+			(vec_select:HI (match_dup 3)
+				       (parallel [(const_int 3)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiabtn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiatbn"
+  [(set (match_operand:DI	                           0 "register_operand" "=y")
+	(minus:DI (match_operand:DI	                   1 "register_operand" "0")
+		  (plus:DI
+		    (mult:DI
+		      (sign_extend:DI
+			(vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				       (parallel [(const_int 1)])))
+		      (sign_extend:DI
+		        (vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				       (parallel [(const_int 0)]))))
+		    (mult:DI
+		      (sign_extend:DI
+		        (vec_select:HI (match_dup 2)
+				       (parallel [(const_int 3)])))
+		      (sign_extend:DI
+			(vec_select:HI (match_dup 3)
+				       (parallel [(const_int 2)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiatbn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiattn"
+  [(set (match_operand:DI	                           0 "register_operand" "=y")
+	(minus:DI (match_operand:DI	                   1 "register_operand" "0")
+		  (plus:DI
+		    (mult:DI
+		      (sign_extend:DI
+			(vec_select:HI (match_operand:V4HI 2 "register_operand" "y")
+				       (parallel [(const_int 1)])))
+		      (sign_extend:DI
+			(vec_select:HI (match_operand:V4HI 3 "register_operand" "y")
+				       (parallel [(const_int 1)]))))
+		    (mult:DI
+		      (sign_extend:DI
+			(vec_select:HI (match_dup 2)
+				       (parallel [(const_int 3)])))
+		      (sign_extend:DI
+			(vec_select:HI (match_dup 3)
+				       (parallel [(const_int 3)])))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiattn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiaxy")]
+)
+
+(define_insn "iwmmxt_wmiawbb"
+  [(set (match_operand:DI	0 "register_operand" "=y")
+	(plus:DI
+	  (match_operand:DI      1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawbb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawbt"
+  [(set (match_operand:DI	                               0 "register_operand" "=y")
+	(plus:DI
+	  (match_operand:DI                                    1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawbt%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawtb"
+  [(set (match_operand:DI	                               0 "register_operand" "=y")
+	(plus:DI
+	  (match_operand:DI                                    1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawtb%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawtt"
+[(set (match_operand:DI	                                     0 "register_operand" "=y")
+      (plus:DI
+	(match_operand:DI                                    1 "register_operand" "0")
+	(mult:DI
+	  (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)])))
+	  (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawtt%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawbbn"
+  [(set (match_operand:DI	                               0 "register_operand" "=y")
+	(minus:DI
+	  (match_operand:DI                                    1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawbbn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawbtn"
+  [(set (match_operand:DI	                               0 "register_operand" "=y")
+	(minus:DI
+	  (match_operand:DI                                    1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawbtn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawtbn"
+  [(set (match_operand:DI	                               0 "register_operand" "=y")
+	(minus:DI
+	  (match_operand:DI                                    1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawtbn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmiawttn"
+  [(set (match_operand:DI	                               0 "register_operand" "=y")
+	(minus:DI
+	  (match_operand:DI                                    1 "register_operand" "0")
+	  (mult:DI
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)])))
+	    (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmiawttn%?\\t%0, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmiawxy")]
+)
+
+(define_insn "iwmmxt_wmerge"
+  [(set (match_operand:DI         0 "register_operand" "=y")
+	(ior:DI
+	  (ashift:DI
+	    (match_operand:DI     2 "register_operand" "y")
+	    (minus:SI
+	      (const_int 64)
+	      (mult:SI
+	        (match_operand:SI 3 "immediate_operand" "i")
+		(const_int 8))))
+	  (lshiftrt:DI
+	    (ashift:DI
+	      (match_operand:DI   1 "register_operand" "y")
+	      (mult:SI
+	        (match_dup 3)
+		(const_int 8)))
+	    (mult:SI
+	      (match_dup 3)
+	      (const_int 8)))))]
+  "TARGET_REALLY_IWMMXT"
+  "wmerge%?\\t%0, %1, %2, %3"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "wmerge")]
+)
+
+(define_insn "iwmmxt_tandc<mode>3"
+  [(set (reg:CC CC_REGNUM)
+	(subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TANDC) 0))
+   (unspec:CC [(reg:SI 15)] UNSPEC_TANDC)]
+  "TARGET_REALLY_IWMMXT"
+  "tandc<MMX_char>%?\\t r15"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "tandc")]
+)
+
+(define_insn "iwmmxt_torc<mode>3"
+  [(set (reg:CC CC_REGNUM)
+	(subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TORC) 0))
+   (unspec:CC [(reg:SI 15)] UNSPEC_TORC)]
+  "TARGET_REALLY_IWMMXT"
+  "torc<MMX_char>%?\\t r15"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "torc")]
+)
+
+(define_insn "iwmmxt_torvsc<mode>3"
+  [(set (reg:CC CC_REGNUM)
+	(subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TORVSC) 0))
+   (unspec:CC [(reg:SI 15)] UNSPEC_TORVSC)]
+  "TARGET_REALLY_IWMMXT"
+  "torvsc<MMX_char>%?\\t r15"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "torvsc")]
+)
+
+(define_insn "iwmmxt_textrc<mode>3"
+  [(set (reg:CC CC_REGNUM)
+	(subreg:CC (unspec:VMMX [(const_int 0)
+		                 (match_operand:SI 0 "immediate_operand" "i")] UNSPEC_TEXTRC) 0))
+   (unspec:CC [(reg:SI 15)] UNSPEC_TEXTRC)]
+  "TARGET_REALLY_IWMMXT"
+  "textrc<MMX_char>%?\\t r15, %0"
+  [(set_attr "predicable" "yes")
+   (set_attr "wtype" "textrc")]
+)
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index fa2027c..8334b2b 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -493,6 +493,11 @@
   (and (match_code "const_int")
        (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64")))
 
+;; iWMMXt predicates
+
+(define_predicate "imm_or_reg_operand"
+  (ior (match_operand 0 "immediate_operand")
+       (match_operand 0 "register_operand")))
 
 ;; Neon predicates
 
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 1128d19..83c18f7 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -49,6 +49,7 @@ MD_INCLUDES=	$(srcdir)/config/arm/arm1020e.md \
 		$(srcdir)/config/arm/fpa.md \
 		$(srcdir)/config/arm/iterators.md \
 		$(srcdir)/config/arm/iwmmxt.md \
+		$(srcdir)/config/arm/iwmmxt2.md \
 		$(srcdir)/config/arm/ldmstm.md \
 		$(srcdir)/config/arm/neon.md \
 		$(srcdir)/config/arm/predicates.md \
-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH, ARM, iWMMXt][4/5]: WMMX machine description
@ 2011-07-06 10:34 Xinyu Qi
  0 siblings, 0 replies; 15+ messages in thread
From: Xinyu Qi @ 2011-07-06 10:34 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 577 bytes --]

Hi,

It is the fourth part of iWMMXt maintenance.

*config/arm/arm.c (arm_output_iwmmxt_shift_immediate): New function. Serving for WMMX immediate shift insn output.
 (arm_output_iwmmxt_tinsr): New function. Serving for tinsr insn output.
*config/arm/arm-protos.h: Add new functions protos.
*config/arm/iwmmxt.md: Add/fix WMMX machine description support.
*config/arm/iwmmxt2.md: New file. Add WMMX2 machine description support.
*config/arm/iterators.md: Add new iterator VMMX2.
*config/arm/arm.md: Add wtype serving for WMMX pipeline description.

Thanks,
Xinyu

[-- Attachment #2: 4_wmmx_md.diff.gz --]
[-- Type: application/x-gzip, Size: 13464 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2012-05-29  4:15 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-14  9:02 [PATCH, ARM, iWMMXt][4/5]: WMMX machine description Xinyu Qi
2011-08-18  9:14 ` Ramana Radhakrishnan
2011-09-05  9:57   ` Xinyu Qi
2011-09-26  5:42   ` PING: " Xinyu Qi
2011-11-19  2:43     ` Ramana Radhakrishnan
2011-11-24  9:56       ` Xinyu Qi
2011-12-14 17:48         ` Richard Earnshaw
2011-12-22  6:50           ` Xinyu Qi
2011-12-22 10:12             ` Richard Earnshaw
2011-12-29  6:24               ` Xinyu Qi
2012-02-03  2:11               ` Xinyu Qi
2012-03-13  8:57               ` Xinyu Qi
2011-10-20  8:12   ` Xinyu Qi
  -- strict thread matches above, loose matches on Subject: below --
2012-05-29  4:13 [PATCH ARM iWMMXt 0/5] Improve iWMMXt support Matt Turner
2012-05-29  4:15 ` [PATCH ARM iWMMXt 4/5] WMMX machine description Matt Turner
2011-07-06 10:34 [PATCH, ARM, iWMMXt][4/5]: " Xinyu Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).