[AArch64][Patch 5/5] Add instruction PSB CSYNC
authorMatthew Wahab <matthew.wahab@arm.com>
Fri, 11 Dec 2015 10:22:40 +0000 (10:22 +0000)
committerMatthew Wahab <matthew.wahab@arm.com>
Fri, 11 Dec 2015 10:22:40 +0000 (10:22 +0000)
The Statistical Profile Extension adds the instruction PSB CSYNC as an
alias for the HINT #17 instruction. This patch adds the instruction to
binutils as a HINT alias that takes an operand.

A new operand type, AARCH64_OPND_BARRIER_PSB, is added to represent the
operand to PSB. A parser for the operand type is added to the assembler
and a printer to the disassembler. The operand name "csync" is added to
the list of HINT options with HINT number #17. Encoding and decoding of
the operand is handled by the ins_hint/ext_hint functions added in the
preceding patches.

gas/
2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>

* config/tc-aarch64.c (aarch64_hint_opt_hsh): New.
(parse_barrier_psb): New.
(parse_operands): Add case for AARCH64_OPND_BARRIER_PSB.
(md_begin): Set up aarch64_hint_opt_hsh.

gas/testsuite/
2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>

* gas/aarch64/system-2.d: Enable the statistical profiling
extension.  Update the expected output.
* gas/aarch64/system-2.s: Add tests for PSB CSYNC.
* gas/aarch64/system.d: Update the expected output.

include/opcode/
2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>

* aarch64.h (aarch64_opnd): Add AARCH64_OPND_BARRIER_PSB.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis-2.c: Regenerate.
* aarch64-opc-2.c: Regenerate.
* aarch64-opc.c (aarch64_hint_options): Add "csync".
(aarch64_print_operands): Handle AARCH64_OPND_BARRIER_PSB.
* aarch64-tbl.h (aarch64_feature_stat_profile): New.
(STAT_PROFILE): New.
(aarch64_opcode_table): Add "psb".
(AARCH64_OPERANDS): Add "BARRIER_PSB".

Change-Id: I5ffb672d26a8b15b48785478d359350a9b70ca09

13 files changed:
gas/ChangeLog
gas/config/tc-aarch64.c
gas/testsuite/ChangeLog
gas/testsuite/gas/aarch64/system-2.d
gas/testsuite/gas/aarch64/system-2.s
gas/testsuite/gas/aarch64/system.d
include/opcode/ChangeLog
include/opcode/aarch64.h
opcodes/aarch64-asm-2.c
opcodes/aarch64-dis-2.c
opcodes/aarch64-opc-2.c
opcodes/aarch64-opc.c
opcodes/aarch64-tbl.h

index 2fcad8e..f69d006 100644 (file)
@@ -1,5 +1,12 @@
 2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>
 
+       * config/tc-aarch64.c (aarch64_hint_opt_hsh): New.
+       (parse_barrier_psb): New.
+       (parse_operands): Add case for AARCH64_OPND_BARRIER_PSB.
+       (md_begin): Set up aarch64_hint_opt_hsh.
+
+2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>
+
        * config/tc-aarch64.c (aarch64_features): Add "profile".
        * doc/c-aarch64.texi (AArch64 Extensions): Add "profile".
 
index 2f115ec..2685ae8 100644 (file)
@@ -406,6 +406,7 @@ static struct hash_control *aarch64_reg_hsh;
 static struct hash_control *aarch64_barrier_opt_hsh;
 static struct hash_control *aarch64_nzcv_hsh;
 static struct hash_control *aarch64_pldop_hsh;
