This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA/ARM 07/21] Add support for new options to DMB/DSB


ARMv8 adds new options to DMB/DSB in A32/T32.

We do a bit of re-engineering in opcodes/arm-dis.c to common up the
decode of the options to DMB/DSB.

gas/ChangeLog:
2012-08-23  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.

gas/testsuite/ChangeLog:
2012-08-23  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.

opcodes/ChangeLog:
2012-08-23  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.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 8f2f88b..d3838ab 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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
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
index 0000000..1a245fa
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a-barrier-arm.d
@@ -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
index 0000000..42dae15
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a-barrier-thumb.d
@@ -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
index 0000000..f7b71c0
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a-barrier.s
@@ -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
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 532a6c8..ccbb6b3 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -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;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]