* config/tc-arm.c (do_mla): Rename to do_mlas, take second
authorZack Weinberg <zackw@panix.com>
Tue, 15 Mar 2005 20:38:00 +0000 (20:38 +0000)
committerZack Weinberg <zackw@panix.com>
Tue, 15 Mar 2005 20:38:00 +0000 (20:38 +0000)
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.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/archv6t2-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/archv6t2-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/archv6t2.d [new file with mode: 0644]
gas/testsuite/gas/arm/archv6t2.s [new file with mode: 0644]
gas/testsuite/gas/arm/arm.exp

index 67906640194b58522edd290dbe6ac11ce8fbc578..ce3663d6831b5fdc946d0a6f2157075254f48553 100644 (file)
@@ -1,3 +1,13 @@
+2005-03-15  Zack Weinberg  <zack@codesourcery.com>
+
+       * 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.
+
 2005-03-15  Nick Clifton  <nickc@redhat.com>
 
        * NEWS: Add cutoff for changes in 2.16 release.
index 3ab5aa1524a411f851828b919cea0da5870f6b3b..5cce0a9a3b6b53d8f42c1e3a5820c3cfac9d8e9f 100644 (file)
@@ -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_archs[] =
   {"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 4ea866d0280bb488f828619258970d217aa223b0..86af7eb244582a080bda516cb6e48eaabe9cfff2 100644 (file)
@@ -1,3 +1,9 @@
+2005-03-15  Zack Weinberg  <zack@codesourcery.com>
+
+       * 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.
+
 2005-03-14  Eric Christopher  <echristo@redhat.com>
 
        * gas/cfi/cfi-mips-1.d, gas/cfi/cfi-mips-1.s: New dump test.
diff --git a/gas/testsuite/gas/arm/archv6t2-bad.l b/gas/testsuite/gas/arm/archv6t2-bad.l
new file mode 100644 (file)
index 0000000..e8da4b8
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/arm/archv6t2-bad.s b/gas/testsuite/gas/arm/archv6t2-bad.s
new file mode 100644 (file)
index 0000000..e568869
--- /dev/null
@@ -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]
diff --git a/gas/testsuite/gas/arm/archv6t2.d b/gas/testsuite/gas/arm/archv6t2.d
new file mode 100644 (file)
index 0000000..8e8b038
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/arm/archv6t2.s b/gas/testsuite/gas/arm/archv6t2.s
new file mode 100644 (file)
index 0000000..292f11c
--- /dev/null
@@ -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 a84c80b0931e43a0405f106741a6de7cc9575753..4ea64543182afad7cdb267e0c6a3dc6e1a9f1e9e 100644 (file)
@@ -49,6 +49,7 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then {
     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 "xscale-*-*"]} then {
     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 {