public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* iwmmxt2 patch for binutils-2.16.92
@ 2006-09-19 13:41 Bridge Wu
  2006-09-19 14:21 ` Joseph S. Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Bridge Wu @ 2006-09-19 13:41 UTC (permalink / raw)
  To: binutils

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

Hello,

Here is iwmmxt2 patch for binutils-2.16.92. It supports Intel IWMMXT2
instruction set.
AS can use '-mcpu=iwmmxt2' option to assemble iwmmxt2 instructions.
OBJDUMP can use '-m iwmmxt2' option to disassemble iwmmxt2 instructions.

-- 
best regards,
-Bridge

[-- Attachment #2: iwmmxt2-binutils-2.16.92.patch --]
[-- Type: application/octet-stream, Size: 36839 bytes --]

diff -Nurp binutils-2.16.92.old/bfd/archures.c binutils-2.16.92/bfd/archures.c
--- binutils-2.16.92.old/bfd/archures.c	2006-09-19 13:52:47.000000000 +0800
+++ binutils-2.16.92/bfd/archures.c	2006-09-19 13:53:09.000000000 +0800
@@ -273,6 +273,7 @@ DESCRIPTION
 .#define bfd_mach_arm_XScale	10
 .#define bfd_mach_arm_ep9312	11
 .#define bfd_mach_arm_iWMMXt	12
+.#define bfd_mach_arm_iWMMXt2	13
 .  bfd_arch_ns32k,     {* National Semiconductors ns32000 *}
 .  bfd_arch_w65,       {* WDC 65816 *}
 .  bfd_arch_tic30,     {* Texas Instruments TMS320C30 *}
diff -Nurp binutils-2.16.92.old/bfd/bfd-in2.h binutils-2.16.92/bfd/bfd-in2.h
--- binutils-2.16.92.old/bfd/bfd-in2.h	2006-09-19 13:52:47.000000000 +0800
+++ binutils-2.16.92/bfd/bfd-in2.h	2006-09-19 13:53:09.000000000 +0800
@@ -1870,6 +1870,7 @@ enum bfd_architecture
 #define bfd_mach_arm_XScale    10
 #define bfd_mach_arm_ep9312    11
 #define bfd_mach_arm_iWMMXt    12
+#define bfd_mach_arm_iWMMXt2   13
   bfd_arch_ns32k,     /* National Semiconductors ns32000 */
   bfd_arch_w65,       /* WDC 65816 */
   bfd_arch_tic30,     /* Texas Instruments TMS320C30 */
diff -Nurp binutils-2.16.92.old/bfd/cpu-arm.c binutils-2.16.92/bfd/cpu-arm.c
--- binutils-2.16.92.old/bfd/cpu-arm.c	2006-09-19 13:52:47.000000000 +0800
+++ binutils-2.16.92/bfd/cpu-arm.c	2006-09-19 13:53:09.000000000 +0800
@@ -92,7 +92,8 @@ processors[] =
   { bfd_mach_arm_4,  "strongarm1100" },
   { bfd_mach_arm_XScale, "xscale" },
   { bfd_mach_arm_ep9312, "ep9312" },
-  { bfd_mach_arm_iWMMXt, "iwmmxt" }
+  { bfd_mach_arm_iWMMXt, "iwmmxt" },
+  { bfd_mach_arm_iWMMXt2, "iwmmxt2" }
 };
 
 static bfd_boolean
@@ -137,7 +138,8 @@ static const bfd_arch_info_type arch_inf
   N (bfd_mach_arm_5TE,    "armv5te", FALSE, & arch_info_struct[9]),
   N (bfd_mach_arm_XScale, "xscale",  FALSE, & arch_info_struct[10]),
   N (bfd_mach_arm_ep9312, "ep9312",  FALSE, & arch_info_struct[11]),
-  N (bfd_mach_arm_iWMMXt,"iwmmxt",  FALSE, NULL)
+  N (bfd_mach_arm_iWMMXt, "iwmmxt",  FALSE, & arch_info_struct[12]),
+  N (bfd_mach_arm_iWMMXt2, "iwmmxt2", FALSE, NULL)
 };
 
 const bfd_arch_info_type bfd_arm_arch =
@@ -179,7 +181,7 @@ bfd_arm_merge_machines (bfd *ibfd, bfd *
      Intel XScale binary, since these architecture have co-processors which
      will not both be present on the same physical hardware.  */
   else if (in == bfd_mach_arm_ep9312
-	   && (out == bfd_mach_arm_XScale || out == bfd_mach_arm_iWMMXt))
+	   && (out == bfd_mach_arm_XScale || out == bfd_mach_arm_iWMMXt || out == bfd_mach_arm_iWMMXt2))
     {
       _bfd_error_handler (_("\
 ERROR: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
@@ -188,7 +190,7 @@ ERROR: %B is compiled for the EP9312, wh
       return FALSE;
     }
   else if (out == bfd_mach_arm_ep9312
-	   && (in == bfd_mach_arm_XScale || in == bfd_mach_arm_iWMMXt))
+	   && (in == bfd_mach_arm_XScale || in == bfd_mach_arm_iWMMXt || in == bfd_mach_arm_iWMMXt2))
     {
       _bfd_error_handler (_("\
 ERROR: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
@@ -309,6 +311,7 @@ bfd_arm_update_notes (bfd *abfd, const c
     case bfd_mach_arm_XScale:  expected = "XScale"; break;
     case bfd_mach_arm_ep9312:  expected = "ep9312"; break;
     case bfd_mach_arm_iWMMXt:  expected = "iWMMXt"; break;
+    case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
     }
 
   if (strcmp (arch_string, expected) != 0)
@@ -355,7 +358,8 @@ architectures[] =
   { "armv5te", bfd_mach_arm_5TE },
   { "XScale",  bfd_mach_arm_XScale },
   { "ep9312",  bfd_mach_arm_ep9312 },
-  { "iWMMXt",  bfd_mach_arm_iWMMXt }
+  { "iWMMXt",  bfd_mach_arm_iWMMXt },
+  { "iWMMXt2", bfd_mach_arm_iWMMXt2 }
 };
 
 /* Extract the machine number stored in a note section.  */
diff -Nurp binutils-2.16.92.old/gas/config/tc-arm.c binutils-2.16.92/gas/config/tc-arm.c
--- binutils-2.16.92.old/gas/config/tc-arm.c	2006-09-19 13:52:47.000000000 +0800
+++ binutils-2.16.92/gas/config/tc-arm.c	2006-09-19 19:06:03.000000000 +0800
@@ -196,6 +196,8 @@ static const arm_feature_set arm_arch_no
 
 static const arm_feature_set arm_cext_iwmmxt =
   ARM_FEATURE (0, ARM_CEXT_IWMMXT);
+static const arm_feature_set arm_cext_iwmmxt2 =
+  ARM_FEATURE (0, ARM_CEXT_IWMMXT2);
 static const arm_feature_set arm_cext_xscale =
   ARM_FEATURE (0, ARM_CEXT_XSCALE);
 static const arm_feature_set arm_cext_maverick =
@@ -278,6 +280,7 @@ struct arm_it
     unsigned reg;
     signed int imm;
     unsigned present	: 1;  /* Operand present.  */
+    unsigned iswc	: 1;  /* Operand was a wCx register */
     unsigned isreg	: 1;  /* Operand was a register.  */
     unsigned immisreg	: 1;  /* .imm field is a second register.  */
     unsigned hasreloc	: 1;  /* Operand has relocation suffix.  */
@@ -3317,6 +3320,132 @@ parse_shifter_operand (char **str, int i
   return SUCCESS;
 }
 
+/* Parse all forms of an ARM address expression except Reg mode.
+   modified from parse_address */
+
+static int
+parse_address_imm (char **str, int i)
+{
+  char *p = *str;
+  int reg;
+
+  if (skip_past_char (&p, '[') == FAIL)
+    {
+      if (skip_past_char (&p, '=') == FAIL)
+	{
+	  /* bare address - translate to PC-relative offset */
+	  inst.reloc.pc_rel = 1;
+	  inst.operands[i].reg = REG_PC;
+	  inst.operands[i].isreg = 1;
+	  inst.operands[i].preind = 1;
+	}
+      /* else a load-constant pseudo op, no special treatment needed here */
+
+      if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+	return FAIL;
+
+      *str = p;
+      return SUCCESS;
+    }
+
+  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
+    {
+      inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
+      return FAIL;
+    }
+  inst.operands[i].reg = reg;
+  inst.operands[i].isreg = 1;
+
+  if (skip_past_comma (&p) == SUCCESS)
+    {
+      inst.operands[i].preind = 1;
+
+	/* [Rn, +#+/-expr] - immediate mode, no Reg mode */
+
+      if (*p == '+') p++;
+      else if (*p == '-') p++, inst.operands[i].negative = 1;
+
+	{
+	  if (inst.operands[i].negative)
+	    {
+	      inst.operands[i].negative = 0;
+	      p--;
+	    }
+	  if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+	    return FAIL;
+	}
+    }
+
+  if (skip_past_char (&p, ']') == FAIL)
+    {
+      inst.error = _("']' expected");
+      return FAIL;
+    }
+
+  if (skip_past_char (&p, '!') == SUCCESS)
+    inst.operands[i].writeback = 1;
+
+  else if (skip_past_comma (&p) == SUCCESS)
+    {
+      if (skip_past_char (&p, '{') == SUCCESS)
+	{
+	  /* [Rn], {expr} - unindexed, with option */
+	  if (parse_immediate (&p, &inst.operands[i].imm,
+			       0, 255, TRUE) == FAIL)
+	    return FAIL;
+
+	  if (skip_past_char (&p, '}') == FAIL)
+	    {
+	      inst.error = _("'}' expected at end of 'option' field");
+	      return FAIL;
+	    }
+	  if (inst.operands[i].preind)
+	    {
+	      inst.error = _("cannot combine index with option");
+	      return FAIL;
+	    }
+	  *str = p;
+	  return SUCCESS;
+	}
+      else
+	{
+	/* [Rn], +#+/-expr - immediate mode, no Reg mode */
+	  inst.operands[i].postind = 1;
+	  inst.operands[i].writeback = 1;
+
+	  if (inst.operands[i].preind)
+	    {
+	      inst.error = _("cannot combine pre- and post-indexing");
+	      return FAIL;
+	    }
+
+	  if (*p == '+') p++;
+	  else if (*p == '-') p++, inst.operands[i].negative = 1;
+
+	    {
+	      if (inst.operands[i].negative)
+		{
+		  inst.operands[i].negative = 0;
+		  p--;
+		}
+	      if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+		return FAIL;
+	    }
+	}
+    }
+
+  /* If at this point neither .preind nor .postind is set, we have a
+     bare [Rn]{!}, which is shorthand for [Rn,#0]{!}.  */
+  if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
+    {
+      inst.operands[i].preind = 1;
+      inst.reloc.exp.X_op = O_constant;
+      inst.reloc.exp.X_add_number = 0;
+    }
+  *str = p;
+  return SUCCESS;
+}
+
 /* Parse all forms of an ARM address expression.  Information is written
    to inst.operands[i] and/or inst.reloc.
 
@@ -3802,6 +3931,7 @@ enum operand_parse_code
   OP_EXP,	/* arbitrary expression */
   OP_EXPi,	/* same, with optional immediate prefix */
   OP_EXPr,	/* same, with optional relocation suffix */
+  OP_ADDR_IMM,	/* Memory address expression, no Reg mode */
 
   OP_CPSF,	/* CPS flags */
   OP_ENDI,	/* Endianness specifier */
@@ -3814,6 +3944,7 @@ enum operand_parse_code
   OP_RR_EXi,	/* ARM register or expression with imm prefix */
   OP_RF_IF,	/* FPA register or immediate */
   OP_RIWR_RIWC, /* iWMMXt R or C reg */
+  OP_RIWR_IMM31, /* iWMMXt R or immediate */
 
   /* Optional operands.	 */
   OP_oI7b,	 /* immediate, prefix optional, 0 .. 7 */
@@ -4039,10 +4170,17 @@ parse_operands (char *str, const unsigne
 		goto failure;
 	      }
 	    inst.operands[i].reg = rege->number;
-	    inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
+	    inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR) || (rege->type == REG_TYPE_MMXWC);
+	    inst.operands[i].iswc = (rege->type == REG_TYPE_MMXWC);
 	  }
 	  break;
 
+	  /* iWMMXt R reg or immediate */
+	case OP_RIWR_IMM31: po_reg_or_goto(REG_TYPE_MMXWR, WR_IMM); break;
+	WR_IMM:
+	  po_imm_or_fail (0, 32, FALSE);
+	  break;
+
 	  /* Misc */
 	case OP_CPSF:	 val = parse_cps_flags (&str);		break;
 	case OP_ENDI:	 val = parse_endian_specifier (&str);	break;
@@ -4078,6 +4216,11 @@ parse_operands (char *str, const unsigne
 	  po_misc_or_fail (parse_address (&str, i));
 	  break;
 
+	  /* Addressing modes, no Reg mode */
+	case OP_ADDR_IMM:
+	  po_misc_or_fail (parse_address_imm (&str, i));
+	  break;
+
 	case OP_SH:
 	  po_misc_or_fail (parse_shifter_operand (&str, i));
 	  break;
@@ -5803,7 +5946,6 @@ do_iwmmxt_wldstbh (void)
 {
   int reloc;
   inst.instruction |= inst.operands[0].reg << 12;
-  inst.reloc.exp.X_add_number *= 4;
   if (thumb_mode)
     reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
   else
@@ -5811,6 +5953,103 @@ do_iwmmxt_wldstbh (void)
   encode_arm_cp_address (1, TRUE, FALSE, reloc);
 }
 
+/* inst.operands[i] was set up by parse_address.  Encode it into an
+   ARM-format instruction.  Reject all forms which cannot be encoded
+   into a coprocessor load/store instruction.  If wb_ok is false,
+   reject use of writeback; if unind_ok is false, reject use of
+   unindexed addressing.  If reloc_override is not 0, use it instead
+   of BFD_ARM_CP_OFF_IMM.  */
+
+static int
+encode_arm_cp_reg_address (int i, int wb_ok, int unind_ok, int reloc_override)
+{
+  inst.instruction |= inst.operands[i].reg << 16;
+
+  assert (!(inst.operands[i].preind && inst.operands[i].postind));
+
+  if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
+    {
+      assert (!inst.operands[i].writeback);
+      if (!unind_ok)
+	{
+	  inst.error = _("instruction does not support unindexed addressing");
+	  return FAIL;
+	}
+      inst.instruction |= inst.operands[i].imm;
+      inst.instruction |= INDEX_UP;
+      return SUCCESS;
+    }
+
+  if (inst.operands[i].preind)
+    inst.instruction |= PRE_INDEX;
+
+  if (inst.operands[i].writeback)
+    {
+      if (inst.operands[i].reg == REG_PC)
+	{
+	  inst.error = _("pc may not be used with write-back");
+	  return FAIL;
+	}
+      if (!wb_ok)
+	{
+	  inst.error = _("instruction does not support writeback");
+	  return FAIL;
+	}
+      inst.instruction |= WRITE_BACK;
+    }
+
+  if (reloc_override)
+    inst.reloc.type = reloc_override;
+  else if (thumb_mode)
+    inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
+  else
+    inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+
+  /* judge if immediate alignment and range reasonable */
+  if (inst.operands[i].immisreg == 1) {
+	/* check immediate range, Reg mode and check negative */
+	if (inst.operands[i].negative == 1)
+		inst.instruction &= ~INDEX_UP;
+	else 
+		inst.instruction |= INDEX_UP;
+
+	if (inst.operands[i].shifted == 1) {
+	  	if (inst.reloc.exp.X_add_number > 15) {
+		      inst.error = _("reg mode: constant out of range");
+		      return FAIL;
+  		}
+		inst.instruction |= (inst.reloc.exp.X_add_number << 4);
+	}
+
+  	/* place the immediate into inst */
+	inst.instruction |= (0xf << 28);
+  	inst.instruction |= inst.operands[i].imm;
+  } else {
+	int offset;
+	offset = inst.reloc.exp.X_add_number;
+
+  	/* check immediate align */
+  	if (offset & 3) {
+		inst.error = _("co-processor address must be word aligned");
+		return FAIL;
+  	}
+
+	if (offset >= 0)
+		inst.instruction |= INDEX_UP;
+	else
+		offset = -offset;
+  	inst.instruction |= (offset >> 2);
+  }
+
+  if (inst.operands[0].iswc == 1)
+  {
+	inst.instruction |=  0xf0000100;
+	inst.instruction &= ~0x00400000;
+  }
+
+  return SUCCESS;
+}
+
 static void
 do_iwmmxt_wldstw (void)
 {
@@ -5822,14 +6061,14 @@ do_iwmmxt_wldstw (void)
     }
 
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_arm_cp_address (1, TRUE, TRUE, 0);
+  encode_arm_cp_reg_address (1, TRUE, TRUE, 0);
 }
 
 static void
 do_iwmmxt_wldstd (void)
 {
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_arm_cp_address (1, TRUE, FALSE, 0);
+  encode_arm_cp_reg_address (1, TRUE, FALSE, 0);
 }
 
 static void
@@ -5850,6 +6089,83 @@ do_iwmmxt_wzero (void)
   inst.instruction |= inst.operands[0].reg << 16;
 }
 \f
+/* iWMMXt2 instructions: strictly in alphabetical order. */
+
+static void
+do_iwmmxt_torvscb (void)
+{
+  constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
+}
+
+static void
+do_iwmmxt_wmerge (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= inst.operands[2].reg;
+  inst.instruction |= inst.operands[3].imm << 21;
+}
+
+/* for wror, wsll, wsra and wsrl */
+static void
+do_iwmmxt_rd_rn_rm_imm5 (void)
+{
+	unsigned long number;
+		
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+
+	if (inst.operands[2].isreg == 1) {
+		inst.instruction |= inst.operands[2].reg;
+		return;
+	}
+
+	if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)) {
+		return;
+	}
+
+	number = inst.operands[2].imm;
+	if (number == 0)
+	{
+		switch ((inst.instruction >> 20) & 0xf)
+		{
+		case 4:
+		case 5:
+		case 6:
+		case 7: 
+		  /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16.  */
+		  number = 16;
+		  inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
+		  break;
+		case 8:
+		case 9:
+		case 10:
+		case 11:
+		  /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32.  */
+		  number = 32;
+		  inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
+		  break;
+		case 12:
+		case 13:
+		case 14:
+		case 15:
+		  {
+			/* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn.  */
+			unsigned long wrn;
+			wrn = (inst.instruction >> 16) & 0xf;
+			inst.instruction &= 0xff0fff0f;
+			inst.instruction |= wrn;
+			/* Bail out here; the instruction is now assembled.  */
+			return;
+		  }
+		}
+	}
+
+	number &= 0x1f;
+	inst.instruction |= (0xf << 28) | ((number & 0x10) << 4) | (number & 0xf);
+}
+
+
 /* Cirrus Maverick instructions.  Simple 2-, 3-, and 4-register
    operations first, then control, shift, and load/store.  */
 
@@ -10045,9 +10361,9 @@ static const struct asm_opcode insns[] =
  cCE(wcmpgtsb,	e300060, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wcmpgtsh,	e700060, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wcmpgtsw,	eb00060, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
- cCE(wldrb,	c100000, 2, (RIWR, ADDR),	    iwmmxt_wldstbh),
- cCE(wldrh,	c500000, 2, (RIWR, ADDR),	    iwmmxt_wldstbh),
- cCE(wldrw,	c100100, 2, (RIWR_RIWC, ADDR),	    iwmmxt_wldstw),
+ cCE(wldrb,	c100000, 2, (RIWR, ADDR_IMM),	    iwmmxt_wldstbh),
+ cCE(wldrh,	c500000, 2, (RIWR, ADDR_IMM),	    iwmmxt_wldstbh),
+ cCE(wldrw,	c100100, 2, (RIWR_RIWC, ADDR_IMM),  iwmmxt_wldstw),
  cCE(wldrd,	c500100, 2, (RIWR, ADDR),	    iwmmxt_wldstd),
  cCE(wmacs,	e600100, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wmacsz,	e700100, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
@@ -10079,38 +10395,38 @@ static const struct asm_opcode insns[] =
  cCE(wpackwus,	e900080, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wpackdss,	ef00080, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wpackdus,	ed00080, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
- cCE(wrorh,	e700040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wrorh,	e700040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wrorhg,	e700148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wrorw,	eb00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wrorw,	eb00040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wrorwg,	eb00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wrord,	ef00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wrord,	ef00040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wrordg,	ef00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
  cCE(wsadb,	e000120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsadbz,	e100120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsadh,	e400120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsadhz,	e500120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wshufh,	e0001e0, 3, (RIWR, RIWR, I255),	    iwmmxt_wshufh),
- cCE(wsllh,	e500040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsllh,	e500040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsllhg,	e500148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsllw,	e900040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsllw,	e900040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsllwg,	e900148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wslld,	ed00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wslld,	ed00040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wslldg,	ed00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrah,	e400040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrah,	e400040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsrahg,	e400148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsraw,	e800040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsraw,	e800040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsrawg,	e800148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrad,	ec00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrad,	ec00040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsradg,	ec00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrlh,	e600040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrlh,	e600040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsrlhg,	e600148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrlw,	ea00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrlw,	ea00040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsrlwg,	ea00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrld,	ee00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrld,	ee00040, 3, (RIWR, RIWR, RIWR_IMM31),	    iwmmxt_rd_rn_rm_imm5),
  cCE(wsrldg,	ee00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wstrb,	c000000, 2, (RIWR, ADDR),	    iwmmxt_wldstbh),
- cCE(wstrh,	c400000, 2, (RIWR, ADDR),	    iwmmxt_wldstbh),
- cCE(wstrw,	c000100, 2, (RIWR_RIWC, ADDR),	    iwmmxt_wldstw),
+ cCE(wstrb,	c000000, 2, (RIWR, ADDR_IMM),	    iwmmxt_wldstbh),
+ cCE(wstrh,	c400000, 2, (RIWR, ADDR_IMM),	    iwmmxt_wldstbh),
+ cCE(wstrw,	c000100, 2, (RIWR_RIWC, ADDR_IMM),  iwmmxt_wldstw),
  cCE(wstrd,	c400100, 2, (RIWR, ADDR),	    iwmmxt_wldstd),
  cCE(wsubbss,	e3001a0, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsubb,	e0001a0, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
@@ -10143,6 +10459,66 @@ static const struct asm_opcode insns[] =
  cCE(wzero,	e300000, 1, (RIWR),		    iwmmxt_wzero),
 
 #undef ARM_VARIANT
+#define ARM_VARIANT &arm_cext_iwmmxt2/* Intel Wireless MMX technology, Version 2  */
+ cCE(torvscb,	e13f190, 1, (RR),		    iwmmxt_torvscb),
+ cCE(torvsch,	e53f190, 1, (RR),		    iwmmxt_torvscb),
+ cCE(torvscw,	e93f190, 1, (RR),		    iwmmxt_torvscb),
+ cCE(wabsb, e2001c0, 2, (RIWR, RIWR), rd_rn),
+ cCE(wabsh, e6001c0, 2, (RIWR, RIWR), rd_rn),
+ cCE(wabsw, ea001c0, 2, (RIWR, RIWR), rd_rn),
+ cCE(wabsdiffb, e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wabsdiffh, e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wabsdiffw, e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(waddbhusl, e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(waddbhusm, e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(waddhc, e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(waddwc, ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(waddsubhx, ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wavg4, e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wavg4r, e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmaddsn, ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmaddsx, eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmaddun, ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmaddux, e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmerge, e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
+ cCE(wmiabb, e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiabt, e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiatb, e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiatt, e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiabbn, e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiabtn, e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiatbn, e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiattn, e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawbb, e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawbt, e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawtb, ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawtt, eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawbbn, ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawbtn, ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawtbn, ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmiawttn, ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulsmr, ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulumr, ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulwumr, ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulwsmr, ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulwum, ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulwsm, ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wmulwl, eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiabb, e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiabt, e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiatb, ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiatt, eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiabbn, ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiabtn, ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiatbn, ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmiattn, ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmulm, e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmulmr, e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmulwm, ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wqmulwmr, ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+ cCE(wsubaddhx, ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
+
+#undef ARM_VARIANT
 #define ARM_VARIANT &arm_cext_maverick /* Cirrus Maverick instructions.	*/
  cCE(cfldrs,	c100400, 2, (RMF, ADDR),	      rd_cpaddr),
  cCE(cfldrd,	c500400, 2, (RMD, ADDR),	      rd_cpaddr),
@@ -12129,9 +12505,11 @@ md_apply_fix (fixS *	fixP,
 
     case BFD_RELOC_ARM_CP_OFF_IMM:
     case BFD_RELOC_ARM_T32_CP_OFF_IMM:
-      if (value < -1023 || value > 1023 || (value & 3))
+      if (value < -1023 || value > 1023) {
 	as_bad_where (fixP->fx_file, fixP->fx_line,
 		      _("co-processor offset out of range"));
+      }
+
     cp_off_common:
       sign = value >= 0;
       if (value < 0)
@@ -12143,8 +12521,6 @@ md_apply_fix (fixS *	fixP,
 	newval = get_thumb32_insn (buf);
       newval &= 0xff7fff00;
       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
-      if (value == 0)
-	newval &= ~WRITE_BACK;
       if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
 	  || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
 	md_number_to_chars (buf, newval, INSN_SIZE);
@@ -12157,6 +12533,7 @@ md_apply_fix (fixS *	fixP,
       if (value < -255 || value > 255)
 	as_bad_where (fixP->fx_file, fixP->fx_line,
 		      _("co-processor offset out of range"));
+	value *= 4;
       goto cp_off_common;
 
     case BFD_RELOC_ARM_THUMB_OFFSET:
@@ -12971,6 +13348,8 @@ md_begin (void)
   /* Record the CPU type as well.  */
   if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
     mach = bfd_mach_arm_iWMMXt;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
+    mach = bfd_mach_arm_iWMMXt2;
   else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
     mach = bfd_mach_arm_XScale;
   else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
@@ -13346,6 +13725,7 @@ static const struct arm_cpu_option_table
   {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
   /* ??? iwmmxt is not a processor.  */
   {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL},
+  {"iwmmxt2",		ARM_ARCH_IWMMXT2, FPU_ARCH_VFP_V2, NULL},
   {"i80200",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
   /* Maverick */
   {"ep9312",	ARM_FEATURE(ARM_AEXT_V4T, ARM_CEXT_MAVERICK), FPU_ARCH_MAVERICK, "ARM920T"},
@@ -13395,6 +13775,7 @@ static const struct arm_arch_option_tabl
   {"armv7m",		ARM_ARCH_V7M,	 FPU_ARCH_VFP},
   {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP},
   {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
+  {"iwmmxt2",		ARM_ARCH_IWMMXT2, FPU_ARCH_VFP},
   {NULL,		ARM_ARCH_NONE,	 ARM_ARCH_NONE}
 };
 
@@ -13410,6 +13791,7 @@ static const struct arm_option_cpu_value
   {"maverick",		ARM_FEATURE (0, ARM_CEXT_MAVERICK)},
   {"xscale",		ARM_FEATURE (0, ARM_CEXT_XSCALE)},
   {"iwmmxt",		ARM_FEATURE (0, ARM_CEXT_IWMMXT)},
+  {"iwmmxt2",		ARM_FEATURE (0, ARM_CEXT_IWMMXT | ARM_CEXT_IWMMXT2)},
   {NULL,		ARM_ARCH_NONE}
 };
 
diff -Nurp binutils-2.16.92.old/include/opcode/arm.h binutils-2.16.92/include/opcode/arm.h
--- binutils-2.16.92.old/include/opcode/arm.h	2006-09-19 13:52:48.000000000 +0800
+++ binutils-2.16.92/include/opcode/arm.h	2006-09-19 13:53:09.000000000 +0800
@@ -49,6 +49,7 @@
 #define ARM_CEXT_XSCALE   0x00000001	/* Allow MIA etc.          */
 #define ARM_CEXT_MAVERICK 0x00000002	/* Use Cirrus/DSP coprocessor.  */
 #define ARM_CEXT_IWMMXT   0x00000004    /* Intel Wireless MMX technology coprocessor.   */
+#define ARM_CEXT_IWMMXT2 0x00000008	/* Intel Wireless MMX2 technology coprocessor.  */
 
 #define FPU_ENDIAN_PURE	 0x80000000	/* Pure-endian doubles.	      */
 #define FPU_ENDIAN_BIG	 0		/* Double words-big-endian.   */
@@ -101,6 +102,8 @@
 #define ARM_ARCH_XSCALE	ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
 #define ARM_ARCH_IWMMXT	\
  ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT)
+#define ARM_ARCH_IWMMXT2	\
+ ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT | ARM_CEXT_IWMMXT2)
 
 #define FPU_VFP_V1xD	(FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE)
 #define FPU_VFP_V1	(FPU_VFP_V1xD | FPU_VFP_EXT_V1)
diff -Nurp binutils-2.16.92.old/opcodes/arm-dis.c binutils-2.16.92/opcodes/arm-dis.c
--- binutils-2.16.92.old/opcodes/arm-dis.c	2006-09-19 13:52:48.000000000 +0800
+++ binutils-2.16.92/opcodes/arm-dis.c	2006-09-19 19:09:37.000000000 +0800
@@ -105,6 +105,85 @@ static const struct opcode32 coprocessor
     
   /* Intel Wireless MMX technology instructions.  */
 #define FIRST_IWMMXT_INSN 0x0e130130
+#if 1
+#define IWMMXT_INSN_COUNT 73
+  {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
+  {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
+  {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
+  {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
+  {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
+  {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
+  {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
+  {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
+  {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
+  {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
+  {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
+  {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
+  {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
+  {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
+  {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
+  {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
+  {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
+  {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
+  {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
+  {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
+#endif
+#if 0
 #define IWMMXT_INSN_COUNT 47
   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
@@ -155,6 +234,7 @@ static const struct opcode32 coprocessor
   {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
+#endif
 
   /* Floating point coprocessor (FPA) instructions */
   {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
@@ -1099,10 +1179,10 @@ static const char *const iwmmxt_wwnames[
 {"b", "h", "w", "d"};
 
 static const char *const iwmmxt_wwssnames[] =
-{"b", "bus", "b", "bss",
- "h", "hus", "h", "hss",
- "w", "wus", "w", "wss",
- "d", "dus", "d", "dss"
+{"b", "bus", "bc", "bss",
+ "h", "hus", "hc", "hss",
+ "w", "wus", "wc", "wss",
+ "d", "dus", "dc", "dss"
 };
 
 static const char *const iwmmxt_regnames[] =
@@ -1198,7 +1278,8 @@ print_insn_coprocessor (struct disassemb
     {
       if (insn->value == FIRST_IWMMXT_INSN
 	  && info->mach != bfd_mach_arm_XScale
-	  && info->mach != bfd_mach_arm_iWMMXt)
+	  && info->mach != bfd_mach_arm_iWMMXt
+	  && info->mach != bfd_mach_arm_iWMMXt2)
 	insn = insn + IWMMXT_INSN_COUNT;
 
       mask = insn->mask;
@@ -1270,6 +1351,53 @@ print_insn_coprocessor (struct disassemb
 			    arm_conditional [(given >> 28) & 0xf]);
 		      break;
 
+		    case 'r':
+		      {
+			int imm4 = (given >> 4) & 0xf;
+			int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
+			int ubit = (given >> 23) & 1;
+			const char *rm = arm_regnames [given & 0xf];
+			const char *rn = arm_regnames [(given >> 16) & 0xf];
+
+			switch (puw_bits)
+			  {
+			  case 1:
+			    /* fall through */
+			  case 3:
+			    func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
+			    if (imm4)
+			      func (stream, ", lsl #%d", imm4);
+			    break;
+
+			  case 4:
+			    /* fall through */
+			  case 5:
+			    /* fall through */
+			  case 6:
+			    /* fall through */
+			  case 7:
+			    func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
+			    if (imm4 > 0)
+			      func (stream, ", lsl #%d", imm4);
+			    func (stream, "]");
+			    if (puw_bits == 5 || puw_bits == 7)
+			      func (stream, "!");
+			    break;
+
+			  default:
+			    func (stream, "INVALID");
+			  }
+		      }
+		      break;
+
+		    case 'i':
+		      {
+			int imm5;
+			imm5 = ((given & 0x100) >> 4) | (given & 0xf);
+			func (stream, "%d", (imm5 == 0) ? 32 : imm5);
+		      }
+		      break;
+
 		    case 'I':
 		      /* Print a Cirrus/DSP shift immediate.  */
 		      /* Immediates are 7bit signed ints with bits 0..3 in
@@ -1728,7 +1856,8 @@ print_insn_arm (bfd_vma pc, struct disas
     {
       if (insn->value == FIRST_IWMMXT_INSN
 	  && info->mach != bfd_mach_arm_XScale
-	  && info->mach != bfd_mach_arm_iWMMXt)
+	  && info->mach != bfd_mach_arm_iWMMXt
+	  && info->mach != bfd_mach_arm_iWMMXt2)
 	insn = insn + IWMMXT_INSN_COUNT;
 
       if ((given & insn->mask) == insn->value

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-19 13:41 iwmmxt2 patch for binutils-2.16.92 Bridge Wu
@ 2006-09-19 14:21 ` Joseph S. Myers
  2006-09-19 20:58   ` Joseph S. Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph S. Myers @ 2006-09-19 14:21 UTC (permalink / raw)
  To: Bridge Wu; +Cc: binutils

On Tue, 19 Sep 2006, Bridge Wu wrote:

> Hello,
> 
> Here is iwmmxt2 patch for binutils-2.16.92. It supports Intel IWMMXT2
> instruction set.
> AS can use '-mcpu=iwmmxt2' option to assemble iwmmxt2 instructions.
> OBJDUMP can use '-m iwmmxt2' option to disassemble iwmmxt2 instructions.

This patch is missing testcases.  I have the patch produced by Wasabi for 
Intel a few years ago - which includes testcases - updated to current 
binutils and ready to submit once I receive confirmation from the FSF 
copyright clerk that the necessary assignment from Intel has gone through.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-19 14:21 ` Joseph S. Myers
@ 2006-09-19 20:58   ` Joseph S. Myers
  2006-09-20  5:20     ` Bridge Wu
  2006-09-25 16:20     ` Nick Clifton
  0 siblings, 2 replies; 9+ messages in thread
From: Joseph S. Myers @ 2006-09-19 20:58 UTC (permalink / raw)
  To: Bridge Wu; +Cc: binutils

Now the assignment issue has apparently been resolved, here is my patch 
version (against current mainline binutils), with tests and ChangeLog 
entries and without new parsing functions (which may have been needed with 
the original patch, but not since the ARM assembler parsing was rewritten) 
or #if 0 additions.  (For the original Wasabi version of these patches, 
see <ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/xscale/mainstone/>.)

Tested arm-none-eabi.  OK to commit?

bfd/
2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
            Ian Lance Taylor  <ian@wasabisystems.com>
            Ben Elliston  <bje@wasabisystems.com>

	* archures.c: Add definition for bfd_mach_arm_iWMMXt2.
	* cpu-arm.c (processors): Add bfd_mach_arm_iWMMXt2.
	(arch_info_struct, bfd_arm_update_notes): Likewise.
	(architectures): Likewise.
	(bfd_arm_merge_machines): Check for iWMMXt2.
	* bfd-in2.h: Rebuild.

gas/
2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
            Ian Lance Taylor  <ian@wasabisystems.com>
            Ben Elliston  <bje@wasabisystems.com>

	* config/tc-arm.c (arm_cext_iwmmxt2): New.
	(enum operand_parse_code): New code OP_RIWR_I32z.
	(parse_operands): Handle OP_RIWR_I32z.
	(do_iwmmxt_wmerge): New function.
	(do_iwmmxt_wldstd): Handle iwmmxt2 case where second operand is
	a register.
	(do_iwmmxt_wrwrwr_or_imm5): New function.
	(insns): Mark instructions as RIWR_I32z as appropriate.
	Also add torvsc<b,h,w>, wabs<b,h,w>, wabsdiff<b,h,w>,
	waddbhus<l,m>, waddhc, waddwc, waddsubhx, wavg4{r}, wmaddu{x,n},
	wmadds{x,n}, wmerge, wmiaxy{n}, wmiawxy{n}, wmul<sm,um>{r},
	wmulw<um,sm,l>{r}, wqmiaxy{n}, wqmulm{r}, wqmulwm{r}, wsubaddhx.
	(md_begin): Handle IWMMXT2.
	(arm_cpus): Add iwmmxt2.
	(arm_extensions): Likewise.
	(arm_archs): Likewise.

gas/testsuite/
2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
            Ian Lance Taylor  <ian@wasabisystems.com>
            Ben Elliston  <bje@wasabisystems.com>

	* gas/arm/iwmmxt2.s: New file.
	* gas/arm/iwmmxt2.d: New file.

include/opcode/
2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
            Ian Lance Taylor  <ian@wasabisystems.com>
            Ben Elliston  <bje@wasabisystems.com>

	* arm.h (ARM_CEXT_IWMMXT2, ARM_ARCH_IWMMXT2): Define.

opcodes/
2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
            Ian Lance Taylor  <ian@wasabisystems.com>
            Ben Elliston  <bje@wasabisystems.com>

	* arm-dis.c (coprocessor_opcodes): The X-qualifier to WMADD may
	only be used with the default multiply-add operation, so if N is
	set, don't bother printing X.  Add new iwmmxt instructions.
	(IWMMXT_INSN_COUNT): Update.
	(iwmmxt_wwssnames): Qualify "wwss" names at index 2, 6, 10 and 14
	with a 'c' suffix.
	(print_insn_coprocessor): Check for iWMMXt2.  Handle format
	specifiers 'r', 'i'.

Index: bfd/archures.c
===================================================================
RCS file: /cvs/src/src/bfd/archures.c,v
retrieving revision 1.118
diff -u -p -r1.118 archures.c
--- bfd/archures.c	16 Sep 2006 23:51:50 -0000	1.118
+++ bfd/archures.c	19 Sep 2006 18:32:02 -0000
@@ -273,6 +273,7 @@ DESCRIPTION
 .#define bfd_mach_arm_XScale	10
 .#define bfd_mach_arm_ep9312	11
 .#define bfd_mach_arm_iWMMXt	12
+.#define bfd_mach_arm_iWMMXt2	13
 .  bfd_arch_ns32k,     {* National Semiconductors ns32000 *}
 .  bfd_arch_w65,       {* WDC 65816 *}
 .  bfd_arch_tic30,     {* Texas Instruments TMS320C30 *}
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.399
diff -u -p -r1.399 bfd-in2.h
--- bfd/bfd-in2.h	16 Sep 2006 23:51:50 -0000	1.399
+++ bfd/bfd-in2.h	19 Sep 2006 18:32:03 -0000
@@ -1893,6 +1893,7 @@ enum bfd_architecture
 #define bfd_mach_arm_XScale    10
 #define bfd_mach_arm_ep9312    11
 #define bfd_mach_arm_iWMMXt    12
+#define bfd_mach_arm_iWMMXt2   13
   bfd_arch_ns32k,     /* National Semiconductors ns32000 */
   bfd_arch_w65,       /* WDC 65816 */
   bfd_arch_tic30,     /* Texas Instruments TMS320C30 */
Index: bfd/cpu-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/cpu-arm.c,v
retrieving revision 1.22
diff -u -p -r1.22 cpu-arm.c
--- bfd/cpu-arm.c	15 May 2006 19:57:34 -0000	1.22
+++ bfd/cpu-arm.c	19 Sep 2006 18:32:03 -0000
@@ -92,7 +92,8 @@ processors[] =
   { bfd_mach_arm_4,  "strongarm1100" },
   { bfd_mach_arm_XScale, "xscale" },
   { bfd_mach_arm_ep9312, "ep9312" },
-  { bfd_mach_arm_iWMMXt, "iwmmxt" }
+  { bfd_mach_arm_iWMMXt, "iwmmxt" },
+  { bfd_mach_arm_iWMMXt2, "iwmmxt2" }
 };
 
 static bfd_boolean
@@ -137,7 +138,8 @@ static const bfd_arch_info_type arch_inf
   N (bfd_mach_arm_5TE,    "armv5te", FALSE, & arch_info_struct[9]),
   N (bfd_mach_arm_XScale, "xscale",  FALSE, & arch_info_struct[10]),
   N (bfd_mach_arm_ep9312, "ep9312",  FALSE, & arch_info_struct[11]),
-  N (bfd_mach_arm_iWMMXt,"iwmmxt",  FALSE, NULL)
+  N (bfd_mach_arm_iWMMXt, "iwmmxt",  FALSE, & arch_info_struct[12]),
+  N (bfd_mach_arm_iWMMXt2, "iwmmxt2", FALSE, NULL)
 };
 
 const bfd_arch_info_type bfd_arm_arch =
@@ -179,7 +181,9 @@ bfd_arm_merge_machines (bfd *ibfd, bfd *
      Intel XScale binary, since these architecture have co-processors which
      will not both be present on the same physical hardware.  */
   else if (in == bfd_mach_arm_ep9312
-	   && (out == bfd_mach_arm_XScale || out == bfd_mach_arm_iWMMXt))
+	   && (out == bfd_mach_arm_XScale
+	       || out == bfd_mach_arm_iWMMXt
+	       || out == bfd_mach_arm_iWMMXt2))
     {
       _bfd_error_handler (_("\
 ERROR: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
@@ -188,7 +192,9 @@ ERROR: %B is compiled for the EP9312, wh
       return FALSE;
     }
   else if (out == bfd_mach_arm_ep9312
-	   && (in == bfd_mach_arm_XScale || in == bfd_mach_arm_iWMMXt))
+	   && (in == bfd_mach_arm_XScale
+	       || in == bfd_mach_arm_iWMMXt
+	       || in == bfd_mach_arm_iWMMXt2))
     {
       _bfd_error_handler (_("\
 ERROR: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
@@ -309,6 +315,7 @@ bfd_arm_update_notes (bfd *abfd, const c
     case bfd_mach_arm_XScale:  expected = "XScale"; break;
     case bfd_mach_arm_ep9312:  expected = "ep9312"; break;
     case bfd_mach_arm_iWMMXt:  expected = "iWMMXt"; break;
+    case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
     }
 
   if (strcmp (arch_string, expected) != 0)
@@ -355,7 +362,8 @@ architectures[] =
   { "armv5te", bfd_mach_arm_5TE },
   { "XScale",  bfd_mach_arm_XScale },
   { "ep9312",  bfd_mach_arm_ep9312 },
-  { "iWMMXt",  bfd_mach_arm_iWMMXt }
+  { "iWMMXt",  bfd_mach_arm_iWMMXt },
+  { "iWMMXt2", bfd_mach_arm_iWMMXt2 }
 };
 
 /* Extract the machine number stored in a note section.  */
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.293
diff -u -p -r1.293 tc-arm.c
--- gas/config/tc-arm.c	16 Sep 2006 16:24:28 -0000	1.293
+++ gas/config/tc-arm.c	19 Sep 2006 18:32:06 -0000
@@ -201,6 +201,8 @@ static const arm_feature_set arm_arch_fu
 static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
 static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
 
+static const arm_feature_set arm_cext_iwmmxt2 =
+  ARM_FEATURE (0, ARM_CEXT_IWMMXT2);
 static const arm_feature_set arm_cext_iwmmxt =
   ARM_FEATURE (0, ARM_CEXT_IWMMXT);
 static const arm_feature_set arm_cext_xscale =
@@ -5371,6 +5373,7 @@ enum operand_parse_code
   OP_VMOV,      /* Neon VMOV operands.  */
   OP_RNDQ_IMVNb,/* Neon D or Q reg, or immediate good for VMVN.  */
   OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift.  */
+  OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2.  */
 
   OP_I0,        /* immediate zero */
   OP_I7,	/* immediate value 0 .. 7 */
@@ -5793,6 +5796,9 @@ parse_operands (char *str, const unsigne
 	  inst.operands[i].isreg = 1;
 	  break;
 
+	case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
+	I32z:		  po_imm_or_fail (0, 32, FALSE);	  break;
+
 	  /* Two kinds of register */
 	case OP_RIWR_RIWC:
 	  {
@@ -7841,6 +7847,15 @@ do_iwmmxt_waligni (void)
 }
 
 static void
+do_iwmmxt_wmerge (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= inst.operands[2].reg;
+  inst.instruction |= inst.operands[3].imm << 21;
+}
+
+static void
 do_iwmmxt_wmov (void)
 {
   /* WMOV rD, rN is an alias for WOR rD, rN, rN.  */
@@ -7879,7 +7894,23 @@ static void
 do_iwmmxt_wldstd (void)
 {
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_arm_cp_address (1, TRUE, FALSE, 0);
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
+      && inst.operands[1].immisreg)
+    {
+      inst.instruction &= ~0x1a000ff;
+      inst.instruction |= (0xf << 28);
+      if (inst.operands[1].preind)
+	inst.instruction |= PRE_INDEX;
+      if (!inst.operands[1].negative)
+	inst.instruction |= INDEX_UP;
+      if (inst.operands[1].writeback)
+	inst.instruction |= WRITE_BACK;
+      inst.instruction |= inst.operands[1].reg << 16;
+      inst.instruction |= inst.reloc.exp.X_add_number << 4;
+      inst.instruction |= inst.operands[1].imm;
+    }
+  else
+    encode_arm_cp_address (1, TRUE, FALSE, 0);
 }
 
 static void
@@ -7899,6 +7930,56 @@ do_iwmmxt_wzero (void)
   inst.instruction |= inst.operands[0].reg << 12;
   inst.instruction |= inst.operands[0].reg << 16;
 }
+
+static void
+do_iwmmxt_wrwrwr_or_imm5 (void)
+{
+  if (inst.operands[2].isreg)
+    do_rd_rn_rm ();
+  else {
+    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
+		_("immediate operand requires iWMMXt2"));
+    do_rd_rn ();
+    if (inst.operands[2].imm == 0)
+      {
+	switch ((inst.instruction >> 20) & 0xf)
+	  {
+	  case 4:
+	  case 5:
+	  case 6:
+	  case 7: 
+	    /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16.  */
+	    inst.operands[2].imm = 16;
+	    inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
+	    break;
+	  case 8:
+	  case 9:
+	  case 10:
+	  case 11:
+	    /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32.  */
+	    inst.operands[2].imm = 32;
+	    inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
+	    break;
+	  case 12:
+	  case 13:
+	  case 14:
+	  case 15:
+	    {
+	      /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn.  */
+	      unsigned long wrn;
+	      wrn = (inst.instruction >> 16) & 0xf;
+	      inst.instruction &= 0xff0fff0f;
+	      inst.instruction |= wrn;
+	      /* Bail out here; the instruction is now assembled.  */
+	      return;
+	    }
+	  }
+      }
+    /* Map 32 -> 0, etc.  */
+    inst.operands[2].imm &= 0x1f;
+    inst.instruction |= (0xf << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
+  }
+}
 \f
 /* Cirrus Maverick instructions.  Simple 2-, 3-, and 4-register
    operations first, then control, shift, and load/store.  */
@@ -15869,34 +15950,34 @@ static const struct asm_opcode insns[] =
  cCE(wpackwus,	e900080, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wpackdss,	ef00080, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wpackdus,	ed00080, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
- cCE(wrorh,	e700040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wrorh,	e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wrorhg,	e700148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wrorw,	eb00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wrorw,	eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wrorwg,	eb00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wrord,	ef00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wrord,	ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wrordg,	ef00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
  cCE(wsadb,	e000120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsadbz,	e100120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsadh,	e400120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wsadhz,	e500120, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
  cCE(wshufh,	e0001e0, 3, (RIWR, RIWR, I255),	    iwmmxt_wshufh),
- cCE(wsllh,	e500040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsllh,	e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsllhg,	e500148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsllw,	e900040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsllw,	e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsllwg,	e900148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wslld,	ed00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wslld,	ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wslldg,	ed00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrah,	e400040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrah,	e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsrahg,	e400148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsraw,	e800040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsraw,	e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsrawg,	e800148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrad,	ec00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrad,	ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsradg,	ec00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrlh,	e600040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrlh,	e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsrlhg,	e600148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrlw,	ea00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrlw,	ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsrlwg,	ea00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
- cCE(wsrld,	ee00040, 3, (RIWR, RIWR, RIWR),	    rd_rn_rm),
+ cCE(wsrld,	ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
  cCE(wsrldg,	ee00148, 3, (RIWR, RIWR, RIWG),	    rd_rn_rm),
  cCE(wstrb,	c000000, 2, (RIWR, ADDR),	    iwmmxt_wldstbh),
  cCE(wstrh,	c400000, 2, (RIWR, ADDR),	    iwmmxt_wldstbh),
@@ -15933,6 +16014,66 @@ static const struct asm_opcode insns[] =
  cCE(wzero,	e300000, 1, (RIWR),		    iwmmxt_wzero),
 
 #undef ARM_VARIANT
+#define ARM_VARIANT &arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2.  */
+ cCE(torvscb,   e13f190, 1, (RR),		    iwmmxt_tandorc),
+ cCE(torvsch,   e53f190, 1, (RR),		    iwmmxt_tandorc),
+ cCE(torvscw,   e93f190, 1, (RR),		    iwmmxt_tandorc),
+ cCE(wabsb,     e2001c0, 2, (RIWR, RIWR),           rd_rn),
+ cCE(wabsh,     e6001c0, 2, (RIWR, RIWR),           rd_rn),
+ cCE(wabsw,     ea001c0, 2, (RIWR, RIWR),           rd_rn),
+ cCE(wabsdiffb, e1001c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wabsdiffh, e5001c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wabsdiffw, e9001c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(waddbhusl, e2001a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(waddbhusm, e6001a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(waddhc,    e600180, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(waddwc,    ea00180, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(waddsubhx, ea001a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wavg4,	e400000, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wavg4r,    e500000, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmaddsn,   ee00100, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmaddsx,   eb00100, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmaddun,   ec00100, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmaddux,   e900100, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmerge,    e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
+ cCE(wmiabb,    e0000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiabt,    e1000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiatb,    e2000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiatt,    e3000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiabbn,   e4000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiabtn,   e5000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiatbn,   e6000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiattn,   e7000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawbb,   e800120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawbt,   e900120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawtb,   ea00120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawtt,   eb00120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawbbn,  ec00120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawbtn,  ed00120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawtbn,  ee00120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmiawttn,  ef00120, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulsmr,   ef00100, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulumr,   ed00100, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulwumr,  ec000c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulwsmr,  ee000c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulwum,   ed000c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulwsm,   ef000c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wmulwl,    eb000c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiabb,   e8000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiabt,   e9000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiatb,   ea000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiatt,   eb000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiabbn,  ec000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiabtn,  ed000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiatbn,  ee000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmiattn,  ef000a0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmulm,    e100080, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmulmr,   e300080, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmulwm,   ec000e0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wqmulwmr,  ee000e0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+ cCE(wsubaddhx, ed001c0, 3, (RIWR, RIWR, RIWR),     rd_rn_rm),
+
+#undef ARM_VARIANT
 #define ARM_VARIANT &arm_cext_maverick /* Cirrus Maverick instructions.	*/
  cCE(cfldrs,	c100400, 2, (RMF, ADDRGLDC),	      rd_cpaddr),
  cCE(cfldrd,	c500400, 2, (RMD, ADDRGLDC),	      rd_cpaddr),
@@ -19168,7 +19309,9 @@ md_begin (void)
 #endif
 
   /* Record the CPU type as well.  */
-  if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
+    mach = bfd_mach_arm_iWMMXt2;
+  else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
     mach = bfd_mach_arm_iWMMXt;
   else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
     mach = bfd_mach_arm_XScale;
@@ -19547,6 +19690,7 @@ static const struct arm_cpu_option_table
   {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
   /* ??? iwmmxt is not a processor.  */
   {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL},
+  {"iwmmxt2",		ARM_ARCH_IWMMXT2,FPU_ARCH_VFP_V2, NULL},
   {"i80200",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
   /* Maverick */
   {"ep9312",	ARM_FEATURE(ARM_AEXT_V4T, ARM_CEXT_MAVERICK), FPU_ARCH_MAVERICK, "ARM920T"},
@@ -19596,6 +19740,7 @@ static const struct arm_arch_option_tabl
   {"armv7m",		ARM_ARCH_V7M,	 FPU_ARCH_VFP},
   {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP},
   {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
+  {"iwmmxt2",		ARM_ARCH_IWMMXT2,FPU_ARCH_VFP},
   {NULL,		ARM_ARCH_NONE,	 ARM_ARCH_NONE}
 };
 
@@ -19611,6 +19756,7 @@ static const struct arm_option_cpu_value
   {"maverick",		ARM_FEATURE (0, ARM_CEXT_MAVERICK)},
   {"xscale",		ARM_FEATURE (0, ARM_CEXT_XSCALE)},
   {"iwmmxt",		ARM_FEATURE (0, ARM_CEXT_IWMMXT)},
+  {"iwmmxt2",		ARM_FEATURE (0, ARM_CEXT_IWMMXT2)},
   {NULL,		ARM_ARCH_NONE}
 };
 
Index: gas/testsuite/gas/arm/iwmmxt2.d
===================================================================
RCS file: gas/testsuite/gas/arm/iwmmxt2.d
diff -N gas/testsuite/gas/arm/iwmmxt2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/iwmmxt2.d	19 Sep 2006 18:32:06 -0000
@@ -0,0 +1,119 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -miwmmxt
+#name: Intel(r) Wireless MMX(tm) technology instructions version 2
+#as: -mcpu=xscale+iwmmxt+iwmmxt2 -EL
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <iwmmxt2> ee654186[ 	]+waddhc[ 	]+wr4, wr5, wr6
+0+004 <[^>]*> eea87189[ 	]+waddwc[ 	]+wr7, wr8, wr9
+0+008 <[^>]*> ce954106[ 	]+wmadduxgt[ 	]+wr4, wr5, wr6
+0+00c <[^>]*> 0ec87109[ 	]+wmadduneq[ 	]+wr7, wr8, wr9
+0+010 <[^>]*> 1eb54106[ 	]+wmaddsxne[ 	]+wr4, wr5, wr6
+0+014 <[^>]*> aee87109[ 	]+wmaddsnge[ 	]+wr7, wr8, wr9
+0+018 <[^>]*> eed21103[ 	]+wmulumr[ 	]+wr1, wr2, wr3
+0+01c <[^>]*> eef21103[ 	]+wmulsmr[ 	]+wr1, wr2, wr3
+0+020 <[^>]*> ce13f190[ 	]+torvscbgt[ 	]+pc
+0+024 <[^>]*> 1e53f190[ 	]+torvschne[ 	]+pc
+0+028 <[^>]*> 0e93f190[ 	]+torvscweq[ 	]+pc
+0+02c <[^>]*> ee2211c0[ 	]+wabsb[ 	]+wr1, wr2
+0+030 <[^>]*> ee6431c0[ 	]+wabsh[ 	]+wr3, wr4
+0+034 <[^>]*> eea651c0[ 	]+wabsw[ 	]+wr5, wr6
+0+038 <[^>]*> ce2211c0[ 	]+wabsbgt[ 	]+wr1, wr2
+0+03c <[^>]*> ee1211c3[ 	]+wabsdiffb[ 	]+wr1, wr2, wr3
+0+040 <[^>]*> ee5541c6[ 	]+wabsdiffh[ 	]+wr4, wr5, wr6
+0+044 <[^>]*> ee9871c9[ 	]+wabsdiffw[ 	]+wr7, wr8, wr9
+0+048 <[^>]*> ce1211c3[ 	]+wabsdiffbgt[ 	]+wr1, wr2, wr3
+0+04c <[^>]*> ee6211a3[ 	]+waddbhusm[ 	]+wr1, wr2, wr3
+0+050 <[^>]*> ee2541a6[ 	]+waddbhusl[ 	]+wr4, wr5, wr6
+0+054 <[^>]*> ce6211a3[ 	]+waddbhusmgt[ 	]+wr1, wr2, wr3
+0+058 <[^>]*> ce2541a6[ 	]+waddbhuslgt[ 	]+wr4, wr5, wr6
+0+05c <[^>]*> ee421003[ 	]+wavg4[ 	]+wr1, wr2, wr3
+0+060 <[^>]*> ce454006[ 	]+wavg4gt[ 	]+wr4, wr5, wr6
+0+064 <[^>]*> ee521003[ 	]+wavg4r[ 	]+wr1, wr2, wr3
+0+068 <[^>]*> ce554006[ 	]+wavg4rgt[ 	]+wr4, wr5, wr6
+0+06c <[^>]*> fc711102[ 	]+wldrd[ 	]+wr1, \[r1\], -r2
+0+070 <[^>]*> fc712132[ 	]+wldrd[ 	]+wr2, \[r1\], -r2, lsl #3
+0+074 <[^>]*> fcf13102[ 	]+wldrd[ 	]+wr3, \[r1\], \+r2
+0+078 <[^>]*> fcf14142[ 	]+wldrd[ 	]+wr4, \[r1\], \+r2, lsl #4
+0+07c <[^>]*> fd515102[ 	]+wldrd[ 	]+wr5, \[r1, -r2\]
+0+080 <[^>]*> fd516132[ 	]+wldrd[ 	]+wr6, \[r1, -r2, lsl #3\]
+0+084 <[^>]*> fdd17102[ 	]+wldrd[ 	]wr7, \[r1, \+r2\]
+0+088 <[^>]*> fdd18142[ 	]+wldrd[ 	]wr8, \[r1, \+r2, lsl #4\]
+0+08c <[^>]*> fd719102[ 	]+wldrd[ 	]wr9, \[r1, -r2\]!
+0+090 <[^>]*> fd71a132[ 	]+wldrd[ 	]wr10, \[r1, -r2, lsl #3\]!
+0+094 <[^>]*> fdf1b102[ 	]+wldrd[ 	]wr11, \[r1, \+r2\]!
+0+098 <[^>]*> fdf1c142[ 	]+wldrd[ 	]wr12, \[r1, \+r2, lsl #4\]!
+0+09c <[^>]*> ee821083[ 	]+wmerge[ 	]wr1, wr2, wr3, #4
+0+0a0 <[^>]*> ce821083[ 	]+wmergegt[ 	]wr1, wr2, wr3, #4
+0+0a4 <[^>]*> 0e3210a3[ 	]+wmiatteq[ 	]wr1, wr2, wr3
+0+0a8 <[^>]*> ce2210a3[ 	]+wmiatbgt[ 	]wr1, wr2, wr3
+0+0ac <[^>]*> 1e1210a3[ 	]+wmiabtne[ 	]wr1, wr2, wr3
+0+0b0 <[^>]*> ce0210a3[ 	]+wmiabbgt[ 	]wr1, wr2, wr3
+0+0b4 <[^>]*> 0e7210a3[ 	]+wmiattneq[ 	]wr1, wr2, wr3
+0+0b8 <[^>]*> 1e6210a3[ 	]+wmiatbnne[ 	]wr1, wr2, wr3
+0+0bc <[^>]*> ce5210a3[ 	]+wmiabtngt[ 	]wr1, wr2, wr3
+0+0c0 <[^>]*> 0e4210a3[ 	]+wmiabbneq[ 	]wr1, wr2, wr3
+0+0c4 <[^>]*> 0eb21123[ 	]+wmiawtteq[ 	]wr1, wr2, wr3
+0+0c8 <[^>]*> cea21123[ 	]+wmiawtbgt[ 	]wr1, wr2, wr3
+0+0cc <[^>]*> 1e921123[ 	]+wmiawbtne[ 	]wr1, wr2, wr3
+0+0d0 <[^>]*> ce821123[ 	]+wmiawbbgt[ 	]wr1, wr2, wr3
+0+0d4 <[^>]*> 1ef21123[ 	]+wmiawttnne[ 	]wr1, wr2, wr3
+0+0d8 <[^>]*> cee21123[ 	]+wmiawtbngt[ 	]wr1, wr2, wr3
+0+0dc <[^>]*> 0ed21123[ 	]+wmiawbtneq[ 	]wr1, wr2, wr3
+0+0e0 <[^>]*> 1ec21123[ 	]+wmiawbbnne[ 	]wr1, wr2, wr3
+0+0e4 <[^>]*> 0ed210c3[ 	]+wmulwumeq[ 	]wr1, wr2, wr3
+0+0e8 <[^>]*> cec210c3[ 	]+wmulwumrgt[ 	]wr1, wr2, wr3
+0+0ec <[^>]*> 1ef210c3[ 	]+wmulwsmne[ 	]wr1, wr2, wr3
+0+0f0 <[^>]*> 0ee210c3[ 	]+wmulwsmreq[ 	]wr1, wr2, wr3
+0+0f4 <[^>]*> ceb210c3[ 	]+wmulwlgt[ 	]wr1, wr2, wr3
+0+0f8 <[^>]*> aeb210c3[ 	]+wmulwlge[ 	]wr1, wr2, wr3
+0+0fc <[^>]*> 1eb210a3[ 	]+wqmiattne[ 	]wr1, wr2, wr3
+0+100 <[^>]*> 0ef210a3[ 	]+wqmiattneq[ 	]wr1, wr2, wr3
+0+104 <[^>]*> cea210a3[ 	]+wqmiatbgt[ 	]wr1, wr2, wr3
+0+108 <[^>]*> aee210a3[ 	]+wqmiatbnge[ 	]wr1, wr2, wr3
+0+10c <[^>]*> 1e9210a3[ 	]+wqmiabtne[ 	]wr1, wr2, wr3
+0+110 <[^>]*> 0ed210a3[ 	]+wqmiabtneq[ 	]wr1, wr2, wr3
+0+114 <[^>]*> ce8210a3[ 	]+wqmiabbgt[ 	]wr1, wr2, wr3
+0+118 <[^>]*> 1ec210a3[ 	]+wqmiabbnne[ 	]wr1, wr2, wr3
+0+11c <[^>]*> ce121083[ 	]+wqmulmgt[ 	]wr1, wr2, wr3
+0+120 <[^>]*> 0e321083[ 	]+wqmulmreq[ 	]wr1, wr2, wr3
+0+124 <[^>]*> cec210e3[ 	]+wqmulwmgt[ 	]wr1, wr2, wr3
+0+128 <[^>]*> 0ee210e3[ 	]+wqmulwmreq[ 	]wr1, wr2, wr3
+0+12c <[^>]*> fc611102[ 	]+wstrd[ 	]+wr1, \[r1\], -r2
+0+130 <[^>]*> fc612132[ 	]+wstrd[ 	]+wr2, \[r1\], -r2, lsl #3
+0+134 <[^>]*> fce13102[ 	]+wstrd[ 	]+wr3, \[r1\], \+r2
+0+138 <[^>]*> fce14142[ 	]+wstrd[ 	]+wr4, \[r1\], \+r2, lsl #4
+0+13c <[^>]*> fd415102[ 	]+wstrd[ 	]+wr5, \[r1, -r2\]
+0+140 <[^>]*> fd416132[ 	]+wstrd[ 	]+wr6, \[r1, -r2, lsl #3\]
+0+144 <[^>]*> fdc17102[ 	]+wstrd[ 	]wr7, \[r1, \+r2\]
+0+148 <[^>]*> fdc18142[ 	]+wstrd[ 	]wr8, \[r1, \+r2, lsl #4\]
+0+14c <[^>]*> fd619102[ 	]+wstrd[ 	]wr9, \[r1, -r2\]!
+0+150 <[^>]*> fd61a132[ 	]+wstrd[ 	]wr10, \[r1, -r2, lsl #3\]!
+0+154 <[^>]*> fde1b102[ 	]+wstrd[ 	]wr11, \[r1, \+r2\]!
+0+158 <[^>]*> fde1c142[ 	]+wstrd[ 	]wr12, \[r1, \+r2, lsl #4\]!
+0+15c <[^>]*> ced211c3[ 	]+wsubaddhxgt[ 	]wr1, wr2, wr3
+0+160 <[^>]*> fe721140[ 	]+wrorh[ 	]wr1, wr2, #16
+0+164 <[^>]*> feb21040[ 	]+wrorw[ 	]wr1, wr2, #32
+0+168 <[^>]*> ee021002[ 	]+wor[ 	]wr1, wr2, wr2
+0+16c <[^>]*> fe721145[ 	]+wrorh[ 	]wr1, wr2, #21
+0+170 <[^>]*> feb2104d[ 	]+wrorw[ 	]wr1, wr2, #13
+0+174 <[^>]*> fef2104e[ 	]+wrord[ 	]wr1, wr2, #14
+0+178 <[^>]*> fe721140[ 	]+wrorh[ 	]wr1, wr2, #16
+0+17c <[^>]*> feb21040[ 	]+wrorw[ 	]wr1, wr2, #32
+0+180 <[^>]*> ee021002[ 	]+wor[ 	]wr1, wr2, wr2
+0+184 <[^>]*> fe59204b[ 	]+wsllh[ 	]wr2, wr9, #11
+0+188 <[^>]*> fe95304d[ 	]+wsllw[ 	]wr3, wr5, #13
+0+18c <[^>]*> fed8304f[ 	]+wslld[ 	]wr3, wr8, #15
+0+190 <[^>]*> fe721140[ 	]+wrorh[ 	]wr1, wr2, #16
+0+194 <[^>]*> feb21040[ 	]+wrorw[ 	]wr1, wr2, #32
+0+198 <[^>]*> ee021002[ 	]+wor[ 	]wr1, wr2, wr2
+0+19c <[^>]*> fe49204c[ 	]+wsrah[ 	]wr2, wr9, #12
+0+1a0 <[^>]*> fe85304e[ 	]+wsraw[ 	]wr3, wr5, #14
+0+1a4 <[^>]*> fec83140[ 	]+wsrad[ 	]wr3, wr8, #16
+0+1a8 <[^>]*> fe721140[ 	]+wrorh[ 	]wr1, wr2, #16
+0+1ac <[^>]*> feb21040[ 	]+wrorw[ 	]wr1, wr2, #32
+0+1b0 <[^>]*> ee021002[ 	]+wor[ 	]wr1, wr2, wr2
+0+1b4 <[^>]*> fe69204c[ 	]+wsrlh[ 	]wr2, wr9, #12
+0+1b8 <[^>]*> fea5304e[ 	]+wsrlw[ 	]wr3, wr5, #14
+0+1bc <[^>]*> fee83140[ 	]+wsrld[ 	]wr3, wr8, #16
Index: gas/testsuite/gas/arm/iwmmxt2.s
===================================================================
RCS file: gas/testsuite/gas/arm/iwmmxt2.s
diff -N gas/testsuite/gas/arm/iwmmxt2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/iwmmxt2.s	19 Sep 2006 18:32:06 -0000
@@ -0,0 +1,137 @@
+	.text
+	.global iwmmxt2
+iwmmxt2:
+
+	waddhc		wr4, wr5, wr6
+	waddwc		wr7, wr8, wr9
+
+	wmadduxgt	wr4, wr5, wr6
+	wmadduneq	wr7, wr8, wr9
+	wmaddsxne	wr4, wr5, wr6
+	wmaddsnge	wr7, wr8, wr9
+
+	wmulumr		wr1, wr2, wr3
+	wmulsmr		wr1, wr2, wr3
+
+	torvscbgt	r15
+	torvschne	r15
+	torvscweq	r15
+
+	wabsb		wr1, wr2
+	wabsh		wr3, wr4
+	wabsw		wr5, wr6
+	wabsbgt		wr1, wr2
+
+	wabsdiffb	wr1, wr2, wr3
+	wabsdiffh	wr4, wr5, wr6
+	wabsdiffw	wr7, wr8, wr9
+	wabsdiffbgt	wr1, wr2, wr3
+
+	waddbhusm	wr1, wr2, wr3
+	waddbhusl	wr4, wr5, wr6
+	waddbhusmgt	wr1, wr2, wr3
+	waddbhuslgt	wr4, wr5, wr6
+
+	wavg4		wr1, wr2, wr3
+	wavg4gt		wr4, wr5, wr6
+	wavg4r		wr1, wr2, wr3
+	wavg4rgt	wr4, wr5, wr6
+
+	wldrd		wr1, [r1], -r2
+	wldrd		wr2, [r1], -r2,lsl #3
+	wldrd		wr3, [r1], +r2
+	wldrd		wr4, [r1], +r2,lsl #4
+	wldrd		wr5, [r1, -r2]
+	wldrd		wr6, [r1, -r2,lsl #3]
+	wldrd		wr7, [r1, +r2]
+	wldrd		wr8, [r1, +r2,lsl #4]
+	wldrd		wr9, [r1, -r2]!
+	wldrd		wr10, [r1, -r2,lsl #3]!
+	wldrd		wr11, [r1, +r2]!
+	wldrd		wr12, [r1, +r2,lsl #4]!
+
+	wmerge		wr1, wr2, wr3, #4
+	wmergegt	wr1, wr2, wr3, #4
+
+	wmiatteq	wr1, wr2, wr3
+	wmiatbgt	wr1, wr2, wr3
+	wmiabtne	wr1, wr2, wr3
+	wmiabbgt	wr1, wr2, wr3
+	wmiattneq	wr1, wr2, wr3
+	wmiatbnne	wr1, wr2, wr3
+	wmiabtngt	wr1, wr2, wr3
+	wmiabbneq	wr1, wr2, wr3
+
+	wmiawtteq	wr1, wr2, wr3
+	wmiawtbgt	wr1, wr2, wr3
+	wmiawbtne	wr1, wr2, wr3
+	wmiawbbgt	wr1, wr2, wr3
+	wmiawttnne	wr1, wr2, wr3
+	wmiawtbngt	wr1, wr2, wr3
+	wmiawbtneq	wr1, wr2, wr3
+	wmiawbbnne	wr1, wr2, wr3
+
+	wmulwumeq	wr1, wr2, wr3
+	wmulwumrgt	wr1, wr2, wr3
+	wmulwsmne	wr1, wr2, wr3
+	wmulwsmreq	wr1, wr2, wr3
+	wmulwlgt	wr1, wr2, wr3
+	wmulwlge	wr1, wr2, wr3
+
+	wqmiattne	wr1, wr2, wr3
+	wqmiattneq	wr1, wr2, wr3
+	wqmiatbgt	wr1, wr2, wr3
+	wqmiatbnge	wr1, wr2, wr3
+	wqmiabtne	wr1, wr2, wr3
+	wqmiabtneq	wr1, wr2, wr3
+	wqmiabbgt	wr1, wr2, wr3
+	wqmiabbnne	wr1, wr2, wr3
+
+	wqmulmgt	wr1, wr2, wr3
+	wqmulmreq	wr1, wr2, wr3
+
+	wqmulwmgt	wr1, wr2, wr3
+	wqmulwmreq	wr1, wr2, wr3
+
+	wstrd		wr1, [r1], -r2
+	wstrd		wr2, [r1], -r2,lsl #3
+	wstrd		wr3, [r1], +r2
+	wstrd		wr4, [r1], +r2,lsl #4
+	wstrd		wr5, [r1, -r2]
+	wstrd		wr6, [r1, -r2,lsl #3]
+	wstrd		wr7, [r1, +r2]
+	wstrd		wr8, [r1, +r2,lsl #4]
+	wstrd		wr9, [r1, -r2]!
+	wstrd		wr10, [r1, -r2,lsl #3]!
+	wstrd		wr11, [r1, +r2]!
+	wstrd		wr12, [r1, +r2,lsl #4]!
+
+	wsubaddhxgt	wr1, wr2, wr3
+
+	wrorh		wr1, wr2, #0
+	wrorw		wr1, wr2, #0
+	wrord		wr1, wr2, #0
+	wrorh		wr1, wr2, #21
+	wrorw		wr1, wr2, #13
+	wrord		wr1, wr2, #14
+
+	wsllh		wr1, wr2, #0
+	wsllw		wr1, wr2, #0
+	wslld		wr1, wr2, #0
+	wsllh		wr2, wr9, #11
+	wsllw		wr3, wr5, #13
+	wslld		wr3, wr8, #15
+
+	wsrah		wr1, wr2, #0
+	wsraw		wr1, wr2, #0
+	wsrad		wr1, wr2, #0
+	wsrah		wr2, wr9, #12
+	wsraw		wr3, wr5, #14
+	wsrad		wr3, wr8, #16
+
+	wsrlh		wr1, wr2, #0
+	wsrlw		wr1, wr2, #0
+	wsrld		wr1, wr2, #0
+	wsrlh		wr2, wr9, #12
+	wsrlw		wr3, wr5, #14
+	wsrld		wr3, wr8, #16
Index: include/opcode/arm.h
===================================================================
RCS file: /cvs/src/src/include/opcode/arm.h,v
retrieving revision 1.10
diff -u -p -r1.10 arm.h
--- include/opcode/arm.h	26 Apr 2006 15:41:16 -0000	1.10
+++ include/opcode/arm.h	19 Sep 2006 18:32:06 -0000
@@ -49,6 +49,7 @@
 #define ARM_CEXT_XSCALE   0x00000001	/* Allow MIA etc.          */
 #define ARM_CEXT_MAVERICK 0x00000002	/* Use Cirrus/DSP coprocessor.  */
 #define ARM_CEXT_IWMMXT   0x00000004    /* Intel Wireless MMX technology coprocessor.   */
+#define ARM_CEXT_IWMMXT2  0x00000008    /* Intel Wireless MMX technology coprocessor version 2.   */
 
 #define FPU_ENDIAN_PURE	 0x80000000	/* Pure-endian doubles.	      */
 #define FPU_ENDIAN_BIG	 0		/* Double words-big-endian.   */
@@ -103,6 +104,8 @@
 #define ARM_ARCH_XSCALE	ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
 #define ARM_ARCH_IWMMXT	\
  ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT)
+#define ARM_ARCH_IWMMXT2	\
+ ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT | ARM_CEXT_IWMMXT2)
 
 #define FPU_VFP_V1xD	(FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE)
 #define FPU_VFP_V1	(FPU_VFP_V1xD | FPU_VFP_EXT_V1)
Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.71
diff -u -p -r1.71 arm-dis.c
--- opcodes/arm-dis.c	16 Sep 2006 18:12:17 -0000	1.71
+++ opcodes/arm-dis.c	19 Sep 2006 18:32:07 -0000
@@ -98,7 +98,11 @@ struct opcode16
    %L			print as an iWMMXt N/M width field.
    %Z			print the Immediate of a WSHUFH instruction.
    %l			like 'A' except use byte offsets for 'B' & 'H'
-			versions.  */
+			versions.
+   %i			print 5-bit immediate in bits 8,3..0
+			(print "32" when 0)
+   %r			print register offset address for wldt/wstr instruction
+*/
 
 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
 
@@ -113,7 +117,7 @@ static const struct opcode32 coprocessor
     
   /* Intel Wireless MMX technology instructions.  */
 #define FIRST_IWMMXT_INSN 0x0e130130
-#define IWMMXT_INSN_COUNT 47
+#define IWMMXT_INSN_COUNT 73
   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
   {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
@@ -128,37 +132,63 @@ static const struct opcode32 coprocessor
   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
   {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
   {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
   {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
   {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
+  {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
+  {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
   {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
+  {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
   {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
   {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
   {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+  {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
   {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
   {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
   {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
+  {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
@@ -1417,10 +1447,10 @@ static const char *const iwmmxt_wwnames[
 {"b", "h", "w", "d"};
 
 static const char *const iwmmxt_wwssnames[] =
-{"b", "bus", "b", "bss",
- "h", "hus", "h", "hss",
- "w", "wus", "w", "wss",
- "d", "dus", "d", "dss"
+{"b", "bus", "bc", "bss",
+ "h", "hus", "hc", "hss",
+ "w", "wus", "wc", "wss",
+ "d", "dus", "dc", "dss"
 };
 
 static const char *const iwmmxt_regnames[] =
@@ -1563,7 +1593,8 @@ print_insn_coprocessor (bfd_vma pc, stru
     {
       if (insn->value == FIRST_IWMMXT_INSN
 	  && info->mach != bfd_mach_arm_XScale
-	  && info->mach != bfd_mach_arm_iWMMXt)
+	  && info->mach != bfd_mach_arm_iWMMXt
+	  && info->mach != bfd_mach_arm_iWMMXt2)
 	insn = insn + IWMMXT_INSN_COUNT;
 
       mask = insn->mask;
@@ -1977,6 +2008,53 @@ print_insn_coprocessor (bfd_vma pc, stru
 			}
 			break;
 
+		      case 'r':
+			{
+			  int imm4 = (given >> 4) & 0xf;
+			  int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
+			  int ubit = (given >> 23) & 1;
+			  const char *rm = arm_regnames [given & 0xf];
+			  const char *rn = arm_regnames [(given >> 16) & 0xf];
+
+			  switch (puw_bits)
+			    {
+			    case 1:
+			      /* fall through */
+			    case 3:
+			      func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
+			      if (imm4)
+				func (stream, ", lsl #%d", imm4);
+			      break;
+
+			    case 4:
+			      /* fall through */
+			    case 5:
+			      /* fall through */
+			    case 6:
+			      /* fall through */
+			    case 7:
+			      func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
+			      if (imm4 > 0)
+				func (stream, ", lsl #%d", imm4);
+			      func (stream, "]");
+			      if (puw_bits == 5 || puw_bits == 7)
+				func (stream, "!");
+			      break;
+
+			    default:
+			      func (stream, "INVALID");
+			    }
+			}
+			break;
+
+		      case 'i':
+			{
+			  long imm5;
+			  imm5 = ((given & 0x100) >> 4) | (given & 0xf);
+			  func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
+			}
+			break;
+
 		      default:
 			abort ();
 		      }

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-19 20:58   ` Joseph S. Myers
@ 2006-09-20  5:20     ` Bridge Wu
  2006-09-20 14:39       ` Joseph S. Myers
  2006-09-25 16:20     ` Nick Clifton
  1 sibling, 1 reply; 9+ messages in thread
From: Bridge Wu @ 2006-09-20  5:20 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: binutils

There is a bug when integrating iwmmxt2. wldr[b/h] and wstr[b/h] will
be assembled into illegal instruction if the immediate number is #0.
This is because write_back bit is cleared in md_apply_fix(). I have
fixed it in my patch.

Test case:
  wldrb wr1, [r1], #0
  wldrh wr1, [r1], #0
  wstrb wr1, [r1], #0
  wstrh wr1, [r1], #0

Joseph, I did not find the fix to this issue in your patch. Could you
test it and merge it once confirmed?

-- 
best regards,
-Bridge

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-20  5:20     ` Bridge Wu
@ 2006-09-20 14:39       ` Joseph S. Myers
  2006-09-21  5:31         ` Bridge Wu
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph S. Myers @ 2006-09-20 14:39 UTC (permalink / raw)
  To: Bridge Wu; +Cc: binutils

