ARMv6T2 ARM instructions - assembler support

Zack Weinberg zack@codesourcery.com
Mon Mar 14 23:22:00 GMT 2005


This patch adds assembler support for the new ARM-format instructions
in ARMv6T2, and tests for them (and hence also for the disassembler
patch I committed last week).

zw

gas:
        * config/tc-arm.c (do_mla): Rename to do_mlas, take second
        is_mls parameter.
        (do_mla, do_mls, five_bit_unsigned_immediate, bfci_lsb_and_width)
        (do_bfc, do_bfi, do_bfx, do_rbit, do_mov16, do_ldsttv4): New functions.
        (insns): Add ARMv6T2 instructions:
        bfc bfi mls movw movt rbit sbfx ubfx ldrht ldrsht ldrsbt strht.
        (arm_archs): Add V6T2 variants.
gas/testsuite:
        * gas/arm/archv6t2.d, gas/arm/archv6t2.s: New dump test.
        * gas/arm/archv6t2-bad.l, gas/arm/archv6t2-bad.l: New errors test.
        * gas/arm/arm.exp: Run them.

===================================================================
Index: config/tc-arm.c
--- config/tc-arm.c	12 Mar 2005 18:25:46 -0000	1.194
+++ config/tc-arm.c	14 Mar 2005 23:18:08 -0000
@@ -2814,7 +2814,7 @@ do_mul (char * str)
 }
 
 static void
-do_mla (char * str)
+do_mlas (char * str, bfd_boolean is_mls)
 {
   int rd, rm;
 
@@ -2847,7 +2847,12 @@ do_mla (char * str)
     }
 
   if (rm == rd)
-    as_tsktsk (_("rd and rm should be different in mla"));
+    {
+      if (is_mls)
+	as_tsktsk (_("rd and rm should be different in mls"));
+      else
+	as_tsktsk (_("rd and rm should be different in mla"));
+    }
 
   if (skip_past_comma (&str) == FAIL
       || (rd = reg_required_here (&str, 8)) == FAIL
@@ -2867,6 +2872,18 @@ do_mla (char * str)
   end_of_line (str);
 }
 
