ARMv6T2 ARM instructions - assembler support

Zack Weinberg zack@codesourcery.com
Tue Mar 15 20:38:00 GMT 2005


Richard Earnshaw <rearnsha@gcc.gnu.org> writes:

> mls doesn't have this restriction.  v6 lifted the restriction for mla
> too, and in practice all v4 or later cores don't have it either, but
> that's hard to fix with the current -mcpu=all implementation.
>
> OK apart from that.
>
> R.
>
> PS.
>
> Just a note on the way I normally write tests.  For each class of
> instruction (a do_xxx function) I try to write a test pattern that sets
> the minimal number of bits in the insn (eg uses r0 everywhere possible)
> and then one pattern for each register (to check that each register is
> setting the right bits).  Finally, if the instruction is conditional, at
> least one pattern should test this case.

I have checked in the appended patch which removes the mls diagnostic
and revises the basic test the way you suggest.  (r9 is used because
that sets the bits at either end of the register field - similarly for
17/18 in bit number fields.)  Thanks for reviewing.

zw

	* config/tc-arm.c (do_mla): Rename to do_mlas, take second
	is_mls parameter; do not diagnose Rm==Rd when is_mls.
	(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.
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	15 Mar 2005 20:34:34 -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;
 
@@ -2846,7 +2846,9 @@ do_mla (char * str)
       return;
     }
 
