]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/tc-aarch64.c
aarch64: Enable Cortex-A720 CPU
[thirdparty/binutils-gdb.git] / gas / config / tc-aarch64.c
index a433925e320371ce2306463fb052b68f38ec7b76..19fbc7c46466ab30725e9ae16ae576aea4de5d6d 100644 (file)
@@ -312,6 +312,7 @@ struct reloc_entry
   BASIC_REG_TYPE(ZAT)  /* za[0-15] (ZA tile) */                        \
   BASIC_REG_TYPE(ZATH) /* za[0-15]h (ZA tile horizontal slice) */      \
   BASIC_REG_TYPE(ZATV) /* za[0-15]v (ZA tile vertical slice) */        \
+  BASIC_REG_TYPE(ZT0)  /* zt0 */                                       \
   /* Typecheck: any 64-bit int reg         (inc SP exc XZR).  */       \
   MULTI_REG_TYPE(R64_SP, REG_TYPE(R_64) | REG_TYPE(SP_64))             \
   /* Typecheck: same, plus SVE registers.  */                          \
@@ -348,6 +349,13 @@ struct reloc_entry
                 | REG_TYPE(FP_B) | REG_TYPE(FP_H)                      \
                 | REG_TYPE(FP_S) | REG_TYPE(FP_D) | REG_TYPE(FP_Q)     \
                 | REG_TYPE(Z) | REG_TYPE(P))                           \