+static struct hash_control *aarch64_hint_opt_hsh;
 
 /* Stuff needed to resolve the label ambiguity
    As:
@@ -3604,6 +3605,41 @@ parse_barrier (char **str)
   return o->value;
 }
 
+/* Parse an operand for a PSB barrier.  Set *HINT_OPT to the hint-option record
+   return 0 if successful.  Otherwise return PARSE_FAIL.  */
+
+static int
+parse_barrier_psb (char **str,
+                  const struct aarch64_name_value_pair ** hint_opt)
+{
+  char *p, *q;
+  const struct aarch64_name_value_pair *o;
+
+  p = q = *str;
+  while (ISALPHA (*q))
+    q++;
+
+  o = hash_find_n (aarch64_hint_opt_hsh, p, q - p);
+  if (!o)
+    {
+      set_fatal_syntax_error
+       ( _("unknown or missing option to PSB"));
+      return PARSE_FAIL;
+    }
+
+  if (o->value != 0x11)
+    {
+      /* PSB only accepts option name 'CSYNC'.  */
+      set_syntax_error
+       (_("the specified option is not accepted for PSB"));
+      return PARSE_FAIL;
+    }
+
+  *str = q;
+  *hint_opt = o;
+  return 0;
+}
+
 /* Parse a system register or a PSTATE field name for an MSR/MRS instruction.
    Returns the encoding for the option, or PARSE_FAIL.
 
@@ -5643,6 +5679,12 @@ sys_reg_ins:
          inst.base.operands[i].prfop = aarch64_prfops + val;
          break;
 
+       case AARCH64_OPND_BARRIER_PSB:
+         val = parse_barrier_psb (&str, &(info->hint_option));
+         if (val == PARSE_FAIL)
+           goto failure;
+         break;
+
        default:
          as_fatal (_("unhandled operand code %d"), operands[i]);
        }
@@ -7506,7 +7548,8 @@ md_begin (void)
       || (aarch64_reg_hsh = hash_new ()) == NULL
       || (aarch64_barrier_opt_hsh = hash_new ()) == NULL
       || (aarch64_nzcv_hsh = hash_new ()) == NULL
-      || (aarch64_pldop_hsh = hash_new ()) == NULL)
+      || (aarch64_pldop_hsh = hash_new ()) == NULL
+      || (aarch64_hint_opt_hsh = hash_new ()) == NULL)
     as_fatal (_("virtual memory exhausted"));
 
   fill_instruction_hash_table ();
@@ -7602,6 +7645,17 @@ md_begin (void)
                           (void *) (aarch64_prfops + i));
     }
 
+  for (i = 0; aarch64_hint_options[i].name != NULL; i++)
+    {
+      const char* name = aarch64_hint_options[i].name;
+
+      checked_hash_insert (aarch64_hint_opt_hsh, name,
+                          (void *) (aarch64_hint_options + i));
+      /* Also hash the name in the upper case.  */
+      checked_hash_insert (aarch64_pldop_hsh, get_upper_str (name),
+                          (void *) (aarch64_hint_options + i));
+    }
+
   /* Set the cpu variant based on the command-line options.  */
   if (!mcpu_cpu_opt)
     mcpu_cpu_opt = march_cpu_opt;
index dafa360..cd81f93 100644 (file)
@@ -1,5 +1,12 @@
 2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>
 
+       * gas/aarch64/system-2.d: Enable the statistical profiling
+       extension.  Update the expected output.
+       * gas/aarch64/system-2.s: Add tests for PSB CSYNC.
+       * gas/aarch64/system.d: Update the expected output.
+
+2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>
+
        * gas/aarch64/sysreg-2.s: Add tests for the statistical profiling
        system registers.
        * gas/aarch64/sysreg-2.d: Enable the statistical profiling
index 9b379cf..f999348 100644 (file)
@@ -1,4 +1,4 @@
-#as: -march=armv8.2-a
+#as: -march=armv8.2-a+profile
 #objdump: -dr
 
 .*:     file format .*
@@ -8,3 +8,5 @@ Disassembly of section \.text:
 0000000000000000 <.*>:
    0:  d503221f        esb
    4:  d503221f        esb
+   8:  d503223f        psb     csync
+   c:  d503223f        psb     csync
index 9b7f216..3402e76 100644 (file)
@@ -4,3 +4,7 @@
        /* RAS Extension.  */
        esb
        hint #0x10