-  if (rm == rd)
+  /* This restriction does not apply to mls (nor to mla in v6, but
+     that's hard to detect at present).  */
+  if (rm == rd && !is_mls)
     as_tsktsk (_("rd and rm should be different in mla"));
 
   if (skip_past_comma (&str) == FAIL
@@ -2867,6 +2869,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 +4526,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 +6811,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 +10386,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 +13150,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	15 Mar 2005 20:34:34 -0000
@@ -0,0 +1,38 @@
+[^:]*: 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: Warning: destination register same as write-back base
+[^:]*:51: Warning: destination register same as write-back base
+[^:]*:52: Warning: destination register same as write-back base
+[^:]*:53: 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	15 Mar 2005 20:34:34 -0000
@@ -0,0 +1,53 @@
+	@ 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
+
+	@ 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	15 Mar 2005 20:34:34 -0000
@@ -0,0 +1,51 @@
+#name: ARM V6T2 instructions
+#as: -march=armv6t2
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+00 <[^>]+> e7c00010 	bfi	r0, r0, #0, #1
+0+04 <[^>]+> 17c00010 	bfine	r0, r0, #0, #1
+0+08 <[^>]+> e7c09010 	bfi	r9, r0, #0, #1
+0+0c <[^>]+> e7c00019 	bfi	r0, r9, #0, #1
+0+10 <[^>]+> e7d10010 	bfi	r0, r0, #0, #18
+0+14 <[^>]+> e7d10890 	bfi	r0, r0, #17, #1
+0+18 <[^>]+> e7c0001f 	bfc	r0, #0, #1
+0+1c <[^>]+> e7c0001f 	bfc	r0, #0, #1
+0+20 <[^>]+> 17c0001f 	bfcne	r0, #0, #1
+0+24 <[^>]+> e7c0901f 	bfc	r9, #0, #1
+0+28 <[^>]+> e7d1001f 	bfc	r0, #0, #18
+0+2c <[^>]+> e7d1089f 	bfc	r0, #17, #1
+0+30 <[^>]+> e7a00050 	sbfx	r0, r0, #0, #1
+0+34 <[^>]+> 17a00050 	sbfxne	r0, r0, #0, #1
+0+38 <[^>]+> e7e00050 	ubfx	r0, r0, #0, #1
+0+3c <[^>]+> e7a09050 	sbfx	r9, r0, #0, #1
+0+40 <[^>]+> e7a00059 	sbfx	r0, r9, #0, #1
+0+44 <[^>]+> e7a008d0 	sbfx	r0, r0, #17, #1
+0+48 <[^>]+> e7b10050 	sbfx	r0, r0, #0, #18
+0+4c <[^>]+> e3ff0f30 	rbit	r0, r0
+0+50 <[^>]+> 13ff0f30 	rbitne	r0, r0
+0+54 <[^>]+> e3ff9f30 	rbit	r9, r0
+0+58 <[^>]+> e3ff0f39 	rbit	r0, r9
+0+5c <[^>]+> e0600090 	mls	r0, r0, r0, r0
+0+60 <[^>]+> 10600090 	mlsne	r0, r0, r0, r0
+0+64 <[^>]+> e0690090 	mls	r9, r0, r0, r0
+0+68 <[^>]+> e0600099 	mls	r0, r9, r0, r0
+0+6c <[^>]+> e0600990 	mls	r0, r0, r9, r0
+0+70 <[^>]+> e0609090 	mls	r0, r0, r0, r9
+0+74 <[^>]+> e3000000 	movw	r0, #0	; 0x0
+0+78 <[^>]+> e3400000 	movt	r0, #0	; 0x0
+0+7c <[^>]+> 13000000 	movwne	r0, #0	; 0x0
+0+80 <[^>]+> e3009000 	movw	r9, #0	; 0x0
+0+84 <[^>]+> e3000999 	movw	r0, #2457	; 0x999
+0+88 <[^>]+> e3090000 	movw	r0, #36864	; 0x9000
+0+8c <[^>]+> e0f900b0 	ldrht	r0, \[r9\]
+0+90 <[^>]+> e0f900f0 	ldrsht	r0, \[r9\]
+0+94 <[^>]+> e0f900d0 	ldrsbt	r0, \[r9\]
+0+98 <[^>]+> e0e900b0 	strht	r0, \[r9\]
+0+9c <[^>]+> 10f900b0 	ldrneht	r0, \[r9\]
+0+a0 <[^>]+> e0b090b9 	ldrht	r9, \[r0\], r9
+0+a4 <[^>]+> e03090b9 	ldrht	r9, \[r0\], -r9
+0+a8 <[^>]+> e0f099b9 	ldrht	r9, \[r0\], #153
+0+ac <[^>]+> e07099b9 	ldrht	r9, \[r0\], #-153
===================================================================
Index: testsuite/gas/arm/archv6t2.s
--- testsuite/gas/arm/archv6t2.s	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.s	15 Mar 2005 20:34:35 -0000
@@ -0,0 +1,55 @@
+	.text
+x:
+	bfi	r0, r0, #0, #1
+	bfine	r0, r0, #0, #1
+
+	bfi	r9, r0, #0, #1
+	bfi	r0, r9, #0, #1
+	bfi	r0, r0, #0, #18
+	bfi	r0, r0, #17, #1
+
+	bfi	r0, #0, #0, #1
+	bfc	r0, #0, #1
+	bfcne	r0, #0, #1
+	bfc	r9, #0, #1
+	bfc	r0, #0, #18
+	bfc	r0, #17, #1
+
+	sbfx	r0, r0, #0, #1
+	sbfxne	r0, r0, #0, #1
+	ubfx	r0, r0, #0, #1
+	sbfx	r9, r0, #0, #1
+	sbfx	r0, r9, #0, #1
+	sbfx	r0, r0, #17, #1
+	sbfx	r0, r0, #0, #18
+	
+	rbit	r0, r0
+	rbitne	r0, r0
+	rbit	r9, r0
+	rbit	r0, r9
+
+	mls	r0, r0, r0, r0
+	mlsne	r0, r0, r0, r0
+	mls	r9, r0, r0, r0
+	mls	r0, r9, r0, r0
+	mls	r0, r0, r9, r0
+	mls	r0, r0, r0, r9
+	
+	movw	r0, #0
+	movt	r0, #0
+	movwne	r0, #0
+	movw	r9, #0
+	movw	r0, #0x0999
+	movw	r0, #0x9000
+
+	@ for these, we must avoid write-back warnings
+	ldrht	r0, [r9]
+	ldrsht	r0, [r9]
+	ldrsbt	r0, [r9]
+	strht	r0, [r9]
+	ldrneht	r0, [r9]
+
+	ldrht	r9, [r0], r9
+	ldrht	r9, [r0], -r9
+	ldrht	r9, [r0], #0x99
+	ldrht	r9, [r0], #-0x99
===================================================================
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	15 Mar 2005 20:34:35 -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