* gas/config/tc-arm.c (asm_barrier_opt): Add arch field.
authorMatthew Gretton-Dann <matthew.gretton-dann@arm.com>
Fri, 24 Aug 2012 08:00:20 +0000 (08:00 +0000)
committerMatthew Gretton-Dann <matthew.gretton-dann@arm.com>
Fri, 24 Aug 2012 08:00:20 +0000 (08:00 +0000)
(mark_feature_used): New function.
(parse_barrier): Check specified option is valid for the
specified architecture.
(UL_BARRIER): New macro.
(barrier_opt_names): Update for new barrier options.
* gas/testsuite/gas/arm/armv8-a-barrier.s: New testcase.
* gas/testsuite/gas/arm/armv8-a-barrier-arm.d: Likewise.
* gas/testsuite/gas/arm/armv8-a-barrier-thumb.d: Likewise.
* opcodes/arm-dis.c (data_barrier_option): New function.
(print_insn_arm): Use data_barrier_option.
(print_insn_thumb32): Use data_barrier_option.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/armv8-a-barrier-arm.d [new file with mode: 0644]
gas/testsuite/gas/arm/armv8-a-barrier-thumb.d [new file with mode: 0644]
gas/testsuite/gas/arm/armv8-a-barrier.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/arm-dis.c

index 5d6b444..da59383 100644 (file)
@@ -1,3 +1,12 @@
+2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * config/tc-arm.c (asm_barrier_opt): Add arch field.
+       (mark_feature_used): New function.
+       (parse_barrier): Check specified option is valid for the
+       specified architecture.
+       (UL_BARRIER): New macro.
+       (barrier_opt_names): Update for new barrier options.
+
 2012-08-24  Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
 
        * config/tc-arm.c (do_setend): Warn on deprecated SETEND.
index 8f2f88b..d3838ab 100644 (file)
@@ -461,8 +461,9 @@ struct asm_psr
 
 struct asm_barrier_opt
 {
-  const char *   template_name;
-  unsigned long  value;
+  const char *    template_name;
+  unsigned long   value;
+  const arm_feature_set arch;
 };
 
 /* The bit that distinguishes CPSR and SPSR.  */
@@ -5766,6 +5767,25 @@ parse_cond (char **str)
   return c->value;
 }
 
+/* If the given feature available in the selected CPU, mark it as used.
+   Returns TRUE iff feature is available.  */
+static bfd_boolean
+mark_feature_used (const arm_feature_set *feature)
+{
+  /* Ensure the option is valid on the current architecture.  */
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
+    return FALSE;
+
+  /* Add the appropriate architecture feature for the barrier option used.
+     */
+  if (thumb_mode)
+    ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
+  else
+    ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
+
+  return TRUE;
+}
+
 /* Parse an option for a barrier instruction.  Returns the encoding for the
    option, or FAIL.  */
 static int
@@ -5783,6 +5803,9 @@ parse_barrier (char **str)
   if (!o)
     return FAIL;
 
+  if (!mark_feature_used (&o->arch))
+    return FAIL;
+
   *str = q;
   return o->value;
 }
@@ -17170,22 +17193,32 @@ static const struct asm_cond conds[] =
   {"al", 0xe}
 };
 
+#define UL_BARRIER(L,U,CODE,FEAT) \
+  { L, CODE, ARM_FEATURE (FEAT, 0) }, \
+  { U, CODE, ARM_FEATURE (FEAT, 0) }
+
 static struct asm_barrier_opt barrier_opt_names[] =
 {
-  { "sy",    0xf }, { "SY",    0xf },
-  { "un",    0x7 }, { "UN",    0x7 },
-  { "st",    0xe }, { "ST",    0xe },
-  { "unst",  0x6 }, { "UNST",  0x6 },
-  { "ish",   0xb }, { "ISH",   0xb },
-  { "sh",    0xb }, { "SH",    0xb },
-  { "ishst", 0xa }, { "ISHST", 0xa },
-  { "shst",  0xa }, { "SHST",  0xa },
-  { "nsh",   0x7 }, { "NSH",   0x7 },
-  { "nshst", 0x6 }, { "NSHST", 0x6 },
-  { "osh",   0x3 }, { "OSH",   0x3 },
-  { "oshst", 0x2 }, { "OSHST", 0x2 }
+  UL_BARRIER ("sy",    "SY",    0xf, ARM_EXT_BARRIER),
+  UL_BARRIER ("st",    "ST",    0xe, ARM_EXT_BARRIER),
+  UL_BARRIER ("ld",    "LD",    0xd, ARM_EXT_V8),
+  UL_BARRIER ("ish",   "ISH",   0xb, ARM_EXT_BARRIER),
+  UL_BARRIER ("sh",    "SH",    0xb, ARM_EXT_BARRIER),
+  UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
+  UL_BARRIER ("shst",  "SHST",  0xa, ARM_EXT_BARRIER),
+  UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
+  UL_BARRIER ("un",    "UN",    0x7, ARM_EXT_BARRIER),
+  UL_BARRIER ("nsh",   "NSH",   0x7, ARM_EXT_BARRIER),
+  UL_BARRIER ("unst",  "UNST",  0x6, ARM_EXT_BARRIER),
+  UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
+  UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
+  UL_BARRIER ("osh",   "OSH",   0x3, ARM_EXT_BARRIER),
+  UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
+  UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
 };
 