+  /* Likewise, but with predicate-as-counter registers added.  */      \
+  MULTI_REG_TYPE(R_ZR_SP_BHSDQ_VZP_PN, REG_TYPE(R_32) | REG_TYPE(R_64) \
+                | REG_TYPE(SP_32) | REG_TYPE(SP_64)                    \
+                | REG_TYPE(ZR_32) | REG_TYPE(ZR_64) | REG_TYPE(V)      \
+                | REG_TYPE(FP_B) | REG_TYPE(FP_H)                      \
+                | REG_TYPE(FP_S) | REG_TYPE(FP_D) | REG_TYPE(FP_Q)     \
+                | REG_TYPE(Z) | REG_TYPE(P) | REG_TYPE(PN))            \
   /* Any integer register; used for error messages only.  */           \
   MULTI_REG_TYPE(R_N, REG_TYPE(R_32) | REG_TYPE(R_64)                  \
                 | REG_TYPE(SP_32) | REG_TYPE(SP_64)                    \
@@ -483,11 +491,11 @@ get_reg_expected_msg (unsigned int mask, unsigned int seen)
   if (mask == reg_type_masks[REG_TYPE_VZP])
     return N_("expected a vector or predicate register at operand %d");
 
-  /* ZA-related registers.  */
+  /* SME-related registers.  */
   if (mask == reg_type_masks[REG_TYPE_ZA])
     return N_("expected a ZA array vector at operand %d");
-  if (mask == reg_type_masks[REG_TYPE_ZA_ZAT])
-    return N_("expected 'za' or a ZA tile at operand %d");
+  if (mask == (reg_type_masks[REG_TYPE_ZA_ZAT] | reg_type_masks[REG_TYPE_ZT0]))
+    return N_("expected ZT0 or a ZA mask at operand %d");
   if (mask == reg_type_masks[REG_TYPE_ZAT])
     return N_("expected a ZA tile at operand %d");
   if (mask == reg_type_masks[REG_TYPE_ZATHV])
@@ -1279,7 +1287,10 @@ parse_typed_reg (char **ccp, aarch64_reg_type type,
   if (!(flags & PTR_FULL_REG) && skip_past_char (&str, '['))
     {
       /* Reject Sn[index] syntax.  */
-      if (reg->type != REG_TYPE_PN && !is_typed_vecreg)
+      if (reg->type != REG_TYPE_Z
+         && reg->type != REG_TYPE_PN
+         && reg->type != REG_TYPE_ZT0
+         && !is_typed_vecreg)
        {
          first_error (_("this type of register can't be indexed"));
          return NULL;
@@ -1382,7 +1393,7 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type,
   char *str = *ccp;
   int nb_regs;
   struct vector_type_el typeinfo, typeinfo_first;
-  int val, val_range, mask;
+  uint32_t val, val_range, mask;
   int in_range;
   int ret_val;
   bool error = false;
@@ -1403,8 +1414,8 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type,
   typeinfo_first.element_size = 0;
   typeinfo_first.index = 0;
   ret_val = 0;
-  val = -1;
-  val_range = -1;
+  val = -1u;
+  val_range = -1u;
   in_range = 0;
   mask = reg_type_mask (type);
   do
@@ -1459,7 +1470,7 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type,
       if (! error)
        for (;;)
          {
-           ret_val |= val_range << (5 * nb_regs);
+           ret_val |= val_range << ((5 * nb_regs) & 31);
            nb_regs++;
            if (val_range == val)
              break;
@@ -6523,9 +6534,11 @@ parse_operands (char *str, const aarch64_opcode *opcode)
   clear_error ();
   skip_whitespace (str);
 
-  if (AARCH64_CPU_HAS_ANY_FEATURES (*opcode->avariant,
-                                   AARCH64_FEATURE_SVE
-                                   | AARCH64_FEATURE_SVE2))
+  if (AARCH64_CPU_HAS_FEATURE (*opcode->avariant, AARCH64_FEATURE_SME2))
+    imm_reg_type = REG_TYPE_R_ZR_SP_BHSDQ_VZP_PN;
+  else if (AARCH64_CPU_HAS_ANY_FEATURES (*opcode->avariant,
+                                        AARCH64_FEATURE_SVE
+                                        | AARCH64_FEATURE_SVE2))
     imm_reg_type = REG_TYPE_R_ZR_SP_BHSDQ_VZP;
   else
     imm_reg_type = REG_TYPE_R_ZR_BHSDQ_V;
@@ -6655,6 +6668,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
        case AARCH64_OPND_SVE_Zm_16:
        case AARCH64_OPND_SVE_Zn:
        case AARCH64_OPND_SVE_Zt:
+       case AARCH64_OPND_SME_Zm:
          reg_type = REG_TYPE_Z;
          goto vector_reg;
 
@@ -6718,10 +6732,24 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 
        case AARCH64_OPND_SVE_Zm3_INDEX:
        case AARCH64_OPND_SVE_Zm3_22_INDEX:
+       case AARCH64_OPND_SVE_Zm3_19_INDEX:
        case AARCH64_OPND_SVE_Zm3_11_INDEX:
        case AARCH64_OPND_SVE_Zm4_11_INDEX:
        case AARCH64_OPND_SVE_Zm4_INDEX:
        case AARCH64_OPND_SVE_Zn_INDEX:
+       case AARCH64_OPND_SME_Zm_INDEX1:
+       case AARCH64_OPND_SME_Zm_INDEX2:
+       case AARCH64_OPND_SME_Zm_INDEX3_1:
+       case AARCH64_OPND_SME_Zm_INDEX3_2:
+       case AARCH64_OPND_SME_Zm_INDEX3_10:
+       case AARCH64_OPND_SME_Zm_INDEX4_1:
+       case AARCH64_OPND_SME_Zm_INDEX4_10:
+       case AARCH64_OPND_SME_Zn_INDEX1_16:
+       case AARCH64_OPND_SME_Zn_INDEX2_15:
+       case AARCH64_OPND_SME_Zn_INDEX2_16:
+       case AARCH64_OPND_SME_Zn_INDEX3_14:
+       case AARCH64_OPND_SME_Zn_INDEX3_15:
+       case AARCH64_OPND_SME_Zn_INDEX4_14:
          reg_type = REG_TYPE_Z;
          goto vector_reg_index;
 
@@ -6735,14 +6763,23 @@ parse_operands (char *str, const aarch64_opcode *opcode)
          reg = aarch64_reg_parse (&str, reg_type, &vectype);
          if (!reg)
            goto failure;
-         if (vectype.type == NT_invtype || !(vectype.defined & NTA_HASINDEX))
+         if (!(vectype.defined & NTA_HASINDEX))
            goto failure;
 
+         if (reg->type == REG_TYPE_Z && vectype.type == NT_invtype)
+           /* Unqualified Zn[index] is allowed in LUTI2 instructions.  */
+           info->qualifier = AARCH64_OPND_QLF_NIL;
+         else
+           {
+             if (vectype.type == NT_invtype)
+               goto failure;
+             info->qualifier = vectype_to_qualifier (&vectype);
+             if (info->qualifier == AARCH64_OPND_QLF_NIL)
+               goto failure;
+           }
+
          info->reglane.regno = reg->number;
          info->reglane.index = vectype.index;
-         info->qualifier = vectype_to_qualifier (&vectype);
-         if (info->qualifier == AARCH64_OPND_QLF_NIL)
-           goto failure;
          break;
 
        case AARCH64_OPND_SVE_ZnxN:
@@ -6792,7 +6829,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
                  goto failure;
                }
 
-             if (vectype.width != 0 && *str != ',')
+             if ((int) vectype.width > 0 && *str != ',')
                {
                  set_fatal_syntax_error
                    (_("expected element type rather than vector type"));
@@ -6865,6 +6902,8 @@ parse_operands (char *str, const aarch64_opcode *opcode)
        case AARCH64_OPND_SVE_SHLIMM_PRED:
        case AARCH64_OPND_SVE_SHLIMM_UNPRED:
        case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
+       case AARCH64_OPND_SME_SHRIMM4:
+       case AARCH64_OPND_SME_SHRIMM5:
        case AARCH64_OPND_SVE_SHRIMM_PRED:
        case AARCH64_OPND_SVE_SHRIMM_UNPRED:
        case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
@@ -7734,12 +7773,50 @@ parse_operands (char *str, const aarch64_opcode *opcode)
          inst.base.operands[i].prfop = aarch64_prfops + val;
          break;
 
+       case AARCH64_OPND_RPRFMOP:
+         po_enum_or_fail (aarch64_rprfmop_array);
+         info->imm.value = val;
+         break;
+
        case AARCH64_OPND_BARRIER_PSB:
          val = parse_barrier_psb (&str, &(info->hint_option));
          if (val == PARSE_FAIL)
            goto failure;
          break;
 
+       case AARCH64_OPND_SME_ZT0:
+         po_reg_or_fail (REG_TYPE_ZT0);
+         break;
+
+       case AARCH64_OPND_SME_ZT0_INDEX:
+         reg = aarch64_reg_parse (&str, REG_TYPE_ZT0, &vectype);
+         if (!reg || vectype.type != NT_invtype)
+           goto failure;
+         if (!(vectype.defined & NTA_HASINDEX))
+           {
+             set_syntax_error (_("missing register index"));
+             goto failure;
+           }
+         info->imm.value = vectype.index;
+         break;
+
+       case AARCH64_OPND_SME_ZT0_LIST:
+         if (*str != '{')
+           {
+             set_expected_reglist_error (REG_TYPE_ZT0, parse_reg (&str));
+             goto failure;
+           }
+         str++;
+         if (!parse_typed_reg (&str, REG_TYPE_ZT0, &vectype, PTR_IN_REGLIST))
+           goto failure;
+         if (*str != '}')
+           {
+             set_syntax_error (_("expected '}' after ZT0"));
+             goto failure;
+           }
+         str++;
+         break;
+
        case AARCH64_OPND_SME_PNn3_INDEX1:
        case AARCH64_OPND_SME_PNn3_INDEX2:
          reg = aarch64_reg_parse (&str, REG_TYPE_PN, &vectype);
@@ -7795,8 +7872,12 @@ parse_operands (char *str, const aarch64_opcode *opcode)
          info->imm.value = val;
          break;
 
+       case AARCH64_OPND_SME_ZA_array_off1x4:
+       case AARCH64_OPND_SME_ZA_array_off2x2:
+       case AARCH64_OPND_SME_ZA_array_off2x4:
        case AARCH64_OPND_SME_ZA_array_off3_0:
        case AARCH64_OPND_SME_ZA_array_off3_5:
+       case AARCH64_OPND_SME_ZA_array_off3x2:
        case AARCH64_OPND_SME_ZA_array_off4:
          if (!parse_dual_indexed_reg (&str, REG_TYPE_ZA,
                                       &info->indexed_za, &qualifier, 0))
@@ -8462,7 +8543,10 @@ static const reg_entry reg_names[] = {
   REGSET16S (za, h, ZATH), REGSET16S (ZA, H, ZATH),
 
   /* SME ZA tile registers (vertical slice).  */
-  REGSET16S (za, v, ZATV), REGSET16S (ZA, V, ZATV)
+  REGSET16S (za, v, ZATV), REGSET16S (ZA, V, ZATV),
+
+  /* SME2 ZT0.  */
+  REGDEF (zt0, 0, ZT0), REGDEF (ZT0, 0, ZT0)
 };
 
 #undef REGDEF
@@ -10143,12 +10227,21 @@ static const struct aarch64_cpu_option_table aarch64_cpus[] = {
                   | AARCH64_FEATURE_MEMTAG
                   | AARCH64_FEATURE_SVE2_BITPERM),
    "Cortex-A510"},
+  {"cortex-a520", AARCH64_FEATURE (AARCH64_ARCH_V9_2,
+                  AARCH64_FEATURE_MEMTAG
+                  | AARCH64_FEATURE_SVE2_BITPERM),
+   "Cortex-A520"},
   {"cortex-a710", AARCH64_FEATURE (AARCH64_ARCH_V9,
                   AARCH64_FEATURE_BFLOAT16
                   | AARCH64_FEATURE_I8MM
                   | AARCH64_FEATURE_MEMTAG
                   | AARCH64_FEATURE_SVE2_BITPERM),
    "Cortex-A710"},
+  {"cortex-a720", AARCH64_FEATURE (AARCH64_ARCH_V9_2,
+                  AARCH64_FEATURE_MEMTAG
+                 | AARCH64_FEATURE_PROFILE
+                  | AARCH64_FEATURE_SVE2_BITPERM),
+   "Cortex-A720"},
   {"ares", AARCH64_FEATURE (AARCH64_ARCH_V8_2,
                                  AARCH64_FEATURE_RCPC | AARCH64_FEATURE_F16
                                  | AARCH64_FEATURE_DOTPROD