+static void
+do_mla (char *str)
+{
+  do_mlas (str, FALSE);
+}
+
+static void
+do_mls (char *str)
+{
+  do_mlas (str, TRUE);
+}
+
 /* Expects *str -> the characters "acc0", possibly with leading blanks.
    Advances *str to the next non-alphanumeric.
    Returns 0, or else FAIL (in which case sets inst.error).
@@ -4512,6 +4529,286 @@ do_cpsi (char * str)
   end_of_line (str);
 }
 
+/* ARM V6T2 bitfield manipulation instructions.  */
+
+static int
+five_bit_unsigned_immediate (char **str)
+{
+  expressionS expr;
+
+  skip_whitespace (*str);
+  if (!is_immediate_prefix (**str))
+    {
+      inst.error = _("immediate expression expected");
+      return -1;
+    }
+  (*str)++;
+  if (my_get_expression (&expr, str))
+    {
+      inst.error = _("bad expression");
+      return -1;
+    }
+  if (expr.X_op != O_constant)
+    {
+      inst.error = _("constant expression expected");
+      return -1;
+    }
+  if (expr.X_add_number < 0 || expr.X_add_number > 32)
+    {
+      inst.error = _("immediate value out of range");
+      return -1;
+    }
+  
+  return expr.X_add_number;
+}
+
+static void
+bfci_lsb_and_width (char *str)
+{
+  int lsb, width;
+
+  if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
+    return;
+
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if ((width = five_bit_unsigned_immediate (&str)) == -1)
+    return;
+
+  end_of_line (str);
+
+  if (width == 0 || lsb == 32)
+    {
+      inst.error = _("immediate value out of range");
+      return;
+    }
+  else if (width + lsb > 32)
+    {
+      inst.error = _("bit-field extends past end of register");
+      return;
+    }
+
+  /* Convert to LSB/MSB and write to register.  */
+  inst.instruction |= lsb << 7;
+  inst.instruction |= (width + lsb - 1) << 16;
+}
+
+static void
+do_bfc (char *str)
+{
+  int rd;
+
+  /* Rd.  */
+  skip_whitespace (str);
+  if (((rd = reg_required_here (&str, 12)) == FAIL)
+      || (skip_past_comma (&str) == FAIL))
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  else if (rd == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  bfci_lsb_and_width (str);
+}
+
+static void
+do_bfi (char *str)
+{
+  int rd, rm;
+
+  /* Rd.  */
+  skip_whitespace (str);
+  if (((rd = reg_required_here (&str, 12)) == FAIL)
+      || (skip_past_comma (&str) == FAIL))
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  else if (rd == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  /* Rm.  Accept #0 in this position as an alternative syntax for bfc.  */
+  skip_whitespace (str);
+  if (is_immediate_prefix (*str))
+    {
+      expressionS expr;
+      str++;
+      if (my_get_expression (&expr, &str))
+	{
+	  inst.error = _("bad expression");
+	  return;
+	}
+      if (expr.X_op != O_constant)
+	{
+	  inst.error = _("constant expression expected");
+	  return;
+	}
+      if (expr.X_add_number != 0)
+	{
+	  inst.error = _("immediate value out of range");
+	  return;
+	}
+      inst.instruction |= 0x0000000f;  /* Rm = PC -> bfc, not bfi.  */
+    }
+  else
+    {
+      if ((rm = reg_required_here (&str, 0)) == FAIL)
+	{
+	  inst.error = BAD_ARGS;
+	  return;
+	}
+      else if (rm == REG_PC)
+	{
+	  inst.error = BAD_PC;
+	  return;
+	}
+    }
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  bfci_lsb_and_width (str);
+}
+
+static void
+do_bfx (char *str)
+{
+  int lsb, width;
+
+  /* Rd.  */
+  skip_whitespace (str);
+  if (reg_required_here (&str, 12) == FAIL
+      || skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  /* Rm.  */
+  skip_whitespace (str);
+  if (reg_required_here (&str, 0) == FAIL
+      || skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
+    return;
+
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if ((width = five_bit_unsigned_immediate (&str)) == -1)
+    return;
+
+  end_of_line (str);
+
+  if (width == 0 || lsb == 32)
+    {
+      inst.error = _("immediate value out of range");
+      return;
+    }
+  else if (width + lsb > 32)
+    {
+      inst.error = _("bit-field extends past end of register");
+      return;
+    }
+
+  inst.instruction |= lsb << 7;
+  inst.instruction |= (width - 1) << 16;
+}
+
+static void
+do_rbit (char *str)
+{
+  /* Rd.  */
+  skip_whitespace (str);
+  if (reg_required_here (&str, 12) == FAIL
+      || skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  /* Rm.  */
+  skip_whitespace (str);
+  if (reg_required_here (&str, 0) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  end_of_line (str);
+}
+
+/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>.  */
+static void
+do_mov16 (char *str)
+{
+  int rd;
+  expressionS expr;
+
+  /* Rd.  */
+  skip_whitespace (str);
+  if (((rd = reg_required_here (&str, 12)) == FAIL)
+      || (skip_past_comma (&str) == FAIL))
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  else if (rd == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  /* Imm16.  */
+  skip_whitespace (str);
+  if (!is_immediate_prefix (*str))
+    {
+      inst.error = _("immediate expression expected");
+      return;
+    }
+  str++;
+  if (my_get_expression (&expr, &str))
+    {
+      inst.error = _("bad expression");
+      return;
+    }
+  if (expr.X_op != O_constant)
+    {
+      inst.error = _("constant expression expected");
+      return;
+    }
+  if (expr.X_add_number < 0 || expr.X_add_number > 65535)
+    {
+      inst.error = _("immediate value out of range");
+      return;
+    }
+
+  end_of_line (str);
+
+  /* The value is in two pieces: 0:11, 16:19.  */
+  inst.instruction |= (expr.X_add_number & 0x00000fff);
+  inst.instruction |= (expr.X_add_number & 0x0000f000) << 4;
+}
+  
+
 /* THUMB V5 breakpoint instruction (argument parse)
 	BKPT <immed_8>.  */
 
@@ -6517,6 +6814,84 @@ do_ldstv4 (char * str)
   end_of_line (str);
 }
 
+static void
+do_ldsttv4 (char * str)
+{
+  int conflict_reg;
+
+  skip_whitespace (str);
+
+  if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+    {
+      if (!inst.error)
+	inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = _("address expected");
+      return;
+    }
+
+  if (*str == '[')
+    {
+      int reg;
+
+      str++;
+
+      skip_whitespace (str);
+
+      if ((reg = reg_required_here (&str, 16)) == FAIL)
+	return;
+
+      /* ldrt/strt always use post-indexed addressing, so if the base is
+	 the same as Rd, we warn.  */
+      if (conflict_reg == reg)
+	as_warn (_("%s register same as write-back base"),
+		 ((inst.instruction & LOAD_BIT)
+		  ? _("destination") : _("source")));
+
+      skip_whitespace (str);
+
+      if (*str == ']')
+	{
+	  str ++;
+
+	  if (skip_past_comma (&str) == SUCCESS)
+	    {
+	      /* [Rn],... (post inc)  */
+	      if (ldst_extend_v4 (&str) == FAIL)
+		return;
+	    }
+	  else
+	    {
+	      /* [Rn]  */
+	      skip_whitespace (str);
+
+	      /* Skip a write-back '!'.  */
+	      if (*str == '!')
+		str++;
+
+	      inst.instruction |= (INDEX_UP|HWOFFSET_IMM);
+	    }
+	}
+      else
+	{
+	  inst.error = _("post-indexed expression expected");
+	  return;
+	}
+    }
+  else
+    {
+      inst.error = _("post-indexed expression expected");
+      return;
+    }
+
+  end_of_line (str);
+}
+
+
 static long
 reg_list (char ** strp)
 {
@@ -10014,6 +10389,21 @@ static const struct asm_opcode insns[] =
   /*  ARM V6Z.  */
   { "smi",       0xe1600070, 3,  ARM_EXT_V6Z,      do_smi},
 
+  /*  ARM V6T2.  */
+  { "bfc",       0xe7c0001f, 3,  ARM_EXT_V6T2,     do_bfc},
+  { "bfi",       0xe7c00010, 3,  ARM_EXT_V6T2,     do_bfi},
+  { "mls",       0xe0600090, 3,  ARM_EXT_V6T2,     do_mls},
+  { "movw",      0xe3000000, 4,  ARM_EXT_V6T2,     do_mov16},
+  { "movt",      0xe3400000, 4,  ARM_EXT_V6T2,     do_mov16},
+  { "rbit",      0xe3ff0f30, 4,  ARM_EXT_V6T2,     do_rbit},
+  { "sbfx",      0xe7a00050, 4,  ARM_EXT_V6T2,     do_bfx},
+  { "ubfx",      0xe7e00050, 4,  ARM_EXT_V6T2,     do_bfx},
+
+  { "ldrht",     0xe03000b0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
+  { "ldrsht",    0xe03000f0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
+  { "ldrsbt",    0xe03000d0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
+  { "strht",     0xe02000b0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
+
   /* Core FPA instruction set (V1).  */
   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
@@ -12763,6 +13153,10 @@ static struct arm_arch_option_table arm_
   {"armv6k",            ARM_ARCH_V6K,    FPU_ARCH_VFP},
   {"armv6z",            ARM_ARCH_V6Z,    FPU_ARCH_VFP},
   {"armv6zk",           ARM_ARCH_V6ZK,   FPU_ARCH_VFP},
+  {"armv6t2",		ARM_ARCH_V6T2,   FPU_ARCH_VFP},
+  {"armv6kt2",		ARM_ARCH_V6KT2,  FPU_ARCH_VFP},
+  {"armv6zt2",		ARM_ARCH_V6ZT2,  FPU_ARCH_VFP},
+  {"armv6zkt2",		ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
   {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP},
   {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
   {NULL, 0, 0}
===================================================================
Index: testsuite/gas/arm/archv6t2-bad.l
--- testsuite/gas/arm/archv6t2-bad.l	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2-bad.l	14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,40 @@
+[^:]*: Assembler messages:
+[^:]*:6: Error: r15 not allowed here -- `bfc pc,#0,#1'
+[^:]*:7: Error: r15 not allowed here -- `bfi pc,r0,#0,#1'
+[^:]*:8: Error: r15 not allowed here -- `movw pc,#0'
+[^:]*:9: Error: r15 not allowed here -- `movt pc,#0'
+[^:]*:12: Error: immediate value out of range -- `bfc r0,#0,#0'
+[^:]*:13: Error: immediate value out of range -- `bfc r0,#32,#0'
+[^:]*:14: Error: immediate value out of range -- `bfc r0,#0,#33'
+[^:]*:15: Error: immediate value out of range -- `bfc r0,#33,#1'
+[^:]*:16: Error: immediate value out of range -- `bfc r0,#32,#1'
+[^:]*:17: Error: bit-field extends past end of register -- `bfc r0,#28,#10'
+[^:]*:19: Error: immediate value out of range -- `bfi r0,r1,#0,#0'
+[^:]*:20: Error: immediate value out of range -- `bfi r0,r1,#32,#0'
+[^:]*:21: Error: immediate value out of range -- `bfi r0,r1,#0,#33'
+[^:]*:22: Error: immediate value out of range -- `bfi r0,r1,#33,#1'
+[^:]*:23: Error: immediate value out of range -- `bfi r0,r1,#32,#1'
+[^:]*:24: Error: bit-field extends past end of register -- `bfi r0,r1,#28,#10'
+[^:]*:26: Error: immediate value out of range -- `sbfx r0,r1,#0,#0'
+[^:]*:27: Error: immediate value out of range -- `sbfx r0,r1,#32,#0'
+[^:]*:28: Error: immediate value out of range -- `sbfx r0,r1,#0,#33'
+[^:]*:29: Error: immediate value out of range -- `sbfx r0,r1,#33,#1'
+[^:]*:30: Error: immediate value out of range -- `sbfx r0,r1,#32,#1'
+[^:]*:31: Error: bit-field extends past end of register -- `sbfx r0,r1,#28,#10'
+[^:]*:33: Error: immediate value out of range -- `ubfx r0,r1,#0,#0'
+[^:]*:34: Error: immediate value out of range -- `ubfx r0,r1,#32,#0'
+[^:]*:35: Error: immediate value out of range -- `ubfx r0,r1,#0,#33'
+[^:]*:36: Error: immediate value out of range -- `ubfx r0,r1,#33,#1'
+[^:]*:37: Error: immediate value out of range -- `ubfx r0,r1,#32,#1'
+[^:]*:38: Error: bit-field extends past end of register -- `ubfx r0,r1,#28,#10'
+[^:]*:41: Error: immediate value out of range -- `bfi r0,#1,#2,#3'
+[^:]*:44: Error: immediate value out of range -- `movt r0,#65537'
+[^:]*:45: Error: immediate value out of range -- `movw r0,#65537'
+[^:]*:46: Error: immediate value out of range -- `movt r0,#-1'
+[^:]*:47: Error: immediate value out of range -- `movw r0,#-1'
+[^:]*:50: rd and rm should be different in mla
+[^:]*:51: rd and rm should be different in mls
+[^:]*:54: Warning: destination register same as write-back base
+[^:]*:55: Warning: destination register same as write-back base
+[^:]*:56: Warning: destination register same as write-back base
+[^:]*:57: Warning: source register same as write-back base
===================================================================
Index: testsuite/gas/arm/archv6t2-bad.s
--- testsuite/gas/arm/archv6t2-bad.s	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2-bad.s	14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,57 @@
+	@ We do not bother testing simple cases, e.g. immediates where
+	@ registers belong, trailing junk at end of line.
+	.text
+x:
+	@ pc not allowed
+	bfc	pc,#0,#1
+	bfi	pc,r0,#0,#1
+	movw	pc,#0
+	movt	pc,#0
+
+	@ bitfield range limits
+	bfc	r0,#0,#0
+	bfc	r0,#32,#0
+	bfc	r0,#0,#33
+	bfc	r0,#33,#1
+	bfc	r0,#32,#1
+	bfc	r0,#28,#10
+
+	bfi	r0,r1,#0,#0
+	bfi	r0,r1,#32,#0
+	bfi	r0,r1,#0,#33
+	bfi	r0,r1,#33,#1
+	bfi	r0,r1,#32,#1
+	bfi	r0,r1,#28,#10
+
+	sbfx	r0,r1,#0,#0
+	sbfx	r0,r1,#32,#0
+	sbfx	r0,r1,#0,#33
+	sbfx	r0,r1,#33,#1
+	sbfx	r0,r1,#32,#1
+	sbfx	r0,r1,#28,#10
+
+	ubfx	r0,r1,#0,#0
+	ubfx	r0,r1,#32,#0
+	ubfx	r0,r1,#0,#33
+	ubfx	r0,r1,#33,#1
+	ubfx	r0,r1,#32,#1
+	ubfx	r0,r1,#28,#10
+
+	@ bfi accepts only #0 in Rm position
+	bfi	r0,#1,#2,#3
+
+	@ mov16 range limits
+	movt	r0,#65537
+	movw	r0,#65537
+	movt	r0,#-1
+	movw	r0,#-1
+
+	@ mla, mls Rd == Rm (warning)
+	mla	r0,r0,r1,r2
+	mls	r0,r0,r1,r2
+
+	@ ldsttv4 Rd == Rn (warning)
+	ldrht	r0,[r0]
+	ldrsbt	r0,[r0]
+	ldrsht	r0,[r0]
+	strht	r0,[r0]
===================================================================
Index: testsuite/gas/arm/archv6t2.d
--- testsuite/gas/arm/archv6t2.d	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.d	14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,48 @@
+#name: ARM V6T2 instructions
+#as: -march=armv6t2
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+00 <[^>]+> e7c2009f 	bfc	r0, #1, #2
+0+04 <[^>]+> 17c2009f 	bfcne	r0, #1, #2
+0+08 <[^>]+> e7c82213 	bfi	r2, r3, #4, #5
+0+0c <[^>]+> 17c82213 	bfine	r2, r3, #4, #5
+0+10 <[^>]+> e7c8221f 	bfc	r2, #4, #5
+0+14 <[^>]+> 17c8221f 	bfcne	r2, #4, #5
+0+18 <[^>]+> e7a532d4 	sbfx	r3, r4, #5, #6
+0+1c <[^>]+> 17a532d4 	sbfxne	r3, r4, #5, #6
+0+20 <[^>]+> e7e64355 	ubfx	r4, r5, #6, #7
+0+24 <[^>]+> 17e64355 	ubfxne	r4, r5, #6, #7
+0+28 <[^>]+> e3ff5f36 	rbit	r5, r6
+0+2c <[^>]+> 13ff5f36 	rbitne	r5, r6
+0+30 <[^>]+> e069cb9a 	mls	r9, sl, fp, ip
+0+34 <[^>]+> 1069cb9a 	mlsne	r9, sl, fp, ip
+0+38 <[^>]+> e301a234 	movw	sl, #4660	; 0x1234
+0+3c <[^>]+> 1301a234 	movwne	sl, #4660	; 0x1234
+0+40 <[^>]+> e345b678 	movt	fp, #22136	; 0x5678
+0+44 <[^>]+> 1345b678 	movtne	fp, #22136	; 0x5678
+0+48 <[^>]+> e0f760b0 	ldrht	r6, \[r7\]
+0+4c <[^>]+> 10f760b0 	ldrneht	r6, \[r7\]
+0+50 <[^>]+> e0b870b0 	ldrht	r7, \[r8\], r0
+0+54 <[^>]+> e03870b0 	ldrht	r7, \[r8\], -r0
+0+58 <[^>]+> e0f980ba 	ldrht	r8, \[r9\], #10
+0+5c <[^>]+> e07980ba 	ldrht	r8, \[r9\], #-10
+0+60 <[^>]+> e0f760f0 	ldrsht	r6, \[r7\]
+0+64 <[^>]+> 10f760f0 	ldrnesht	r6, \[r7\]
+0+68 <[^>]+> e0b870f0 	ldrsht	r7, \[r8\], r0
+0+6c <[^>]+> e03870f0 	ldrsht	r7, \[r8\], -r0
+0+70 <[^>]+> e0f980fa 	ldrsht	r8, \[r9\], #10
+0+74 <[^>]+> e07980fa 	ldrsht	r8, \[r9\], #-10
+0+78 <[^>]+> e0f760d0 	ldrsbt	r6, \[r7\]
+0+7c <[^>]+> 10f760d0 	ldrnesbt	r6, \[r7\]
+0+80 <[^>]+> e0b870d0 	ldrsbt	r7, \[r8\], r0
+0+84 <[^>]+> e03870d0 	ldrsbt	r7, \[r8\], -r0
+0+88 <[^>]+> e0f980da 	ldrsbt	r8, \[r9\], #10
+0+8c <[^>]+> e0e760b0 	strht	r6, \[r7\]
+0+90 <[^>]+> 10e760b0 	strneht	r6, \[r7\]
+0+94 <[^>]+> e0a870b0 	strh	r7, \[r8\], r0
+0+98 <[^>]+> e02870b0 	strh	r7, \[r8\], -r0
+0+9c <[^>]+> e0e980ba 	strht	r8, \[r9\], #10
+0+a0 <[^>]+> e06980ba 	strht	r8, \[r9\], #-10
===================================================================
Index: testsuite/gas/arm/archv6t2.s
--- testsuite/gas/arm/archv6t2.s	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.s	14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,51 @@
+	.text
+x:
+	bfc	r0, #1, #2
+	bfcne	r0, #1, #2
+	bfi	r2, r3, #4, #5
+	bfine	r2, r3, #4, #5
+	bfi	r2, #0, #4, #5
+	bfine	r2, #0, #4, #5
+
+	sbfx	r3, r4, #5, #6
+	sbfxne	r3, r4, #5, #6
+	ubfx	r4, r5, #6, #7
+	ubfxne	r4, r5, #6, #7
+
+	rbit	r5, r6
+	rbitne	r5, r6
+
+	mls	r9, r10, r11, r12
+	mlsne	r9, r10, r11, r12
+
+	movw	r10, #0x1234
+	movwne	r10, #0x1234
+	movt	r11, #0x5678
+	movtne	r11, #0x5678
+
+	ldrht	r6, [r7]
+	ldrneht	r6, [r7]
+	ldrht	r7, [r8], r0
+	ldrht	r7, [r8], -r0
+	ldrht	r8, [r9], #10
+	ldrht	r8, [r9], #-10
+	
+	ldrsht	r6, [r7]
+	ldrnesht	r6, [r7]
+	ldrsht	r7, [r8], r0
+	ldrsht	r7, [r8], -r0
+	ldrsht	r8, [r9], #10
+	ldrsht	r8, [r9], #-10
+
+	ldrsbt	r6, [r7]
+	ldrnesbt	r6, [r7]
+	ldrsbt	r7, [r8], r0
+	ldrsbt	r7, [r8], -r0
+	ldrsbt	r8, [r9], #10
+	
+	strht	r6, [r7]
+	strneht	r6, [r7]
+	strht	r7, [r8], r0
+	strht	r7, [r8], -r0
+	strht	r8, [r9], #10
+	strht	r8, [r9], #-10
===================================================================
Index: testsuite/gas/arm/arm.exp
--- testsuite/gas/arm/arm.exp	12 Mar 2005 18:25:47 -0000	1.36
+++ testsuite/gas/arm/arm.exp	14 Mar 2005 23:18:08 -0000
@@ -49,6 +49,7 @@ if {[istarget *arm*-*-*] || [istarget "x
     run_dump_test "reg-alias"
     run_dump_test "maverick"    
     run_dump_test "archv6"
+    run_dump_test "archv6t2"
     run_dump_test "thumbv6"
     run_dump_test "thumbv6k"
     run_dump_test "arch6zk"
@@ -57,6 +58,7 @@ if {[istarget *arm*-*-*] || [istarget "x
     run_errors_test "req" "-mcpu=arm7m" ".req errors"
     run_errors_test "armv1-bad" "-mcpu=arm7m" "ARM v1 errors"
     run_errors_test "r15-bad" "" "Invalid use of r15 errors"
+    run_errors_test "archv6t2-bad" "-march=armv6t2" "Invalid V6T2 instructions"
 
     if {[istarget *-*-*coff] || [istarget *-*-pe] || [istarget *-*-wince] ||
         [istarget *-*-*aout*] || [istarget *-*-netbsd] || [istarget *-*-riscix*]} then {



More information about the Binutils mailing list