+#undef UL_BARRIER
+
 /* Table of ARM-format instructions.   */
 
 /* Macros for gluing together operand strings.  N.B. In all cases
index 2cdaada..d70a2c6 100644 (file)
@@ -1,5 +1,11 @@
 2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
+       * gas/arm/armv8-a-barrier.s: New testcase.
+       * gas/arm/armv8-a-barrier-arm.d: Likewise.
+       * gas/arm/armv8-a-barrier-thumb.d: Likewise.
+
+2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
        * gas/arm/armv8-a-bad.l: Update
        * gas/arm/armv8-a-bad.s: Likewise.
 
diff --git a/gas/testsuite/gas/arm/armv8-a-barrier-arm.d b/gas/testsuite/gas/arm/armv8-a-barrier-arm.d
new file mode 100644 (file)
index 0000000..1a245fa
--- /dev/null
@@ -0,0 +1,24 @@
+#name: Valid v8-A barrier (ARM)
+#as: -march=armv8-a
+#source: armv8-a-barrier.s
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f57ff04d    dsb     ld
+0[0-9a-f]+ <[^>]+> f57ff049    dsb     ishld
+0[0-9a-f]+ <[^>]+> f57ff045    dsb     nshld
+0[0-9a-f]+ <[^>]+> f57ff041    dsb     oshld
+0[0-9a-f]+ <[^>]+> f57ff05d    dmb     ld
+0[0-9a-f]+ <[^>]+> f57ff059    dmb     ishld
+0[0-9a-f]+ <[^>]+> f57ff055    dmb     nshld
+0[0-9a-f]+ <[^>]+> f57ff051    dmb     oshld
+0[0-9a-f]+ <[^>]+> f57ff04d    dsb     ld
+0[0-9a-f]+ <[^>]+> f57ff049    dsb     ishld
+0[0-9a-f]+ <[^>]+> f57ff045    dsb     nshld
+0[0-9a-f]+ <[^>]+> f57ff041    dsb     oshld
+0[0-9a-f]+ <[^>]+> f57ff05d    dmb     ld
+0[0-9a-f]+ <[^>]+> f57ff059    dmb     ishld
+0[0-9a-f]+ <[^>]+> f57ff055    dmb     nshld
+0[0-9a-f]+ <[^>]+> f57ff051    dmb     oshld
diff --git a/gas/testsuite/gas/arm/armv8-a-barrier-thumb.d b/gas/testsuite/gas/arm/armv8-a-barrier-thumb.d
new file mode 100644 (file)
index 0000000..42dae15
--- /dev/null
@@ -0,0 +1,24 @@
+#name: Valid v8-A barrier (Thumb)
+#as: -march=armv8-a -mthumb
+#source: armv8-a-barrier.s
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f3bf 8f4d   dsb     ld
+0[0-9a-f]+ <[^>]+> f3bf 8f49   dsb     ishld
+0[0-9a-f]+ <[^>]+> f3bf 8f45   dsb     nshld
+0[0-9a-f]+ <[^>]+> f3bf 8f41   dsb     oshld
+0[0-9a-f]+ <[^>]+> f3bf 8f5d   dmb     ld
+0[0-9a-f]+ <[^>]+> f3bf 8f59   dmb     ishld
+0[0-9a-f]+ <[^>]+> f3bf 8f55   dmb     nshld
+0[0-9a-f]+ <[^>]+> f3bf 8f51   dmb     oshld
+0[0-9a-f]+ <[^>]+> f3bf 8f4d   dsb     ld
+0[0-9a-f]+ <[^>]+> f3bf 8f49   dsb     ishld
+0[0-9a-f]+ <[^>]+> f3bf 8f45   dsb     nshld
+0[0-9a-f]+ <[^>]+> f3bf 8f41   dsb     oshld
+0[0-9a-f]+ <[^>]+> f3bf 8f5d   dmb     ld
+0[0-9a-f]+ <[^>]+> f3bf 8f59   dmb     ishld
+0[0-9a-f]+ <[^>]+> f3bf 8f55   dmb     nshld
+0[0-9a-f]+ <[^>]+> f3bf 8f51   dmb     oshld
diff --git a/gas/testsuite/gas/arm/armv8-a-barrier.s b/gas/testsuite/gas/arm/armv8-a-barrier.s
new file mode 100644 (file)
index 0000000..f7b71c0
--- /dev/null
@@ -0,0 +1,18 @@
+       .syntax unified
+       .text
+       dsb ld
+       dsb ishld
+       dsb nshld
+       dsb oshld
+       dmb ld
+       dmb ishld
+       dmb nshld
+       dmb oshld
+       dsb LD
+       dsb ISHLD
+       dsb NSHLD
+       dsb OSHLD
+       dmb LD
+       dmb ISHLD
+       dmb NSHLD
+       dmb OSHLD
index 6a1db6d..2b60eb5 100644 (file)
@@ -1,3 +1,9 @@
+2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * arm-dis.c (data_barrier_option): New function.
+       (print_insn_arm): Use data_barrier_option.
+       (print_insn_thumb32): Use data_barrier_option.
+
 2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com
 
        * arm-dis.c (COND_UNCOND): New constant.
index 532a6c8..ccbb6b3 100644 (file)
@@ -863,6 +863,8 @@ static const struct opcode32 arm_opcodes[] =
   /* V7 instructions.  */
   {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
   {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
+  {ARM_EXT_V8, 0xf57ff051, 0xfffffff3, "dmb\t%U"},
+  {ARM_EXT_V8, 0xf57ff041, 0xfffffff3, "dsb\t%U"},
   {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
   {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
   {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
@@ -1414,6 +1416,8 @@ static const struct opcode32 thumb32_opcodes[] =
   /* V7 instructions.  */
   {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
   {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
+  {ARM_EXT_V8, 0xf3bf8f51, 0xfffffff3, "dmb%c\t%U"},
+  {ARM_EXT_V8, 0xf3bf8f41, 0xfffffff3, "dsb%c\t%U"},
   {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
   {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
   {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
@@ -2985,6 +2989,28 @@ banked_regname (unsigned reg)
     }
 }
 
+/* Return the name of the DMB/DSB option.  */
+static const char *
+data_barrier_option (unsigned option)
+{
+  switch (option & 0xf)
+    {
+    case 0xf: return "sy";
+    case 0xe: return "st";
+    case 0xd: return "ld";
+    case 0xb: return "ish";
+    case 0xa: return "ishst";
+    case 0x9: return "ishld";
+    case 0x7: return "un";
+    case 0x6: return "unst";
+    case 0x5: return "nshld";
+    case 0x3: return "osh";
+    case 0x2: return "oshst";
+    case 0x1: return "oshld";
+    default:  return NULL;
+    }
+}
+
 /* Print one ARM instruction from PC on INFO->STREAM.  */
 
 static void
@@ -3335,20 +3361,11 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        } 
                      else 
                        {
-                         switch (given & 0xf)
-                           {
-                           case 0xf: func (stream, "sy"); break;
-                           case 0x7: func (stream, "un"); break;
-                           case 0xe: func (stream, "st"); break;
-                           case 0x6: func (stream, "unst"); break;
-                           case 0xb: func (stream, "ish"); break;
-                           case 0xa: func (stream, "ishst"); break;
-                           case 0x3: func (stream, "osh"); break;
-                           case 0x2: func (stream, "oshst"); break;
-                           default:
+                         const char * opt = data_barrier_option (given & 0xf);
+                         if (opt != NULL)
+                           func (stream, "%s", opt);
+                         else
                              func (stream, "#%d", (int) given & 0xf);
-                             break;
-                           }
                        }
                      break;
 
@@ -4222,20 +4239,11 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  }
                else 
                  {
-                   switch (given & 0xf)
-                     {
-                       case 0xf: func (stream, "sy"); break;
-                       case 0x7: func (stream, "un"); break;
-                       case 0xe: func (stream, "st"); break;
-                       case 0x6: func (stream, "unst"); break;
-                       case 0xb: func (stream, "ish"); break;
-                       case 0xa: func (stream, "ishst"); break;
-                       case 0x3: func (stream, "osh"); break;
-                       case 0x2: func (stream, "oshst"); break;
-                       default:
-                         func (stream, "#%d", (int) given & 0xf);
-                         break;
-                     }
+                   const char * opt = data_barrier_option (given & 0xf);
+                   if (opt != NULL)
+                     func (stream, "%s", opt);
+                   else
+                     func (stream, "#%d", (int) given & 0xf);
                   }
                break;