public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* ARMv6T2 ARM instructions - assembler support
@ 2005-03-14 23:22 Zack Weinberg
  2005-03-15  3:51 ` Zack Weinberg
  2005-03-15 10:07 ` Richard Earnshaw
  0 siblings, 2 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-03-14 23:22 UTC (permalink / raw)
  To: binutils


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 {

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

* Re: ARMv6T2 ARM instructions - assembler support
  2005-03-14 23:22 ARMv6T2 ARM instructions - assembler support Zack Weinberg
@ 2005-03-15  3:51 ` Zack Weinberg
  2005-03-15 10:07 ` Richard Earnshaw
  1 sibling, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-03-15  3:51 UTC (permalink / raw)
  To: binutils


Something I neglected to mention.  The ARM-ARM suggests that MOVT and
MOVW should be synthesized by the assembler for MOV immediates that
can't be expressed by a <shifter_operand>.  I did not implement this.
Also, it's possible to intuit from the existence of relocations for
these instructions in the Mar 8 revision of ARMELF, that they should
allow most link-time expressions as well as bare immediates.  I did
not implement that, either.  (Both are in the pipeline.)

zw

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

* Re: ARMv6T2 ARM instructions - assembler support
  2005-03-14 23:22 ARMv6T2 ARM instructions - assembler support Zack Weinberg
  2005-03-15  3:51 ` Zack Weinberg
@ 2005-03-15 10:07 ` Richard Earnshaw
  2005-03-15 20:38   ` Zack Weinberg
  1 sibling, 1 reply; 5+ messages in thread
From: Richard Earnshaw @ 2005-03-15 10:07 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: binutils

On Mon, 2005-03-14 at 23:21, Zack Weinberg wrote:
> 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.
>  
> @@ -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"));
> +    }
>  

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.


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

* Re: ARMv6T2 ARM instructions - assembler support
  2005-03-15 10:07 ` Richard Earnshaw
@ 2005-03-15 20:38   ` Zack Weinberg
  2005-03-16 14:30     ` Richard Earnshaw
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-03-15 20:38 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: binutils

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 {

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

* Re: ARMv6T2 ARM instructions - assembler support
  2005-03-15 20:38   ` Zack Weinberg
@ 2005-03-16 14:30     ` Richard Earnshaw
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Earnshaw @ 2005-03-16 14:30 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: binutils

On Tue, 2005-03-15 at 20:38, Zack Weinberg wrote:

> 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.

Looks great, thanks.

R.

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

end of thread, other threads:[~2005-03-16  8:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-14 23:22 ARMv6T2 ARM instructions - assembler support Zack Weinberg
2005-03-15  3:51 ` Zack Weinberg
2005-03-15 10:07 ` Richard Earnshaw
2005-03-15 20:38   ` Zack Weinberg
2005-03-16 14:30     ` Richard Earnshaw

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).