Blame SOURCES/binutils-2.27-ARMv8.2.patch

be6651
diff -rup binutils.orig/gas/config/tc-arm.c binutils-2.27/gas/config/tc-arm.c
be6651
--- binutils.orig/gas/config/tc-arm.c	2017-08-09 10:26:30.032741952 +0100
be6651
+++ binutils-2.27/gas/config/tc-arm.c	2017-08-09 11:17:17.747598541 +0100
be6651
@@ -147,8 +147,10 @@ static const arm_feature_set *legacy_cpu
be6651
 static const arm_feature_set *legacy_fpu = NULL;
be6651
 
be6651
 static const arm_feature_set *mcpu_cpu_opt = NULL;
be6651
+static arm_feature_set *dyn_mcpu_ext_opt = NULL;
be6651
 static const arm_feature_set *mcpu_fpu_opt = NULL;
be6651
 static const arm_feature_set *march_cpu_opt = NULL;
be6651
+static arm_feature_set *dyn_march_ext_opt = NULL;
be6651
 static const arm_feature_set *march_fpu_opt = NULL;
be6651
 static const arm_feature_set *mfpu_opt = NULL;
be6651
 static const arm_feature_set *object_arch = NULL;
be6651
@@ -187,7 +189,6 @@ static const arm_feature_set arm_ext_v5j
be6651
 static const arm_feature_set arm_ext_v6 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6);
be6651
 static const arm_feature_set arm_ext_v6k = ARM_FEATURE_CORE_LOW (ARM_EXT_V6K);
be6651
 static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2);
be6651
-static const arm_feature_set arm_ext_v6m = ARM_FEATURE_CORE_LOW (ARM_EXT_V6M);
be6651
 static const arm_feature_set arm_ext_v6_notm =
be6651
   ARM_FEATURE_CORE_LOW (ARM_EXT_V6_NOTM);
be6651
 static const arm_feature_set arm_ext_v6_dsp =
be6651
@@ -201,11 +202,11 @@ static const arm_feature_set arm_ext_v7
be6651
 static const arm_feature_set arm_ext_v7a = ARM_FEATURE_CORE_LOW (ARM_EXT_V7A);
be6651
 static const arm_feature_set arm_ext_v7r = ARM_FEATURE_CORE_LOW (ARM_EXT_V7R);
be6651
 #ifdef OBJ_ELF
be6651
-static const arm_feature_set arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
be6651
+static const arm_feature_set ATTRIBUTE_UNUSED arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
be6651
 #endif
be6651
 static const arm_feature_set arm_ext_v8 = ARM_FEATURE_CORE_LOW (ARM_EXT_V8);
be6651
 static const arm_feature_set arm_ext_m =
be6651
-  ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_OS | ARM_EXT_V7M,
be6651
+  ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_V7M,
be6651
 		    ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
be6651
 static const arm_feature_set arm_ext_mp = ARM_FEATURE_CORE_LOW (ARM_EXT_MP);
be6651
 static const arm_feature_set arm_ext_sec = ARM_FEATURE_CORE_LOW (ARM_EXT_SEC);
be6651
@@ -234,14 +235,16 @@ static const arm_feature_set arm_ext_ras
be6651
 /* FP16 instructions.  */
be6651
 static const arm_feature_set arm_ext_fp16 =
be6651
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST);
be6651
+static const arm_feature_set arm_ext_v8_3 =
be6651
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A);
be6651
 
be6651
 static const arm_feature_set arm_arch_any = ARM_ANY;
be6651
+#ifdef OBJ_ELF
be6651
+static const arm_feature_set fpu_any = FPU_ANY;
be6651
+#endif
be6651
 static const arm_feature_set arm_arch_full ATTRIBUTE_UNUSED = ARM_FEATURE (-1, -1, -1);
be6651
 static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
be6651
 static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
be6651
-#ifdef OBJ_ELF
be6651
-static const arm_feature_set arm_arch_v6m_only = ARM_ARCH_V6M_ONLY;
be6651
-#endif
be6651
 
be6651
 static const arm_feature_set arm_cext_iwmmxt2 =
be6651
   ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2);
be6651
@@ -291,6 +294,8 @@ static const arm_feature_set crc_ext_arm
be6651
   ARM_FEATURE_COPROC (CRC_EXT_ARMV8);
be6651
 static const arm_feature_set fpu_neon_ext_v8_1 =
be6651
   ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA);
be6651
+static const arm_feature_set fpu_neon_ext_dotprod =
be6651
+  ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD);
be6651
 
be6651
 static int mfloat_abi_opt = -1;
be6651
 /* Record user cpu selection for object attributes.  */
be6651
@@ -685,9 +690,11 @@ struct asm_opcode
be6651
 #define T2_SUBS_PC_LR	0xf3de8f00
be6651
 
be6651
 #define DATA_OP_SHIFT	21
be6651
+#define SBIT_SHIFT	20
be6651
 
be6651
 #define T2_OPCODE_MASK	0xfe1fffff
be6651
 #define T2_DATA_OP_SHIFT 21
be6651
+#define T2_SBIT_SHIFT	 20
be6651
 
be6651
 #define A_COND_MASK         0xf0000000
be6651
 #define A_PUSH_POP_OP_MASK  0x0fff0000
be6651
@@ -1276,6 +1283,7 @@ arm_reg_alt_syntax (char **ccp, char *st
be6651
 	if (*ccp != start && processor <= 15)
be6651
 	  return processor;
be6651
       }
be6651
+      /* Fall through.  */
be6651
 
be6651
     case REG_TYPE_MMXWC:
be6651
       /* WC includes WCG.  ??? I'm not sure this is true for all
be6651
@@ -2705,7 +2713,7 @@ mapping_state (enum mstate state)
be6651
 
be6651
 	Some Thumb instructions are alignment-sensitive modulo 4 bytes,
be6651
 	but themselves require 2-byte alignment; this applies to some
be6651
-	PC- relative forms.  However, these cases will invovle implicit
be6651
+	PC- relative forms.  However, these cases will involve implicit
be6651
 	literal pool generation or an explicit .align >=2, both of
be6651
 	which will cause the section to me marked with sufficient
be6651
 	alignment.  Thus, we don't handle those cases here.  */
be6651
@@ -3042,7 +3050,7 @@ s_ccs_ref (int unused ATTRIBUTE_UNUSED)
be6651
 }
be6651
 
be6651
 /*  If name is not NULL, then it is used for marking the beginning of a
be6651
-    function, wherease if it is NULL then it means the function end.  */
be6651
+    function, whereas if it is NULL then it means the function end.  */
be6651
 static void
be6651
 asmfunc_debug (const char * name)
be6651
 {
be6651
@@ -3375,7 +3383,7 @@ tc_start_label_without_colon (void)
be6651
 }
be6651
 
be6651
 /* Can't use symbol_new here, so have to create a symbol and then at
be6651
-   a later date assign it a value. Thats what these functions do.  */
be6651
+   a later date assign it a value. That's what these functions do.  */
be6651
 
be6651
 static void
be6651
 symbol_locate (symbolS *    symbolP,
be6651
@@ -4964,9 +4972,13 @@ parse_ifimm_zero (char **in)
be6651
   int error_code;
be6651
 
be6651
   if (!is_immediate_prefix (**in))
be6651
-    return FALSE;
be6651
-
be6651
-  ++*in;
be6651
+    {
be6651
+      /* In unified syntax, all prefixes are optional.  */
be6651
+      if (!unified_syntax)
be6651
+	return FALSE;
be6651
+    }
be6651
+  else
be6651
+    ++*in;
be6651
 
be6651
   /* Accept #0x0 as a synonym for #0.  */
be6651
   if (strncmp (*in, "0x", 2) == 0)
be6651
@@ -6530,6 +6542,8 @@ enum operand_parse_code
be6651
   OP_EXPi,	/* same, with optional immediate prefix */
be6651
   OP_EXPr,	/* same, with optional relocation suffix */
be6651
   OP_HALF,	/* 0 .. 65535 or low/high reloc.  */
be6651
+  OP_IROT1,	/* VCADD rotate immediate: 90, 270.  */
be6651
+  OP_IROT2,	/* VCMLA rotate immediate: 0, 90, 180, 270.  */
be6651
 
be6651
   OP_CPSF,	/* CPS flags */
be6651
   OP_ENDI,	/* Endianness specifier */
be6651
@@ -6541,7 +6555,7 @@ enum operand_parse_code
be6651
   OP_APSR_RR,   /* ARM register or "APSR_nzcv".  */
be6651
 
be6651
   OP_RRnpc_I0,	/* ARM register or literal 0 */
be6651
-  OP_RR_EXr,	/* ARM register or expression with opt. reloc suff. */
be6651
+  OP_RR_EXr,	/* ARM register or expression with opt. reloc stuff. */
be6651
   OP_RR_EXi,	/* ARM register or expression with imm prefix */
be6651
   OP_RF_IF,	/* FPA register or immediate */
be6651
   OP_RIWR_RIWC, /* iWMMXt R or C reg */
be6651
@@ -7178,8 +7192,14 @@ parse_operands (char *str, const unsigne
be6651
 	    {
be6651
 	      if (inst.operands[i].reg == REG_PC)
be6651
 		inst.error = BAD_PC;
be6651
-	      else if (inst.operands[i].reg == REG_SP)
be6651
-		inst.error = BAD_SP;
be6651
+	      else if (inst.operands[i].reg == REG_SP
be6651
+		       /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
be6651
+			  relaxed since ARMv8-A.  */
be6651
+		       && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
be6651
+		{
be6651
+		  gas_assert (thumb);
be6651
+		  inst.error = BAD_SP;
be6651
+		}
be6651
 	    }
be6651
 	  break;
be6651
 
be6651
@@ -7277,14 +7297,23 @@ parse_operands (char *str, const unsigne
be6651
 
be6651
 /* Reject "bad registers" for Thumb-2 instructions.  Many Thumb-2
be6651
    instructions are unpredictable if these registers are used.  This
be6651
-   is the BadReg predicate in ARM's Thumb-2 documentation.  */
be6651
-#define reject_bad_reg(reg)				\
be6651
-  do							\
be6651
-   if (reg == REG_SP || reg == REG_PC)			\
be6651
-     {							\
be6651
-       inst.error = (reg == REG_SP) ? BAD_SP : BAD_PC;	\
be6651
-       return;						\
be6651
-     }							\
be6651
+   is the BadReg predicate in ARM's Thumb-2 documentation.
be6651
+
be6651
+   Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
be6651
+   places, while the restriction on REG_SP was relaxed since ARMv8-A.  */
be6651
+#define reject_bad_reg(reg)					\
be6651
+  do								\
be6651
+   if (reg == REG_PC)						\
be6651
+     {								\
be6651
+       inst.error = BAD_PC;					\
be6651
+       return;							\
be6651
+     }								\
be6651
+   else if (reg == REG_SP					\
be6651
+	    && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))	\
be6651
+     {								\
be6651
+       inst.error = BAD_SP;					\
be6651
+       return;							\
be6651
+     }								\
be6651
   while (0)
be6651
 
be6651
 /* If REG is R13 (the stack pointer), warn that its use is
be6651
@@ -7303,7 +7332,7 @@ parse_operands (char *str, const unsigne
be6651
 
be6651
    The only binary encoding difference is the Coprocessor number.  Coprocessor
be6651
    9 is used for half-precision calculations or conversions.  The format of the
be6651
-   instruction is the same as the equivalent Coprocessor 10 instuction that
be6651
+   instruction is the same as the equivalent Coprocessor 10 instruction that
be6651
    exists for Single-Precision operation.  */
be6651
 
be6651
 static void
be6651
@@ -7426,6 +7455,24 @@ encode_arm_vfp_reg (int reg, enum vfp_re
be6651
 static void
be6651
 encode_arm_shift (int i)
be6651
 {
be6651
+  /* Register-shifted register.  */
be6651
+  if (inst.operands[i].immisreg)
be6651
+    {
be6651
+      int op_index;
be6651
+      for (op_index = 0; op_index <= i; ++op_index)
be6651
+	{
be6651
+	  /* Check the operand only when it's presented.  In pre-UAL syntax,
be6651
+	     if the destination register is the same as the first operand, two
be6651
+	     register form of the instruction can be used.  */
be6651
+	  if (inst.operands[op_index].present && inst.operands[op_index].isreg
be6651
+	      && inst.operands[op_index].reg == REG_PC)
be6651
+	    as_warn (UNPRED_REG ("r15"));
be6651
+	}
be6651
+
be6651
+      if (inst.operands[i].imm == REG_PC)
be6651
+	as_warn (UNPRED_REG ("r15"));
be6651
+    }
be6651
+
be6651
   if (inst.operands[i].shift_kind == SHIFT_RRX)
be6651
     inst.instruction |= SHIFT_ROR << 5;
be6651
   else
be6651
@@ -7930,17 +7977,13 @@ move_or_literal_pool (int i, enum lit_ty
be6651
 	{
be6651
 	  if (thumb_p)
be6651
 	    {
be6651
-	      /* This can be encoded only for a low register.  */
be6651
-	      if ((v & ~0xFF) == 0 && (inst.operands[i].reg < 8))
be6651
-		{
be6651
-		  /* This can be done with a mov(1) instruction.  */
be6651
-		  inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
be6651
-		  inst.instruction |= v;
be6651
-		  return TRUE;
be6651
-		}
be6651
+	      /* LDR should not use lead in a flag-setting instruction being
be6651
+		 chosen so we do not check whether movs can be used.  */
be6651
 
be6651
-	      if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
be6651
+	      if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
be6651
 		  || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
be6651
+		  && inst.operands[i].reg != 13
be6651
+		  && inst.operands[i].reg != 15)
be6651
 		{
be6651
 		  /* Check if on thumb2 it can be done with a mov.w, mvn or
be6651
 		     movw instruction.  */
be6651
@@ -8326,6 +8369,12 @@ do_adr (void)
be6651
   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
be6651
   inst.reloc.pc_rel = 1;
be6651
   inst.reloc.exp.X_add_number -= 8;
be6651
+
be6651
+  if (inst.reloc.exp.X_op == O_symbol
be6651
+      && inst.reloc.exp.X_add_symbol != NULL
be6651
+      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
be6651
+      && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
be6651
+    inst.reloc.exp.X_add_number += 1;  
be6651
 }
be6651
 
be6651
 /* This is a pseudo-op of the form "adrl rd, label" to be converted
be6651
@@ -8344,6 +8393,12 @@ do_adrl (void)
be6651
   inst.reloc.pc_rel	       = 1;
be6651
   inst.size		       = INSN_SIZE * 2;
be6651
   inst.reloc.exp.X_add_number -= 8;
be6651
+
be6651
+  if (inst.reloc.exp.X_op == O_symbol
be6651
+      && inst.reloc.exp.X_add_symbol != NULL
be6651
+      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
be6651
+      && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
be6651
+    inst.reloc.exp.X_add_number += 1;  
be6651
 }
be6651
 
be6651
 static void
be6651
@@ -8622,7 +8677,7 @@ do_co_reg (void)
be6651
 	  || inst.instruction == 0xfe000010)
be6651
 	/* MCR, MCR2  */
be6651
 	reject_bad_reg (Rd);
be6651
-      else
be6651
+      else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
be6651
 	/* MRC, MRC2  */
be6651
 	constraint (Rd == REG_SP, BAD_SP);
be6651
     }
be6651
@@ -8691,6 +8746,14 @@ do_co_reg2c (void)
be6651
       constraint (Rn == REG_PC, BAD_PC);
be6651
     }
be6651
 
be6651
+  /* Only check the MRRC{2} variants.  */
be6651
+  if ((inst.instruction & 0x0FF00000) == 0x0C500000)
be6651
+    {
be6651
+       /* If Rd == Rn, error that the operation is
be6651
+	  unpredictable (example MRRC p3,#1,r1,r1,c4).  */
be6651
+       constraint (Rd == Rn, BAD_OVERLAP);
be6651
+    }
be6651
+
be6651
   inst.instruction |= inst.operands[0].reg << 8;
be6651
   inst.instruction |= inst.operands[1].imm << 4;
be6651
   inst.instruction |= Rd << 12;
be6651
@@ -8916,7 +8979,7 @@ check_ldr_r15_aligned (void)
be6651
 	      && (inst.operands[0].reg == REG_PC
be6651
 	      && inst.operands[1].reg == REG_PC
be6651
 	      && (inst.reloc.exp.X_add_number & 0x3)),
be6651
-	      _("ldr to register 15 must be 4-byte alligned"));
be6651
+	      _("ldr to register 15 must be 4-byte aligned"));
be6651
 }
be6651
 
be6651
 static void
be6651
@@ -9025,9 +9088,9 @@ do_mov16 (void)
be6651
 
be6651
   top = (inst.instruction & 0x00400000) != 0;
be6651
   constraint (top && inst.reloc.type == BFD_RELOC_ARM_MOVW,
be6651
-	      _(":lower16: not allowed this instruction"));
be6651
+	      _(":lower16: not allowed in this instruction"));
be6651
   constraint (!top && inst.reloc.type == BFD_RELOC_ARM_MOVT,
be6651
-	      _(":upper16: not allowed instruction"));
be6651
+	      _(":upper16: not allowed in this instruction"));
be6651
   inst.instruction |= inst.operands[0].reg << 12;
be6651
   if (inst.reloc.type == BFD_RELOC_UNUSED)
be6651
     {
be6651
@@ -9079,6 +9142,11 @@ do_vmrs (void)
be6651
       return;
be6651
     }
be6651
 
be6651
+  /* MVFR2 is only valid at ARMv8-A.  */
be6651
+  if (inst.operands[1].reg == 5)
be6651
+    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
be6651
+		_(BAD_FPU));
be6651
+
be6651
   /* APSR_ sets isvec. All other refs to PC are illegal.  */
be6651
   if (!inst.operands[0].isvec && Rt == REG_PC)
be6651
     {
be6651
@@ -9105,6 +9173,11 @@ do_vmsr (void)
be6651
       return;
be6651
     }
be6651
 
be6651
+  /* MVFR2 is only valid for ARMv8-A.  */
be6651
+  if (inst.operands[0].reg == 5)
be6651
+    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
be6651
+		_(BAD_FPU));
be6651
+
be6651
   /* If we get through parsing the register name, we just insert the number
be6651
      generated into the instruction without further validation.  */
be6651
   inst.instruction |= (inst.operands[0].reg << 16);
be6651
@@ -10453,7 +10526,7 @@ do_t_add_sub_w (void)
be6651
 }
be6651
 
be6651
 /* Parse an add or subtract instruction.  We get here with inst.instruction
be6651
-   equalling any of THUMB_OPCODE_add, adds, sub, or subs.  */
be6651
+   equaling any of THUMB_OPCODE_add, adds, sub, or subs.  */
be6651
 
be6651
 static void
be6651
 do_t_add_sub (void)
be6651
@@ -10484,7 +10557,8 @@ do_t_add_sub (void)
be6651
 	{
be6651
 	  int add;
be6651
 
be6651
-	  constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
be6651
+	  if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
be6651
+	    constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
be6651
 
be6651
 	  add = (inst.instruction == T_MNEM_add
be6651
 		 || inst.instruction == T_MNEM_adds);
be6651
@@ -10608,7 +10682,8 @@ do_t_add_sub (void)
be6651
 	    }
be6651
 
be6651
 	  constraint (Rd == REG_PC, BAD_PC);
be6651
-	  constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
be6651
+	  if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
be6651
+	    constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
be6651
 	  constraint (Rs == REG_PC, BAD_PC);
be6651
 	  reject_bad_reg (Rn);
be6651
 
be6651
@@ -10701,9 +10776,14 @@ do_t_adr (void)
be6651
       inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
be6651
       inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
be6651
       inst.reloc.pc_rel = 1;
be6651
-
be6651
       inst.instruction |= Rd << 4;
be6651
     }
be6651
+
be6651
+  if (inst.reloc.exp.X_op == O_symbol
be6651
+      && inst.reloc.exp.X_add_symbol != NULL
be6651
+      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
be6651
+      && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
be6651
+    inst.reloc.exp.X_add_number += 1;
be6651
 }
be6651
 
be6651
 /* Arithmetic instructions for which there is just one 16-bit
be6651
@@ -11856,7 +11936,8 @@ do_t_mov_cmp (void)
be6651
 		  /* This is mov.w.  */
be6651
 		  constraint (Rn == REG_PC, BAD_PC);
be6651
 		  constraint (Rm == REG_PC, BAD_PC);
be6651
-		  constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
be6651
+		  if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
be6651
+		    constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
be6651
 		}
be6651
 	    }
be6651
 	  else
be6651
@@ -12082,12 +12163,12 @@ do_t_mov16 (void)
be6651
   top = (inst.instruction & 0x00800000) != 0;
be6651
   if (inst.reloc.type == BFD_RELOC_ARM_MOVW)
be6651
     {
be6651
-      constraint (top, _(":lower16: not allowed this instruction"));
be6651
+      constraint (top, _(":lower16: not allowed in this instruction"));
be6651
       inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVW;
be6651
     }
be6651
   else if (inst.reloc.type == BFD_RELOC_ARM_MOVT)
be6651
     {
be6651
-      constraint (!top, _(":upper16: not allowed this instruction"));
be6651
+      constraint (!top, _(":upper16: not allowed in this instruction"));
be6651
       inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVT;
be6651
     }
be6651
 
be6651
@@ -13049,17 +13130,6 @@ do_t_sxth (void)
be6651
 static void
be6651
 do_t_swi (void)
be6651
 {
be6651
-  /* We have to do the following check manually as ARM_EXT_OS only applies
be6651
-     to ARM_EXT_V6M.  */
be6651
-  if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6m))
be6651
-    {
be6651
-      if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_os)
be6651
-	  /* This only applies to the v6m howver, not later architectures.  */
be6651
-	  && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7))
be6651
-	as_bad (_("SVC is not permitted on this architecture"));
be6651
-      ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, arm_ext_os);
be6651
-    }
be6651
-
be6651
   inst.reloc.type = BFD_RELOC_ARM_SWI;
be6651
 }
be6651
 
be6651
@@ -13077,7 +13147,8 @@ do_t_tb (void)
be6651
   Rn = inst.operands[0].reg;
be6651
   Rm = inst.operands[0].imm;
be6651
 
be6651
-  constraint (Rn == REG_SP, BAD_SP);
be6651
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
be6651
+    constraint (Rn == REG_SP, BAD_SP);
be6651
   reject_bad_reg (Rm);
be6651
 
