* gas/config/tc-avr.c: Change ISA for devices with USB support to
[external/binutils.git] / gas / config / tc-arm.c
index 4cd2745..72eb0de 100644 (file)
@@ -1,7 +1,5 @@
 /* tc-arm.c -- Assemble for the ARM
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright 1994-2013 Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
        Modified by David Taylor (dtaylor@armltd.co.uk)
        Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
@@ -240,6 +238,8 @@ static const arm_feature_set fpu_neon_ext_armv8 =
   ARM_FEATURE (0, FPU_NEON_EXT_ARMV8);
 static const arm_feature_set fpu_crypto_ext_armv8 =
   ARM_FEATURE (0, FPU_CRYPTO_EXT_ARMV8);
+static const arm_feature_set crc_ext_armv8 =
+  ARM_FEATURE (0, CRC_EXT_ARMV8);
 
 static int mfloat_abi_opt = -1;
 /* Record user cpu selection for object attributes.  */
@@ -750,6 +750,7 @@ struct asm_opcode
 #define BAD_PC_WRITEBACK \
        _("cannot use writeback with PC-relative addressing")
 #define BAD_RANGE     _("branch out of range")
+#define UNPRED_REG(R)  _("using " R " results in unpredictable behaviour")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -885,6 +886,9 @@ const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
 static inline int
 skip_past_char (char ** str, char c)
 {
+  /* PR gas/14987: Allow for whitespace before the expected character.  */
+  skip_whitespace (*str);
+
   if (**str == c)
     {
       (*str)++;
@@ -5168,6 +5172,9 @@ parse_address_main (char **str, int i, int group_relocations,
       return PARSE_OPERAND_SUCCESS;
     }
 
+  /* PR gas/14887: Allow for whitespace after the opening bracket.  */
+  skip_whitespace (p);
+
   if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
     {
       inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
@@ -6331,22 +6338,16 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
   do                                                      \
     {                                                     \
       val = parse_barrier (&str);                         \
-      if (val == FAIL)                                    \
-       {                                                  \
-         if (ISALPHA (*str))                              \
-             goto failure;                                \
-         else                                             \
-             goto immediate;                              \
-       }                                                  \
-      else                                                \
+      if (val == FAIL && ! ISALPHA (*str))                \
+       goto immediate;                                    \
+      if (val == FAIL                                     \
+         /* ISB can only take SY as an option.  */        \
+         || ((inst.instruction & 0xf0) == 0x60            \
+              && val != 0xf))                             \
        {                                                  \
-         if ((inst.instruction & 0xf0) == 0x60            \
-             && val != 0xf)                               \
-           {                                              \
-              /* ISB can only take SY as an option.  */   \
-              inst.error = _("invalid barrier type");     \
-              goto failure;                               \
-           }                                              \
+          inst.error = _("invalid barrier type");         \
+          backtrack_pos = 0;                              \
+          goto failure;                                   \
        }                                                  \
     }                                                     \
   while (0)
@@ -7195,8 +7196,10 @@ encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
   if (inst.operands[i].immisreg)
     {
       constraint ((inst.operands[i].imm == REG_PC
-                  || inst.operands[i].reg == REG_PC),
+                  || (is_t && inst.operands[i].reg == REG_PC)),
                  BAD_PC_ADDRESSING);
+      constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
+                 BAD_PC_WRITEBACK);
       inst.instruction |= inst.operands[i].imm;
       if (!inst.operands[i].negative)
        inst.instruction |= INDEX_UP;
@@ -7534,13 +7537,7 @@ static void
 do_barrier (void)
 {
   if (inst.operands[0].present)
-    {
-      constraint ((inst.instruction & 0xf0) != 0x40
-                 && inst.operands[0].imm > 0xf
-                 && inst.operands[0].imm < 0x0,
-                 _("bad barrier type"));
-      inst.instruction |= inst.operands[0].imm;
-    }
+    inst.instruction |= inst.operands[0].imm;
   else
     inst.instruction |= 0xf;
 }
@@ -7821,7 +7818,7 @@ do_co_reg (void)
            && inst.operands[4].reg == r->crm
            && inst.operands[5].imm == r->opc2)
          {
-           if (!check_obsolete (&r->obsoleted, r->obs_msg)
+           if (! ARM_CPU_IS_ANY (cpu_variant)
                && warn_on_deprecated
                && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
              as_warn ("%s", r->dep_msg);
@@ -8249,32 +8246,22 @@ do_vmrs (void)
 {
   unsigned Rt = inst.operands[0].reg;
 
-  if (thumb_mode && inst.operands[0].reg == REG_SP)
+  if (thumb_mode && Rt == REG_SP)
     {
       inst.error = BAD_SP;
       return;
     }
 
   /* APSR_ sets isvec. All other refs to PC are illegal.  */
-  if (!inst.operands[0].isvec && inst.operands[0].reg == REG_PC)
+  if (!inst.operands[0].isvec && Rt == REG_PC)
     {
       inst.error = BAD_PC;
       return;
     }
 
-  switch (inst.operands[1].reg)
-    {
-    case 0: /* FPSID */
-    case 1: /* FPSCR */
-    case 6: /* MVFR1 */
-    case 7: /* MVFR0 */
-    case 8: /* FPEXC */
-      inst.instruction |= (inst.operands[1].reg << 16);
-      break;
-    default:
-      first_error (_("operand 1 must be a VFP extension System Register"));
-    }
-
+  /* If we get through parsing the register name, we just insert the number
+     generated into the instruction without further validation.  */
+  inst.instruction |= (inst.operands[1].reg << 16);
   inst.instruction |= (Rt << 12);
 }
 
@@ -8291,17 +8278,9 @@ do_vmsr (void)
       return;
     }
 
-  switch (inst.operands[0].reg)
-    {
-    case 0: /* FPSID  */
-    case 1: /* FPSCR  */
-    case 8: /* FPEXC */
-      inst.instruction |= (inst.operands[0].reg << 16);
-      break;
-    default:
-      first_error (_("operand 0 must be FPSID or FPSCR pr FPEXC"));
-    }
-
+  /* If we get through parsing the register name, we just insert the number
+     generated into the instruction without further validation.  */
+  inst.instruction |= (inst.operands[0].reg << 16);
   inst.instruction |= (Rt << 12);
 }
 
@@ -9464,8 +9443,8 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
       constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
       constraint (is_t && inst.operands[i].writeback,
                  _("cannot use writeback with this instruction"));
-      constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0)
-                 && !inst.reloc.pc_rel, BAD_PC_ADDRESSING);
+      constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
+                 BAD_PC_ADDRESSING);
 
       if (is_d)
        {
@@ -10062,21 +10041,6 @@ do_t_arit3c (void)
 }
 
 static void