+
+       /* Statistical profiling.  */
+       psb csync
+       hint #0x11
index d4dcf86..2da13ee 100644 (file)
@@ -29,7 +29,7 @@ Disassembly of section \.text:
   54:  d50321df        hint    #0xe
   58:  d50321ff        hint    #0xf
   5c:  d503221f        (hint   #0x10|esb)
-  60:  d503223f        hint    #0x11
+  60:  d503223f        (hint   #0x11|psb       csync)
   64:  d503225f        hint    #0x12
   68:  d503227f        hint    #0x13
   6c:  d503229f        hint    #0x14
index 603bdb9..f307a2a 100644 (file)
@@ -1,5 +1,18 @@
 2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>
 
+       * aarch64.h (aarch64_opnd): Add AARCH64_OPND_BARRIER_PSB.
+       * aarch64-asm-2.c: Regenerate.
+       * aarch64-dis-2.c: Regenerate.
+       * aarch64-opc-2.c: Regenerate.
+       * aarch64-opc.c (aarch64_hint_options): Add "csync".
+       (aarch64_print_operands): Handle AARCH64_OPND_BARRIER_PSB.
+       * aarch64-tbl.h (aarch64_feature_stat_profile): New.
+       (STAT_PROFILE): New.
+       (aarch64_opcode_table): Add "psb".
+       (AARCH64_OPERANDS): Add "BARRIER_PSB".
+
+2015-12-11  Matthew Wahab  <matthew.wahab@arm.com>
+
        * aarch64.h (aarch64_hint_options): Declare.
        (aarch64_opnd_info): Add field hint_option.
 
index 70486c9..b8a2c01 100644 (file)
@@ -237,6 +237,7 @@ enum aarch64_opnd
   AARCH64_OPND_BARRIER,                /* Barrier operand.  */
   AARCH64_OPND_BARRIER_ISB,    /* Barrier operand for ISB.  */
   AARCH64_OPND_PRFOP,          /* Prefetch operation.  */
+  AARCH64_OPND_BARRIER_PSB,    /* Barrier operand for PSB.  */
 };
 
 /* Qualifier constrains an operand.  It either specifies a variant of an
index 2d1a22b..8644c05 100644 (file)
@@ -422,6 +422,7 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode)
     case 1004: /* movz */
       value = 1004;    /* --> movz.  */
       break;
+    case 1018: /* psb */
     case 1017: /* esb */
     case 1016: /* sevl */
     case 1015: /* sev */
@@ -432,12 +433,12 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode)
     case 1010: /* hint */
       value = 1010;    /* --> hint.  */
       break;
-    case 1026: /* tlbi */
-    case 1025: /* ic */
-    case 1024: /* dc */
-    case 1023: /* at */
-    case 1022: /* sys */
-      value = 1022;    /* --> sys.  */
+    case 1027: /* tlbi */
+    case 1026: /* ic */
+    case 1025: /* dc */
+    case 1024: /* at */
+    case 1023: /* sys */
+      value = 1023;    /* --> sys.  */
       break;
     default: return NULL;
     }
@@ -562,6 +563,8 @@ aarch64_insert_operand (const aarch64_operand *self,
       return aarch64_ins_barrier (self, info, code, inst);
     case 87:
       return aarch64_ins_prfop (self, info, code, inst);
+    case 88:
+      return aarch64_ins_hint (self, info, code, inst);
     default: assert (0); abort ();
     }
 }
index 6139af3..96b0287 100644 (file)
@@ -3319,7 +3319,7 @@ aarch64_opcode_lookup_1 (uint32_t word)
                              10987654321098765432109876543210
                              xxxxxxxxxxxxxxxxxxxxx1xx1x10x01x
                              sysl.  */
-                          return 1028;
+                          return 1029;
                         }
                     }
                 }
@@ -3342,7 +3342,7 @@ aarch64_opcode_lookup_1 (uint32_t word)
                          10987654321098765432109876543210
                          xxxxxxxxxxxxxxxxxxxxxxxx0110x1xx
                          tbz.  */
-                      return 1030;
+                      return 1031;
                     }
                 }
               else
@@ -3361,7 +3361,7 @@ aarch64_opcode_lookup_1 (uint32_t word)
                          10987654321098765432109876543210
                          xxxxxxxxxxxxxxxxxxxxxxxx1110x1xx
                          tbnz.  */
-                      return 1031;
+                      return 1032;
                     }
                 }
             }
@@ -8857,15 +8857,15 @@ aarch64_find_next_opcode (const aarch64_opcode *opcode)
     case 794: value = 798; break;      /* ldnp --> ldp.  */
     case 798: return NULL;             /* ldp --> NULL.  */
     case 1009: value = 1010; break;    /* msr --> hint.  */