be6651
   constraint (!half && inst.operands[0].shifted,
be6651
@@ -13317,6 +13388,8 @@ NEON_ENC_TAB
be6651
   X(3, (D, Q, S), MIXED),		\
be6651
   X(4, (D, D, D, I), DOUBLE),		\
be6651
   X(4, (Q, Q, Q, I), QUAD),		\
be6651
+  X(4, (D, D, S, I), DOUBLE),		\
be6651
+  X(4, (Q, Q, S, I), QUAD),		\
be6651
   X(2, (F, F), SINGLE),			\
be6651
   X(3, (F, F, F), SINGLE),		\
be6651
   X(2, (F, I), SINGLE),			\
be6651
@@ -14390,6 +14463,11 @@ static void
be6651
 do_vfp_nsyn_push (void)
be6651
 {
be6651
   nsyn_insert_sp ();
be6651
+
be6651
+  constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
be6651
+	      _("register list must contain at least 1 and at most 16 "
be6651
+		"registers"));
be6651
+
be6651
   if (inst.operands[1].issingle)
be6651
     do_vfp_nsyn_opcode ("fstmdbs");
be6651
   else
be6651
@@ -14400,6 +14478,11 @@ static void
be6651
 do_vfp_nsyn_pop (void)
be6651
 {
be6651
   nsyn_insert_sp ();
be6651
+
be6651
+  constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
be6651
+	      _("register list must contain at least 1 and at most 16 "
be6651
+		"registers"));
be6651
+
be6651
   if (inst.operands[1].issingle)
be6651
     do_vfp_nsyn_opcode ("fldmias");
be6651
   else
be6651
@@ -14952,7 +15035,14 @@ do_neon_ceq (void)
be6651
    scalars, which are encoded in 5 bits, M : Rm.
be6651
    For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
be6651
    M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
be6651
-   index in M.  */
be6651
+   index in M.
be6651
+
be6651
+   Dot Product instructions are similar to multiply instructions except elsize
be6651
+   should always be 32.
be6651
+
be6651
+   This function translates SCALAR, which is GAS's internal encoding of indexed
be6651
+   scalar register, to raw encoding.  There is also register and index range
be6651
+   check based on ELSIZE.  */
be6651
 
be6651
 static unsigned
be6651
 neon_scalar_for_mul (unsigned scalar, unsigned elsize)
be6651
@@ -17220,6 +17310,153 @@ do_vrintm (void)
be6651
   do_vrint_1 (neon_cvt_mode_m);
be6651
 }
be6651
 
be6651
+static unsigned
be6651
+neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
be6651
+{
be6651
+  unsigned regno = NEON_SCALAR_REG (opnd);
be6651
+  unsigned elno = NEON_SCALAR_INDEX (opnd);
be6651
+
be6651
+  if (elsize == 16 && elno < 2 && regno < 16)
be6651
+    return regno | (elno << 4);
be6651
+  else if (elsize == 32 && elno == 0)
be6651
+    return regno;
be6651
+
be6651
+  first_error (_("scalar out of range"));
be6651
+  return 0;
be6651
+}
be6651
+
be6651
+static void
be6651
+do_vcmla (void)
be6651
+{
be6651
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
be6651
+	      _(BAD_FPU));
be6651
+  constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex"));
be6651
+  unsigned rot = inst.reloc.exp.X_add_number;
be6651
+  constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
be6651
+	      _("immediate out of range"));
be6651
+  rot /= 90;
be6651
+  if (inst.operands[2].isscalar)
be6651
+    {
be6651
+      enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
be6651
+      unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
be6651
+				       N_KEY | N_F16 | N_F32).size;
be6651
+      unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
be6651
+      inst.is_neon = 1;
be6651
+      inst.instruction = 0xfe000800;
be6651
+      inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
be6651
+      inst.instruction |= HI1 (inst.operands[0].reg) << 22;
be6651
+      inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
be6651
+      inst.instruction |= HI1 (inst.operands[1].reg) << 7;
be6651
+      inst.instruction |= LOW4 (m);
be6651
+      inst.instruction |= HI1 (m) << 5;
be6651
+      inst.instruction |= neon_quad (rs) << 6;
be6651
+      inst.instruction |= rot << 20;
be6651
+      inst.instruction |= (size == 32) << 23;
be6651
+    }
be6651
+  else
be6651
+    {
be6651
+      enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
be6651
+      unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
be6651
+				       N_KEY | N_F16 | N_F32).size;
be6651
+      neon_three_same (neon_quad (rs), 0, -1);
be6651
+      inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup.  */
be6651
+      inst.instruction |= 0xfc200800;
be6651
+      inst.instruction |= rot << 23;
be6651
+      inst.instruction |= (size == 32) << 20;
be6651
+    }
be6651
+}
be6651
+
be6651
+static void
be6651
+do_vcadd (void)
be6651
+{
be6651
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
be6651
+	      _(BAD_FPU));
be6651
+  constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex"));
be6651
+  unsigned rot = inst.reloc.exp.X_add_number;
be6651
+  constraint (rot != 90 && rot != 270, _("immediate out of range"));
be6651
+  enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
be6651
+  unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
be6651
+				   N_KEY | N_F16 | N_F32).size;
be6651
+  neon_three_same (neon_quad (rs), 0, -1);
be6651
+  inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup.  */
be6651
+  inst.instruction |= 0xfc800800;
be6651
+  inst.instruction |= (rot == 270) << 24;
be6651
+  inst.instruction |= (size == 32) << 20;
be6651
+}
be6651
+
be6651
+/* Dot Product instructions encoding support.  */
be6651
+
be6651
+static void
be6651
+do_neon_dotproduct (int unsigned_p)
be6651
+{
be6651
+  enum neon_shape rs;
be6651
+  unsigned scalar_oprd2 = 0;
be6651
+  int high8;
be6651
+
be6651
+  if (inst.cond != COND_ALWAYS)
be6651
+    as_warn (_("Dot Product instructions cannot be conditional,  the behaviour "
be6651
+	       "is UNPREDICTABLE"));
be6651
+
be6651
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
be6651
+	      _(BAD_FPU));
be6651
+
be6651
+  /* Dot Product instructions are in three-same D/Q register format or the third
be6651
+     operand can be a scalar index register.  */
be6651
+  if (inst.operands[2].isscalar)
be6651
+    {
be6651
+      scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
be6651
+      high8 = 0xfe000000;
be6651
+      rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
be6651
+    }
be6651
+  else
be6651
+    {
be6651
+      high8 = 0xfc000000;
be6651
+      rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
be6651
+    }
be6651
+
be6651
+  if (unsigned_p)
be6651
+    neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
be6651
+  else
be6651
+    neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
be6651
+
be6651
+  /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
be6651
+     Product instruction, so we pass 0 as the "ubit" parameter.  And the
be6651
+     "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter.  */
be6651
+  neon_three_same (neon_quad (rs), 0, 32);
be6651
+
be6651
+  /* Undo neon_dp_fixup.  Dot Product instructions are using a slightly
be6651
+     different NEON three-same encoding.  */
be6651
+  inst.instruction &= 0x00ffffff;
be6651
+  inst.instruction |= high8;
be6651
+  /* Encode 'U' bit which indicates signedness.  */
be6651
+  inst.instruction |= (unsigned_p ? 1 : 0) << 4;
be6651
+  /* Re-encode operand2 if it's indexed scalar operand.  What has been encoded
be6651
+     from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
be6651
+     the instruction encoding.  */
be6651
+  if (inst.operands[2].isscalar)
be6651
+    {
be6651
+      inst.instruction &= 0xffffffd0;
be6651
+      inst.instruction |= LOW4 (scalar_oprd2);
be6651
+      inst.instruction |= HI1 (scalar_oprd2) << 5;
be6651
+    }
be6651
+}
be6651
+
be6651
+/* Dot Product instructions for signed integer.  */
be6651
+
be6651
+static void
be6651
+do_neon_dotproduct_s (void)
be6651
+{
be6651
+  return do_neon_dotproduct (0);
be6651
+}
be6651
+
be6651
+/* Dot Product instructions for unsigned integer.  */
be6651
+
be6651
+static void
be6651
+do_neon_dotproduct_u (void)
be6651
+{
be6651
+  return do_neon_dotproduct (1);
be6651
+}
be6651
+
be6651
 /* Crypto v1 instructions.  */
be6651
 static void
be6651
 do_crypto_2op_1 (unsigned elttype, int op)
be6651
@@ -17401,6 +17638,16 @@ do_crc32cw (void)
be6651
   do_crc32_1 (1, 2);
be6651
 }
be6651
 
be6651
+static void
be6651
+do_vjcvt (void)
be6651
+{
be6651
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
be6651
+	      _(BAD_FPU));
be6651
+  neon_check_type (2, NS_FD, N_S32, N_F64);
be6651
+  do_vfp_sp_dp_cvt ();
be6651
+  do_vfp_cond_or_thumb ();
be6651
+}
be6651
+
be6651
 
be6651
 /* Overall per-instruction processing.	*/
be6651
 
be6651
@@ -17755,7 +18002,7 @@ opcode_lookup (char **str)
be6651
 	case OT_odd_infix_unc:
be6651
 	  if (!unified_syntax)
be6651
 	    return 0;
be6651
-	  /* else fall through */
be6651
+	  /* Fall through.  */
be6651
 
be6651
 	case OT_csuffix:
be6651
 	case OT_csuffixF:
be6651
@@ -17878,7 +18125,7 @@ now_it_add_mask (int cond)
be6651
      set_it_insn_type_last ()           ditto
be6651
      in_it_block ()                     ditto
be6651
      it_fsm_post_encode ()              from md_assemble ()
be6651
-     force_automatic_it_block_close ()  from label habdling functions
be6651
+     force_automatic_it_block_close ()  from label handling functions
be6651
 
be6651
    Rationale:
be6651
      1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
be6651
@@ -17911,7 +18158,7 @@ now_it_add_mask (int cond)
be6651
 	for covering other cases.
be6651
 
be6651
 	Calling handle_it_state () may not transition the IT block state to
be6651
-	OUTSIDE_IT_BLOCK immediatelly, since the (current) state could be
be6651
+	OUTSIDE_IT_BLOCK immediately, since the (current) state could be
be6651
 	still queried. Instead, if the FSM determines that the state should
be6651
 	be transitioned to OUTSIDE_IT_BLOCK, a flag is marked to be closed
be6651
 	after the tencode () function: that's what it_fsm_post_encode () does.
be6651
@@ -18002,7 +18249,7 @@ handle_it_state (void)
be6651
       switch (inst.it_insn_type)
be6651
 	{
be6651
 	case OUTSIDE_IT_INSN:
be6651
-	  /* The closure of the block shall happen immediatelly,
be6651
+	  /* The closure of the block shall happen immediately,
be6651
 	     so any in_it_block () call reports the block as closed.  */
be6651
 	  force_automatic_it_block_close ();
be6651
 	  break;
be6651
@@ -18236,6 +18483,13 @@ t32_insn_ok (arm_feature_set arch, const
be6651
       && opcode->tencode == do_t_branch)
be6651
     return TRUE;
be6651
 
be6651
+  /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit.  */
be6651
+  if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
be6651
+      && opcode->tencode == do_t_mov_cmp
be6651
+      /* Make sure CMP instruction is not affected.  */
be6651
+      && opcode->aencode == do_mov)
be6651
+    return TRUE;
be6651
+
be6651
   /* Wide instruction variants of all instructions with narrow *and* wide
be6651
      variants become available with ARMv6t2.  Other opcodes are either
be6651
      narrow-only or wide-only and are thus available if OPCODE is valid.  */
