[gas][aarch64] Armv8.6-a option [1/X]
[deliverable/binutils-gdb.git] / gas / config / tc-aarch64.c
index 1f8d94ea1e295782402d0deda298e18627332dd3..fb1ec0bcc31116cb320fe2530bdc74995b0bf7dc 100644 (file)
@@ -529,7 +529,7 @@ const char EXP_CHARS[] = "eE";
 /* As in 0f12.456  */
 /* or   0d1.2345e12  */
 
-const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+const char FLT_CHARS[] = "rRsSfFdDxXeEpPhH";
 
 /* Prefix character that indicates the start of an immediate value.  */
 #define is_immediate_prefix(C) ((C) == '#')
@@ -1936,6 +1936,28 @@ s_aarch64_elf_cons (int nbytes)
   demand_empty_rest_of_line ();
 }
 
+/* Mark symbol that it follows a variant PCS convention.  */
+
+static void
+s_variant_pcs (int ignored ATTRIBUTE_UNUSED)
+{
+  char *name;
+  char c;
+  symbolS *sym;
+  asymbol *bfdsym;
+  elf_symbol_type *elfsym;
+
+  c = get_symbol_name (&name);
+  if (!*name)
+    as_bad (_("Missing symbol name in directive"));
+  sym = symbol_find_or_make (name);
+  restore_line_pointer (c);
+  demand_empty_rest_of_line ();
+  bfdsym = symbol_get_bfdsym (sym);
+  elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+  gas_assert (elfsym);
+  elfsym->internal_elf_sym.st_other |= STO_AARCH64_VARIANT_PCS;
+}
 #endif /* OBJ_ELF */
 
 /* Output a 32-bit word, but mark as an instruction.  */
@@ -2082,7 +2104,9 @@ const pseudo_typeS md_pseudo_table[] = {
   {"long", s_aarch64_elf_cons, 4},
   {"xword", s_aarch64_elf_cons, 8},
   {"dword", s_aarch64_elf_cons, 8},
+  {"variant_pcs", s_variant_pcs, 0},
 #endif
+  {"float16", float_cons, 'h'},
   {0, 0, 0}
 };
 \f