-    case 1010: value = 1018; break;    /* hint --> clrex.  */
-    case 1018: value = 1019; break;    /* clrex --> dsb.  */
-    case 1019: value = 1020; break;    /* dsb --> dmb.  */
-    case 1020: value = 1021; break;    /* dmb --> isb.  */
-    case 1021: value = 1022; break;    /* isb --> sys.  */
-    case 1022: value = 1027; break;    /* sys --> msr.  */
-    case 1027: return NULL;            /* msr --> NULL.  */
-    case 1028: value = 1029; break;    /* sysl --> mrs.  */
-    case 1029: return NULL;            /* mrs --> NULL.  */
+    case 1010: value = 1019; break;    /* hint --> clrex.  */
+    case 1019: value = 1020; break;    /* clrex --> dsb.  */
+    case 1020: value = 1021; break;    /* dsb --> dmb.  */
+    case 1021: value = 1022; break;    /* dmb --> isb.  */
+    case 1022: value = 1023; break;    /* isb --> sys.  */
+    case 1023: value = 1028; break;    /* sys --> msr.  */
+    case 1028: return NULL;            /* msr --> NULL.  */
+    case 1029: value = 1030; break;    /* sysl --> mrs.  */
+    case 1030: return NULL;            /* mrs --> NULL.  */
     case 361: value = 362; break;      /* st4 --> st1.  */
     case 362: value = 363; break;      /* st1 --> st2.  */
     case 363: value = 364; break;      /* st2 --> st3.  */
@@ -9145,8 +9145,8 @@ aarch64_find_alias_opcode (const aarch64_opcode *opcode)
     case 952: value = 1001; break;     /* lduminl --> stuminl.  */
     case 1002: value = 1003; break;    /* movn --> mov.  */
     case 1004: value = 1005; break;    /* movz --> mov.  */
-    case 1010: value = 1017; break;    /* hint --> esb.  */
-    case 1022: value = 1026; break;    /* sys --> tlbi.  */
+    case 1010: value = 1018; break;    /* hint --> psb.  */
+    case 1023: value = 1027; break;    /* sys --> tlbi.  */
     default: return NULL;
     }
 
@@ -9271,6 +9271,7 @@ aarch64_find_next_alias_opcode (const aarch64_opcode *opcode)
     case 1001: value = 952; break;     /* stuminl --> lduminl.  */
     case 1003: value = 1002; break;    /* mov --> movn.  */
     case 1005: value = 1004; break;    /* mov --> movz.  */
+    case 1018: value = 1017; break;    /* psb --> esb.  */
     case 1017: value = 1016; break;    /* esb --> sevl.  */
     case 1016: value = 1015; break;    /* sevl --> sev.  */
     case 1015: value = 1014; break;    /* sev --> wfi.  */
@@ -9278,10 +9279,10 @@ aarch64_find_next_alias_opcode (const aarch64_opcode *opcode)
     case 1013: value = 1012; break;    /* wfe --> yield.  */
     case 1012: value = 1011; break;    /* yield --> nop.  */
     case 1011: value = 1010; break;    /* nop --> hint.  */
-    case 1026: value = 1025; break;    /* tlbi --> ic.  */
-    case 1025: value = 1024; break;    /* ic --> dc.  */
-    case 1024: value = 1023; break;    /* dc --> at.  */
-    case 1023: value = 1022; break;    /* at --> sys.  */
+    case 1027: value = 1026; break;    /* tlbi --> ic.  */
+    case 1026: value = 1025; break;    /* ic --> dc.  */
+    case 1025: value = 1024; break;    /* dc --> at.  */
+    case 1024: value = 1023; break;    /* at --> sys.  */
     default: return NULL;
     }
 
@@ -9411,6 +9412,8 @@ aarch64_extract_operand (const aarch64_operand *self,
       return aarch64_ext_barrier (self, info, code, inst);
     case 87:
       return aarch64_ext_prfop (self, info, code, inst);
+    case 88:
+      return aarch64_ext_hint (self, info, code, inst);
     default: assert (0); abort ();
     }
 }