be6651
@@ -18296,7 +18550,10 @@ md_assemble (char *str)
be6651
 	  || (thumb_mode == 1
be6651
 	      && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
be6651
 	{
be6651
-	  as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
be6651
+	  if (opcode->tencode == do_t_swi)
be6651
+	    as_bad (_("SVC is not permitted on this architecture"));
be6651
+	  else
be6651
+	    as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
be6651
 	  return;
be6651
 	}
be6651
       if (inst.cond != COND_ALWAYS && !unified_syntax
be6651
@@ -18663,6 +18920,7 @@ static const struct reg_entry reg_names[
be6651
   REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
be6651
   REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
be6651
   REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
be6651
+  REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
be6651
 
be6651
   /* Maverick DSP coprocessor registers.  */
be6651
   REGSET(mvf,MVF),  REGSET(mvd,MVD),  REGSET(mvfx,MVFX),  REGSET(mvdx,MVDX),
be6651
@@ -18780,24 +19038,32 @@ static const struct asm_psr psrs[] =
be6651
 /* Table of V7M psr names.  */
be6651
 static const struct asm_psr v7m_psrs[] =
be6651
 {
be6651
-  {"apsr",	  0 }, {"APSR",		0 },
be6651
-  {"iapsr",	  1 }, {"IAPSR",	1 },
be6651
-  {"eapsr",	  2 }, {"EAPSR",	2 },
be6651
-  {"psr",	  3 }, {"PSR",		3 },
be6651
-  {"xpsr",	  3 }, {"XPSR",		3 }, {"xPSR",	  3 },
be6651
-  {"ipsr",	  5 }, {"IPSR",		5 },
be6651
-  {"epsr",	  6 }, {"EPSR",		6 },
be6651
-  {"iepsr",	  7 }, {"IEPSR",	7 },
be6651
-  {"msp",	  8 }, {"MSP",		8 }, {"msp_s",     8 }, {"MSP_S",     8 },
be6651
-  {"psp",	  9 }, {"PSP",		9 }, {"psp_s",     9 }, {"PSP_S",     9 },
be6651
-  {"primask",	  16}, {"PRIMASK",	16},
be6651
-  {"basepri",	  17}, {"BASEPRI",	17},
be6651
-  {"basepri_max", 18}, {"BASEPRI_MAX",	18},
be6651
-  {"basepri_max", 18}, {"BASEPRI_MASK",	18}, /* Typo, preserved for backwards compatibility.  */
be6651
-  {"faultmask",	  19}, {"FAULTMASK",	19},
be6651
-  {"control",	  20}, {"CONTROL",	20},
be6651
-  {"msp_ns",	0x88}, {"MSP_NS",     0x88},
be6651
-  {"psp_ns",	0x89}, {"PSP_NS",     0x89}
be6651
+  {"apsr",	   0x0 }, {"APSR",	   0x0 },
be6651
+  {"iapsr",	   0x1 }, {"IAPSR",	   0x1 },
be6651
+  {"eapsr",	   0x2 }, {"EAPSR",	   0x2 },
be6651
+  {"psr",	   0x3 }, {"PSR",	   0x3 },
be6651
+  {"xpsr",	   0x3 }, {"XPSR",	   0x3 }, {"xPSR",	  3 },
be6651
+  {"ipsr",	   0x5 }, {"IPSR",	   0x5 },
be6651
+  {"epsr",	   0x6 }, {"EPSR",	   0x6 },
be6651
+  {"iepsr",	   0x7 }, {"IEPSR",	   0x7 },
be6651
+  {"msp",	   0x8 }, {"MSP",	   0x8 },
be6651
+  {"psp",	   0x9 }, {"PSP",	   0x9 },
be6651
+  {"msplim",	   0xa }, {"MSPLIM",	   0xa },
be6651
+  {"psplim",	   0xb }, {"PSPLIM",	   0xb },
be6651
+  {"primask",	   0x10}, {"PRIMASK",	   0x10},
be6651
+  {"basepri",	   0x11}, {"BASEPRI",	   0x11},
be6651
+  {"basepri_max",  0x12}, {"BASEPRI_MAX",  0x12},
be6651
+  {"faultmask",	   0x13}, {"FAULTMASK",	   0x13},
be6651
+  {"control",	   0x14}, {"CONTROL",	   0x14},
be6651
+  {"msp_ns",	   0x88}, {"MSP_NS",	   0x88},
be6651
+  {"psp_ns",	   0x89}, {"PSP_NS",	   0x89},
be6651
+  {"msplim_ns",	   0x8a}, {"MSPLIM_NS",	   0x8a},
be6651
+  {"psplim_ns",	   0x8b}, {"PSPLIM_NS",	   0x8b},
be6651
+  {"primask_ns",   0x90}, {"PRIMASK_NS",   0x90},
be6651
+  {"basepri_ns",   0x91}, {"BASEPRI_NS",   0x91},
be6651
+  {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
be6651
+  {"control_ns",   0x94}, {"CONTROL_NS",   0x94},
be6651
+  {"sp_ns",	   0x98}, {"SP_NS",	   0x98 }
be6651
 };
be6651
 
be6651
 /* Table of all shift-in-operand names.	 */
be6651
@@ -19112,8 +19378,6 @@ static const struct asm_opcode insns[] =
be6651
  tC3("ldmia",	8900000, _ldmia,    2, (RRw, REGLST), ldmstm, t_ldmstm),
be6651
  tC3("ldmfd",	8900000, _ldmia,    2, (RRw, REGLST), ldmstm, t_ldmstm),
be6651
 
be6651
- TCE("swi",	f000000, df00,     1, (EXPi),        swi, t_swi),
be6651
- TCE("svc",	f000000, df00,     1, (EXPi),        swi, t_swi),
be6651
  tCE("b",	a000000, _b,	   1, (EXPr),	     branch, t_branch),
be6651
  TCE("bl",	b000000, f000f800, 1, (EXPr),	     bl, t_branch23),
be6651
 
be6651
@@ -19142,6 +19406,12 @@ static const struct asm_opcode insns[] =
be6651
  TC3("rsbs",	0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
be6651
 
be6651
 #undef  THUMB_VARIANT
be6651
+#define THUMB_VARIANT  & arm_ext_os
be6651
+
be6651
+ TCE("swi",	f000000, df00,     1, (EXPi),        swi, t_swi),
be6651
+ TCE("svc",	f000000, df00,     1, (EXPi),        swi, t_swi),
be6651
+
be6651
+#undef  THUMB_VARIANT
be6651
 #define THUMB_VARIANT  & arm_ext_v6
be6651
 
be6651
  TCE("cpy",       1a00000, 4600,     2, (RR, RR),      rd_rm, t_cpy),
be6651
@@ -19729,6 +19999,21 @@ static const struct asm_opcode insns[] =
be6651
  TUE ("esb", 320f010, f3af8010, 0, (), noargs,  noargs),
be6651
 
be6651
 #undef  ARM_VARIANT
be6651
+#define ARM_VARIANT   & arm_ext_v8_3
be6651
+#undef  THUMB_VARIANT
be6651
+#define THUMB_VARIANT & arm_ext_v8_3
be6651
+ NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
be6651
+ NUF (vcmla, 0, 4, (RNDQ, RNDQ, RNDQ_RNSC, EXPi), vcmla),
be6651
+ NUF (vcadd, 0, 4, (RNDQ, RNDQ, RNDQ, EXPi), vcadd),
be6651
+
be6651
+#undef  ARM_VARIANT
be6651
+#define ARM_VARIANT   & fpu_neon_ext_dotprod
be6651
+#undef  THUMB_VARIANT
be6651
+#define THUMB_VARIANT & fpu_neon_ext_dotprod
be6651
+ NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
be6651
+ NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
be6651
+
be6651
+#undef  ARM_VARIANT
be6651
 #define ARM_VARIANT  & fpu_fpa_ext_v1  /* Core FPA instruction set (V1).  */
be6651
 #undef  THUMB_VARIANT
be6651
 #define THUMB_VARIANT NULL
be6651
@@ -21706,7 +21991,7 @@ arm_frag_align_code (int n, int max)
be6651
    Note - despite the name this initialisation is not done when the frag
be6651
    is created, but only when its type is assigned.  A frag can be created
be6651
    and used a long time before its type is set, so beware of assuming that
be6651
-   this initialisationis performed first.  */
be6651
+   this initialisation is performed first.  */
be6651
 
be6651
 #ifndef OBJ_ELF
be6651
 void
be6651
@@ -21720,7 +22005,7 @@ arm_init_frag (fragS * fragP, int max_ch
be6651
 void
be6651
 arm_init_frag (fragS * fragP, int max_chars)
be6651
 {
be6651
-  int frag_thumb_mode;
be6651
+  bfd_boolean frag_thumb_mode;
be6651
 
be6651
   /* If the current ARM vs THUMB mode has not already
be6651
      been recorded into this frag then do so now.  */
be6651
@@ -22731,6 +23016,23 @@ md_apply_fix (fixS *	fixP,
be6651
 	     changing the opcode.  */
be6651
 	  if (newimm == (unsigned int) FAIL)
be6651
 	    newimm = negate_data_op (&temp, value);
be6651
+	  /* MOV accepts both ARM modified immediate (A1 encoding) and
be6651
+	     UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
be6651
+	     When disassembling, MOV is preferred when there is no encoding
be6651
+	     overlap.  */
be6651
+	  if (newimm == (unsigned int) FAIL
be6651
+	      && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
be6651
+	      && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
be6651
+	      && !((temp >> SBIT_SHIFT) & 0x1)
be6651
+	      && value >= 0 && value <= 0xffff)
be6651
+	    {
be6651
+	      /* Clear bits[23:20] to change encoding from A1 to A2.  */
be6651
+	      temp &= 0xff0fffff;
be6651
+	      /* Encoding high 4bits imm.  Code below will encode the remaining
be6651
+		 low 12bits.  */
be6651
+	      temp |= (value & 0x0000f000) << 4;
be6651
+	      newimm = value & 0x00000fff;
be6651
+	    }
be6651
 	}
be6651
 
be6651
       if (newimm == (unsigned int) FAIL)
be6651
@@ -22816,6 +23118,7 @@ md_apply_fix (fixS *	fixP,
be6651
     case BFD_RELOC_ARM_OFFSET_IMM:
be6651
       if (!fixP->fx_done && seg->use_rela_p)
be6651
 	value = 0;
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_ARM_LITERAL:
be6651
       sign = value > 0;
be6651
@@ -23046,32 +23349,59 @@ md_apply_fix (fixS *	fixP,
be6651
       newval |= md_chars_to_number (buf+2, THUMB_SIZE);
be6651
 
be6651
       newimm = FAIL;
be6651
-      if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
be6651
+      if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
be6651
+	   /* ARMv8-M Baseline MOV will reach here, but it doesn't support
be6651
+	      Thumb2 modified immediate encoding (T2).  */
be6651
+	   && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
be6651
 	  || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
be6651
 	{
be6651
 	  newimm = encode_thumb32_immediate (value);
be6651
 	  if (newimm == (unsigned int) FAIL)
be6651
 	    newimm = thumb32_negate_data_op (&newval, value);
be6651
 	}
be6651
-      if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE
be6651
-	  && newimm == (unsigned int) FAIL)
be6651
+      if (newimm == (unsigned int) FAIL)
be6651
 	{
be6651
-	  /* Turn add/sum into addw/subw.  */
be6651
-	  if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
be6651
-	    newval = (newval & 0xfeffffff) | 0x02000000;
be6651
-	  /* No flat 12-bit imm encoding for addsw/subsw.  */
be6651
-	  if ((newval & 0x00100000) == 0)
be6651
+	  if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
be6651
 	    {
be6651
-	      /* 12 bit immediate for addw/subw.  */
be6651
-	      if (value < 0)
be6651
+	      /* Turn add/sum into addw/subw.  */
be6651
+	      if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
be6651
+		newval = (newval & 0xfeffffff) | 0x02000000;
be6651
+	      /* No flat 12-bit imm encoding for addsw/subsw.  */
be6651
+	      if ((newval & 0x00100000) == 0)
be6651
 		{
be6651
-		  value = -value;
be6651
-		  newval ^= 0x00a00000;
be6651
+		  /* 12 bit immediate for addw/subw.  */
be6651
+		  if (value < 0)
be6651
+		    {
be6651
+		      value = -value;
be6651
+		      newval ^= 0x00a00000;
be6651
+		    }
be6651
+		  if (value > 0xfff)
be6651
+		    newimm = (unsigned int) FAIL;
be6651
+		  else
be6651
+		    newimm = value;
be6651
+		}
be6651
+	    }
be6651
+	  else
be6651
+	    {
be6651
+	      /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
be6651
+		 UINT16 (T3 encoding), MOVW only accepts UINT16.  When
be6651
+		 disassembling, MOV is preferred when there is no encoding
be6651
+		 overlap.
be6651
+		 NOTE: MOV is using ORR opcode under Thumb 2 mode.  */
be6651
+	      if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
be6651
+		  && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
be6651
+		  && !((newval >> T2_SBIT_SHIFT) & 0x1)
be6651
+		  && value >= 0 && value <=0xffff)
be6651
+		{
be6651
+		  /* Toggle bit[25] to change encoding from T2 to T3.  */
be6651
+		  newval ^= 1 << 25;
be6651
+		  /* Clear bits[19:16].  */
be6651
+		  newval &= 0xfff0ffff;
be6651
+		  /* Encoding high 4bits imm.  Code below will encode the
be6651
+		     remaining low 12bits.  */
be6651
+		  newval |= (value & 0x0000f000) << 4;
be6651
+		  newimm = value & 0x00000fff;
be6651
 		}
be6651
-	      if (value > 0xfff)
be6651
-		newimm = (unsigned int) FAIL;
be6651
-	      else
be6651
-		newimm = value;
be6651
 	    }
be6651
 	}
be6651
 
be6651
@@ -23174,6 +23504,7 @@ md_apply_fix (fixS *	fixP,
be6651
 	  newval = md_chars_to_number (buf, INSN_SIZE);
be6651
 	  fixP->fx_done = 0;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_ARM_PLT32:
be6651
 #endif
be6651
@@ -23210,7 +23541,7 @@ md_apply_fix (fixS *	fixP,
be6651
       /* We are going to store value (shifted right by two) in the
be6651
 	 instruction, in a 24 bit, signed field.  Bits 26 through 32 either
be6651
 	 all clear or all set and bit 0 must be clear.  For B/BL bit 1 must
be6651
-	 also be be clear.  */
be6651
+	 also be clear.  */
be6651
       if (value & temp)
be6651
 	as_bad_where (fixP->fx_file, fixP->fx_line,
be6651
 		      _("misaligned branch destination"));
be6651
@@ -24066,6 +24397,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_8_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_16:
be6651
       if (fixp->fx_pcrel)
be6651
@@ -24073,6 +24405,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_16_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_32:
be6651
       if (fixp->fx_pcrel)
be6651
@@ -24080,6 +24413,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_32_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_ARM_MOVW:
be6651
       if (fixp->fx_pcrel)
be6651
@@ -24087,6 +24421,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_ARM_MOVW_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_ARM_MOVT:
be6651
       if (fixp->fx_pcrel)
be6651
@@ -24094,6 +24429,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_ARM_MOVT_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_ARM_THUMB_MOVW:
be6651
       if (fixp->fx_pcrel)
be6651
@@ -24101,6 +24437,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_ARM_THUMB_MOVT:
be6651
       if (fixp->fx_pcrel)
be6651
@@ -24108,6 +24445,7 @@ tc_gen_reloc (asection *section, fixS *f
be6651
 	  code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
be6651
 	  break;
be6651
 	}
be6651
+      /* Fall through.  */
be6651
 
be6651
     case BFD_RELOC_NONE:
be6651
     case BFD_RELOC_ARM_PCREL_BRANCH:
be6651
@@ -24791,7 +25129,12 @@ md_begin (void)
be6651
       mcpu_cpu_opt = legacy_cpu;
be6651
     }
be6651
   else if (!mcpu_cpu_opt)
be6651
-    mcpu_cpu_opt = march_cpu_opt;
be6651
+    {
be6651
+      mcpu_cpu_opt = march_cpu_opt;
be6651
+      dyn_mcpu_ext_opt = dyn_march_ext_opt;
be6651
+      /* Avoid double free in arm_md_end.  */
be6651
+      dyn_march_ext_opt = NULL;
be6651
+    }
be6651
 
be6651
   if (legacy_fpu)
be6651
     {
be6651
@@ -24831,16 +25174,22 @@ md_begin (void)
be6651
       mcpu_cpu_opt = &cpu_default;
be6651
       selected_cpu = cpu_default;
be6651
     }
be6651
-  else if (no_cpu_selected ())
be6651
-    selected_cpu = cpu_default;
be6651
+  else if (dyn_mcpu_ext_opt)
be6651
+    ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt);
be6651
+  else
be6651
+    selected_cpu = *mcpu_cpu_opt;
be6651
 #else
be6651
-  if (mcpu_cpu_opt)
be6651
+  if (mcpu_cpu_opt && dyn_mcpu_ext_opt)
be6651
+    ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt);
be6651
+  else if (mcpu_cpu_opt)
be6651
     selected_cpu = *mcpu_cpu_opt;
be6651
   else
be6651
     mcpu_cpu_opt = &arm_arch_any;
be6651
 #endif
be6651
 
be6651
   ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
be6651
+  if (dyn_mcpu_ext_opt)
be6651
+    ARM_MERGE_FEATURE_SETS (cpu_variant, cpu_variant, *dyn_mcpu_ext_opt);
be6651
 
be6651
   autoselect_thumb_from_cpu_variant ();
be6651
 
be6651
@@ -25215,6 +25564,7 @@ struct arm_cpu_option_table
be6651
   const char *name;
be6651
   size_t name_len;
be6651
   const arm_feature_set	value;
be6651
+  const arm_feature_set	ext;
be6651
   /* For some CPUs we assume an FPU unless the user explicitly sets
be6651
      -mfpu=...	*/
be6651
   const arm_feature_set	default_fpu;
be6651
@@ -25225,174 +25575,387 @@ struct arm_cpu_option_table
be6651
 
be6651
 /* This list should, at a minimum, contain all the cpu names
be6651
    recognized by GCC.  */
be6651
-#define ARM_CPU_OPT(N, V, DF, CN) { N, sizeof (N) - 1, V, DF, CN }
be6651
+#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
be6651
 static const struct arm_cpu_option_table arm_cpus[] =
be6651
 {
be6651
-  ARM_CPU_OPT ("all",		ARM_ANY,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm1",		ARM_ARCH_V1,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm2",		ARM_ARCH_V2,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm250",	ARM_ARCH_V2S,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm3",		ARM_ARCH_V2S,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm6",		ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm60",		ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm600",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm610",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm620",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7",		ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7m",		ARM_ARCH_V3M,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7d",		ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7dm",	ARM_ARCH_V3M,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7di",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7dmi",	ARM_ARCH_V3M,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm70",		ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm700",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm700i",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm710",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm710t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm720",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm720t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm740t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm710c",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7100",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7500",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7500fe",	ARM_ARCH_V3,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7tdmi",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm7tdmi-s",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm8",		ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm810",	ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("strongarm",	ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("strongarm1",	ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("strongarm110",	ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("strongarm1100",	ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("strongarm1110",	ARM_ARCH_V4,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm9",		ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm920",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    "ARM920T"),
be6651
-  ARM_CPU_OPT ("arm920t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm922t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm940t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,    NULL),
be6651
-  ARM_CPU_OPT ("arm9tdmi",	ARM_ARCH_V4T,	 FPU_ARCH_FPA,	  NULL),
be6651
-  ARM_CPU_OPT ("fa526",		ARM_ARCH_V4,	 FPU_ARCH_FPA,	  NULL),
be6651
-  ARM_CPU_OPT ("fa626",		ARM_ARCH_V4,	 FPU_ARCH_FPA,	  NULL),
be6651
+  ARM_CPU_OPT ("all",		  NULL,		       ARM_ANY,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm1",		  NULL,		       ARM_ARCH_V1,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm2",		  NULL,		       ARM_ARCH_V2,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm250",	  NULL,		       ARM_ARCH_V2S,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm3",		  NULL,		       ARM_ARCH_V2S,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm6",		  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm60",		  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm600",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm610",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm620",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7",		  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7m",		  NULL,		       ARM_ARCH_V3M,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7d",		  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7dm",	  NULL,		       ARM_ARCH_V3M,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7di",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7dmi",	  NULL,		       ARM_ARCH_V3M,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm70",		  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm700",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm700i",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm710",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm710t",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm720",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm720t",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm740t",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm710c",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7100",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7500",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7500fe",	  NULL,		       ARM_ARCH_V3,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7t",		  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7tdmi",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm7tdmi-s",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm8",		  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm810",	  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("strongarm",	  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("strongarm1",	  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("strongarm110",	  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("strongarm1100",	  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("strongarm1110",	  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm9",		  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm920",	  "ARM920T",	       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm920t",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm922t",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm940t",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("arm9tdmi",	  NULL,		       ARM_ARCH_V4T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("fa526",		  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+  ARM_CPU_OPT ("fa626",		  NULL,		       ARM_ARCH_V4,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_FPA),
be6651
+
be6651
   /* For V5 or later processors we default to using VFP; but the user
be6651
      should really set the FPU type explicitly.	 */
be6651
-  ARM_CPU_OPT ("arm9e-r0",	ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm9e",		ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm926ej",	ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2, "ARM926EJ-S"),
be6651
-  ARM_CPU_OPT ("arm926ejs",	ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2, "ARM926EJ-S"),
be6651
-  ARM_CPU_OPT ("arm926ej-s",	ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm946e-r0",	ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm946e",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, "ARM946E-S"),
be6651
-  ARM_CPU_OPT ("arm946e-s",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm966e-r0",	ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm966e",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, "ARM966E-S"),
be6651
-  ARM_CPU_OPT ("arm966e-s",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm968e-s",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm10t",	ARM_ARCH_V5T,	 FPU_ARCH_VFP_V1, NULL),
be6651
-  ARM_CPU_OPT ("arm10tdmi",	ARM_ARCH_V5T,	 FPU_ARCH_VFP_V1, NULL),
be6651
-  ARM_CPU_OPT ("arm10e",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm1020",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, "ARM1020E"),
be6651
-  ARM_CPU_OPT ("arm1020t",	ARM_ARCH_V5T,	 FPU_ARCH_VFP_V1, NULL),
be6651
-  ARM_CPU_OPT ("arm1020e",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm1022e",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm1026ejs",	ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2,
be6651
-								 "ARM1026EJ-S"),
be6651
-  ARM_CPU_OPT ("arm1026ej-s",	ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("fa606te",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("fa616te",	ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("fa626te",	ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("fmp626",	ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("fa726te",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm1136js",	ARM_ARCH_V6,	 FPU_NONE,	  "ARM1136J-S"),
be6651
-  ARM_CPU_OPT ("arm1136j-s",	ARM_ARCH_V6,	 FPU_NONE,	  NULL),
be6651
-  ARM_CPU_OPT ("arm1136jfs",	ARM_ARCH_V6,	 FPU_ARCH_VFP_V2,
be6651
-								 "ARM1136JF-S"),
be6651
-  ARM_CPU_OPT ("arm1136jf-s",	ARM_ARCH_V6,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("mpcore",	ARM_ARCH_V6K,	 FPU_ARCH_VFP_V2, "MPCore"),
be6651
-  ARM_CPU_OPT ("mpcorenovfp",	ARM_ARCH_V6K,	 FPU_NONE,	  "MPCore"),
be6651
-  ARM_CPU_OPT ("arm1156t2-s",	ARM_ARCH_V6T2,	 FPU_NONE,	  NULL),
be6651
-  ARM_CPU_OPT ("arm1156t2f-s",	ARM_ARCH_V6T2,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("arm1176jz-s",	ARM_ARCH_V6KZ,	 FPU_NONE,	  NULL),
be6651
-  ARM_CPU_OPT ("arm1176jzf-s",	ARM_ARCH_V6KZ,	 FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("cortex-a5",	ARM_ARCH_V7A_MP_SEC,
be6651
-						 FPU_NONE,	  "Cortex-A5"),
be6651
-  ARM_CPU_OPT ("cortex-a7",	ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
be6651
-								  "Cortex-A7"),
be6651
-  ARM_CPU_OPT ("cortex-a8",	ARM_ARCH_V7A_SEC,
be6651
-						 ARM_FEATURE_COPROC (FPU_VFP_V3
be6651
-							| FPU_NEON_EXT_V1),
be6651
-								  "Cortex-A8"),
be6651
-  ARM_CPU_OPT ("cortex-a9",	ARM_ARCH_V7A_MP_SEC,
be6651
-						 ARM_FEATURE_COPROC (FPU_VFP_V3
be6651
-							| FPU_NEON_EXT_V1),
be6651
-								  "Cortex-A9"),
be6651
-  ARM_CPU_OPT ("cortex-a12",	ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
be6651
-								  "Cortex-A12"),
be6651
-  ARM_CPU_OPT ("cortex-a15",	ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
be6651
-								  "Cortex-A15"),
be6651
-  ARM_CPU_OPT ("cortex-a17",	ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
be6651
-								  "Cortex-A17"),
be6651
-  ARM_CPU_OPT ("cortex-a32",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Cortex-A32"),
be6651
-  ARM_CPU_OPT ("cortex-a35",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Cortex-A35"),
be6651
-  ARM_CPU_OPT ("cortex-a53",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Cortex-A53"),
be6651
-  ARM_CPU_OPT ("cortex-a57",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Cortex-A57"),
be6651
-  ARM_CPU_OPT ("cortex-a72",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Cortex-A72"),
be6651
-  ARM_CPU_OPT ("cortex-a73",    ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Cortex-A73"),
be6651
-  ARM_CPU_OPT ("cortex-r4",	ARM_ARCH_V7R,	 FPU_NONE,	  "Cortex-R4"),
be6651
-  ARM_CPU_OPT ("cortex-r4f",	ARM_ARCH_V7R,	 FPU_ARCH_VFP_V3D16,
be6651
-								  "Cortex-R4F"),
be6651
-  ARM_CPU_OPT ("cortex-r5",	ARM_ARCH_V7R_IDIV,
be6651
-						 FPU_NONE,	  "Cortex-R5"),
be6651
-  ARM_CPU_OPT ("cortex-r7",	ARM_ARCH_V7R_IDIV,
be6651
-						 FPU_ARCH_VFP_V3D16,
be6651
-								  "Cortex-R7"),
be6651
-  ARM_CPU_OPT ("cortex-r8",	ARM_ARCH_V7R_IDIV,
be6651
-						 FPU_ARCH_VFP_V3D16,
be6651
-								  "Cortex-R8"),
be6651
-  ARM_CPU_OPT ("cortex-m7",	ARM_ARCH_V7EM,	 FPU_NONE,	  "Cortex-M7"),
be6651
-  ARM_CPU_OPT ("cortex-m4",	ARM_ARCH_V7EM,	 FPU_NONE,	  "Cortex-M4"),
be6651
-  ARM_CPU_OPT ("cortex-m3",	ARM_ARCH_V7M,	 FPU_NONE,	  "Cortex-M3"),
be6651
-  ARM_CPU_OPT ("cortex-m1",	ARM_ARCH_V6SM,	 FPU_NONE,	  "Cortex-M1"),
be6651
-  ARM_CPU_OPT ("cortex-m0",	ARM_ARCH_V6SM,	 FPU_NONE,	  "Cortex-M0"),
be6651
-  ARM_CPU_OPT ("cortex-m0plus",	ARM_ARCH_V6SM,	 FPU_NONE,	  "Cortex-M0+"),
be6651
-  ARM_CPU_OPT ("exynos-m1",	ARM_ARCH_V8A,	 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Samsung " \
be6651
-								  "Exynos M1"),
be6651
-  ARM_CPU_OPT ("qdf24xx",	ARM_ARCH_V8A,	 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-								  "Qualcomm "
be6651
-								  "QDF24XX"),
be6651
+  ARM_CPU_OPT ("arm9e-r0",	  NULL,		       ARM_ARCH_V5TExP,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm9e",		  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm926ej",	  "ARM926EJ-S",	       ARM_ARCH_V5TEJ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm926ejs",	  "ARM926EJ-S",	       ARM_ARCH_V5TEJ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm926ej-s",	  NULL,		       ARM_ARCH_V5TEJ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm946e-r0",	  NULL,		       ARM_ARCH_V5TExP,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm946e",	  "ARM946E-S",	       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm946e-s",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm966e-r0",	  NULL,		       ARM_ARCH_V5TExP,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm966e",	  "ARM966E-S",	       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm966e-s",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm968e-s",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm10t",	  NULL,		       ARM_ARCH_V5T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V1),
be6651
+  ARM_CPU_OPT ("arm10tdmi",	  NULL,		       ARM_ARCH_V5T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V1),
be6651
+  ARM_CPU_OPT ("arm10e",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1020",	  "ARM1020E",	       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1020t",	  NULL,		       ARM_ARCH_V5T,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V1),
be6651
+  ARM_CPU_OPT ("arm1020e",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1022e",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1026ejs",	  "ARM1026EJ-S",       ARM_ARCH_V5TEJ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1026ej-s",	  NULL,		       ARM_ARCH_V5TEJ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("fa606te",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("fa616te",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("fa626te",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("fmp626",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("fa726te",	  NULL,		       ARM_ARCH_V5TE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1136js",	  "ARM1136J-S",	       ARM_ARCH_V6,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("arm1136j-s",	  NULL,		       ARM_ARCH_V6,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("arm1136jfs",	  "ARM1136JF-S",       ARM_ARCH_V6,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1136jf-s",	  NULL,		       ARM_ARCH_V6,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("mpcore",	  "MPCore",	       ARM_ARCH_V6K,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("mpcorenovfp",	  "MPCore",	       ARM_ARCH_V6K,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("arm1156t2-s",	  NULL,		       ARM_ARCH_V6T2,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("arm1156t2f-s",	  NULL,		       ARM_ARCH_V6T2,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("arm1176jz-s",	  NULL,		       ARM_ARCH_V6KZ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("arm1176jzf-s",	  NULL,		       ARM_ARCH_V6KZ,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("cortex-a5",	  "Cortex-A5",	       ARM_ARCH_V7A,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-a7",	  "Cortex-A7",	       ARM_ARCH_V7VE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_NEON_VFP_V4),
be6651
+  ARM_CPU_OPT ("cortex-a8",	  "Cortex-A8",	       ARM_ARCH_V7A,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
be6651
+	       ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
be6651
+  ARM_CPU_OPT ("cortex-a9",	  "Cortex-A9",	       ARM_ARCH_V7A,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
be6651
+	       ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
be6651
+  ARM_CPU_OPT ("cortex-a12",	  "Cortex-A12",	       ARM_ARCH_V7VE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_NEON_VFP_V4),
be6651
+  ARM_CPU_OPT ("cortex-a15",	  "Cortex-A15",	       ARM_ARCH_V7VE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_NEON_VFP_V4),
be6651
+  ARM_CPU_OPT ("cortex-a17",	  "Cortex-A17",	       ARM_ARCH_V7VE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_NEON_VFP_V4),
be6651
+  ARM_CPU_OPT ("cortex-a32",	  "Cortex-A32",	       ARM_ARCH_V8A,
be6651
+	       ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a35",	  "Cortex-A35",	       ARM_ARCH_V8A,
be6651
+	       ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a53",	  "Cortex-A53",	       ARM_ARCH_V8A,
be6651
+	       ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a55",    "Cortex-A55",	       ARM_ARCH_V8_2A,
be6651
+	       ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a57",	  "Cortex-A57",	       ARM_ARCH_V8A,
be6651
+	       ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a72",	  "Cortex-A72",	       ARM_ARCH_V8A,
be6651
+	      ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	      FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a73",	  "Cortex-A73",	       ARM_ARCH_V8A,
be6651
+	      ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	      FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-a75",    "Cortex-A75",	       ARM_ARCH_V8_2A,
be6651
+	       ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-r4",	  "Cortex-R4",	       ARM_ARCH_V7R,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-r4f",	  "Cortex-R4F",	       ARM_ARCH_V7R,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V3D16),
be6651
+  ARM_CPU_OPT ("cortex-r5",	  "Cortex-R5",	       ARM_ARCH_V7R,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-r7",	  "Cortex-R7",	       ARM_ARCH_V7R,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
be6651
+	       FPU_ARCH_VFP_V3D16),
be6651
+  ARM_CPU_OPT ("cortex-r8",	  "Cortex-R8",	       ARM_ARCH_V7R,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
be6651
+	       FPU_ARCH_VFP_V3D16),
be6651
+  ARM_CPU_OPT ("cortex-r52",	  "Cortex-R52",	       ARM_ARCH_V8R,
be6651
+	      ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	      FPU_ARCH_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("cortex-m33",	  "Cortex-M33",	       ARM_ARCH_V8M_MAIN,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m23",	  "Cortex-M23",	       ARM_ARCH_V8M_BASE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m7",	  "Cortex-M7",	       ARM_ARCH_V7EM,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m4",	  "Cortex-M4",	       ARM_ARCH_V7EM,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m3",	  "Cortex-M3",	       ARM_ARCH_V7M,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m1",	  "Cortex-M1",	       ARM_ARCH_V6SM,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m0",	  "Cortex-M0",	       ARM_ARCH_V6SM,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("cortex-m0plus",	  "Cortex-M0+",	       ARM_ARCH_V6SM,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_NONE),
be6651
+  ARM_CPU_OPT ("exynos-m1",	  "Samsung Exynos M1", ARM_ARCH_V8A,
be6651
+	       ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
 
be6651
   /* ??? XSCALE is really an architecture.  */
be6651
-  ARM_CPU_OPT ("xscale",	ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
be6651
+  ARM_CPU_OPT ("xscale",	  NULL,		       ARM_ARCH_XSCALE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+
be6651
   /* ??? iwmmxt is not a processor.  */
be6651
-  ARM_CPU_OPT ("iwmmxt",	ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("iwmmxt2",	ARM_ARCH_IWMMXT2,FPU_ARCH_VFP_V2, NULL),
be6651
-  ARM_CPU_OPT ("i80200",	ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
be6651
+  ARM_CPU_OPT ("iwmmxt",	  NULL,		       ARM_ARCH_IWMMXT,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("iwmmxt2",	  NULL,		       ARM_ARCH_IWMMXT2,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+  ARM_CPU_OPT ("i80200",	  NULL,		       ARM_ARCH_XSCALE,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_VFP_V2),
be6651
+
be6651
   /* Maverick */
be6651
-  ARM_CPU_OPT ("ep9312",	ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
be6651
-						 FPU_ARCH_MAVERICK, "ARM920T"),
be6651
+  ARM_CPU_OPT ("ep9312",	  "ARM920T",
be6651
+	       ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
be6651
+	       ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
be6651
+
be6651
   /* Marvell processors.  */
be6651
-  ARM_CPU_OPT ("marvell-pj4",   ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP
be6651
-						  | ARM_EXT_SEC,
be6651
-						  ARM_EXT2_V6T2_V8M),
be6651
-						FPU_ARCH_VFP_V3D16, NULL),
be6651
-  ARM_CPU_OPT ("marvell-whitney", ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP
be6651
-						    | ARM_EXT_SEC,
be6651
-						    ARM_EXT2_V6T2_V8M),
be6651
-					       FPU_ARCH_NEON_VFP_V4, NULL),
be6651
+  ARM_CPU_OPT ("marvell-pj4",	  NULL,		       ARM_ARCH_V7A,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
be6651
+	       FPU_ARCH_VFP_V3D16),
be6651
+  ARM_CPU_OPT ("marvell-whitney", NULL,		       ARM_ARCH_V7A,
be6651
+	       ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
be6651
+	       FPU_ARCH_NEON_VFP_V4),
be6651
+
be6651
   /* APM X-Gene family.  */
be6651
-  ARM_CPU_OPT ("xgene1",        ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-	                                                          "APM X-Gene 1"),
be6651
-  ARM_CPU_OPT ("xgene2",        ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
-	                                                          "APM X-Gene 2"),
be6651
+  ARM_CPU_OPT ("xgene1",	  "APM X-Gene 1",      ARM_ARCH_V8A,
be6651
+	       ARM_ARCH_NONE,
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
+  ARM_CPU_OPT ("xgene2",	  "APM X-Gene 2",      ARM_ARCH_V8A,
be6651
+	       ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
be6651
+	       FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
be6651
 
be6651
-  { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
be6651
+  { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
be6651
 };
be6651
 #undef ARM_CPU_OPT
be6651
 
be6651
@@ -25459,6 +26022,8 @@ static const struct arm_arch_option_tabl
be6651
   ARM_ARCH_OPT ("armv8-a",	ARM_ARCH_V8A,	 FPU_ARCH_VFP),
be6651
   ARM_ARCH_OPT ("armv8.1-a",	ARM_ARCH_V8_1A,	 FPU_ARCH_VFP),
be6651
   ARM_ARCH_OPT ("armv8.2-a",	ARM_ARCH_V8_2A,	 FPU_ARCH_VFP),
be6651
+  ARM_ARCH_OPT ("armv8.3-a",	ARM_ARCH_V8_3A,	 FPU_ARCH_VFP),
be6651
+  ARM_ARCH_OPT ("armv8-r",	ARM_ARCH_V8R,	 FPU_ARCH_VFP),
be6651
   ARM_ARCH_OPT ("xscale",	ARM_ARCH_XSCALE, FPU_ARCH_VFP),
be6651
   ARM_ARCH_OPT ("iwmmxt",	ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
be6651
   ARM_ARCH_OPT ("iwmmxt2",	ARM_ARCH_IWMMXT2,FPU_ARCH_VFP),
be6651
@@ -25490,6 +26055,9 @@ static const struct arm_option_extension
be6651
   ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
be6651
 			 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
be6651
 				   ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
be6651
+  ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
be6651
+			  ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
be6651
+			  ARM_ARCH_V8_2A),
be6651
   ARM_EXT_OPT ("dsp",	ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
be6651
 			ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
be6651
 			ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
be6651
@@ -25502,6 +26070,13 @@ static const struct arm_option_extension
be6651
 			ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
be6651
 			ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
be6651
 			ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
be6651
+  /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
be6651
+     Thumb divide instruction.  Due to this having the same name as the
be6651
+     previous entry, this will be ignored when doing command-line parsing and
be6651
+     only considered by build attribute selection code.  */
be6651
+  ARM_EXT_OPT ("idiv",	ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
be6651
+			ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
be6651
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
be6651
   ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
be6651
 			ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
be6651
   ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
be6651
@@ -25517,13 +26092,13 @@ static const struct arm_option_extension
be6651
 				   ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
be6651
   ARM_EXT_OPT ("pan",	ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
be6651
 			ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
be6651
-			ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
be6651
+			ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
be6651
   ARM_EXT_OPT ("ras",	ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
be6651
 			ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
be6651
-			ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
be6651
+			ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
be6651
   ARM_EXT_OPT ("rdma",  FPU_ARCH_NEON_VFP_ARMV8_1,
be6651
 			ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
be6651
-			ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
be6651
+			ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
be6651
   ARM_EXT_OPT2 ("sec",	ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
be6651
 			ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
be6651
 			ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
be6651
@@ -25581,6 +26156,7 @@ static const struct arm_option_fpu_value
be6651
   {"arm1136jf-s",	FPU_ARCH_VFP_V2},
be6651
   {"maverick",		FPU_ARCH_MAVERICK},
be6651
   {"neon",              FPU_ARCH_VFP_V3_PLUS_NEON_V1},
be6651
+  {"neon-vfpv3",	FPU_ARCH_VFP_V3_PLUS_NEON_V1},
be6651
   {"neon-fp16",		FPU_ARCH_NEON_FP16},
be6651
   {"vfpv4",		FPU_ARCH_VFP_V4},
be6651
   {"vfpv4-d16",		FPU_ARCH_VFP_V4D16},
be6651
@@ -25632,10 +26208,9 @@ struct arm_long_option_table
be6651
 };
be6651
 
be6651
 static bfd_boolean
be6651
-arm_parse_extension (const char *str, const arm_feature_set **opt_p)
be6651
+arm_parse_extension (const char *str, const arm_feature_set *opt_set,
be6651
+		     arm_feature_set **ext_set_p)
be6651
 {
be6651
-  arm_feature_set *ext_set = XNEW (arm_feature_set);
be6651
-
be6651
   /* We insist on extensions being specified in alphabetical order, and with
be6651
      extensions being added before being removed.  We achieve this by having
be6651
      the global ARM_EXTENSIONS table in alphabetical order, and using the
be6651
@@ -25646,9 +26221,11 @@ arm_parse_extension (const char *str, co
be6651
   const arm_feature_set arm_any = ARM_ANY;
be6651
   int adding_value = -1;
be6651
 
be6651
-  /* Copy the feature set, so that we can modify it.  */
be6651
-  *ext_set = **opt_p;
be6651
-  *opt_p = ext_set;
be6651
+  if (!*ext_set_p)
be6651
+    {
be6651
+      *ext_set_p = XNEW (arm_feature_set);
be6651
+      **ext_set_p = arm_arch_none;
be6651
+    }
be6651
 
be6651
   while (str != NULL && *str != 0)
be6651
     {
be6651
@@ -25716,7 +26293,7 @@ arm_parse_extension (const char *str, co
be6651
 		/* Empty entry.  */
be6651
 		if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
be6651
 		  continue;
be6651
-		if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *ext_set))
be6651
+		if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
be6651
 		  break;
be6651
 	      }
be6651
 	    if (i == nb_allowed_archs)
be6651
@@ -25727,10 +26304,15 @@ arm_parse_extension (const char *str, co
be6651
 
be6651
 	    /* Add or remove the extension.  */
be6651
 	    if (adding_value)
be6651
-	      ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
be6651
+	      ARM_MERGE_FEATURE_SETS (**ext_set_p, **ext_set_p,
be6651
+				      opt->merge_value);
be6651
 	    else
be6651
-	      ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
be6651
+	      ARM_CLEAR_FEATURE (**ext_set_p, **ext_set_p, opt->clear_value);
be6651
 
be6651
+	    /* Allowing Thumb division instructions for ARMv7 in autodetection
be6651
+	       rely on this break so that duplicate extensions (extensions
be6651
+	       with the same name as a previous extension in the list) are not
be6651
+	       considered for command-line parsing.  */
be6651
 	    break;
be6651
 	  }
be6651
 
be6651
@@ -25786,6 +26368,9 @@ arm_parse_cpu (const char *str)
be6651
     if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
be6651
       {
be6651
 	mcpu_cpu_opt = &opt->value;
be6651
+	if (!dyn_mcpu_ext_opt)
be6651
+	  dyn_mcpu_ext_opt = XNEW (arm_feature_set);
be6651
+	*dyn_mcpu_ext_opt = opt->ext;
be6651
 	mcpu_fpu_opt = &opt->default_fpu;
be6651
 	if (opt->canonical_name)
be6651
 	  {
be6651
@@ -25805,7 +26390,7 @@ arm_parse_cpu (const char *str)
be6651
 	  }
be6651
 
be6651
 	if (ext != NULL)
be6651
-	  return arm_parse_extension (ext, &mcpu_cpu_opt);
be6651
+	  return arm_parse_extension (ext, mcpu_cpu_opt, &dyn_mcpu_ext_opt);
be6651
 
be6651
 	return TRUE;
be6651
       }
be6651
@@ -25840,7 +26425,7 @@ arm_parse_arch (const char *str)
be6651
 	strcpy (selected_cpu_name, opt->name);
be6651
 
be6651
 	if (ext != NULL)
be6651
-	  return arm_parse_extension (ext, &march_cpu_opt);
be6651
+	  return arm_parse_extension (ext, march_cpu_opt, &dyn_march_ext_opt);
be6651
 
be6651
 	return TRUE;
be6651
       }
be6651
@@ -26080,30 +26665,62 @@ typedef struct
be6651
   arm_feature_set flags;
be6651
 } cpu_arch_ver_table;
be6651
 
be6651
-/* Mapping from CPU features to EABI CPU arch values.  As a general rule, table
be6651
-   must be sorted least features first but some reordering is needed, eg. for
be6651
-   Thumb-2 instructions to be detected as coming from ARMv6T2.  */
be6651
+/* Mapping from CPU features to EABI CPU arch values.  Table must be sorted
be6651
+   chronologically for architectures, with an exception for ARMv6-M and
be6651
+   ARMv6S-M due to legacy reasons.  No new architecture should have a
be6651
+   special case.  This allows for build attribute selection results to be
be6651
+   stable when new architectures are added.  */
be6651
 static const cpu_arch_ver_table cpu_arch_ver[] =
be6651
 {
be6651
+    {0, ARM_ARCH_V1},
be6651
+    {0, ARM_ARCH_V2},
be6651
+    {0, ARM_ARCH_V2S},
be6651
+    {0, ARM_ARCH_V3},
be6651
+    {0, ARM_ARCH_V3M},
be6651
+    {1, ARM_ARCH_V4xM},
be6651
     {1, ARM_ARCH_V4},
be6651
+    {2, ARM_ARCH_V4TxM},
be6651
     {2, ARM_ARCH_V4T},
be6651
+    {3, ARM_ARCH_V5xM},
be6651
     {3, ARM_ARCH_V5},
be6651
+    {3, ARM_ARCH_V5TxM},
be6651
     {3, ARM_ARCH_V5T},
be6651
+    {4, ARM_ARCH_V5TExP},
be6651
     {4, ARM_ARCH_V5TE},
be6651
     {5, ARM_ARCH_V5TEJ},
be6651
     {6, ARM_ARCH_V6},
be6651
-    {9, ARM_ARCH_V6K},
be6651
     {7, ARM_ARCH_V6Z},
be6651
+    {7, ARM_ARCH_V6KZ},
be6651
+    {9, ARM_ARCH_V6K},
be6651
+    {8, ARM_ARCH_V6T2},
be6651
+    {8, ARM_ARCH_V6KT2},
be6651
+    {8, ARM_ARCH_V6ZT2},
be6651
+    {8, ARM_ARCH_V6KZT2},
be6651
+
be6651
+    /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
be6651
+       always selected build attributes to match those of ARMv6-M
be6651
+       (resp. ARMv6S-M).  However, due to these architectures being a strict
be6651
+       subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
be6651
+       would be selected when fully respecting chronology of architectures.
be6651
+       It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
be6651
+       move them before ARMv7 architectures.  */
be6651
     {11, ARM_ARCH_V6M},
be6651
     {12, ARM_ARCH_V6SM},
be6651
-    {8, ARM_ARCH_V6T2},
be6651
-    {10, ARM_ARCH_V7VE},
be6651
+
be6651
+    {10, ARM_ARCH_V7},
be6651
+    {10, ARM_ARCH_V7A},
be6651
     {10, ARM_ARCH_V7R},
be6651
     {10, ARM_ARCH_V7M},
be6651
+    {10, ARM_ARCH_V7VE},
be6651
+    {13, ARM_ARCH_V7EM},
be6651
     {14, ARM_ARCH_V8A},
be6651
+    {14, ARM_ARCH_V8_1A},
be6651
+    {14, ARM_ARCH_V8_2A},
be6651
+    {14, ARM_ARCH_V8_3A},
be6651
     {16, ARM_ARCH_V8M_BASE},
be6651
     {17, ARM_ARCH_V8M_MAIN},
be6651
-    {0, ARM_ARCH_NONE}
be6651
+    {15, ARM_ARCH_V8R},
be6651
+    {-1, ARM_ARCH_NONE}
be6651
 };
be6651
 
be6651
 /* Set an attribute if it has not already been set by the user.  */
be6651
@@ -26125,92 +26742,210 @@ aeabi_set_attribute_string (int tag, con
be6651
     bfd_elf_add_proc_attr_string (stdoutput, tag, value);
be6651
 }
be6651
 
be6651
-/* Set the public EABI object attributes.  */
be6651
-void
be6651
-aeabi_set_public_attributes (void)
be6651
+/* Return whether features in the *NEEDED feature set are available via
be6651
+   extensions for the architecture whose feature set is *ARCH_FSET.  */
be6651
+static bfd_boolean
be6651
+have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
be6651
+			    const arm_feature_set *needed)
be6651
 {
be6651
-  int arch;
be6651
-  char profile;
be6651
-  int virt_sec = 0;
be6651
-  int fp16_optional = 0;
be6651
-  arm_feature_set arm_arch = ARM_ARCH_NONE;
be6651
-  arm_feature_set flags;
be6651
-  arm_feature_set tmp;
be6651
-  arm_feature_set arm_arch_v8m_base = ARM_ARCH_V8M_BASE;
be6651
-  const cpu_arch_ver_table *p;
be6651
-
be6651
-  /* Choose the architecture based on the capabilities of the requested cpu
be6651
-     (if any) and/or the instructions actually used.  */
be6651
-  ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
be6651
-  ARM_MERGE_FEATURE_SETS (flags, flags, *mfpu_opt);
be6651
-  ARM_MERGE_FEATURE_SETS (flags, flags, selected_cpu);
be6651
+  int i, nb_allowed_archs;
be6651
+  arm_feature_set ext_fset;
be6651
+  const struct arm_option_extension_value_table *opt;
be6651
 
be6651
-  if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
be6651
-    ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
be6651
+  ext_fset = arm_arch_none;
be6651
+  for (opt = arm_extensions; opt->name != NULL; opt++)
be6651
+    {
be6651
+      /* Extension does not provide any feature we need.  */
be6651
+      if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
be6651
+	continue;
be6651
 
be6651
-  if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
be6651
-    ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
be6651
+      nb_allowed_archs =
be6651
+	sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
be6651
+      for (i = 0; i < nb_allowed_archs; i++)
be6651
+	{
be6651
+	  /* Empty entry.  */
be6651
+	  if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
be6651
+	    break;
be6651
 
be6651
-  selected_cpu = flags;
be6651
+	  /* Extension is available, add it.  */
be6651
+	  if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
be6651
+	    ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
be6651
+	}
be6651
+    }
be6651
 
be6651
-  /* Allow the user to override the reported architecture.  */
be6651
-  if (object_arch)
be6651
+  /* Can we enable all features in *needed?  */
be6651
+  return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
be6651
+}
be6651
+
be6651
+/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
be6651
+   a given architecture feature set *ARCH_EXT_FSET including extension feature
be6651
+   set *EXT_FSET.  Selection logic used depend on EXACT_MATCH:
be6651
+   - if true, check for an exact match of the architecture modulo extensions;
be6651
+   - otherwise, select build attribute value of the first superset
be6651
+     architecture released so that results remains stable when new architectures
be6651
+     are added.
be6651
+   For -march/-mcpu=all the build attribute value of the most featureful
be6651
+   architecture is returned.  Tag_CPU_arch_profile result is returned in
be6651
+   PROFILE.  */
be6651
+static int
be6651
+get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
be6651
+			      const arm_feature_set *ext_fset,
be6651
+			      char *profile, int exact_match)
be6651
+{
be6651
+  arm_feature_set arch_fset;
be6651
+  const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
be6651
+
be6651
+  /* Select most featureful architecture with all its extensions if building
be6651
+     for -march=all as the feature sets used to set build attributes.  */
be6651
+  if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
be6651
     {
be6651
-      ARM_CLEAR_FEATURE (flags, flags, arm_arch_any);
be6651
-      ARM_MERGE_FEATURE_SETS (flags, flags, *object_arch);
be6651
+      /* Force revisiting of decision for each new architecture.  */
be6651
+      gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8M_MAIN);
be6651
+      *profile = 'A';
be6651
+      return TAG_CPU_ARCH_V8;
be6651
     }
be6651
 
be6651
-  /* We need to make sure that the attributes do not identify us as v6S-M
be6651
-     when the only v6S-M feature in use is the Operating System Extensions.  */
be6651
-  if (ARM_CPU_HAS_FEATURE (flags, arm_ext_os))
be6651
-      if (!ARM_CPU_HAS_FEATURE (flags, arm_arch_v6m_only))
be6651
-	ARM_CLEAR_FEATURE (flags, flags, arm_ext_os);
be6651
+  ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
be6651
 
be6651
-  tmp = flags;
be6651
-  arch = 0;
be6651
-  for (p = cpu_arch_ver; p->val; p++)
be6651
+  for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
be6651
     {
be6651
-      if (ARM_CPU_HAS_FEATURE (tmp, p->flags))
be6651
+      arm_feature_set known_arch_fset;
be6651
+
be6651
+      ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
be6651
+      if (exact_match)
be6651
 	{
be6651
-	  arch = p->val;
be6651
-	  arm_arch = p->flags;
be6651
-	  ARM_CLEAR_FEATURE (tmp, tmp, p->flags);
be6651
+	  /* Base architecture match user-specified architecture and
be6651
+	     extensions, eg. ARMv6S-M matching -march=armv6-m+os.  */
be6651
+	  if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
be6651
+	    {
be6651
+	      p_ver_ret = p_ver;
be6651
+	      goto found;
be6651
+	    }
be6651
+	  /* Base architecture match user-specified architecture only
be6651
+	     (eg. ARMv6-M in the same case as above).  Record it in case we
be6651
+	     find a match with above condition.  */
be6651
+	  else if (p_ver_ret == NULL
be6651
+		   && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
be6651
+	    p_ver_ret = p_ver;
be6651
 	}
be6651
-    }
be6651
+      else
be6651
+	{
be6651
 
be6651
-  /* The table lookup above finds the last architecture to contribute
be6651
-     a new feature.  Unfortunately, Tag13 is a subset of the union of
be6651
-     v6T2 and v7-M, so it is never seen as contributing a new feature.
be6651
-     We can not search for the last entry which is entirely used,
be6651
-     because if no CPU is specified we build up only those flags
be6651
-     actually used.  Perhaps we should separate out the specified
be6651
-     and implicit cases.  Avoid taking this path for -march=all by
be6651
-     checking for contradictory v7-A / v7-M features.  */
be6651
-  if (arch == TAG_CPU_ARCH_V7
be6651
-      && !ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
be6651
-      && ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m)
be6651
-      && ARM_CPU_HAS_FEATURE (flags, arm_ext_v6_dsp))
be6651
-    {
be6651
-      arch = TAG_CPU_ARCH_V7E_M;
be6651
-      arm_arch = (arm_feature_set) ARM_ARCH_V7EM;
be6651
+	  /* Architecture has all features wanted.  */
be6651
+	  if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
be6651
+	    {
be6651
+	      arm_feature_set added_fset;
be6651
+
be6651
+	      /* Compute features added by this architecture over the one
be6651
+		 recorded in p_ver_ret.  */
be6651
+	      if (p_ver_ret != NULL)
be6651
+		ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
be6651
+				   p_ver_ret->flags);
be6651
+	      /* First architecture that match incl. with extensions, or the
be6651
+		 only difference in features over the recorded match is
be6651
+		 features that were optional and are now mandatory.  */
be6651
+	      if (p_ver_ret == NULL
be6651
+		  || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
be6651
+		{
be6651
+		  p_ver_ret = p_ver;
be6651
+		  goto found;
be6651
+		}
be6651
+	    }
be6651
+	  else if (p_ver_ret == NULL)
be6651
+	    {
be6651
+	      arm_feature_set needed_ext_fset;
be6651
+
be6651
+	      ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
be6651
+
be6651
+	      /* Architecture has all features needed when using some
be6651
+		 extensions.  Record it and continue searching in case there
be6651
+		 exist an architecture providing all needed features without
be6651
+		 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
be6651
+		 OS extension).  */
be6651
+	      if (have_ext_for_needed_feat_p (&known_arch_fset,
be6651
+					      &needed_ext_fset))
be6651
+		p_ver_ret = p_ver;
be6651
+	    }
be6651
+	}
be6651
     }
be6651
 
be6651
-  ARM_CLEAR_FEATURE (tmp, flags, arm_arch_v8m_base);
be6651
-  if (arch == TAG_CPU_ARCH_V8M_BASE && ARM_CPU_HAS_FEATURE (tmp, arm_arch_any))
be6651
+  if (p_ver_ret == NULL)
be6651
+    return -1;
be6651
+
be6651
+found:
be6651
+  /* Tag_CPU_arch_profile.  */
be6651
+  if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
be6651
+      || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
be6651
+      || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
be6651
+	  && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
be6651
+    *profile = 'A';
be6651
+  else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
be6651
+    *profile = 'R';
be6651
+  else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
be6651
+    *profile = 'M';
be6651
+  else
be6651
+    *profile = '\0';
be6651
+  return p_ver_ret->val;
be6651
+}
be6651
+
be6651
+/* Set the public EABI object attributes.  */
be6651
+static void
be6651
+aeabi_set_public_attributes (void)
be6651
+{
be6651
+  char profile;
be6651
+  int arch = -1;
be6651
+  int virt_sec = 0;
be6651
+  int fp16_optional = 0;
be6651
+  int skip_exact_match = 0;
be6651
+  arm_feature_set flags, flags_arch, flags_ext;
be6651
+
be6651
+  /* Autodetection mode, choose the architecture based the instructions
be6651
+     actually used.  */
be6651
+  if (no_cpu_selected ())
be6651
     {
be6651
-      arch = TAG_CPU_ARCH_V8M_MAIN;
be6651
-      arm_arch = (arm_feature_set) ARM_ARCH_V8M_MAIN;
be6651
+      ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
be6651
+
be6651
+      if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
be6651
+	ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
be6651
+
be6651
+      if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
be6651
+	ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
be6651
+
be6651
+      /* Code run during relaxation relies on selected_cpu being set.  */
be6651
+      selected_cpu = flags;
be6651
     }
be6651
+  /* Otherwise, choose the architecture based on the capabilities of the
be6651
+     requested cpu.  */
be6651
+  else
be6651
+    flags = selected_cpu;
be6651
+  ARM_MERGE_FEATURE_SETS (flags, flags, *mfpu_opt);
be6651
 
be6651
-  /* In cpu_arch_ver ARMv8-A is before ARMv8-M for atomics to be detected as
be6651
-     coming from ARMv8-A.  However, since ARMv8-A has more instructions than
be6651
-     ARMv8-M, -march=all must be detected as ARMv8-A.  */
be6651
-  if (arch == TAG_CPU_ARCH_V8M_MAIN
be6651
-      && ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
be6651
+  /* Allow the user to override the reported architecture.  */
be6651
+  if (object_arch)
be6651
     {
be6651
-      arch = TAG_CPU_ARCH_V8;
be6651
-      arm_arch = (arm_feature_set) ARM_ARCH_V8A;
be6651
+      ARM_CLEAR_FEATURE (flags_arch, *object_arch, fpu_any);
be6651
+      flags_ext = arm_arch_none;
be6651
     }
be6651
+  else
be6651
+    {
be6651
+      ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
be6651
+      flags_ext = dyn_mcpu_ext_opt ? *dyn_mcpu_ext_opt : arm_arch_none;
be6651
+      skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
be6651
+    }
be6651
+
be6651
+  /* When this function is run again after relaxation has happened there is no
be6651
+     way to determine whether an architecture or CPU was specified by the user:
be6651
+     - selected_cpu is set above for relaxation to work;
be6651
+     - march_cpu_opt is not set if only -mcpu or .cpu is used;
be6651
+     - mcpu_cpu_opt is set to arm_arch_any for autodetection.
be6651
+     Therefore, if not in -march=all case we first try an exact match and fall
be6651
+     back to autodetection.  */
be6651
+  if (!skip_exact_match)
be6651
+    arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
be6651
+  if (arch == -1)
be6651
+    arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
be6651
+  if (arch == -1)
be6651
+    as_bad (_("no architecture contains all the instructions used\n"));
be6651
 
be6651
   /* Tag_CPU_name.  */
be6651
   if (selected_cpu_name[0])
be6651
@@ -26233,40 +26968,22 @@ aeabi_set_public_attributes (void)
be6651
   aeabi_set_attribute_int (Tag_CPU_arch, arch);
be6651
 
be6651
   /* Tag_CPU_arch_profile.  */
be6651
-  if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
be6651
-      || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
be6651
-      || (ARM_CPU_HAS_FEATURE (flags, arm_ext_atomics)
be6651
-	  && !ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only)))
be6651
-    profile = 'A';
be6651
-  else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7r))
be6651
-    profile = 'R';
be6651
-  else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_m))
be6651
-    profile = 'M';
be6651
-  else
be6651
-    profile = '\0';
be6651
-
be6651
   if (profile != '\0')
be6651
     aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
be6651
 
be6651
   /* Tag_DSP_extension.  */
be6651
-  if (ARM_CPU_HAS_FEATURE (flags, arm_ext_dsp))
be6651
-    {
be6651
-      arm_feature_set ext;
be6651
-
be6651
-      /* DSP instructions not in architecture.  */
be6651
-      ARM_CLEAR_FEATURE (ext, flags, arm_arch);
be6651
-      if (ARM_CPU_HAS_FEATURE (ext, arm_ext_dsp))
be6651
-	aeabi_set_attribute_int (Tag_DSP_extension, 1);
be6651
-    }
be6651
+  if (dyn_mcpu_ext_opt && ARM_CPU_HAS_FEATURE (*dyn_mcpu_ext_opt, arm_ext_dsp))
be6651
+    aeabi_set_attribute_int (Tag_DSP_extension, 1);
be6651
 
be6651
+  ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
be6651
   /* Tag_ARM_ISA_use.  */
be6651
   if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
be6651
-      || arch == 0)
be6651
+      || ARM_FEATURE_ZERO (flags_arch))
be6651
     aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
be6651
 
be6651
   /* Tag_THUMB_ISA_use.  */
be6651
   if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
be6651
-      || arch == 0)
be6651
+      || ARM_FEATURE_ZERO (flags_arch))
be6651
     {
be6651
       int thumb_isa_use;
be6651
 
be6651
@@ -26348,9 +27065,7 @@ aeabi_set_public_attributes (void)
be6651
      by the base architecture.
be6651
 
be6651
      For new architectures we will have to check these tests.  */
be6651
-  gas_assert (arch <= TAG_CPU_ARCH_V8
be6651
-	      || (arch >= TAG_CPU_ARCH_V8M_BASE
be6651
-		  && arch <= TAG_CPU_ARCH_V8M_MAIN));
be6651
+  gas_assert (arch <= TAG_CPU_ARCH_V8M_MAIN);
be6651
   if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
be6651
       || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
be6651
     aeabi_set_attribute_int (Tag_DIV_use, 0);
be6651
@@ -26373,6 +27088,18 @@ aeabi_set_public_attributes (void)
be6651
     aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
be6651
 }
be6651
 
be6651
+/* Post relaxation hook.  Recompute ARM attributes now that relaxation is
be6651
+   finished and free extension feature bits which will not be used anymore.  */
be6651
+void
be6651
+arm_md_post_relax (void)
be6651
+{
be6651
+  aeabi_set_public_attributes ();
be6651
+  XDELETE (dyn_mcpu_ext_opt);
be6651
+  dyn_mcpu_ext_opt = NULL;
be6651
+  XDELETE (dyn_march_ext_opt);
be6651
+  dyn_march_ext_opt = NULL;
be6651
+}
be6651
+
be6651
 /* Add the default contents for the .ARM.attributes section.  */
be6651
 void
be6651
 arm_md_end (void)
be6651
@@ -26405,7 +27132,10 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
be6651
     if (streq (opt->name, name))
be6651
       {
be6651
 	mcpu_cpu_opt = &opt->value;
be6651
-	selected_cpu = opt->value;
be6651
+	if (!dyn_mcpu_ext_opt)
be6651
+	  dyn_mcpu_ext_opt = XNEW (arm_feature_set);
be6651
+	*dyn_mcpu_ext_opt = opt->ext;
be6651
+	ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt);
be6651
 	if (opt->canonical_name)
be6651
 	  strcpy (selected_cpu_name, opt->canonical_name);
be6651
 	else
be6651
@@ -26417,6 +27147,8 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
be6651
 	    selected_cpu_name[i] = 0;
be6651
 	  }
be6651
 	ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
be6651
+	if (dyn_mcpu_ext_opt)
be6651
+	  ARM_MERGE_FEATURE_SETS (cpu_variant, cpu_variant, *dyn_mcpu_ext_opt);
be6651
 	*input_line_pointer = saved_char;
be6651
 	demand_empty_rest_of_line ();
be6651
 	return;
be6651
@@ -26447,9 +27179,11 @@ s_arm_arch (int ignored ATTRIBUTE_UNUSED
be6651
     if (streq (opt->name, name))
be6651
       {
be6651
 	mcpu_cpu_opt = &opt->value;
be6651
-	selected_cpu = opt->value;
be6651
+	XDELETE (dyn_mcpu_ext_opt);
be6651
+	dyn_mcpu_ext_opt = NULL;
be6651
+	selected_cpu = *mcpu_cpu_opt;
be6651
 	strcpy (selected_cpu_name, opt->name);
be6651
-	ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
be6651
+	ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, *mfpu_opt);
be6651
 	*input_line_pointer = saved_char;
be6651
 	demand_empty_rest_of_line ();
be6651
 	return;
be6651
@@ -26536,16 +27270,26 @@ s_arm_arch_extension (int ignored ATTRIB
be6651
 	    break;
be6651
 	  }
be6651
 
be6651
+	if (!dyn_mcpu_ext_opt)
be6651
+	  {
be6651
+	    dyn_mcpu_ext_opt = XNEW (arm_feature_set);
be6651
+	    *dyn_mcpu_ext_opt = arm_arch_none;
be6651
+	  }
be6651
 	if (adding_value)
be6651
-	  ARM_MERGE_FEATURE_SETS (selected_cpu, selected_cpu,
be6651
+	  ARM_MERGE_FEATURE_SETS (*dyn_mcpu_ext_opt, *dyn_mcpu_ext_opt,
be6651
 				  opt->merge_value);
be6651
 	else
be6651
-	  ARM_CLEAR_FEATURE (selected_cpu, selected_cpu, opt->clear_value);
be6651
+	  ARM_CLEAR_FEATURE (*dyn_mcpu_ext_opt, *dyn_mcpu_ext_opt,
be6651
+			     opt->clear_value);
be6651
 
be6651
-	mcpu_cpu_opt = &selected_cpu;
be6651
-	ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
be6651
+	ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt);
be6651
+	ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, *mfpu_opt);
be6651
 	*input_line_pointer = saved_char;
be6651
 	demand_empty_rest_of_line ();
be6651
+	/* Allowing Thumb division instructions for ARMv7 in autodetection rely
be6651
+	   on this return so that duplicate extensions (extensions with the
be6651
+	   same name as a previous extension in the list) are not considered
be6651
+	   for command-line parsing.  */
be6651
 	return;
be6651
       }
be6651
 
be6651
@@ -26576,6 +27320,8 @@ s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
be6651
       {
be6651
 	mfpu_opt = &opt->value;
be6651
 	ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
be6651
+	if (dyn_mcpu_ext_opt)
be6651
+	  ARM_MERGE_FEATURE_SETS (cpu_variant, cpu_variant, *dyn_mcpu_ext_opt);
be6651
 	*input_line_pointer = saved_char;
be6651
 	demand_empty_rest_of_line ();
be6651
 	return;
be6651
diff -rup binutils.orig/gas/config/tc-arm.h binutils-2.27/gas/config/tc-arm.h
be6651
--- binutils.orig/gas/config/tc-arm.h	2017-08-09 10:26:30.032741952 +0100
be6651
+++ binutils-2.27/gas/config/tc-arm.h	2017-08-09 11:17:35.442400257 +0100
be6651
@@ -118,8 +118,8 @@ extern bfd_boolean tc_start_label_withou
be6651
 extern void arm_md_end (void);
be6651
 bfd_boolean arm_is_eabi (void);
be6651
 
be6651
-#define md_post_relax_hook		aeabi_set_public_attributes ()
be6651
-extern void aeabi_set_public_attributes (void);
be6651
+#define md_post_relax_hook		arm_md_post_relax ()
be6651
+extern void arm_md_post_relax (void);
be6651
 #endif
be6651
 
be6651
 /* NOTE: The fake label creation in stabs.c:s_stab_generic() has
be6651
diff -rup binutils.orig/gas/doc/c-arm.texi binutils-2.27/gas/doc/c-arm.texi
be6651
--- binutils.orig/gas/doc/c-arm.texi	2017-08-09 10:26:30.039741874 +0100
be6651
+++ binutils-2.27/gas/doc/c-arm.texi	2017-08-09 10:28:00.216732329 +0100
be6651
@@ -172,6 +172,7 @@ been added, again in ascending alphabeti
be6651
 The following extensions are currently supported:
be6651
 @code{crc}
be6651
 @code{crypto} (Cryptography Extensions for v8-A architecture, implies @code{fp+simd}),
be6651
+@code{dotprod} (Dot Product Extensions for v8.2-A architecture, implies @code{fp+simd}),
be6651
 @code{fp} (Floating Point Extensions for v8-A architecture),
be6651
 @code{idiv} (Integer Divide Extensions for v7-A and v7-R architectures),
be6651
 @code{iwmmxt},
be6651
@@ -185,7 +186,7 @@ architectures),
be6651
 @code{simd} (Advanced SIMD Extensions for v8-A architecture, implies @code{fp}),
be6651
 @code{virt} (Virtualization Extensions for v7-A architecture, implies
be6651
 @code{idiv}),
be6651
-@code{pan} (Priviliged Access Never Extensions for v8-A architecture),
be6651
+@code{pan} (Privileged Access Never Extensions for v8-A architecture),
be6651
 @code{ras} (Reliability, Availability and Serviceability extensions
be6651
 for v8-A architecture),
be6651
 @code{rdma} (ARMv8.1 Advanced SIMD extensions for v8-A architecture, implies
be6651
@@ -230,6 +231,8 @@ names are recognized:
be6651
 @code{armv8-a},
be6651
 @code{armv8.1-a},
be6651
 @code{armv8.2-a},
be6651
+@code{armv8.3-a},
be6651
+@code{armv8-r},
be6651
 @code{iwmmxt}
be6651
 @code{iwmmxt2}
be6651
 and
be6651
@@ -281,7 +284,7 @@ The following format options are recogni
be6651
 @code{arm1136jf-s},
be6651
 @code{maverick},
be6651
 @code{neon},
be6651
-@code{neon-vfpv4},
be6651
+@code{neon-vfpv3},
be6651
 @code{neon-fp-armv8},
be6651
 @code{crypto-neon-fp-armv8},
be6651
 @code{neon-fp-armv8.1}
be6651
@@ -293,7 +296,7 @@ also affects the way in which the @code{
be6651
 when assembling little-endian code.
be6651
 
be6651
 The default is dependent on the processor selected.  For Architecture 5 or
be6651
-later, the default is to assembler for VFP instructions; for earlier
be6651
+later, the default is to assemble for VFP instructions; for earlier
be6651
 architectures the default is to assemble for FPA instructions.
be6651
 
be6651
 @cindex @code{-mthumb} command line option, ARM
be6651
@@ -931,7 +934,7 @@ between Arm and Thumb instructions and s
be6651
 interworking is not going to be performed.  The presence of this
be6651
 directive also implies @code{.thumb}
be6651
 
be6651
-This directive is not neccessary when generating EABI objects.  On these
be6651
+This directive is not necessary when generating EABI objects.  On these
be6651
 targets the encoding is implicit when generating Thumb code.
be6651
 
be6651
 @cindex @code{.thumb_set} directive, ARM
be6651
@@ -966,7 +969,7 @@ should only be done if it is really nece
be6651
 
be6651
 @cindex @code{.unwind_raw} directive, ARM
be6651
 @item .unwind_raw @var{offset}, @var{byte1}, @dots{}
be6651
-Insert one of more arbitary unwind opcode bytes, which are known to adjust
be6651
+Insert one of more arbitrary unwind opcode bytes, which are known to adjust
be6651
 the stack pointer by @var{offset} bytes.
be6651
 
be6651
 For example @code{.unwind_raw 4, 0xb1, 0x01} is equivalent to
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/archv8m-cmse-msr-base.d binutils-2.27/gas/testsuite/gas/arm/archv8m-cmse-msr-base.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/archv8m-cmse-msr-base.d	2017-08-09 10:26:30.056741684 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/archv8m-cmse-msr-base.d	2017-08-09 11:51:59.357287965 +0100
be6651
@@ -6,27 +6,71 @@
be6651
 .*: +file format .*arm.*
be6651
 
be6651
 Disassembly of section .text:
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8889 	msr	PSP_NS, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8889 	msr	PSP_NS, r0
be6651
-0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8088 	mrs	r0, MSP_NS
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8089 	mrs	r0, PSP_NS
be6651
-0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8088 	mrs	r0, MSP_NS
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8089 	mrs	r0, PSP_NS
be6651
+0+.* <[^>]*> f3ef 8109 	mrs	r1, PSP
be6651
+0+.* <[^>]*> f3ef 8189 	mrs	r1, PSP_NS
be6651
+0+.* <[^>]*> f3ef 8109 	mrs	r1, PSP
be6651
+0+.* <[^>]*> f3ef 8189 	mrs	r1, PSP_NS
be6651
+0+.* <[^>]*> f3ef 820a 	mrs	r2, MSPLIM
be6651
+0+.* <[^>]*> f3ef 828a 	mrs	r2, MSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 820a 	mrs	r2, MSPLIM
be6651
+0+.* <[^>]*> f3ef 828a 	mrs	r2, MSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 830b 	mrs	r3, PSPLIM
be6651
+0+.* <[^>]*> f3ef 838b 	mrs	r3, PSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 830b 	mrs	r3, PSPLIM
be6651
+0+.* <[^>]*> f3ef 838b 	mrs	r3, PSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 8410 	mrs	r4, PRIMASK
be6651
+0+.* <[^>]*> f3ef 8490 	mrs	r4, PRIMASK_NS
be6651
+0+.* <[^>]*> f3ef 8410 	mrs	r4, PRIMASK
be6651
+0+.* <[^>]*> f3ef 8490 	mrs	r4, PRIMASK_NS
be6651
+0+.* <[^>]*> f3ef 8511 	mrs	r5, BASEPRI
be6651
+0+.* <[^>]*> f3ef 8591 	mrs	r5, BASEPRI_NS
be6651
+0+.* <[^>]*> f3ef 8511 	mrs	r5, BASEPRI
be6651
+0+.* <[^>]*> f3ef 8591 	mrs	r5, BASEPRI_NS
be6651
+0+.* <[^>]*> f3ef 8613 	mrs	r6, FAULTMASK
be6651
+0+.* <[^>]*> f3ef 8693 	mrs	r6, FAULTMASK_NS
be6651
+0+.* <[^>]*> f3ef 8613 	mrs	r6, FAULTMASK
be6651
+0+.* <[^>]*> f3ef 8693 	mrs	r6, FAULTMASK_NS
be6651
+0+.* <[^>]*> f3ef 8714 	mrs	r7, CONTROL
be6651
+0+.* <[^>]*> f3ef 8794 	mrs	r7, CONTROL_NS
be6651
+0+.* <[^>]*> f3ef 8714 	mrs	r7, CONTROL
be6651
+0+.* <[^>]*> f3ef 8794 	mrs	r7, CONTROL_NS
be6651
+0+.* <[^>]*> f3ef 8898 	mrs	r8, SP_NS
be6651
+0+.* <[^>]*> f3ef 8898 	mrs	r8, SP_NS
be6651
+0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
+0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
+0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
+0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
+0+.* <[^>]*> f381 8809 	msr	PSP, r1
be6651
+0+.* <[^>]*> f381 8889 	msr	PSP_NS, r1
be6651
+0+.* <[^>]*> f381 8809 	msr	PSP, r1
be6651
+0+.* <[^>]*> f381 8889 	msr	PSP_NS, r1
be6651
+0+.* <[^>]*> f382 880a 	msr	MSPLIM, r2
be6651
+0+.* <[^>]*> f382 888a 	msr	MSPLIM_NS, r2
be6651
+0+.* <[^>]*> f382 880a 	msr	MSPLIM, r2
be6651
+0+.* <[^>]*> f382 888a 	msr	MSPLIM_NS, r2
be6651
+0+.* <[^>]*> f383 880b 	msr	PSPLIM, r3
be6651
+0+.* <[^>]*> f383 888b 	msr	PSPLIM_NS, r3
be6651
+0+.* <[^>]*> f383 880b 	msr	PSPLIM, r3
be6651
+0+.* <[^>]*> f383 888b 	msr	PSPLIM_NS, r3
be6651
+0+.* <[^>]*> f384 8810 	msr	PRIMASK, r4
be6651
+0+.* <[^>]*> f384 8890 	msr	PRIMASK_NS, r4
be6651
+0+.* <[^>]*> f384 8810 	msr	PRIMASK, r4
be6651
+0+.* <[^>]*> f384 8890 	msr	PRIMASK_NS, r4
be6651
+0+.* <[^>]*> f385 8811 	msr	BASEPRI, r5
be6651
+0+.* <[^>]*> f385 8891 	msr	BASEPRI_NS, r5
be6651
+0+.* <[^>]*> f385 8811 	msr	BASEPRI, r5
be6651
+0+.* <[^>]*> f385 8891 	msr	BASEPRI_NS, r5
be6651
+0+.* <[^>]*> f386 8813 	msr	FAULTMASK, r6
be6651
+0+.* <[^>]*> f386 8893 	msr	FAULTMASK_NS, r6
be6651
+0+.* <[^>]*> f386 8813 	msr	FAULTMASK, r6
be6651
+0+.* <[^>]*> f386 8893 	msr	FAULTMASK_NS, r6
be6651
+0+.* <[^>]*> f387 8814 	msr	CONTROL, r7
be6651
+0+.* <[^>]*> f387 8894 	msr	CONTROL_NS, r7
be6651
+0+.* <[^>]*> f387 8814 	msr	CONTROL, r7
be6651
+0+.* <[^>]*> f387 8894 	msr	CONTROL_NS, r7
be6651
+0+.* <[^>]*> f388 8898 	msr	SP_NS, r8
be6651
+0+.* <[^>]*> f388 8898 	msr	SP_NS, r8
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/archv8m-cmse-msr-main.d binutils-2.27/gas/testsuite/gas/arm/archv8m-cmse-msr-main.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/archv8m-cmse-msr-main.d	2017-08-09 10:26:30.056741684 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/archv8m-cmse-msr-main.d	2017-08-09 11:52:33.776902849 +0100
be6651
@@ -6,27 +6,71 @@
be6651
 .*: +file format .*arm.*
be6651
 
be6651
 Disassembly of section .text:
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8889 	msr	PSP_NS, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8889 	msr	PSP_NS, r0
be6651
-0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8088 	mrs	r0, MSP_NS
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8089 	mrs	r0, PSP_NS
be6651
-0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8088 	mrs	r0, MSP_NS
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8089 	mrs	r0, PSP_NS
be6651
+0+.* <[^>]*> f3ef 8109 	mrs	r1, PSP
be6651
+0+.* <[^>]*> f3ef 8189 	mrs	r1, PSP_NS
be6651
+0+.* <[^>]*> f3ef 8109 	mrs	r1, PSP
be6651
+0+.* <[^>]*> f3ef 8189 	mrs	r1, PSP_NS
be6651
+0+.* <[^>]*> f3ef 820a 	mrs	r2, MSPLIM
be6651
+0+.* <[^>]*> f3ef 828a 	mrs	r2, MSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 820a 	mrs	r2, MSPLIM
be6651
+0+.* <[^>]*> f3ef 828a 	mrs	r2, MSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 830b 	mrs	r3, PSPLIM
be6651
+0+.* <[^>]*> f3ef 838b 	mrs	r3, PSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 830b 	mrs	r3, PSPLIM
be6651
+0+.* <[^>]*> f3ef 838b 	mrs	r3, PSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 8410 	mrs	r4, PRIMASK
be6651
+0+.* <[^>]*> f3ef 8490 	mrs	r4, PRIMASK_NS
be6651
+0+.* <[^>]*> f3ef 8410 	mrs	r4, PRIMASK
be6651
+0+.* <[^>]*> f3ef 8490 	mrs	r4, PRIMASK_NS
be6651
+0+.* <[^>]*> f3ef 8511 	mrs	r5, BASEPRI
be6651
+0+.* <[^>]*> f3ef 8591 	mrs	r5, BASEPRI_NS
be6651
+0+.* <[^>]*> f3ef 8511 	mrs	r5, BASEPRI
be6651
+0+.* <[^>]*> f3ef 8591 	mrs	r5, BASEPRI_NS
be6651
+0+.* <[^>]*> f3ef 8613 	mrs	r6, FAULTMASK
be6651
+0+.* <[^>]*> f3ef 8693 	mrs	r6, FAULTMASK_NS
be6651
+0+.* <[^>]*> f3ef 8613 	mrs	r6, FAULTMASK
be6651
+0+.* <[^>]*> f3ef 8693 	mrs	r6, FAULTMASK_NS
be6651
+0+.* <[^>]*> f3ef 8714 	mrs	r7, CONTROL
be6651
+0+.* <[^>]*> f3ef 8794 	mrs	r7, CONTROL_NS
be6651
+0+.* <[^>]*> f3ef 8714 	mrs	r7, CONTROL
be6651
+0+.* <[^>]*> f3ef 8794 	mrs	r7, CONTROL_NS
be6651
+0+.* <[^>]*> f3ef 8898 	mrs	r8, SP_NS
be6651
+0+.* <[^>]*> f3ef 8898 	mrs	r8, SP_NS
be6651
+0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
+0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
+0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
+0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
+0+.* <[^>]*> f381 8809 	msr	PSP, r1
be6651
+0+.* <[^>]*> f381 8889 	msr	PSP_NS, r1
be6651
+0+.* <[^>]*> f381 8809 	msr	PSP, r1
be6651
+0+.* <[^>]*> f381 8889 	msr	PSP_NS, r1
be6651
+0+.* <[^>]*> f382 880a 	msr	MSPLIM, r2
be6651
+0+.* <[^>]*> f382 888a 	msr	MSPLIM_NS, r2
be6651
+0+.* <[^>]*> f382 880a 	msr	MSPLIM, r2
be6651
+0+.* <[^>]*> f382 888a 	msr	MSPLIM_NS, r2
be6651
+0+.* <[^>]*> f383 880b 	msr	PSPLIM, r3
be6651
+0+.* <[^>]*> f383 888b 	msr	PSPLIM_NS, r3
be6651
+0+.* <[^>]*> f383 880b 	msr	PSPLIM, r3
be6651
+0+.* <[^>]*> f383 888b 	msr	PSPLIM_NS, r3
be6651
+0+.* <[^>]*> f384 8810 	msr	PRIMASK, r4
be6651
+0+.* <[^>]*> f384 8890 	msr	PRIMASK_NS, r4
be6651
+0+.* <[^>]*> f384 8810 	msr	PRIMASK, r4
be6651
+0+.* <[^>]*> f384 8890 	msr	PRIMASK_NS, r4
be6651
+0+.* <[^>]*> f385 8811 	msr	BASEPRI, r5
be6651
+0+.* <[^>]*> f385 8891 	msr	BASEPRI_NS, r5
be6651
+0+.* <[^>]*> f385 8811 	msr	BASEPRI, r5
be6651
+0+.* <[^>]*> f385 8891 	msr	BASEPRI_NS, r5
be6651
+0+.* <[^>]*> f386 8813 	msr	FAULTMASK, r6
be6651
+0+.* <[^>]*> f386 8893 	msr	FAULTMASK_NS, r6
be6651
+0+.* <[^>]*> f386 8813 	msr	FAULTMASK, r6
be6651
+0+.* <[^>]*> f386 8893 	msr	FAULTMASK_NS, r6
be6651
+0+.* <[^>]*> f387 8814 	msr	CONTROL, r7
be6651
+0+.* <[^>]*> f387 8894 	msr	CONTROL_NS, r7
be6651
+0+.* <[^>]*> f387 8814 	msr	CONTROL, r7
be6651
+0+.* <[^>]*> f387 8894 	msr	CONTROL_NS, r7
be6651
+0+.* <[^>]*> f388 8898 	msr	SP_NS, r8
be6651
+0+.* <[^>]*> f388 8898 	msr	SP_NS, r8
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/archv8m-cmse-msr.s binutils-2.27/gas/testsuite/gas/arm/archv8m-cmse-msr.s
be6651
--- binutils.orig/gas/testsuite/gas/arm/archv8m-cmse-msr.s	2017-08-09 10:26:30.056741684 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/archv8m-cmse-msr.s	2017-08-09 11:50:44.728124484 +0100
be6651
@@ -1,25 +1,109 @@
be6651
 T:
be6651
-msr   MSP, r0
be6651
-msr   MSP_S, r0
be6651
-msr   MSP_NS, r0
be6651
-msr   PSP, r0
be6651
-msr   PSP_S, r0
be6651
-msr   PSP_NS, r0
be6651
-msr   msp, r0
be6651
-msr   msp_s, r0
be6651
-msr   msp_ns, r0
be6651
-msr   psp, r0
be6651
-msr   psp_s, r0
be6651
-msr   psp_ns, r0
be6651
+## MRS ##
be6651
+
be6651
+# MSP
be6651
 mrs   r0, MSP
be6651
-mrs   r0, MSP_S
be6651
 mrs   r0, MSP_NS
be6651
-mrs   r0, PSP
be6651
-mrs   r0, PSP_S
be6651
-mrs   r0, PSP_NS
be6651
 mrs   r0, msp
be6651
-mrs   r0, msp_s
be6651
 mrs   r0, msp_ns
be6651
-mrs   r0, psp
be6651
-mrs   r0, psp_s
be6651
-mrs   r0, psp_ns
be6651
+
be6651
+# PSP
be6651
+mrs   r1, PSP
be6651
+mrs   r1, PSP_NS
be6651
+mrs   r1, psp
be6651
+mrs   r1, psp_ns
be6651
+
be6651
+# MSPLIM
be6651
+mrs   r2, MSPLIM
be6651
+mrs   r2, MSPLIM_NS
be6651
+mrs   r2, msplim
be6651
+mrs   r2, msplim_ns
be6651
+
be6651
+# PSPLIM
be6651
+mrs   r3, PSPLIM
be6651
+mrs   r3, PSPLIM_NS
be6651
+mrs   r3, psplim
be6651
+mrs   r3, psplim_ns
be6651
+
be6651
+# PRIMASK
be6651
+mrs   r4, PRIMASK
be6651
+mrs   r4, PRIMASK_NS
be6651
+mrs   r4, primask
be6651
+mrs   r4, primask_ns
be6651
+
be6651
+# BASEPRI
be6651
+mrs   r5, BASEPRI
be6651
+mrs   r5, BASEPRI_NS
be6651
+mrs   r5, basepri
be6651
+mrs   r5, basepri_ns
be6651
+
be6651
+# FAULTMASK
be6651
+mrs   r6, FAULTMASK
be6651
+mrs   r6, FAULTMASK_NS
be6651
+mrs   r6, faultmask
be6651
+mrs   r6, faultmask_ns
be6651
+
be6651
+# CONTROL
be6651
+mrs   r7, CONTROL
be6651
+mrs   r7, CONTROL_NS
be6651
+mrs   r7, control
be6651
+mrs   r7, control_ns
be6651
+
be6651
+# SP_NS
be6651
+mrs   r8, SP_NS
be6651
+mrs   r8, sp_ns
be6651
+
be6651
+
be6651
+## MSR ##
be6651
+
be6651
+# MSP
be6651
+msr   MSP,	    r0
be6651
+msr   MSP_NS,	    r0
be6651
+msr   msp,	    r0
be6651
+msr   msp_ns,	    r0
be6651
+
be6651
+# PSP
be6651
+msr   PSP,	    r1
be6651
+msr   PSP_NS,	    r1
be6651
+msr   psp,	    r1
be6651
+msr   psp_ns,	    r1
be6651
+
be6651
+# MSPLIM
be6651
+msr   MSPLIM,	    r2
be6651
+msr   MSPLIM_NS,    r2
be6651
+msr   msplim,	    r2
be6651
+msr   msplim_ns,    r2
be6651
+
be6651
+# PSPLIM
be6651
+msr   PSPLIM,	    r3
be6651
+msr   PSPLIM_NS,    r3
be6651
+msr   psplim,	    r3
be6651
+msr   psplim_ns,    r3
be6651
+
be6651
+# PRIMASK
be6651
+msr   PRIMASK,	    r4
be6651
+msr   PRIMASK_NS,   r4
be6651
+msr   primask,	    r4
be6651
+msr   primask_ns,   r4
be6651
+
be6651
+# BASEPRI
be6651
+msr   BASEPRI,	    r5
be6651
+msr   BASEPRI_NS,   r5
be6651
+msr   basepri,	    r5
be6651
+msr   basepri_ns,   r5
be6651
+
be6651
+# FAULTMASK
be6651
+msr   FAULTMASK,    r6
be6651
+msr   FAULTMASK_NS, r6
be6651
+msr   faultmask,    r6
be6651
+msr   faultmask_ns, r6
be6651
+
be6651
+# CONTROL
be6651
+msr   CONTROL,	    r7
be6651
+msr   CONTROL_NS,   r7
be6651
+msr   control,	    r7
be6651
+msr   control_ns,   r7
be6651
+
be6651
+# SP_NS
be6651
+msr   SP_NS,	    r8
be6651
+msr   sp_ns,	    r8
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/archv8m-main-dsp-4.d binutils-2.27/gas/testsuite/gas/arm/archv8m-main-dsp-4.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/archv8m-main-dsp-4.d	2017-08-09 10:26:30.056741684 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/archv8m-main-dsp-4.d	2017-08-09 11:54:37.162524973 +0100
be6651
@@ -6,27 +6,71 @@
be6651
 .*: +file format .*arm.*
be6651
 
be6651
 Disassembly of section .text:
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8889 	msr	PSP_NS, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
-0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8809 	msr	PSP, r0
be6651
-0+.* <[^>]*> f380 8889 	msr	PSP_NS, r0
be6651
-0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8088 	mrs	r0, MSP_NS
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8089 	mrs	r0, PSP_NS
be6651
-0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8008 	mrs	r0, MSP
be6651
 0+.* <[^>]*> f3ef 8088 	mrs	r0, MSP_NS
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8009 	mrs	r0, PSP
be6651
-0+.* <[^>]*> f3ef 8089 	mrs	r0, PSP_NS
be6651
+0+.* <[^>]*> f3ef 8109 	mrs	r1, PSP
be6651
+0+.* <[^>]*> f3ef 8189 	mrs	r1, PSP_NS
be6651
+0+.* <[^>]*> f3ef 8109 	mrs	r1, PSP
be6651
+0+.* <[^>]*> f3ef 8189 	mrs	r1, PSP_NS
be6651
+0+.* <[^>]*> f3ef 820a 	mrs	r2, MSPLIM
be6651
+0+.* <[^>]*> f3ef 828a 	mrs	r2, MSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 820a 	mrs	r2, MSPLIM
be6651
+0+.* <[^>]*> f3ef 828a 	mrs	r2, MSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 830b 	mrs	r3, PSPLIM
be6651
+0+.* <[^>]*> f3ef 838b 	mrs	r3, PSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 830b 	mrs	r3, PSPLIM
be6651
+0+.* <[^>]*> f3ef 838b 	mrs	r3, PSPLIM_NS
be6651
+0+.* <[^>]*> f3ef 8410 	mrs	r4, PRIMASK
be6651
+0+.* <[^>]*> f3ef 8490 	mrs	r4, PRIMASK_NS
be6651
+0+.* <[^>]*> f3ef 8410 	mrs	r4, PRIMASK
be6651
+0+.* <[^>]*> f3ef 8490 	mrs	r4, PRIMASK_NS
be6651
+0+.* <[^>]*> f3ef 8511 	mrs	r5, BASEPRI
be6651
+0+.* <[^>]*> f3ef 8591 	mrs	r5, BASEPRI_NS
be6651
+0+.* <[^>]*> f3ef 8511 	mrs	r5, BASEPRI
be6651
+0+.* <[^>]*> f3ef 8591 	mrs	r5, BASEPRI_NS
be6651
+0+.* <[^>]*> f3ef 8613 	mrs	r6, FAULTMASK
be6651
+0+.* <[^>]*> f3ef 8693 	mrs	r6, FAULTMASK_NS
be6651
+0+.* <[^>]*> f3ef 8613 	mrs	r6, FAULTMASK
be6651
+0+.* <[^>]*> f3ef 8693 	mrs	r6, FAULTMASK_NS
be6651
+0+.* <[^>]*> f3ef 8714 	mrs	r7, CONTROL
be6651
+0+.* <[^>]*> f3ef 8794 	mrs	r7, CONTROL_NS
be6651
+0+.* <[^>]*> f3ef 8714 	mrs	r7, CONTROL
be6651
+0+.* <[^>]*> f3ef 8794 	mrs	r7, CONTROL_NS
be6651
+0+.* <[^>]*> f3ef 8898 	mrs	r8, SP_NS
be6651
+0+.* <[^>]*> f3ef 8898 	mrs	r8, SP_NS
be6651
+0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
+0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
+0+.* <[^>]*> f380 8808 	msr	MSP, r0
be6651
+0+.* <[^>]*> f380 8888 	msr	MSP_NS, r0
be6651
+0+.* <[^>]*> f381 8809 	msr	PSP, r1
be6651
+0+.* <[^>]*> f381 8889 	msr	PSP_NS, r1
be6651
+0+.* <[^>]*> f381 8809 	msr	PSP, r1
be6651
+0+.* <[^>]*> f381 8889 	msr	PSP_NS, r1
be6651
+0+.* <[^>]*> f382 880a 	msr	MSPLIM, r2
be6651
+0+.* <[^>]*> f382 888a 	msr	MSPLIM_NS, r2
be6651
+0+.* <[^>]*> f382 880a 	msr	MSPLIM, r2
be6651
+0+.* <[^>]*> f382 888a 	msr	MSPLIM_NS, r2
be6651
+0+.* <[^>]*> f383 880b 	msr	PSPLIM, r3
be6651
+0+.* <[^>]*> f383 888b 	msr	PSPLIM_NS, r3
be6651
+0+.* <[^>]*> f383 880b 	msr	PSPLIM, r3
be6651
+0+.* <[^>]*> f383 888b 	msr	PSPLIM_NS, r3
be6651
+0+.* <[^>]*> f384 8810 	msr	PRIMASK, r4
be6651
+0+.* <[^>]*> f384 8890 	msr	PRIMASK_NS, r4
be6651
+0+.* <[^>]*> f384 8810 	msr	PRIMASK, r4
be6651
+0+.* <[^>]*> f384 8890 	msr	PRIMASK_NS, r4
be6651
+0+.* <[^>]*> f385 8811 	msr	BASEPRI, r5
be6651
+0+.* <[^>]*> f385 8891 	msr	BASEPRI_NS, r5
be6651
+0+.* <[^>]*> f385 8811 	msr	BASEPRI, r5
be6651
+0+.* <[^>]*> f385 8891 	msr	BASEPRI_NS, r5
be6651
+0+.* <[^>]*> f386 8813 	msr	FAULTMASK, r6
be6651
+0+.* <[^>]*> f386 8893 	msr	FAULTMASK_NS, r6
be6651
+0+.* <[^>]*> f386 8813 	msr	FAULTMASK, r6
be6651
+0+.* <[^>]*> f386 8893 	msr	FAULTMASK_NS, r6
be6651
+0+.* <[^>]*> f387 8814 	msr	CONTROL, r7
be6651
+0+.* <[^>]*> f387 8894 	msr	CONTROL_NS, r7
be6651
+0+.* <[^>]*> f387 8814 	msr	CONTROL, r7
be6651
+0+.* <[^>]*> f387 8894 	msr	CONTROL_NS, r7
be6651
+0+.* <[^>]*> f388 8898 	msr	SP_NS, r8
be6651
+0+.* <[^>]*> f388 8898 	msr	SP_NS, r8
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/attr-march-armv1.d binutils-2.27/gas/testsuite/gas/arm/attr-march-armv1.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/attr-march-armv1.d	2017-08-09 10:26:30.058741661 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/attr-march-armv1.d	2017-08-09 11:56:00.992588823 +0100
be6651
@@ -8,5 +8,4 @@
be6651
 Attribute Section: aeabi
be6651
 File Attributes
be6651
   Tag_CPU_name: "1"
be6651
-  Tag_CPU_arch: v4
be6651
   Tag_ARM_ISA_use: Yes
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/attr-march-armv2a.d binutils-2.27/gas/testsuite/gas/arm/attr-march-armv2a.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/attr-march-armv2a.d	2017-08-09 10:26:30.058741661 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/attr-march-armv2a.d	2017-08-09 11:56:27.548292268 +0100
be6651
@@ -8,5 +8,4 @@
be6651
 Attribute Section: aeabi
be6651
 File Attributes
be6651
   Tag_CPU_name: "2A"
be6651
-  Tag_CPU_arch: v4
be6651
   Tag_ARM_ISA_use: Yes
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/attr-march-armv2.d binutils-2.27/gas/testsuite/gas/arm/attr-march-armv2.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/attr-march-armv2.d	2017-08-09 10:26:30.058741661 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/attr-march-armv2.d	2017-08-09 11:56:09.713491434 +0100
be6651
@@ -8,5 +8,4 @@
be6651
 Attribute Section: aeabi
be6651
 File Attributes
be6651
   Tag_CPU_name: "2"
be6651
-  Tag_CPU_arch: v4
be6651
   Tag_ARM_ISA_use: Yes
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/attr-march-armv2s.d binutils-2.27/gas/testsuite/gas/arm/attr-march-armv2s.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/attr-march-armv2s.d	2017-08-09 10:26:30.058741661 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/attr-march-armv2s.d	2017-08-09 11:56:35.794200184 +0100
be6651
@@ -8,5 +8,4 @@
be6651
 Attribute Section: aeabi
be6651
 File Attributes
be6651
   Tag_CPU_name: "2S"
be6651
-  Tag_CPU_arch: v4
be6651
   Tag_ARM_ISA_use: Yes
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/attr-march-armv3.d binutils-2.27/gas/testsuite/gas/arm/attr-march-armv3.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/attr-march-armv3.d	2017-08-09 10:26:30.058741661 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/attr-march-armv3.d	2017-08-09 11:56:52.435014353 +0100
be6651
@@ -8,5 +8,4 @@
be6651
 Attribute Section: aeabi
be6651
 File Attributes
be6651
   Tag_CPU_name: "3"
be6651
-  Tag_CPU_arch: v4
be6651
   Tag_ARM_ISA_use: Yes
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/attr-march-armv3m.d binutils-2.27/gas/testsuite/gas/arm/attr-march-armv3m.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/attr-march-armv3m.d	2017-08-09 10:26:30.058741661 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/attr-march-armv3m.d	2017-08-09 11:56:57.715955379 +0100
be6651
@@ -8,5 +8,4 @@
be6651
 Attribute Section: aeabi
be6651
 File Attributes
be6651
   Tag_CPU_name: "3M"
be6651
-  Tag_CPU_arch: v4
be6651
   Tag_ARM_ISA_use: Yes
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/ldr-bad.l binutils-2.27/gas/testsuite/gas/arm/ldr-bad.l
be6651
--- binutils.orig/gas/testsuite/gas/arm/ldr-bad.l	2017-08-09 10:26:30.062741616 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/ldr-bad.l	2017-08-09 11:59:45.777078600 +0100
be6651
@@ -1,7 +1,7 @@
be6651
 [^:]*: Assembler messages:
be6651
 [^:]*:5: Warning: destination register same as write-back base
be6651
-[^:]*:9: Error: ldr to register 15 must be 4-byte alligned -- `ldr r15,\[r15,#5\]'
be6651
-[^:]*:12: Error: ldr to register 15 must be 4-byte alligned -- `ldr r15,.-0xab7'
be6651
+[^:]*:9: Error: ldr to register 15 must be 4-byte aligned -- `ldr r15,\[r15,#5\]'
be6651
+[^:]*:12: Error: ldr to register 15 must be 4-byte aligned -- `ldr r15,.-0xab7'
be6651
 [^:]*:15: Warning: destination register same as write-back base
be6651
 [^:]*:16: Error: cannot use register index with PC-relative addressing -- `ldr r2,\[r15,r2\]!'
be6651
 [^:]*:19: Error: cannot use register index with PC-relative addressing -- `ldr r1,\[r1,r15\]'
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/ldr-t-bad.l binutils-2.27/gas/testsuite/gas/arm/ldr-t-bad.l
be6651
--- binutils.orig/gas/testsuite/gas/arm/ldr-t-bad.l	2017-08-09 10:26:30.062741616 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/ldr-t-bad.l	2017-08-09 12:00:06.268849764 +0100
be6651
@@ -1,9 +1,9 @@
be6651
 [^:]*: Assembler messages:
be6651
 [^:]*:8: Error: registers may not be the same -- `ldr r1,\[r1,#5\]!'
be6651
-[^:]*:12: Error: ldr to register 15 must be 4-byte alligned -- `ldr r15,\[r15,#5\]'
be6651
+[^:]*:12: Error: ldr to register 15 must be 4-byte aligned -- `ldr r15,\[r15,#5\]'
be6651
 [^:]*:16: Error: branch must be last instruction in IT block -- `ldrge r15,\[r15,#4\]'
be6651
 [^:]*:25: Error: branch must be last instruction in IT block -- `ldrge r15,.0x4'
be6651
-[^:]*:30: Error: ldr to register 15 must be 4-byte alligned -- `ldr r15,.-0xab7'
be6651
+[^:]*:30: Error: ldr to register 15 must be 4-byte aligned -- `ldr r15,.-0xab7'
be6651
 [^:]*:36: Error: branch must be last instruction in IT block -- `ldrge r15,\[r15,r1\]'
be6651
 [^:]*:41: Error: r13 not allowed here -- `ldr r1,\[r2,r13\]'
be6651
 [^:]*:42: Error: r15 not allowed here -- `ldr r2,\[r2,r15\]'
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/ld-sp-warn.l binutils-2.27/gas/testsuite/gas/arm/ld-sp-warn.l
be6651
--- binutils.orig/gas/testsuite/gas/arm/ld-sp-warn.l	2017-08-09 10:26:30.062741616 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/ld-sp-warn.l	2017-08-09 11:59:02.223564973 +0100
be6651
@@ -2,4 +2,3 @@
be6651
 [^:]*:3: Warning: This instruction may be unpredictable if executed on M-profile cores with interrupts enabled.
be6651
 [^:]*:4: Warning: This instruction may be unpredictable if executed on M-profile cores with interrupts enabled.
be6651
 [^:]*:7: Error: Thumb does not support register indexing with writeback -- `ldr r1,\[r0,r1\]!'
be6651
-[^:]*:8: Error: r13 not allowed here -- `ldrsb sp,\[r2,#16\]!'
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/strex-bad-t.d binutils-2.27/gas/testsuite/gas/arm/strex-bad-t.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/strex-bad-t.d	2017-08-09 10:26:30.066741571 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/strex-bad-t.d	2017-08-09 12:01:22.679996462 +0100
be6651
@@ -1,3 +1,4 @@
be6651
 # name: Bad addressing modes STREXH/STREXB. - THUMB
be6651
+# as: -march=armv7-a
be6651
 # error-output: strex-bad-t.l
be6651
 
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d binutils-2.27/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d	2017-08-09 10:26:30.067741560 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d	2017-08-09 11:57:45.943416812 +0100
be6651
@@ -6,19 +6,23 @@
be6651
 .*: +file format .*arm.*
be6651
 
be6651
 Disassembly of section \.text:
be6651
-0[0-9a-f]+ <[^>]+> 2000[[:space:]]+movs[[:space:]]+r0, #0.*
be6651
-0[0-9a-f]+ <[^>]+> 2108[[:space:]]+movs[[:space:]]+r1, #8.*
be6651
-0[0-9a-f]+ <[^>]+> 2251[[:space:]]+movs[[:space:]]+r2, #81.*
be6651
-0[0-9a-f]+ <[^>]+> 231f[[:space:]]+movs[[:space:]]+r3, #31.*
be6651
-0[0-9a-f]+ <[^>]+> 242f[[:space:]]+movs[[:space:]]+r4, #47.*
be6651
-0[0-9a-f]+ <[^>]+> 253f[[:space:]]+movs[[:space:]]+r5, #63.*
be6651
-0[0-9a-f]+ <[^>]+> 2680[[:space:]]+movs[[:space:]]+r6, #128.*
be6651
-0[0-9a-f]+ <[^>]+> 27ff[[:space:]]+movs[[:space:]]+r7, #255.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 0000[[:space:]]+mov\.w[[:space:]]+r0, #0.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 0108[[:space:]]+mov\.w[[:space:]]+r1, #8.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 0251[[:space:]]+mov\.w[[:space:]]+r2, #81.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 031f[[:space:]]+mov\.w[[:space:]]+r3, #31.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 042f[[:space:]]+mov\.w[[:space:]]+r4, #47.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 053f[[:space:]]+mov\.w[[:space:]]+r5, #63.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 0680[[:space:]]+mov\.w[[:space:]]+r6, #128.*
be6651
+0[0-9a-f]+ <[^>]+> f04f 07ff[[:space:]]+mov\.w[[:space:]]+r7, #255.*
be6651
 0[0-9a-f]+ <[^>]+> f04f 0800[[:space:]]+mov\.w[[:space:]]+r8, #0.*
be6651
 0[0-9a-f]+ <[^>]+> f04f 0908[[:space:]]+mov\.w[[:space:]]+r9, #8.*
be6651
 0[0-9a-f]+ <[^>]+> f04f 0a51[[:space:]]+mov\.w[[:space:]]+sl, #81.*
be6651
 0[0-9a-f]+ <[^>]+> f04f 0b1f[[:space:]]+mov\.w[[:space:]]+fp, #31.*
be6651
 0[0-9a-f]+ <[^>]+> f04f 0c2f[[:space:]]+mov\.w[[:space:]]+ip, #47.*
be6651
-0[0-9a-f]+ <[^>]+> f04f 0d3f[[:space:]]+mov\.w[[:space:]]+sp, #63.*
be6651
 0[0-9a-f]+ <[^>]+> f04f 0e80[[:space:]]+mov\.w[[:space:]]+lr, #128.*
be6651
-0[0-9a-f]+ <[^>]+> f04f 0fff[[:space:]]+mov\.w[[:space:]]+pc, #255.*
be6651
+0[0-9a-f]+ <[^>]+> f64f 78ff[[:space:]]+movw[[:space:]]+r8, #65535.*
be6651
+0[0-9a-f]+ <[^>]+> f24f 09f0[[:space:]]+movw[[:space:]]+r9, #61680.*
be6651
+0[0-9a-f]+ <[^>]+> f8df d004[[:space:]]+ldr\.w[[:space:]]+sp, \[pc, #4\].*
be6651
+0[0-9a-f]+ <[^>]+> f8df f004[[:space:]]+ldr\.w[[:space:]]+pc, \[pc, #4\].*
be6651
+0[0-9a-f]+ <[^>]+> 0000003f[[:space:]]+.word[[:space:]]+0x0000003f.*
be6651
+0[0-9a-f]+ <[^>]+> 000000ff[[:space:]]+.word[[:space:]]+0x000000ff.*
be6651
diff -rup binutils.orig/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s binutils-2.27/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s
be6651
--- binutils.orig/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s	2017-08-09 10:26:30.067741560 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s	2017-08-09 11:58:27.561952048 +0100
be6651
@@ -2,8 +2,8 @@
be6651
 	.syntax unified
be6651
 	.thumb_func
be6651
 thumb2_ldr:
be6651
-	# These can be encoded into movs since constant is small
be6651
-	# And register can be encoded in 3 bits
be6651
+	# These must be encoded into mov.w despite constant and register being
be6651
+	# small enough as ldr should not generate a flag-setting instruction.
be6651
 	ldr r0,=0x00
be6651
 	ldr r1,=0x08
be6651
 	ldr r2,=0x51
be6651
@@ -12,13 +12,19 @@ thumb2_ldr:
be6651
 	ldr r5,=0x3F
be6651
 	ldr r6,=0x80
be6651
 	ldr r7,=0xFF
be6651
-	# These shall be encoded into mov.w
be6651
-	# Since register cannot be encoded in 3 bits
be6651
+	# These shall be encoded into mov.w since register cannot be encoded in
be6651
+	# 3 bits
be6651
 	ldr r8,=0x00
be6651
 	ldr r9,=0x08
be6651
 	ldr r10,=0x51
be6651
 	ldr r11,=0x1F
be6651
 	ldr r12,=0x2F
be6651
-	ldr r13,=0x3F
be6651
 	ldr r14,=0x80
be6651
+	# These shall be encoded into movw since immediate cannot be encoded
be6651
+	# with mov.w
be6651
+	ldr r8,=0xFFFF
be6651
+	ldr r9,=0xF0F0
be6651
+	# These should be encoded as ldr since mov immediate is unpredictable
be6651
+	# for sp and pc
be6651
+	ldr r13,=0x3F
be6651
 	ldr r15,=0xFF
be6651
diff -rup binutils.orig/include/opcode/arm.h binutils-2.27/include/opcode/arm.h
be6651
--- binutils.orig/include/opcode/arm.h	2017-08-09 10:26:30.209739969 +0100
be6651
+++ binutils-2.27/include/opcode/arm.h	2017-08-09 11:11:08.487736404 +0100
be6651
@@ -64,6 +64,8 @@
be6651
 #define ARM_EXT2_FP16_INST 0x00000020	/* ARM V8.2A FP16 instructions.  */
be6651
 #define ARM_EXT2_V8M_MAIN  0x00000040	/* ARMv8-M Mainline.  */
be6651
 #define ARM_EXT2_RAS	 0x00000080	/* RAS extension.  */
be6651
+#define ARM_EXT2_V8_3A	 0x00000100	/* ARM V8.3A.  */
be6651
+#define ARM_EXT2_V8A	 0x00000200	/* ARMv8-A.  */
be6651
 
be6651
 /* Co-processor space extensions.  */
be6651
 #define ARM_CEXT_XSCALE   0x00000001	/* Allow MIA etc.          */
be6651
@@ -92,6 +94,7 @@
be6651
 #define CRC_EXT_ARMV8	 0x00004000	/* CRC32 for ARMv8.  */
be6651
 #define FPU_VFP_EXT_ARMV8xD 0x00002000	/* Single-precision FP for ARMv8.  */
be6651
 #define FPU_NEON_EXT_RDMA 0x00001000     /* v8.1 Adv.SIMD extensions.  */
be6651
+#define FPU_NEON_EXT_DOTPROD 0x00000800	/* Dot Product extension.  */
be6651
 
be6651
 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
be6651
    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
be6651
@@ -105,12 +108,14 @@
be6651
 #define ARM_AEXT_V3M	(ARM_AEXT_V3	| ARM_EXT_V3M)
be6651
 #define ARM_AEXT_V4xM	(ARM_AEXT_V3	| ARM_EXT_V4)
be6651
 #define ARM_AEXT_V4	(ARM_AEXT_V3M	| ARM_EXT_V4)
be6651
-#define ARM_AEXT_V4TxM	(ARM_AEXT_V4xM	| ARM_EXT_V4T)
be6651
-#define ARM_AEXT_V4T	(ARM_AEXT_V4	| ARM_EXT_V4T)
be6651
+#define ARM_AEXT_V4TxM	(ARM_AEXT_V4xM	| ARM_EXT_V4T | ARM_EXT_OS)
be6651
+#define ARM_AEXT_V4T	(ARM_AEXT_V4	| ARM_EXT_V4T | ARM_EXT_OS)
be6651
 #define ARM_AEXT_V5xM	(ARM_AEXT_V4xM	| ARM_EXT_V5)
be6651
 #define ARM_AEXT_V5	(ARM_AEXT_V4	| ARM_EXT_V5)
be6651
-#define ARM_AEXT_V5TxM	(ARM_AEXT_V5xM	| ARM_EXT_V4T | ARM_EXT_V5T)
be6651
-#define ARM_AEXT_V5T	(ARM_AEXT_V5	| ARM_EXT_V4T | ARM_EXT_V5T)
be6651
+#define ARM_AEXT_V5TxM	(ARM_AEXT_V5xM	| ARM_EXT_V4T | ARM_EXT_V5T \
be6651
+			 | ARM_EXT_OS)
be6651
+#define ARM_AEXT_V5T	(ARM_AEXT_V5	| ARM_EXT_V4T | ARM_EXT_V5T \
be6651
+			 | ARM_EXT_OS)
be6651
 #define ARM_AEXT_V5TExP	(ARM_AEXT_V5T	| ARM_EXT_V5ExP)
be6651
 #define ARM_AEXT_V5TE	(ARM_AEXT_V5TExP | ARM_EXT_V5E)
be6651
 #define ARM_AEXT_V5TEJ	(ARM_AEXT_V5TE	| ARM_EXT_V5J)
be6651
@@ -135,7 +140,7 @@
be6651
 #define ARM_AEXT_V6M_ONLY \
be6651
   ((ARM_EXT_BARRIER | ARM_EXT_V6M | ARM_EXT_THUMB_MSR) & ~(ARM_AEXT_NOTM))
be6651
 #define ARM_AEXT_V6M \
be6651
-  ((ARM_AEXT_V6K | ARM_AEXT_V6M_ONLY) & ~(ARM_AEXT_NOTM))
be6651
+  ((ARM_AEXT_V6K | ARM_AEXT_V6M_ONLY) & ~(ARM_AEXT_NOTM | ARM_EXT_OS))
be6651
 #define ARM_AEXT_V6SM (ARM_AEXT_V6M | ARM_EXT_OS)
be6651
 #define ARM_AEXT_V7M \
be6651
   ((ARM_AEXT_V7_ARM | ARM_EXT_V6M | ARM_EXT_V7M | ARM_EXT_DIV) \
be6651
@@ -146,13 +151,19 @@
be6651
 #define ARM_AEXT_V8A \
be6651
   (ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC | ARM_EXT_DIV | ARM_EXT_ADIV \
be6651
    | ARM_EXT_VIRT | ARM_EXT_V8)
be6651
-#define ARM_AEXT2_V8A	(ARM_EXT2_V6T2_V8M | ARM_EXT2_ATOMICS)
be6651
+#define ARM_AEXT2_V8AR	(ARM_EXT2_V6T2_V8M | ARM_EXT2_ATOMICS)
be6651
+#define ARM_AEXT2_V8A	(ARM_AEXT2_V8AR | ARM_EXT2_V8A)
be6651
 #define ARM_AEXT2_V8_1A	(ARM_AEXT2_V8A | ARM_EXT2_PAN)
be6651
 #define ARM_AEXT2_V8_2A	(ARM_AEXT2_V8_1A | ARM_EXT2_V8_2A | ARM_EXT2_RAS)
be6651
+#define ARM_AEXT2_V8_3A	(ARM_AEXT2_V8_2A | ARM_EXT2_V8_3A)
be6651
 #define ARM_AEXT_V8M_BASE (ARM_AEXT_V6SM | ARM_EXT_DIV)
be6651
 #define ARM_AEXT_V8M_MAIN ARM_AEXT_V7M
be6651
+#define ARM_AEXT_V8M_MAIN_DSP ARM_AEXT_V7EM
be6651
 #define ARM_AEXT2_V8M	(ARM_EXT2_V8M | ARM_EXT2_ATOMICS | ARM_EXT2_V6T2_V8M)
be6651
 #define ARM_AEXT2_V8M_MAIN (ARM_AEXT2_V8M | ARM_EXT2_V8M_MAIN)
be6651
+#define ARM_AEXT2_V8M_MAIN_DSP ARM_AEXT2_V8M_MAIN
be6651
+#define ARM_AEXT_V8R	ARM_AEXT_V8A
be6651
+#define ARM_AEXT2_V8R	ARM_AEXT2_V8AR
be6651
 
be6651
 /* Processors with specific extensions in the co-processor space.  */
be6651
 #define ARM_ARCH_XSCALE	ARM_FEATURE_LOW (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
be6651
@@ -224,6 +235,8 @@
be6651
 #define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1 \
be6651
   ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8 \
be6651
 		      | FPU_NEON_EXT_RDMA)
be6651
+#define FPU_ARCH_DOTPROD_NEON_VFP_ARMV8 \
be6651
+  ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD | FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
be6651
 
be6651
 
be6651
 #define FPU_ARCH_ENDIAN_PURE ARM_FEATURE_COPROC (FPU_ENDIAN_PURE)
be6651
@@ -263,18 +276,26 @@
be6651
 #define ARM_ARCH_V7M	ARM_FEATURE_CORE (ARM_AEXT_V7M, ARM_EXT2_V6T2_V8M)
be6651
 #define ARM_ARCH_V7EM	ARM_FEATURE_CORE (ARM_AEXT_V7EM, ARM_EXT2_V6T2_V8M)
be6651
 #define ARM_ARCH_V8A	ARM_FEATURE_CORE (ARM_AEXT_V8A, ARM_AEXT2_V8A)
be6651
+#define ARM_ARCH_V8A_CRC ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8A, \
be6651
+				      CRC_EXT_ARMV8)
be6651
 #define ARM_ARCH_V8_1A	ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A,	\
be6651
 				     CRC_EXT_ARMV8 | FPU_NEON_EXT_RDMA)
be6651
 #define ARM_ARCH_V8_2A	ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_2A,	\
be6651
 				     CRC_EXT_ARMV8 | FPU_NEON_EXT_RDMA)
be6651
+#define ARM_ARCH_V8_3A	ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_3A,	\
be6651
+				     CRC_EXT_ARMV8 | FPU_NEON_EXT_RDMA)
be6651
 #define ARM_ARCH_V8M_BASE ARM_FEATURE_CORE (ARM_AEXT_V8M_BASE, ARM_AEXT2_V8M)
be6651
 #define ARM_ARCH_V8M_MAIN ARM_FEATURE_CORE (ARM_AEXT_V8M_MAIN, \
be6651
 					    ARM_AEXT2_V8M_MAIN)
be6651
+#define ARM_ARCH_V8M_MAIN_DSP ARM_FEATURE_CORE (ARM_AEXT_V8M_MAIN_DSP, \
be6651
+						ARM_AEXT2_V8M_MAIN_DSP)
be6651
+#define ARM_ARCH_V8R	ARM_FEATURE_CORE (ARM_AEXT_V8R, ARM_AEXT2_V8R)
be6651
 
be6651
 /* Some useful combinations:  */
be6651
 #define ARM_ARCH_NONE	ARM_FEATURE_LOW (0, 0)
be6651
 #define FPU_NONE	ARM_FEATURE_LOW (0, 0)
be6651
 #define ARM_ANY		ARM_FEATURE (-1, -1, 0)	/* Any basic core.  */
be6651
+#define FPU_ANY		ARM_FEATURE_COPROC (-1) /* Any FPU.  */
be6651
 #define ARM_FEATURE_ALL	ARM_FEATURE (-1, -1, -1)/* All CPU and FPU features.  */
be6651
 #define FPU_ANY_HARD	ARM_FEATURE_COPROC (FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
be6651
 /* Extensions containing some Thumb-2 instructions.  If any is present, Thumb
be6651
diff -rup binutils.orig/opcodes/arm-dis.c binutils-2.27/opcodes/arm-dis.c
be6651
--- binutils.orig/opcodes/arm-dis.c	2017-08-09 10:26:30.352738367 +0100
be6651
+++ binutils-2.27/opcodes/arm-dis.c	2017-08-09 11:44:50.913090391 +0100
be6651
@@ -26,6 +26,7 @@
be6651
 #include "opcode/arm.h"
be6651
 #include "opintl.h"
be6651
 #include "safe-ctype.h"
be6651
+#include "libiberty.h"
be6651
 #include "floatformat.h"
be6651
 
be6651
 /* FIXME: This shouldn't be done here.  */
be6651
@@ -41,10 +42,6 @@
be6651
 #define strneq(a,b,n)	(strncmp ((a), (b), (n)) == 0)
be6651
 #endif
be6651
 
be6651
-#ifndef NUM_ELEM
be6651
-#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
be6651
-#endif
be6651
-
be6651
 /* Cached mapping symbol state.  */
be6651
 enum map_type
be6651
 {
be6651
@@ -116,6 +113,7 @@ struct opcode16
be6651
    %<bitfield>G         print as an iWMMXt general purpose or control register
be6651
    %<bitfield>D		print as a NEON D register
be6651
    %<bitfield>Q		print as a NEON Q register
be6651
+   %<bitfield>V		print as a NEON D or Q register
be6651
    %<bitfield>E		print a quarter-float immediate value
be6651
 
be6651
    %y		print a single precision VFP reg.
be6651
@@ -505,6 +503,8 @@ static const struct opcode32 coprocessor
be6651
     0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
be6651
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
be6651
     0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
be6651
+  {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
be6651
+    0x0ee50a10, 0x0fff0fff, "vmsr%c\tmvfr2, %12-15r"},
be6651
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
be6651
     0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
be6651
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
be6651
@@ -517,6 +517,8 @@ static const struct opcode32 coprocessor
be6651
     0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
be6651
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
be6651
     0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
be6651
+  {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
be6651
+    0x0ef50a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr2"},
be6651
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
be6651
     0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
be6651
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
be6651
@@ -882,6 +884,34 @@ static const struct opcode32 coprocessor
be6651
     0xfc400000, 0xfff00000,
be6651
     "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
be6651
 
be6651
+  /* ARMv8.3 AdvSIMD instructions in the space of coprocessor 8.  */
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfc800800, 0xfeb00f10, "vcadd%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfc900800, 0xfeb00f10, "vcadd%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfc200800, 0xff300f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%23'90"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfd200800, 0xff300f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%23?21%23?780"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfc300800, 0xff300f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%23'90"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfd300800, 0xff300f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%23?21%23?780"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfe000800, 0xffa00f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3D[%5?10], #%20'90"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfe200800, 0xffa00f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3D[%5?10], #%20?21%20?780"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfe800800, 0xffa00f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5D[0], #%20'90"},
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0xfea00800, 0xffa00f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5D[0], #%20?21%20?780"},
be6651
+
be6651
+  /* Dot Product instructions in the space of coprocessor 13.  */
be6651
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
be6651
+    0xfc200d00, 0xffb00f00, "v%4?usdot.%4?us8\t%12-15,22V, %16-19,7V, %0-3,5V"},
be6651
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
be6651
+    0xfe000d00, 0xff000f00, "v%4?usdot.%4?us8\t%12-15,22V, %16-19,7V, %0-3D[%5?10]"},
be6651
+
be6651
   /* V5 coprocessor instructions.  */
be6651
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
be6651
     0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
be6651
@@ -971,6 +1001,10 @@ static const struct opcode32 coprocessor
be6651
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
be6651
     0x0e300940, 0x0fb00f50, "vsub%c.f16\t%y1, %y2, %y0"},
be6651
 
be6651
+  /* ARMv8.3 javascript conversion instruction.  */
be6651
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
be6651
+    0x0eb90bc0, 0x0fbf0fd0, "vjcvt%c.s32.f64\t%y1, %z0"},
be6651
+
be6651
   {ARM_FEATURE_CORE_LOW (0), 0, 0, 0}
be6651
 };
be6651
 
be6651
@@ -2286,8 +2320,6 @@ static const struct opcode32 arm_opcodes
be6651
     0x01300000, 0x0ff00010, "teq%p%c\t%16-19r, %o"},
be6651
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
be6651
     0x01300010, 0x0ff00010, "teq%p%c\t%16-19R, %o"},
be6651
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
be6651
-    0x0130f000, 0x0ff0f010, "bx%c\t%0-3r"},
be6651
 
be6651
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
be6651
     0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
be6651
@@ -3171,18 +3203,20 @@ arm_regname;
be6651
 
be6651
 static const arm_regname regnames[] =
be6651
 {
be6651
-  { "raw" , "Select raw register names",
be6651
+  { "reg-names-raw", N_("Select raw register names"),
be6651
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
be6651
-  { "gcc",  "Select register names used by GCC",
be6651
+  { "reg-names-gcc", N_("Select register names used by GCC"),
be6651
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
be6651
-  { "std",  "Select register names used in ARM's ISA documentation",
be6651
+  { "reg-names-std", N_("Select register names used in ARM's ISA documentation"),
be6651
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
be6651
-  { "apcs", "Select register names used in the APCS",
be6651
+  { "force-thumb", N_("Assume all insns are Thumb insns"), {NULL} },
be6651
+  { "no-force-thumb", N_("Examine preceding label to determine an insn's type"), {NULL} },
be6651
+  { "reg-names-apcs", N_("Select register names used in the APCS"),
be6651
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
be6651
-  { "atpcs", "Select register names used in the ATPCS",
be6651
+  { "reg-names-atpcs", N_("Select register names used in the ATPCS"),
be6651
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
be6651
-  { "special-atpcs", "Select special register names used in the ATPCS",
be6651
-    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
be6651
+  { "reg-names-special-atpcs", N_("Select special register names used in the ATPCS"),
be6651
+    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
be6651
 };
be6651
 
be6651
 static const char *const iwmmxt_wwnames[] =
be6651
@@ -3208,7 +3242,7 @@ static const char *const iwmmxt_cregname
be6651
 /* Default to GCC register name set.  */
be6651
 static unsigned int regname_selected = 1;
be6651
 
be6651
-#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
be6651
+#define NUM_ARM_REGNAMES  ARRAY_SIZE (regnames)
be6651
 #define arm_regnames      regnames[regname_selected].reg_names
be6651
 
be6651
 static bfd_boolean force_thumb = FALSE;
be6651
@@ -3227,31 +3261,6 @@ static bfd_vma ifthen_address;
be6651
 
be6651
 
be6651
 /* Functions.  */
be6651
-int
be6651
-get_arm_regname_num_options (void)
be6651
-{
be6651
-  return NUM_ARM_REGNAMES;
be6651
-}
be6651
-
be6651
-int
be6651
-set_arm_regname_option (int option)
be6651
-{
be6651
-  int old = regname_selected;
be6651
-  regname_selected = option;
be6651
-  return old;
be6651
-}
be6651
-
be6651
-int
be6651
-get_arm_regnames (int option,
be6651
-		  const char **setname,
be6651
-		  const char **setdescription,
be6651
-		  const char *const **register_names)
be6651
-{
be6651
-  *setname = regnames[option].name;
be6651
-  *setdescription = regnames[option].description;
be6651
-  *register_names = regnames[option].reg_names;
be6651
-  return 16;
be6651
-}
be6651
 
be6651
 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
be6651
    Returns pointer to following character of the format string and
be6651
@@ -3669,10 +3678,15 @@ print_insn_coprocessor (bfd_vma pc,
be6651
 			  }
be6651
 			func (stream, "%s", arm_regnames[value]);
be6651
 			break;
be6651
+		      case 'V':
be6651
+			if (given & (1 << 6))
be6651
+			  goto Q;
be6651
+			/* FALLTHROUGH */
be6651
 		      case 'D':
be6651
 			func (stream, "d%ld", value);
be6651
 			break;
be6651
 		      case 'Q':
be6651
+		      Q:
be6651
 			if (value & 1)
be6651
 			  func (stream, "<illegal reg q%ld.5>", value >> 1);
be6651
 			else
be6651
@@ -4686,6 +4700,7 @@ print_insn_arm (bfd_vma pc, struct disas
be6651
 
be6651
 		    case 'S':
be6651
 		      allow_unpredictable = TRUE;
be6651
+		      /* Fall through.  */
be6651
 		    case 's':
be6651
                       if ((given & 0x004f0000) == 0x004f0000)
be6651
 			{
be6651
@@ -5427,22 +5442,31 @@ psr_name (int regno)
be6651
 {
be6651
   switch (regno)
be6651
     {
be6651
-    case 0: return "APSR";
be6651
-    case 1: return "IAPSR";
be6651
-    case 2: return "EAPSR";
be6651
-    case 3: return "PSR";
be6651
-    case 5: return "IPSR";
be6651
-    case 6: return "EPSR";
be6651
-    case 7: return "IEPSR";
be6651
-    case 8: return "MSP";
be6651
-    case 9: return "PSP";
be6651
-    case 16: return "PRIMASK";
be6651
-    case 17: return "BASEPRI";
be6651
-    case 18: return "BASEPRI_MAX";
be6651
-    case 19: return "FAULTMASK";
be6651
-    case 20: return "CONTROL";
be6651
+    case 0x0: return "APSR";
be6651
+    case 0x1: return "IAPSR";
be6651
+    case 0x2: return "EAPSR";
be6651
+    case 0x3: return "PSR";
be6651
+    case 0x5: return "IPSR";
be6651
+    case 0x6: return "EPSR";
be6651
+    case 0x7: return "IEPSR";
be6651
+    case 0x8: return "MSP";
be6651
+    case 0x9: return "PSP";
be6651
+    case 0xa: return "MSPLIM";
be6651
+    case 0xb: return "PSPLIM";
be6651
+    case 0x10: return "PRIMASK";
be6651
+    case 0x11: return "BASEPRI";
be6651
+    case 0x12: return "BASEPRI_MAX";
be6651
+    case 0x13: return "FAULTMASK";
be6651
+    case 0x14: return "CONTROL";
be6651
     case 0x88: return "MSP_NS";
be6651
     case 0x89: return "PSP_NS";
be6651
+    case 0x8a: return "MSPLIM_NS";
be6651
+    case 0x8b: return "PSPLIM_NS";
be6651
+    case 0x90: return "PRIMASK_NS";
be6651
+    case 0x91: return "BASEPRI_NS";
be6651
+    case 0x93: return "FAULTMASK_NS";
be6651
+    case 0x94: return "CONTROL_NS";
be6651
+    case 0x98: return "SP_NS";
be6651
     default: return "<unknown>";
be6651
     }
be6651
 }
be6651
@@ -5717,7 +5741,7 @@ print_insn_thumb32 (bfd_vma pc, struct d
be6651
 		      if (off || !U)
be6651
 			{
be6651
 			  func (stream, ", #%c%u", U ? '+' : '-', off * 4);
be6651
-			  value_in_comment = off * 4 * U ? 1 : -1;
be6651
+			  value_in_comment = off * 4 * (U ? 1 : -1);
be6651
 			}
be6651
 		      func (stream, "]");
be6651
 		      if (W)
be6651
@@ -5729,7 +5753,7 @@ print_insn_thumb32 (bfd_vma pc, struct d
be6651
 		      if (W)
be6651
 			{
be6651
 			  func (stream, "#%c%u", U ? '+' : '-', off * 4);
be6651
-			  value_in_comment = off * 4 * U ? 1 : -1;
be6651
+			  value_in_comment = off * 4 * (U ? 1 : -1);
be6651
 			}
be6651
 		      else
be6651
 			{
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp-bad.d binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp-bad.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp-bad.d	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp-bad.d	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,2 @@
be6651
+#as: -march=armv8.3-a+fp
be6651
+#error-output: armv8_3-a-fp-bad.l
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,7 @@
be6651
+[^:]+: Assembler messages:
be6651
+[^:]+:3: Error: operand types can't be inferred -- `vjcvt s0,d1'
be6651
+[^:]+:4: Error: VFP single precision register expected -- `vjcvt\.s32\.f64 r0,d1'
be6651
+[^:]+:5: Error: VFP/Neon double precision register expected -- `vjcvt\.s32\.f64 s0,s1'
be6651
+[^:]+:6: Error: VFP/Neon double precision register expected -- `vjcvt\.s32\.f32 s0,s1'
be6651
+[^:]+:7: Error: bad type in Neon instruction -- `vjcvt\.s32\.f32 s0,d1'
be6651
+[^:]+:8: Error: bad type in Neon instruction -- `vjcvt\.f32\.f64 s0,d1'
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp-bad.s binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp-bad.s
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp-bad.s	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp-bad.s	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,8 @@
be6651
+	.text
be6651
+	.arm
be6651
+	vjcvt s0, d1
be6651
+	vjcvt.s32.f64 r0, d1
be6651
+	vjcvt.s32.f64 s0, s1
be6651
+	vjcvt.s32.f32 s0, s1
be6651
+	vjcvt.s32.f32 s0, d1
be6651
+	vjcvt.f32.f64 s0, d1
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp.d binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp.d	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp.d	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,15 @@
be6651
+#as: -march=armv8.3-a+fp
be6651
+#objdump: -dr
be6651
+#skip: *-*-pe *-wince-* *-*-coff
be6651
+
be6651
+.*: +file format .*arm.*
be6651
+
be6651
+Disassembly of section .text:
be6651
+
be6651
+[0-9a-f]+ <.*>:
be6651
+   [0-9a-f]+:	eef90bc7 	vjcvt.s32.f64	s1, d7
be6651
+   [0-9a-f]+:	eef90bc7 	vjcvt.s32.f64	s1, d7
be6651
+
be6651
+[0-9a-f]+ <.*>:
be6651
+   [0-9a-f]+:	eef9 0bc7 	vjcvt.s32.f64	s1, d7
be6651
+
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp.s binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp.s
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-fp.s	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-fp.s	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,8 @@
be6651
+	.text
be6651
+A1:
be6651
+	.arm
be6651
+	vjcvt.s32.f64 s1, d7
be6651
+	vjcvtal.s32.f64 s1, d7
be6651
+T1:
be6651
+	.thumb
be6651
+	vjcvt.s32.f64 s1, d7
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd-bad.d binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd-bad.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd-bad.d	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd-bad.d	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,2 @@
be6651
+#as: -march=armv8.3-a+fp16+simd
be6651
+#error-output: armv8_3-a-simd-bad.l
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,39 @@
be6651
+[^:]+: Assembler messages:
be6651
+[^:]+:6: Error: operand types can't be inferred -- `vcadd d0,d1,d2,#90'
be6651
+[^:]+:7: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#0'
be6651
+[^:]+:8: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#180'
be6651
+[^:]+:9: Error: Neon double or quad precision register expected -- `vcadd\.f16 s0,s1,s2,#90'
be6651
+[^:]+:10: Error: bad type in Neon instruction -- `vcadd\.f64 d0,d1,d2,#90'
be6651
+[^:]+:11: Error: bad type in Neon instruction -- `vcadd\.f64 q0,q1,q2,#90'
be6651
+[^:]+:13: Error: operand types can't be inferred -- `vcmla d0,d1,d2,#90'
be6651
+[^:]+:14: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#-90'
be6651
+[^:]+:15: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#120'
be6651
+[^:]+:16: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#360'
be6651
+[^:]+:17: Error: Neon double or quad precision register expected -- `vcmla\.f16 s0,s1,s2,#90'
be6651
+[^:]+:18: Error: bad type in Neon instruction -- `vcmla\.f64 d0,d1,d2,#90'
be6651
+[^:]+:19: Error: bad type in Neon instruction -- `vcmla\.f64 q0,q1,q2,#90'
be6651
+[^:]+:21: Error: only D registers may be indexed -- `vcmla\.f16 q0,q1,q2\[0\],#90'
be6651
+[^:]+:22: Error: only D registers may be indexed -- `vcmla\.f32 q0,q1,q2\[0\],#90'
be6651
+[^:]+:23: Error: scalar out of range -- `vcmla\.f16 d0,d1,d2\[2\],#90'
be6651
+[^:]+:24: Error: scalar out of range -- `vcmla\.f16 q0,q1,d2\[2\],#90'
be6651
+[^:]+:25: Error: scalar out of range -- `vcmla\.f16 q0,q1,d16\[1\],#90'
be6651
+[^:]+:26: Error: scalar out of range -- `vcmla\.f32 q0,q1,d2\[1\],#90'
be6651
+[^:]+:31: Error: operand types can't be inferred -- `vcadd d0,d1,d2,#90'
be6651
+[^:]+:32: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#0'
be6651
+[^:]+:33: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#180'
be6651
+[^:]+:34: Error: Neon double or quad precision register expected -- `vcadd\.f16 s0,s1,s2,#90'
be6651
+[^:]+:35: Error: bad type in Neon instruction -- `vcadd\.f64 d0,d1,d2,#90'
be6651
+[^:]+:36: Error: bad type in Neon instruction -- `vcadd\.f64 q0,q1,q2,#90'
be6651
+[^:]+:38: Error: operand types can't be inferred -- `vcmla d0,d1,d2,#90'
be6651
+[^:]+:39: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#-90'
be6651
+[^:]+:40: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#120'
be6651
+[^:]+:41: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#360'
be6651
+[^:]+:42: Error: Neon double or quad precision register expected -- `vcmla\.f16 s0,s1,s2,#90'
be6651
+[^:]+:43: Error: bad type in Neon instruction -- `vcmla\.f64 d0,d1,d2,#90'
be6651
+[^:]+:44: Error: bad type in Neon instruction -- `vcmla\.f64 q0,q1,q2,#90'
be6651
+[^:]+:46: Error: only D registers may be indexed -- `vcmla\.f16 q0,q1,q2\[0\],#90'
be6651
+[^:]+:47: Error: only D registers may be indexed -- `vcmla\.f32 q0,q1,q2\[0\],#90'
be6651
+[^:]+:48: Error: scalar out of range -- `vcmla\.f16 d0,d1,d2\[2\],#90'
be6651
+[^:]+:49: Error: scalar out of range -- `vcmla\.f16 q0,q1,d2\[2\],#90'
be6651
+[^:]+:50: Error: scalar out of range -- `vcmla\.f16 q0,q1,d16\[1\],#90'
be6651
+[^:]+:51: Error: scalar out of range -- `vcmla\.f32 q0,q1,d2\[1\],#90'
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd-bad.s binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd-bad.s
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd-bad.s	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd-bad.s	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,51 @@
be6651
+	.text
be6651
+
be6651
+A1:
be6651
+	.arm
be6651
+
be6651
+	vcadd d0,d1,d2,#90
be6651
+	vcadd.f32 q0,q1,q2,#0
be6651
+	vcadd.f32 q0,q1,q2,#180
be6651
+	vcadd.f16 s0,s1,s2,#90
be6651
+	vcadd.f64 d0,d1,d2,#90
be6651
+	vcadd.f64 q0,q1,q2,#90
be6651
+
be6651
+	vcmla d0,d1,d2,#90
be6651
+	vcmla.f32 q0,q1,q2,#-90
be6651
+	vcmla.f32 q0,q1,q2,#120
be6651
+	vcmla.f32 q0,q1,q2,#360
be6651
+	vcmla.f16 s0,s1,s2,#90
be6651
+	vcmla.f64 d0,d1,d2,#90
be6651
+	vcmla.f64 q0,q1,q2,#90
be6651
+
be6651
+	vcmla.f16 q0,q1,q2[0],#90
be6651
+	vcmla.f32 q0,q1,q2[0],#90
be6651
+	vcmla.f16 d0,d1,d2[2],#90
be6651
+	vcmla.f16 q0,q1,d2[2],#90
be6651
+	vcmla.f16 q0,q1,d16[1],#90
be6651
+	vcmla.f32 q0,q1,d2[1],#90
be6651
+
be6651
+T1:
be6651
+	.thumb
be6651
+
be6651
+	vcadd d0,d1,d2,#90
be6651
+	vcadd.f32 q0,q1,q2,#0
be6651
+	vcadd.f32 q0,q1,q2,#180
be6651
+	vcadd.f16 s0,s1,s2,#90
be6651
+	vcadd.f64 d0,d1,d2,#90
be6651
+	vcadd.f64 q0,q1,q2,#90
be6651
+
be6651
+	vcmla d0,d1,d2,#90
be6651
+	vcmla.f32 q0,q1,q2,#-90
be6651
+	vcmla.f32 q0,q1,q2,#120
be6651
+	vcmla.f32 q0,q1,q2,#360
be6651
+	vcmla.f16 s0,s1,s2,#90
be6651
+	vcmla.f64 d0,d1,d2,#90
be6651
+	vcmla.f64 q0,q1,q2,#90
be6651
+
be6651
+	vcmla.f16 q0,q1,q2[0],#90
be6651
+	vcmla.f32 q0,q1,q2[0],#90
be6651
+	vcmla.f16 d0,d1,d2[2],#90
be6651
+	vcmla.f16 q0,q1,d2[2],#90
be6651
+	vcmla.f16 q0,q1,d16[1],#90
be6651
+	vcmla.f32 q0,q1,d2[1],#90
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd.d binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd.d
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd.d	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd.d	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,59 @@
be6651
+#as: -march=armv8.3-a+fp16+simd
be6651
+#objdump: -dr
be6651
+#skip: *-*-pe *-wince-* *-*-coff
be6651
+
be6651
+.*: +file format .*arm.*
be6651
+
be6651
+Disassembly of section .text:
be6651
+
be6651
+[0-9a-f]+ <.*>:
be6651
+ +[0-9a-f]+:	fc942846 	vcadd.f32	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fd942846 	vcadd.f32	q1, q2, q3, #270
be6651
+ +[0-9a-f]+:	fcc658a7 	vcadd.f16	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fc842846 	vcadd.f16	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fcd658a7 	vcadd.f32	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fc342846 	vcmla.f32	q1, q2, q3, #0
be6651
+ +[0-9a-f]+:	fcb42846 	vcmla.f32	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fd342846 	vcmla.f32	q1, q2, q3, #180
be6651
+ +[0-9a-f]+:	fdb42846 	vcmla.f32	q1, q2, q3, #270
be6651
+ +[0-9a-f]+:	fce658a7 	vcmla.f16	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fca42846 	vcmla.f16	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fcf658a7 	vcmla.f32	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fe565883 	vcmla.f16	d21, d22, d3\[0\], #90
be6651
+ +[0-9a-f]+:	fe5658a3 	vcmla.f16	d21, d22, d3\[1\], #90
be6651
+ +[0-9a-f]+:	fe142843 	vcmla.f16	q1, q2, d3\[0\], #90
be6651
+ +[0-9a-f]+:	fe142863 	vcmla.f16	q1, q2, d3\[1\], #90
be6651
+ +[0-9a-f]+:	fed658a7 	vcmla.f32	d21, d22, d23\[0\], #90
be6651
+ +[0-9a-f]+:	fe942867 	vcmla.f32	q1, q2, d23\[0\], #90
be6651
+ +[0-9a-f]+:	fe042863 	vcmla.f16	q1, q2, d3\[1\], #0
be6651
+ +[0-9a-f]+:	fe242863 	vcmla.f16	q1, q2, d3\[1\], #180
be6651
+ +[0-9a-f]+:	fe342863 	vcmla.f16	q1, q2, d3\[1\], #270
be6651
+ +[0-9a-f]+:	fe842843 	vcmla.f32	q1, q2, d3\[0\], #0
be6651
+ +[0-9a-f]+:	fea42843 	vcmla.f32	q1, q2, d3\[0\], #180
be6651
+ +[0-9a-f]+:	feb42843 	vcmla.f32	q1, q2, d3\[0\], #270
be6651
+
be6651
+[0-9a-f]+ <.*>:
be6651
+ +[0-9a-f]+:	fc94 2846 	vcadd.f32	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fd94 2846 	vcadd.f32	q1, q2, q3, #270
be6651
+ +[0-9a-f]+:	fcc6 58a7 	vcadd.f16	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fc84 2846 	vcadd.f16	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fcd6 58a7 	vcadd.f32	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fc34 2846 	vcmla.f32	q1, q2, q3, #0
be6651
+ +[0-9a-f]+:	fcb4 2846 	vcmla.f32	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fd34 2846 	vcmla.f32	q1, q2, q3, #180
be6651
+ +[0-9a-f]+:	fdb4 2846 	vcmla.f32	q1, q2, q3, #270
be6651
+ +[0-9a-f]+:	fce6 58a7 	vcmla.f16	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fca4 2846 	vcmla.f16	q1, q2, q3, #90
be6651
+ +[0-9a-f]+:	fcf6 58a7 	vcmla.f32	d21, d22, d23, #90
be6651
+ +[0-9a-f]+:	fe56 5883 	vcmla.f16	d21, d22, d3\[0\], #90
be6651
+ +[0-9a-f]+:	fe56 58a3 	vcmla.f16	d21, d22, d3\[1\], #90
be6651
+ +[0-9a-f]+:	fe14 2843 	vcmla.f16	q1, q2, d3\[0\], #90
be6651
+ +[0-9a-f]+:	fe14 2863 	vcmla.f16	q1, q2, d3\[1\], #90
be6651
+ +[0-9a-f]+:	fed6 58a7 	vcmla.f32	d21, d22, d23\[0\], #90
be6651
+ +[0-9a-f]+:	fe94 2867 	vcmla.f32	q1, q2, d23\[0\], #90
be6651
+ +[0-9a-f]+:	fe04 2863 	vcmla.f16	q1, q2, d3\[1\], #0
be6651
+ +[0-9a-f]+:	fe24 2863 	vcmla.f16	q1, q2, d3\[1\], #180
be6651
+ +[0-9a-f]+:	fe34 2863 	vcmla.f16	q1, q2, d3\[1\], #270
be6651
+ +[0-9a-f]+:	fe84 2843 	vcmla.f32	q1, q2, d3\[0\], #0
be6651
+ +[0-9a-f]+:	fea4 2843 	vcmla.f32	q1, q2, d3\[0\], #180
be6651
+ +[0-9a-f]+:	feb4 2843 	vcmla.f32	q1, q2, d3\[0\], #270
be6651
diff -rupN binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd.s binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd.s
be6651
--- binutils.orig/gas/testsuite/gas/arm/armv8_3-a-simd.s	1970-01-01 01:00:00.000000000 +0100
be6651
+++ binutils-2.27/gas/testsuite/gas/arm/armv8_3-a-simd.s	2017-08-09 12:10:22.428965485 +0100
be6651
@@ -0,0 +1,63 @@
be6651
+	.text
be6651
+
be6651
+A1:
be6651
+	.arm
be6651
+
be6651
+	vcadd.f32 q1,q2,q3,#90
be6651
+	vcadd.f32 q1,q2,q3,#270
be6651
+	vcadd.f16 d21,d22,d23,#90
be6651
+	vcadd.f16 q1,q2,q3,#90
be6651
+	vcadd.f32 d21,d22,d23,#90
be6651
+
be6651
+	vcmla.f32 q1,q2,q3,#0
be6651
+	vcmla.f32 q1,q2,q3,#90
be6651
+	vcmla.f32 q1,q2,q3,#180
be6651
+	vcmla.f32 q1,q2,q3,#270
be6651
+	vcmla.f16 d21,d22,d23,#90
be6651
+	vcmla.f16 q1,q2,q3,#90
be6651
+	vcmla.f32 d21,d22,d23,#90
be6651
+
be6651
+	vcmla.f16 d21,d22,d3[0],#90
be6651
+	vcmla.f16 d21,d22,d3[1],#90
be6651
+	vcmla.f16 q1,q2,d3[0],#90
be6651
+	vcmla.f16 q1,q2,d3[1],#90
be6651
+	vcmla.f32 d21,d22,d23[0],#90
be6651
+	vcmla.f32 q1,q2,d23[0],#90
be6651
+
be6651
+	vcmla.f16 q1,q2,d3[1],#0
be6651
+	vcmla.f16 q1,q2,d3[1],#180
be6651
+	vcmla.f16 q1,q2,d3[1],#270
be6651
+	vcmla.f32 q1,q2,d3[0],#0
be6651
+	vcmla.f32 q1,q2,d3[0],#180
be6651
+	vcmla.f32 q1,q2,d3[0],#270
be6651
+
be6651
+T1:
be6651
+	.thumb
be6651
+
be6651
+	vcadd.f32 q1,q2,q3,#90
be6651
+	vcadd.f32 q1,q2,q3,#270
be6651
+	vcadd.f16 d21,d22,d23,#90
be6651
+	vcadd.f16 q1,q2,q3,#90
be6651
+	vcadd.f32 d21,d22,d23,#90
be6651
+
be6651
+	vcmla.f32 q1,q2,q3,#0
be6651
+	vcmla.f32 q1,q2,q3,#90
be6651
+	vcmla.f32 q1,q2,q3,#180
be6651
+	vcmla.f32 q1,q2,q3,#270
be6651
+	vcmla.f16 d21,d22,d23,#90
be6651
+	vcmla.f16 q1,q2,q3,#90
be6651
+	vcmla.f32 d21,d22,d23,#90
be6651
+
be6651
+	vcmla.f16 d21,d22,d3[0],#90
be6651
+	vcmla.f16 d21,d22,d3[1],#90
be6651
+	vcmla.f16 q1,q2,d3[0],#90
be6651
+	vcmla.f16 q1,q2,d3[1],#90
be6651
+	vcmla.f32 d21,d22,d23[0],#90
be6651
+	vcmla.f32 q1,q2,d23[0],#90
be6651
+
be6651
+	vcmla.f16 q1,q2,d3[1],#0
be6651
+	vcmla.f16 q1,q2,d3[1],#180
be6651
+	vcmla.f16 q1,q2,d3[1],#270
be6651
+	vcmla.f32 q1,q2,d3[0],#0
be6651
+	vcmla.f32 q1,q2,d3[0],#180
be6651
+	vcmla.f32 q1,q2,d3[0],#270