-do_t_barrier (void)
-{
-  if (inst.operands[0].present)
-    {
-      constraint ((inst.instruction & 0xf0) != 0x40
-                 && inst.operands[0].imm > 0xf
-                 && inst.operands[0].imm < 0x0,
-                 _("bad barrier type"));
-      inst.instruction |= inst.operands[0].imm;
-    }
-  else
-    inst.instruction |= 0xf;
-}
-
-static void
 do_t_bfc (void)
 {
   unsigned Rd;
@@ -15353,6 +15317,16 @@ do_neon_mov (void)
         unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
         unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
 
+       /* .<size> is optional here, defaulting to .32. */
+       if (inst.vectype.elems == 0
+           && inst.operands[0].vectype.type == NT_invtype
+           && inst.operands[1].vectype.type == NT_invtype)
+         {
+           inst.vectype.el[0].type = NT_untyped;
+           inst.vectype.el[0].size = 32;
+           inst.vectype.elems = 1;
+         }
+
         et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
         logsize = neon_logbits (et.size);
 
@@ -15402,6 +15376,16 @@ do_neon_mov (void)
         unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
         unsigned abcdebits = 0;
 
+       /* .<dt> is optional here, defaulting to .32. */
+       if (inst.vectype.elems == 0
+           && inst.operands[0].vectype.type == NT_invtype
+           && inst.operands[1].vectype.type == NT_invtype)
+         {
+           inst.vectype.el[0].type = NT_untyped;
+           inst.vectype.el[0].size = 32;
+           inst.vectype.elems = 1;
+         }
+
        et = neon_check_type (2, NS_NULL,
                              N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
         logsize = neon_logbits (et.size);
@@ -15490,6 +15474,11 @@ do_neon_mov (void)
       do_vfp_nsyn_opcode ("fmsrr");
       break;
 
+    case NS_NULL:
+      /* neon_select_shape has determined that the instruction
+        shape is wrong and has already set the error message.  */
+      break;
+
     default:
       abort ();
     }
@@ -15678,12 +15667,12 @@ do_neon_ldr_str (void)
      And is UNPREDICTABLE in thumb mode.  */
   if (!is_ldr
       && inst.operands[1].reg == REG_PC
-      && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
+      && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
     {
-      if (!thumb_mode && warn_on_deprecated)
-       as_warn (_("Use of PC here is deprecated"));
-      else
+      if (thumb_mode)
        inst.error = _("Use of PC here is UNPREDICTABLE");
+      else if (warn_on_deprecated)
+       as_warn (_("Use of PC here is deprecated"));
     }
 
   if (inst.operands[0].issingle)
@@ -15987,6 +15976,11 @@ do_neon_ldx_stx (void)
 
     case NEON_ALL_LANES:
       NEON_ENCODE (DUP, inst);
+      if (inst.instruction == N_INV)
+       {
+         first_error ("only loads support such operands");
+         break;
+       }
       do_neon_ld_dup ();
       break;
 
@@ -16305,6 +16299,63 @@ do_sha256su0 (void)
 {
   do_crypto_2op_1 (N_32, 1);
 }
+
+static void
+do_crc32_1 (unsigned int poly, unsigned int sz)
+{
+  unsigned int Rd = inst.operands[0].reg;
+  unsigned int Rn = inst.operands[1].reg;
+  unsigned int Rm = inst.operands[2].reg;
+
+  set_it_insn_type (OUTSIDE_IT_INSN);
+  inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
+  inst.instruction |= LOW4 (Rn) << 16;
+  inst.instruction |= LOW4 (Rm);
+  inst.instruction |= sz << (thumb_mode ? 4 : 21);
+  inst.instruction |= poly << (thumb_mode ? 20 : 9);
+
+  if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
+    as_warn (UNPRED_REG ("r15"));
+  if (thumb_mode && (Rd == REG_SP || Rn == REG_SP || Rm == REG_SP))
+    as_warn (UNPRED_REG ("r13"));
+}
+
+static void
+do_crc32b (void)
+{
+  do_crc32_1 (0, 0);
+}
+
+static void
+do_crc32h (void)
+{
+  do_crc32_1 (0, 1);
+}
+
+static void
+do_crc32w (void)
+{
+  do_crc32_1 (0, 2);
+}
+
+static void
+do_crc32cb (void)
+{
+  do_crc32_1 (1, 0);
+}
+
+static void
+do_crc32ch (void)
+{
+  do_crc32_1 (1, 1);
+}
+
+static void
+do_crc32cw (void)
+{
+  do_crc32_1 (1, 2);
+}
+
 \f
 /* Overall per-instruction processing. */
 
@@ -17039,7 +17090,7 @@ it_fsm_post_encode (void)
     {
       if (inst.instruction >= 0x10000)
        {
-         as_warn (_("it blocks containing wide Thumb instructions are "
+         as_warn (_("IT blocks containing 32-bit Thumb instructions are "
                     "deprecated in ARMv8"));
          now_it.warn_deprecated = TRUE;
        }
@@ -17051,7 +17102,7 @@ it_fsm_post_encode (void)
            {
              if ((inst.instruction & p->mask) == p->pattern)
                {
-                 as_warn (_("it blocks containing 16-bit Thumb intsructions "
+                 as_warn (_("IT blocks containing 16-bit Thumb instructions "
                             "of the following class are deprecated in ARMv8: "
                             "%s"), p->description);
                  now_it.warn_deprecated = TRUE;
@@ -17064,8 +17115,8 @@ it_fsm_post_encode (void)
 
       if (now_it.block_length > 1)
        {
-         as_warn (_("it blocks of more than one conditional instruction are "
-                    "deprecated in ARMv8"));
+         as_warn (_("IT blocks containing more than one conditional "
+                    "instruction are deprecated in ARMv8"));
          now_it.warn_deprecated = TRUE;
        }
     }
@@ -17469,7 +17520,7 @@ static const struct reg_entry reg_names[] =
   REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
   REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
   REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
-  REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(SP_fiq,512|(13<<16),RNB),
+  REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
   REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
   REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
 
@@ -17790,6 +17841,13 @@ static struct asm_barrier_opt barrier_opt_names[] =
   { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
     THUMB_VARIANT, do_##ae, do_##te }
 
+/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
+   Used by mnemonics that have very minimal differences in the encoding for
+   ARM and Thumb variants and can be handled in a common function.  */
+#define TUEc(mnem, op, top, nops, ops, en) \
+  { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
+    THUMB_VARIANT, do_##en, do_##en }
+
 /* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
    condition code field.  */
 #define TUF(mnem, op, top, nops, ops, ae, te)                          \
@@ -18189,17 +18247,23 @@ static const struct asm_opcode insns[] =
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT  & arm_ext_v6_notm
  TUF("rfeia",  8900a00, e990c000, 1, (RRw),                       rfe, rfe),
+ TUF("rfe",    8900a00, e990c000, 1, (RRw),                       rfe, rfe),
   UF(rfeib,    9900a00,           1, (RRw),                       rfe),
   UF(rfeda,    8100a00,           1, (RRw),                       rfe),
  TUF("rfedb",  9100a00, e810c000, 1, (RRw),                       rfe, rfe),
  TUF("rfefd",  8900a00, e990c000, 1, (RRw),                       rfe, rfe),
-  UF(rfefa,    9900a00,           1, (RRw),                       rfe),
 UF(rfeea,    8100a00,           1, (RRw),                       rfe),
TUF("rfeed",  9100a00, e810c000, 1, (RRw),                       rfe, rfe),
+  UF(rfefa,    8100a00,           1, (RRw),                       rfe),
TUF("rfeea",  9100a00, e810c000, 1, (RRw),                       rfe, rfe),
 UF(rfeed,    9900a00,           1, (RRw),                       rfe),
  TUF("srsia",  8c00500, e980c000, 2, (oRRw, I31w),                srs,  srs),
+ TUF("srs",    8c00500, e980c000, 2, (oRRw, I31w),                srs,  srs),
+ TUF("srsea",  8c00500, e980c000, 2, (oRRw, I31w),                srs,  srs),
   UF(srsib,    9c00500,           2, (oRRw, I31w),                srs),
+  UF(srsfa,    9c00500,           2, (oRRw, I31w),                srs),
   UF(srsda,    8400500,           2, (oRRw, I31w),                srs),
+  UF(srsed,    8400500,           2, (oRRw, I31w),                srs),
  TUF("srsdb",  9400500, e800c000, 2, (oRRw, I31w),                srs,  srs),
+ TUF("srsfd",  9400500, e800c000, 2, (oRRw, I31w),                srs,  srs),
 
 /*  ARM V6 not included in V7M (eg. integer SIMD).  */
 #undef  THUMB_VARIANT
@@ -18421,9 +18485,9 @@ static const struct asm_opcode insns[] =
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT  & arm_ext_barrier
 
- TUF("dmb",    57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier,  t_barrier),
- TUF("dsb",    57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier,  t_barrier),
- TUF("isb",    57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier,  t_barrier),
+ TUF("dmb",    57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
+ TUF("dsb",    57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
+ TUF("isb",    57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
 
  /* ARM V7 instructions.  */
 #undef  ARM_VARIANT
@@ -18522,6 +18586,17 @@ static const struct asm_opcode insns[] =
   nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
 
 #undef  ARM_VARIANT
+#define ARM_VARIANT & crc_ext_armv8
+#undef  THUMB_VARIANT
+#define THUMB_VARIANT & crc_ext_armv8
+  TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
+  TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
+  TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
+  TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
+  TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
+  TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
+
+#undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_fpa_ext_v1  /* Core FPA instruction set (V1).  */
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT NULL
@@ -21537,8 +21612,9 @@ md_apply_fix (fixS *    fixP,
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("invalid literal constant: pool needs to be closer"));
          else
-           as_bad (_("bad immediate value for 8-bit offset (%ld)"),
-                   (long) value);
+           as_bad_where (fixP->fx_file, fixP->fx_line,
+                         _("bad immediate value for 8-bit offset (%ld)"),
+                         (long) value);
          break;
        }
 
@@ -22040,18 +22116,18 @@ md_apply_fix (fixS *  fixP,
 
     thumb_bl_common:
 
-#ifdef OBJ_ELF
-       if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
-          && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
-        fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
-#endif
-
       if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
        /* For a BLX instruction, make sure that the relocation is rounded up
           to a word boundary.  This follows the semantics of the instruction
           which specifies that bit 1 of the target address will come from bit
           1 of the base address.  */
-       value = (value + 1) & ~ 1;
+       value = (value + 3) & ~ 3;
+
+#ifdef OBJ_ELF
+       if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
+          && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
+        fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+#endif
 
       if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
        {
@@ -23872,11 +23948,18 @@ static const struct arm_cpu_option_table arm_cpus[] =
   ARM_CPU_OPT ("cortex-a15",   ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
                                                 FPU_ARCH_NEON_VFP_V4,
                                                                  "Cortex-A15"),
+  ARM_CPU_OPT ("cortex-a53",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+                                                                 "Cortex-A53"),
+  ARM_CPU_OPT ("cortex-a57",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+                                                                 "Cortex-A57"),
   ARM_CPU_OPT ("cortex-r4",    ARM_ARCH_V7R,    FPU_NONE,        "Cortex-R4"),
   ARM_CPU_OPT ("cortex-r4f",   ARM_ARCH_V7R,    FPU_ARCH_VFP_V3D16,
                                                                  "Cortex-R4F"),
   ARM_CPU_OPT ("cortex-r5",    ARM_ARCH_V7R_IDIV,
                                                 FPU_NONE,        "Cortex-R5"),
+  ARM_CPU_OPT ("cortex-r7",    ARM_ARCH_V7R_IDIV,
+                                                FPU_ARCH_VFP_V3D16,
+                                                                 "Cortex-R7"),
   ARM_CPU_OPT ("cortex-m4",    ARM_ARCH_V7EM,   FPU_NONE,        "Cortex-M4"),
   ARM_CPU_OPT ("cortex-m3",    ARM_ARCH_V7M,    FPU_NONE,        "Cortex-M3"),
   ARM_CPU_OPT ("cortex-m1",    ARM_ARCH_V6SM,   FPU_NONE,        "Cortex-M1"),
@@ -23890,8 +23973,11 @@ static const struct arm_cpu_option_table arm_cpus[] =
   ARM_CPU_OPT ("i80200",       ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
   /* Maverick */
   ARM_CPU_OPT ("ep9312",       ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
-                                                FPU_ARCH_MAVERICK,
-                                                                 "ARM920T"),
+                                                FPU_ARCH_MAVERICK, "ARM920T"),
+  /* Marvell processors.  */
+  ARM_CPU_OPT ("marvell-pj4",   ARM_FEATURE (ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC, 0),
+                                               FPU_ARCH_VFP_V3D16, NULL),
+
   { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
 };
 #undef ARM_CPU_OPT
@@ -23969,6 +24055,7 @@ struct arm_option_extension_value_table
 #define ARM_EXT_OPT(N, V, AA) { N, sizeof (N) - 1, V, AA }
 static const struct arm_option_extension_value_table arm_extensions[] =
 {
+  ARM_EXT_OPT ("crc",  ARCH_CRC_ARMV8, ARM_FEATURE (ARM_EXT_V8, 0)),
   ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
                                   ARM_FEATURE (ARM_EXT_V8, 0)),
   ARM_EXT_OPT ("fp",     FPU_ARCH_VFP_ARMV8,