@@ -3378,6 +3402,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
      [base,Xm,SXTX {#imm}]
      [base,Wm,(S|U)XTW {#imm}]
    Pre-indexed
+     [base]!                    // in ldraa/ldrab exclusive
      [base,#imm]!
    Post-indexed
      [base],#imm
@@ -3692,29 +3717,42 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
     }
 
   /* If at this point neither .preind nor .postind is set, we have a
-     bare [Rn]{!}; reject [Rn]! accept [Rn] as a shorthand for [Rn,#0].
+     bare [Rn]{!}; only accept [Rn]! as a shorthand for [Rn,#0]! for ldraa and
+     ldrab, accept [Rn] as a shorthand for [Rn,#0].
      For SVE2 vector plus scalar offsets, allow [Zn.<T>] as shorthand for
      [Zn.<T>, xzr].  */
   if (operand->addr.preind == 0 && operand->addr.postind == 0)
     {
       if (operand->addr.writeback)
        {
-         /* Reject [Rn]!   */
-         set_syntax_error (_("missing offset in the pre-indexed address"));
-         return FALSE;
+         if (operand->type == AARCH64_OPND_ADDR_SIMM10)
+            {
+              /* Accept [Rn]! as a shorthand for [Rn,#0]!   */
+              operand->addr.offset.is_reg = 0;
+              operand->addr.offset.imm = 0;
+              operand->addr.preind = 1;
+            }
+          else
+           {
+            /* Reject [Rn]!   */
+            set_syntax_error (_("missing offset in the pre-indexed address"));
+            return FALSE;
+          }
        }
-
-      operand->addr.preind = 1;
-      if (operand->type == AARCH64_OPND_SVE_ADDR_ZX)
-       {
-         operand->addr.offset.is_reg = 1;
-         operand->addr.offset.regno = REG_ZR;
-         *offset_qualifier = AARCH64_OPND_QLF_X;
-       }
-      else
+       else
        {
-         inst.reloc.exp.X_op = O_constant;
-         inst.reloc.exp.X_add_number = 0;
+          operand->addr.preind = 1;
+          if (operand->type == AARCH64_OPND_SVE_ADDR_ZX)
+          {
+            operand->addr.offset.is_reg = 1;
+            operand->addr.offset.regno = REG_ZR;
+            *offset_qualifier = AARCH64_OPND_QLF_X;
+          }
+          else
+          {
+            inst.reloc.exp.X_op = O_constant;
+            inst.reloc.exp.X_add_number = 0;
+          }
        }
     }
 
@@ -5710,11 +5748,20 @@ parse_operands (char *str, const aarch64_opcode *opcode)
              val = parse_vector_reg_list (&str, reg_type, &vectype);
              if (val == PARSE_FAIL)
                goto failure;
+
              if (! reg_list_valid_p (val, /* accept_alternate */ 0))
                {
                  set_fatal_syntax_error (_("invalid register list"));
                  goto failure;
                }
+
+             if (vectype.width != 0 && *str != ',')
+               {
+                 set_fatal_syntax_error
+                   (_("expected element type rather than vector type"));
+                 goto failure;
+               }
+
              info->reglist.first_regno = (val >> 2) & 0x1f;
              info->reglist.num_regs = (val & 0x3) + 1;
            }
@@ -7330,7 +7377,7 @@ aarch64_init_frag (fragS * fragP, int max_chars)
 
   /* PR 21809: Do not set a mapping state for debug sections
      - it just confuses other tools.  */
-  if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
+  if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
     return;
 
   switch (fragP->fr_type)
@@ -8767,6 +8814,8 @@ struct aarch64_cpu_option_table
    recognized by GCC.  */
 static const struct aarch64_cpu_option_table aarch64_cpus[] = {
   {"all", AARCH64_ANY, NULL},
+  {"cortex-a34", AARCH64_FEATURE (AARCH64_ARCH_V8,
+                                 AARCH64_FEATURE_CRC), "Cortex-A34"},
   {"cortex-a35", AARCH64_FEATURE (AARCH64_ARCH_V8,
                                  AARCH64_FEATURE_CRC), "Cortex-A35"},
   {"cortex-a53", AARCH64_FEATURE (AARCH64_ARCH_V8,
@@ -8786,6 +8835,26 @@ static const struct aarch64_cpu_option_table aarch64_cpus[] = {
   {"cortex-a76", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
                                  AARCH64_FEATURE_RCPC | AARCH64_FEATURE_F16 | AARCH64_FEATURE_DOTPROD),
                                  "Cortex-A76"},
+  {"cortex-a76ae", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
+                                   AARCH64_FEATURE_F16 | AARCH64_FEATURE_RCPC
+                                   | AARCH64_FEATURE_DOTPROD
+                                   | AARCH64_FEATURE_SSBS),
+                                   "Cortex-A76AE"},
+  {"cortex-a77", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
+                                 AARCH64_FEATURE_F16 | AARCH64_FEATURE_RCPC
+                                 | AARCH64_FEATURE_DOTPROD
+                                 | AARCH64_FEATURE_SSBS),
+                                 "Cortex-A77"},
+  {"cortex-a65", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
+                                 AARCH64_FEATURE_F16 | AARCH64_FEATURE_RCPC
+                                 | AARCH64_FEATURE_DOTPROD
+                                 | AARCH64_FEATURE_SSBS),
+                                 "Cortex-A65"},
+  {"cortex-a65ae", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
+                                   AARCH64_FEATURE_F16 | AARCH64_FEATURE_RCPC
+                                   | AARCH64_FEATURE_DOTPROD
+                                   | AARCH64_FEATURE_SSBS),
+                                   "Cortex-A65AE"},
   {"ares", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
                                  AARCH64_FEATURE_RCPC | AARCH64_FEATURE_F16
                                  | AARCH64_FEATURE_DOTPROD
@@ -8849,6 +8918,7 @@ static const struct aarch64_arch_option_table aarch64_archs[] = {
   {"armv8.3-a", AARCH64_ARCH_V8_3},
   {"armv8.4-a", AARCH64_ARCH_V8_4},
   {"armv8.5-a", AARCH64_ARCH_V8_5},
+  {"armv8.6-a", AARCH64_ARCH_V8_6},
   {NULL, AARCH64_ARCH_NONE}
 };
 
@@ -8931,7 +9001,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
   {"sve2-sha3",                AARCH64_FEATURE (AARCH64_FEATURE_SVE2_SHA3, 0),
                        AARCH64_FEATURE (AARCH64_FEATURE_SVE2
                                         | AARCH64_FEATURE_SHA3, 0)},
-  {"bitperm",          AARCH64_FEATURE (AARCH64_FEATURE_SVE2_BITPERM, 0),
+  {"sve2-bitperm",     AARCH64_FEATURE (AARCH64_FEATURE_SVE2_BITPERM, 0),
                        AARCH64_FEATURE (AARCH64_FEATURE_SVE2, 0)},
   {NULL,               AARCH64_ARCH_NONE, AARCH64_ARCH_NONE},
 };
@@ -9397,3 +9467,35 @@ aarch64_copy_symbol_attributes (symbolS * dest, symbolS * src)
 {
   AARCH64_GET_FLAG (dest) = AARCH64_GET_FLAG (src);
 }
+
+#ifdef OBJ_ELF
+/* Same as elf_copy_symbol_attributes, but without copying st_other.
+   This is needed so AArch64 specific st_other values can be independently
+   specified for an IFUNC resolver (that is called by the dynamic linker)
+   and the symbol it resolves (aliased to the resolver).  In particular,
+   if a function symbol has special st_other value set via directives,
+   then attaching an IFUNC resolver to that symbol should not override
+   the st_other setting.  Requiring the directive on the IFUNC resolver
+   symbol would be unexpected and problematic in C code, where the two
+   symbols appear as two independent function declarations.  */
+
+void
+aarch64_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
+{
+  struct elf_obj_sy *srcelf = symbol_get_obj (src);
+  struct elf_obj_sy *destelf = symbol_get_obj (dest);
+  if (srcelf->size)
+    {
+      if (destelf->size == NULL)
+       destelf->size = XNEW (expressionS);
+      *destelf->size = *srcelf->size;
+    }
+  else
+    {
+      if (destelf->size != NULL)
+       free (destelf->size);
+      destelf->size = NULL;
+    }
+  S_SET_SIZE (dest, S_GET_SIZE (src));
+}
+#endif
This page took 0.027819 seconds and 4 git commands to generate.