diff mbox

[ARM,iWMMXt,4/5] WMMX machine description

Message ID 1338264799-12374-5-git-send-email-mattst88@gmail.com
State New
Headers show

Commit Message

Matt Turner May 29, 2012, 4:13 a.m. UTC
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 mbox

Patch

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 \