index ef7e0a4..01f9302 100644 (file)
@@ -112,6 +112,7 @@ const struct aarch64_operand aarch64_operands[] =
   {AARCH64_OPND_CLASS_SYSTEM, "BARRIER", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a barrier option name"},
   {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_ISB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the ISB option name SY or an optional 4-bit unsigned immediate"},
   {AARCH64_OPND_CLASS_SYSTEM, "PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a prefetch operation specifier"},
+  {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_PSB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the PSB option name CSYNC"},
   {AARCH64_OPND_CLASS_NIL, "", 0, {0}, "DUMMY"},
 };
 
index 5f65f8c..1557582 100644 (file)
@@ -344,6 +344,7 @@ const struct aarch64_name_value_pair aarch64_barrier_options[16] =
 
 const struct aarch64_name_value_pair aarch64_hint_options[] =
 {
+  { "csync", 0x11 },    /* PSB CSYNC.  */
   { NULL, 0x0 },
 };
 
@@ -2731,6 +2732,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
        snprintf (buf, size, "#0x%02x", opnd->prfop->value);
       break;
 
+    case AARCH64_OPND_BARRIER_PSB:
+      snprintf (buf, size, "%s", opnd->hint_option->name);
+      break;
+
     default:
       assert (0);
     }
index 9e743db..35f950f 100644 (file)
@@ -1303,6 +1303,8 @@ static const aarch64_feature_set aarch64_feature_v8_2 =
   AARCH64_FEATURE (AARCH64_FEATURE_V8_2, 0);
 static const aarch64_feature_set aarch64_feature_fp_f16 =
   AARCH64_FEATURE (AARCH64_FEATURE_F16 | AARCH64_FEATURE_FP, 0);
+static const aarch64_feature_set aarch64_feature_stat_profile =
+  AARCH64_FEATURE (AARCH64_FEATURE_PROFILE, 0);
 
 #define CORE   &aarch64_feature_v8
 #define FP     &aarch64_feature_fp
@@ -1314,6 +1316,7 @@ static const aarch64_feature_set aarch64_feature_fp_f16 =
 #define RDMA   &aarch64_feature_rdma
 #define FP_F16 &aarch64_feature_fp_f16
 #define RAS    &aarch64_feature_ras
+#define STAT_PROFILE   &aarch64_feature_stat_profile
 #define ARMV8_2        &aarch64_feature_v8_2
 
 struct aarch64_opcode aarch64_opcode_table[] =
@@ -2460,6 +2463,8 @@ struct aarch64_opcode aarch64_opcode_table[] =
   {"sev", 0xd503209f, 0xffffffff, ic_system, 0, CORE, OP0 (), {}, F_ALIAS},
   {"sevl", 0xd50320bf, 0xffffffff, ic_system, 0, CORE, OP0 (), {}, F_ALIAS},
   {"esb", 0xd503221f, 0xffffffff, ic_system, 0, RAS, OP0 (), {}, F_ALIAS},
+  {"psb", 0xd503223f, 0xffffffff, ic_system, 0, STAT_PROFILE,
+   OP1 (BARRIER_PSB), {}, F_ALIAS },
   {"clrex", 0xd503305f, 0xfffff0ff, ic_system, 0, CORE, OP1 (UIMM4), {}, F_OPD0_OPT | F_DEFAULT (0xF)},
   {"dsb", 0xd503309f, 0xfffff0ff, ic_system, 0, CORE, OP1 (BARRIER), {}, 0},
   {"dmb", 0xd50330bf, 0xfffff0ff, ic_system, 0, CORE, OP1 (BARRIER), {}, 0},
@@ -2662,4 +2667,6 @@ struct aarch64_opcode aarch64_opcode_table[] =
     Y(SYSTEM, barrier, "BARRIER_ISB", 0, F(),                          \
       "the ISB option name SY or an optional 4-bit unsigned immediate")        \
     Y(SYSTEM, prfop, "PRFOP", 0, F(),                                  \
-      "a prefetch operation specifier")
+      "a prefetch operation specifier")                                        \
+    Y (SYSTEM, hint, "BARRIER_PSB", 0, F (),                           \
+      "the PSB option name CSYNC")