On Wed, 20 Sep 2006, Bridge Wu wrote:

> There is a bug when integrating iwmmxt2. wldr[b/h] and wstr[b/h] will
> be assembled into illegal instruction if the immediate number is #0.
> This is because write_back bit is cleared in md_apply_fix(). I have
> fixed it in my patch.
> 
> Test case:
>  wldrb wr1, [r1], #0
>  wldrh wr1, [r1], #0
>  wstrb wr1, [r1], #0
>  wstrh wr1, [r1], #0
> 
> Joseph, I did not find the fix to this issue in your patch. Could you
> test it and merge it once confirmed?

You do not say what you expect these instructions to assemble to, and your 
patch does not apply cleanly to current binutils CVS mainline so I cannot 
tell what they assemble to with your patch.  They are valid iWMMXt1 
instructions without needing an iWMMXt2 patch; with my patch, and with 
unpatched mainline, they assemble to

00000000 <.text> ec911000       wldrb   wr1, [r1]
00000004 <.text+0x4> ecd11000   wldrh   wr1, [r1]
00000008 <.text+0x8> ec811000   wstrb   wr1, [r1]
0000000c <.text+0xc> ecc11000   wstrh   wr1, [r1]

If there is a bug here, it would not seem to be one in my patch, since the 
results are the same as without the patch.  As such I hope this bug can be 
considered separately from my patch; you can enter a report in binutils 
Bugzilla, or submit a patch against current binutils mainline (currently 
2.17.50 20060920) that fixes this bug (only) and includes testcases for 
the assembler testsuite.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-20 14:39       ` Joseph S. Myers
@ 2006-09-21  5:31         ` Bridge Wu
  2006-09-21 14:06           ` Joseph S. Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Bridge Wu @ 2006-09-21  5:31 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: binutils

The correct disassembly result should be as below. bit 21 (write_back)
should be set, otherwise, it will be illegal instruction.
 0:  ecb11000        wldrb   wr1, [r1]
14:  ecf11000        wldrh   wr1, [r1]
50:  eca11000       wstrb   wr1, [r1]
54:  ece11000       wstrh   wr1, [r1]

This does exists in iWMMXt1 instruction, not introduced by iWMMXt2
patch. I made a mistake due to I noticed it on iWMMXt2 spec. I will
submit a patch to current binutils separately.

-- 
best regards,
-Bridge

On 9/20/06, Joseph S. Myers <joseph@codesourcery.com> wrote:
>
> You do not say what you expect these instructions to assemble to, and your
> patch does not apply cleanly to current binutils CVS mainline so I cannot
> tell what they assemble to with your patch.  They are valid iWMMXt1
> instructions without needing an iWMMXt2 patch; with my patch, and with
> unpatched mainline, they assemble to
>
> 00000000 <.text> ec911000       wldrb   wr1, [r1]
> 00000004 <.text+0x4> ecd11000   wldrh   wr1, [r1]
> 00000008 <.text+0x8> ec811000   wstrb   wr1, [r1]
> 0000000c <.text+0xc> ecc11000   wstrh   wr1, [r1]
>
> If there is a bug here, it would not seem to be one in my patch, since the
> results are the same as without the patch.  As such I hope this bug can be
> considered separately from my patch; you can enter a report in binutils
> Bugzilla, or submit a patch against current binutils mainline (currently
> 2.17.50 20060920) that fixes this bug (only) and includes testcases for
> the assembler testsuite.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-21  5:31         ` Bridge Wu
@ 2006-09-21 14:06           ` Joseph S. Myers
  0 siblings, 0 replies; 9+ messages in thread
From: Joseph S. Myers @ 2006-09-21 14:06 UTC (permalink / raw)
  To: Bridge Wu; +Cc: binutils

On Thu, 21 Sep 2006, Bridge Wu wrote:

> The correct disassembly result should be as below. bit 21 (write_back)
> should be set, otherwise, it will be illegal instruction.
> 0:  ecb11000        wldrb   wr1, [r1]
> 14:  ecf11000        wldrh   wr1, [r1]
> 50:  eca11000       wstrb   wr1, [r1]
> 54:  ece11000       wstrh   wr1, [r1]
> 
> This does exists in iWMMXt1 instruction, not introduced by iWMMXt2
> patch. I made a mistake due to I noticed it on iWMMXt2 spec. I will
> submit a patch to current binutils separately.

Thanks for resolving this as an iWMMXt1 issue.  Hopefully now someone can 
review my iWMMXt2 patch?

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-19 20:58   ` Joseph S. Myers
  2006-09-20  5:20     ` Bridge Wu
@ 2006-09-25 16:20     ` Nick Clifton
  2006-09-26 10:41       ` Bridge Wu
  1 sibling, 1 reply; 9+ messages in thread
From: Nick Clifton @ 2006-09-25 16:20 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Bridge Wu, binutils

Hi Joseph,

> bfd/
> 2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
>             Joseph Myers  <joseph@codesourcery.com>
>             Ian Lance Taylor  <ian@wasabisystems.com>
>             Ben Elliston  <bje@wasabisystems.com>
> 
> 	* archures.c: Add definition for bfd_mach_arm_iWMMXt2.
> 	* cpu-arm.c (processors): Add bfd_mach_arm_iWMMXt2.
> 	(arch_info_struct, bfd_arm_update_notes): Likewise.
> 	(architectures): Likewise.
> 	(bfd_arm_merge_machines): Check for iWMMXt2.
> 	* bfd-in2.h: Rebuild.
> 
> gas/
> 2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
>             Joseph Myers  <joseph@codesourcery.com>
>             Ian Lance Taylor  <ian@wasabisystems.com>
>             Ben Elliston  <bje@wasabisystems.com>
> 
> 	* config/tc-arm.c (arm_cext_iwmmxt2): New.
> 	(enum operand_parse_code): New code OP_RIWR_I32z.
> 	(parse_operands): Handle OP_RIWR_I32z.
> 	(do_iwmmxt_wmerge): New function.
> 	(do_iwmmxt_wldstd): Handle iwmmxt2 case where second operand is
> 	a register.
> 	(do_iwmmxt_wrwrwr_or_imm5): New function.
> 	(insns): Mark instructions as RIWR_I32z as appropriate.
> 	Also add torvsc<b,h,w>, wabs<b,h,w>, wabsdiff<b,h,w>,
> 	waddbhus<l,m>, waddhc, waddwc, waddsubhx, wavg4{r}, wmaddu{x,n},
> 	wmadds{x,n}, wmerge, wmiaxy{n}, wmiawxy{n}, wmul<sm,um>{r},
> 	wmulw<um,sm,l>{r}, wqmiaxy{n}, wqmulm{r}, wqmulwm{r}, wsubaddhx.
> 	(md_begin): Handle IWMMXT2.
> 	(arm_cpus): Add iwmmxt2.
> 	(arm_extensions): Likewise.
> 	(arm_archs): Likewise.
> 
> gas/testsuite/
> 2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
>             Joseph Myers  <joseph@codesourcery.com>
>             Ian Lance Taylor  <ian@wasabisystems.com>
>             Ben Elliston  <bje@wasabisystems.com>
> 
> 	* gas/arm/iwmmxt2.s: New file.
> 	* gas/arm/iwmmxt2.d: New file.
> 
> include/opcode/
> 2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
>             Joseph Myers  <joseph@codesourcery.com>
>             Ian Lance Taylor  <ian@wasabisystems.com>
>             Ben Elliston  <bje@wasabisystems.com>
> 
> 	* arm.h (ARM_CEXT_IWMMXT2, ARM_ARCH_IWMMXT2): Define.
> 
> opcodes/
> 2006-09-19  Mark Shinwell  <shinwell@codesourcery.com>
>             Joseph Myers  <joseph@codesourcery.com>
>             Ian Lance Taylor  <ian@wasabisystems.com>
>             Ben Elliston  <bje@wasabisystems.com>
> 
> 	* arm-dis.c (coprocessor_opcodes): The X-qualifier to WMADD may
> 	only be used with the default multiply-add operation, so if N is
> 	set, don't bother printing X.  Add new iwmmxt instructions.
> 	(IWMMXT_INSN_COUNT): Update.
> 	(iwmmxt_wwssnames): Qualify "wwss" names at index 2, 6, 10 and 14
> 	with a 'c' suffix.
> 	(print_insn_coprocessor): Check for iWMMXt2.  Handle format
> 	specifiers 'r', 'i'.

Approved - please apply.

Cheers
   Nick

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

* Re: iwmmxt2 patch for binutils-2.16.92
  2006-09-25 16:20     ` Nick Clifton
@ 2006-09-26 10:41       ` Bridge Wu
  0 siblings, 0 replies; 9+ messages in thread
From: Bridge Wu @ 2006-09-26 10:41 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Joseph S. Myers, binutils

May be a little later, I verified Joseph's iwmmxt2 patch by building
into arm-iwmmxt-linux-gnueabi target. It does works.

-Bridge

On 9/26/06, Nick Clifton <nickc@redhat.com> wrote:
> Hi Joseph,
>
> Approved - please apply.
>
> Cheers
>    Nick
>

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

end of thread, other threads:[~2006-09-26 10:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-19 13:41 iwmmxt2 patch for binutils-2.16.92 Bridge Wu
2006-09-19 14:21 ` Joseph S. Myers
2006-09-19 20:58   ` Joseph S. Myers
2006-09-20  5:20     ` Bridge Wu
2006-09-20 14:39       ` Joseph S. Myers
2006-09-21  5:31         ` Bridge Wu
2006-09-21 14:06           ` Joseph S. Myers
2006-09-25 16:20     ` Nick Clifton
2006-09-26 10:41       ` Bridge Wu

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