public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [Patch 1/2] [binutils][arm] arm support for ARMv8.m Custom Datapath Extension
  2020-02-10 11:37 [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Matthew Malcomson
@ 2020-02-10 11:37 ` Matthew Malcomson
  2020-02-10 11:37 ` [Patch 2/2] [binutils][arm] Implement Custom Datapath Extensions for MVE Matthew Malcomson
  2020-02-10 15:11 ` [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Nick Clifton
  2 siblings, 0 replies; 7+ messages in thread
From: Matthew Malcomson @ 2020-02-10 11:37 UTC (permalink / raw)
  To: binutils; +Cc: Richard.Earnshaw, nickc, nd, ramana.radhakrishnan

[-- Attachment #1: Type: text/plain, Size: 68477 bytes --]

This patch is part of a series that adds support for the Armv8.m
ARMv8.m Custom Datapath Extension to binutils.

This patch introduces the Custom Instructions Class 1/2/3 (Single/
Dual, Accumulator/Non-accumulator varianats) to the arm backend.

The following Custom Instructions are added: cx1, cx1a,
cx1d, cx1da, cx2, cx2a, cx2d, cx2da, cx3, cx3a, cx3d, cx3da.

Specification can be found at
https://developer.arm.com/docs/ddi0607/latest

This patch distinguishes between enabling CDE for different coprocessor
numbers by defining multiple architecture flags.  This means that the
parsing of the architecture extension flags is kept entirely in the
existing code path.

We introduce a new IT block state to indicate the behaviour of these
instructions.  This new state allows being used in an IT block or
outside an IT block, but does not allow the instruction to be used
inside a VPT block.
We need this since the CX*A instruction versions can be used in IT
blocks, but they aren't to have the conditional suffixes on them.  Hence
we need to mark an instruction as allowed in either position.

We also need a new flag to objdump, in order to determine whether to
disassemble an instruction as CDE related or not.

Successfully regression tested on arm-none-eabi, and arm-wince-pe.

gas/ChangeLog:

2020-02-10  Stam Markianos-Wright  <stam.markianos-wright@arm.com>
	    Matthew Malcomson  <matthew.malcomson@arm.com>

	* config/tc-arm.c (arm_ext_cde*): New feature sets for each
	CDE coprocessor that can be enabled.
	(enum pred_instruction_type): New pred type.
	(BAD_NO_VPT): New error message.
	(BAD_CDE): New error message.
	(BAD_CDE_COPROC): New error message.
	(enum operand_parse_code): Add new immediate operands.
	(parse_operands): Account for new immediate operands.
	(check_cde_operand): New.
	(cde_coproc_enabled): New.
	(cde_coproc_pos): New.
	(cde_handle_coproc): New.
	(cxn_handle_predication): New.
	(do_custom_instruction_1): New.
	(do_custom_instruction_2): New.
	(do_custom_instruction_3): New.
	(do_cx1): New.
	(do_cx1a): New.
	(do_cx1d): New.
	(do_cx1da): New.
	(do_cx2): New.
	(do_cx2a): New.
	(do_cx2d): New.
	(do_cx2da): New.
	(do_cx3): New.
	(do_cx3a): New.
	(do_cx3d): New.
	(do_cx3da): New.
	(handle_pred_state): Define new IT block behaviour.
	(insns): Add newn CX*{,d}{,a} instructions.
	(CDE_EXTENSIONS,armv8m_main_ext_table,armv8_1m_main_ext_table):
	Define new cdecp extension strings.
	* doc/c-arm.texi: Document new cdecp extension arguments.
	* testsuite/gas/arm/cde-scalar.d: New test.
	* testsuite/gas/arm/cde-scalar.s: New test.
	* testsuite/gas/arm/cde-warnings.d: New test.
	* testsuite/gas/arm/cde-warnings.l: New test.
	* testsuite/gas/arm/cde-warnings.s: New test.
	* testsuite/gas/arm/cde.d: New test.
	* testsuite/gas/arm/cde.s: New test.

include/ChangeLog:

2020-02-10  Stam Markianos-Wright  <stam.markianos-wright@arm.com>
	    Matthew Malcomson  <matthew.malcomson@arm.com>

	* opcode/arm.h (ARM_EXT2_CDE): New extension macro.
	(ARM_EXT2_CDE0): New extension macro.
	(ARM_EXT2_CDE1): New extension macro.
	(ARM_EXT2_CDE2): New extension macro.
	(ARM_EXT2_CDE3): New extension macro.
	(ARM_EXT2_CDE4): New extension macro.
	(ARM_EXT2_CDE5): New extension macro.
	(ARM_EXT2_CDE6): New extension macro.
	(ARM_EXT2_CDE7): New extension macro.

opcodes/ChangeLog:

2020-02-10  Stam Markianos-Wright  <stam.markianos-wright@arm.com>
	    Matthew Malcomson  <matthew.malcomson@arm.com>

	* arm-dis.c (struct cdeopcode32): New.
	(CDE_OPCODE): New macro.
	(cde_opcodes): New disassembly table.
	(regnames): New option to table.
	(cde_coprocs): New global variable.
	(print_insn_cde): New
	(print_insn_thumb32): Use print_insn_cde.
	(parse_arm_disassembler_options): Parse coprocN args.



###############     Attachment also inlined for ease of reply    ###############


diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 16cbac4279ef96d0edff57f83cb20935ae5196eb..b6a1867d28bfefdfd8035a7f48e287b8cb58ba4e 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -282,6 +282,24 @@ static const arm_feature_set arm_ext_i8mm =
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM);
 static const arm_feature_set arm_ext_crc =
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC);
+static const arm_feature_set arm_ext_cde =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE);
+static const arm_feature_set arm_ext_cde0 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE0);
+static const arm_feature_set arm_ext_cde1 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE1);
+static const arm_feature_set arm_ext_cde2 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE2);
+static const arm_feature_set arm_ext_cde3 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE3);
+static const arm_feature_set arm_ext_cde4 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE4);
+static const arm_feature_set arm_ext_cde5 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE5);
+static const arm_feature_set arm_ext_cde6 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE6);
+static const arm_feature_set arm_ext_cde7 =
+  ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE7);
 
 static const arm_feature_set arm_arch_any = ARM_ANY;
 static const arm_feature_set fpu_any = FPU_ANY;
@@ -482,7 +500,9 @@ enum pred_instruction_type
    VPT_INSN,		   /* The VPT/VPST insn has been parsed.  */
    MVE_OUTSIDE_PRED_INSN , /* Instruction to indicate a MVE instruction without
 			      a predication code.  */
-   MVE_UNPREDICABLE_INSN   /* MVE instruction that is non-predicable.  */
+   MVE_UNPREDICABLE_INSN,  /* MVE instruction that is non-predicable.  */
+   NEUTRAL_IT_NO_VPT_INSN, /* Instruction that can be either inside or outside
+			      an IT block, but must not be in a VPT block.  */
 };
 
 /* The maximum number of operands we need.  */
@@ -882,6 +902,7 @@ struct asm_opcode
 #define BAD_ADDR_MODE   _("instruction does not accept this addressing mode")
 #define BAD_BRANCH	_("branch must be last instruction in IT block")
 #define BAD_BRANCH_OFF	_("branch out of range or not a multiple of 2")
+#define BAD_NO_VPT	_("instruction not allowed in VPT block")
 #define BAD_NOT_IT	_("instruction not allowed in IT block")
 #define BAD_NOT_VPT	_("instruction missing MVE vector predication code")
 #define BAD_FPU		_("selected FPU does not support instruction")
@@ -899,6 +920,8 @@ struct asm_opcode
 #define BAD_RANGE	_("branch out of range")
 #define BAD_FP16	_("selected processor does not support fp16 instruction")
 #define BAD_BF16	_("selected processor does not support bf16 instruction")
+#define BAD_CDE	_("selected processor does not support cde instruction")
+#define BAD_CDE_COPROC	_("coprocessor for insn is not enabled for cde")
 #define UNPRED_REG(R)	_("using " R " results in unpredictable behaviour")
 #define THUMB1_RELOC_ONLY  _("relocation valid in thumb1 code only")
 #define MVE_NOT_IT	_("Warning: instruction is UNPREDICTABLE in an IT " \
@@ -7138,7 +7161,8 @@ enum operand_parse_code
   OP_I64,	/*		   1 .. 64 */
   OP_I64z,	/*		   0 .. 64 */
   OP_I255,	/*		   0 .. 255 */
-
+  OP_I511,	/*		   0 .. 511 */
+  OP_I8191,	/*		   0 .. 8191 */
   OP_I4b,	/* immediate, prefix optional, 1 .. 4 */
   OP_I7b,	/*			       0 .. 7 */
   OP_I15b,	/*			       0 .. 15 */
@@ -7653,7 +7677,8 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_I64:	 po_imm_or_fail (  1,     64, FALSE);   break;
 	case OP_I64z:	 po_imm_or_fail (  0,     64, FALSE);   break;
 	case OP_I255:	 po_imm_or_fail (  0,	 255, FALSE);	break;
-
+	case OP_I511:	 po_imm_or_fail (  0,	 511, FALSE);	break;
+	case OP_I8191:   po_imm_or_fail (  0,	 8191, FALSE);	break;
 	case OP_I4b:	 po_imm_or_fail (  1,	   4, TRUE);	break;
 	case OP_oI7b:
 	case OP_I7b:	 po_imm_or_fail (  0,	   7, TRUE);	break;
@@ -21572,6 +21597,249 @@ do_vummla (void)
 
 }
 
+static void
+check_cde_operand (size_t index, int is_dual)
+{
+  unsigned Rx = inst.operands[index].reg;
+  bfd_boolean isvec = inst.operands[index].isvec;
+  if (is_dual == 0 && thumb_mode)
+    constraint (
+		!((Rx <= 14 && Rx != 13) || (Rx == REG_PC && isvec)),
+		_("Register must be r0-r14 except r13, or APSR_nzcv."));
+  else
+    constraint ( !((Rx <= 10 && Rx % 2 == 0 )),
+      _("Register must be an even register between r0-r10."));
+}
+
+static bfd_boolean
+cde_coproc_enabled (unsigned coproc)
+{
+  switch (coproc)
+  {
+    case 0: return mark_feature_used (&arm_ext_cde0);
+    case 1: return mark_feature_used (&arm_ext_cde1);
+    case 2: return mark_feature_used (&arm_ext_cde2);
+    case 3: return mark_feature_used (&arm_ext_cde3);
+    case 4: return mark_feature_used (&arm_ext_cde4);
+    case 5: return mark_feature_used (&arm_ext_cde5);
+    case 6: return mark_feature_used (&arm_ext_cde6);
+    case 7: return mark_feature_used (&arm_ext_cde7);
+    default: return FALSE;
+  }
+}
+
+#define cde_coproc_pos 8
+static void
+cde_handle_coproc (void)
+{
+  unsigned coproc = inst.operands[0].reg;
+  constraint (coproc > 7, _("CDE Coprocessor must be in range 0-7"));
+  constraint (!(cde_coproc_enabled (coproc)), BAD_CDE_COPROC);
+  inst.instruction |= coproc << cde_coproc_pos;
+}
+#undef cde_coproc_pos
+
+static void
+cxn_handle_predication (bfd_boolean is_accum)
+{
+  /* This function essentially checks for a suffix, not whether the instruction
+     is inside an IT block or not.
+     The CX* instructions should never have a conditional suffix -- this is not
+     mentioned in the syntax.  */
+  if (conditional_insn ())
+    inst.error = BAD_SYNTAX;
+  /* Here we ensure that if the current element  */
+  else if (is_accum)
+    set_pred_insn_type (NEUTRAL_IT_NO_VPT_INSN);
+  else
+    set_pred_insn_type (OUTSIDE_PRED_INSN);
+}
+
+static void
+do_custom_instruction_1 (int is_dual, bfd_boolean is_accum)
+{
+
+  constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
+
+  unsigned imm, Rd;
+
+  Rd = inst.operands[1].reg;
+  check_cde_operand (1, is_dual);
+
+  if (is_dual == 1)
+    {
+      constraint (inst.operands[2].reg != Rd + 1,
+		  _("cx1d requires consecutive destination registers."));
+      imm = inst.operands[3].imm;
+    }
+  else if (is_dual == 0)
+    imm = inst.operands[2].imm;
+  else
+    abort ();
+
+  inst.instruction |= Rd << 12;
+  inst.instruction |= (imm & 0x1F80) << 9;
+  inst.instruction |= (imm & 0x0040) << 1;
+  inst.instruction |= (imm & 0x003f);
+
+  cde_handle_coproc ();
+  cxn_handle_predication (is_accum);
+}
+
+static void
+do_custom_instruction_2 (int is_dual, bfd_boolean is_accum)
+{
+
+  constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
+
+  unsigned imm, Rd, Rn;
+
+  Rd = inst.operands[1].reg;
+
+  if (is_dual == 1)
+    {
+      constraint (inst.operands[2].reg != Rd + 1,
+		  _("cx2d requires consecutive destination registers."));
+      imm = inst.operands[4].imm;
+      Rn = inst.operands[3].reg;
+    }
+  else if (is_dual == 0)
+  {
+    imm = inst.operands[3].imm;
+    Rn = inst.operands[2].reg;
+  }
+  else
+    abort ();
+
+  check_cde_operand (2 + is_dual, /* is_dual = */0);
+  check_cde_operand (1, is_dual);
+
+  inst.instruction |= Rd << 12;
+  inst.instruction |= Rn << 16;
+
+  inst.instruction |= (imm & 0x0380) << 13;
+  inst.instruction |= (imm & 0x0040) << 1;
+  inst.instruction |= (imm & 0x003f);
+
+  cde_handle_coproc ();
+  cxn_handle_predication (is_accum);
+}
+
+static void
+do_custom_instruction_3 (int is_dual, bfd_boolean is_accum)
+{
+
+  constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
+
+  unsigned imm, Rd, Rn, Rm;
+
+  Rd = inst.operands[1].reg;
+
+  if (is_dual == 1)
+    {
+      constraint (inst.operands[2].reg != Rd + 1,
+		  _("cx3d requires consecutive destination registers."));
+      imm = inst.operands[5].imm;
+      Rn = inst.operands[3].reg;
+      Rm = inst.operands[4].reg;
+    }
+  else if (is_dual == 0)
+  {
+    imm = inst.operands[4].imm;
+    Rn = inst.operands[2].reg;
+    Rm = inst.operands[3].reg;
+  }
+  else
+    abort ();
+
+  check_cde_operand (1, is_dual);
+  check_cde_operand (2 + is_dual, /* is_dual = */0);
+  check_cde_operand (3 + is_dual, /* is_dual = */0);
+
+  inst.instruction |= Rd;
+  inst.instruction |= Rn << 16;
+  inst.instruction |= Rm << 12;
+
+  inst.instruction |= (imm & 0x0038) << 17;
+  inst.instruction |= (imm & 0x0004) << 5;
+  inst.instruction |= (imm & 0x0003) << 4;
+
+  cde_handle_coproc ();
+  cxn_handle_predication (is_accum);
+}
+
+static void
+do_cx1 (void)
+{
+  return do_custom_instruction_1 (0, 0);
+}
+
+static void
+do_cx1a (void)
+{
+  return do_custom_instruction_1 (0, 1);
+}
+
+static void
+do_cx1d (void)
+{
+  return do_custom_instruction_1 (1, 0);
+}
+
+static void
+do_cx1da (void)
+{
+  return do_custom_instruction_1 (1, 1);
+}
+
+static void
+do_cx2 (void)
+{
+  return do_custom_instruction_2 (0, 0);
+}
+
+static void
+do_cx2a (void)
+{
+  return do_custom_instruction_2 (0, 1);
+}
+
+static void
+do_cx2d (void)
+{
+  return do_custom_instruction_2 (1, 0);
+}
+
+static void
+do_cx2da (void)
+{
+  return do_custom_instruction_2 (1, 1);
+}
+
+static void
+do_cx3 (void)
+{
+  return do_custom_instruction_3 (0, 0);
+}
+
+static void
+do_cx3a (void)
+{
+  return do_custom_instruction_3 (0, 1);
+}
+
+static void
+do_cx3d (void)
+{
+  return do_custom_instruction_3 (1, 0);
+}
+
+static void
+do_cx3da (void)
+{
+  return do_custom_instruction_3 (1, 1);
+}
+
 /* Crypto v1 instructions.  */
 static void
 do_crypto_2op_1 (unsigned elttype, int op)
@@ -22474,6 +22742,7 @@ handle_pred_state (void)
 	    gas_assert (0);
 	case IF_INSIDE_IT_LAST_INSN:
 	case NEUTRAL_IT_INSN:
+	case NEUTRAL_IT_NO_VPT_INSN:
 	  break;
 
 	case VPT_INSN:
@@ -22537,6 +22806,13 @@ handle_pred_state (void)
 	    close_automatic_it_block ();
 	  break;
 
+	case NEUTRAL_IT_NO_VPT_INSN:
+	  if (now_pred.type == VECTOR_PRED)
+	    {
+	      inst.error = BAD_NO_VPT;
+	      break;
+	    }
+	  /* Fallthrough.  */
 	case NEUTRAL_IT_INSN:
 	  now_pred.block_length++;
 	  now_pred.insn_cond = TRUE;
@@ -22720,6 +22996,13 @@ handle_pred_state (void)
 	      }
 	    break;
 
+	  case NEUTRAL_IT_NO_VPT_INSN:
+	    if (now_pred.type == VECTOR_PRED)
+	      {
+		inst.error = BAD_NO_VPT;
+		break;
+	      }
+	    /* Fallthrough.  */
 	  case NEUTRAL_IT_INSN:
 	    /* The BKPT instruction is unconditional even in a IT or VPT
 	       block.  */
@@ -26097,6 +26380,24 @@ static const struct asm_opcode insns[] =
  TUF ("vusmmla", ca00c40, fca00c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
  TUF ("vusdot", c800d00, fc800d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vusdot, vusdot),
  TUF ("vsudot", c800d10, fc800d10, 3, (RNDQ, RNDQ, RNSC), vsudot, vsudot),
+
+#undef	ARM_VARIANT
+#undef	THUMB_VARIANT
+#define	THUMB_VARIANT &arm_ext_cde
+ ToC ("cx1", ee000000, 3, (RCP, APSR_RR, I8191), cx1),
+ ToC ("cx1a", fe000000, 3, (RCP, APSR_RR, I8191), cx1a),
+ ToC ("cx1d", ee000040, 4, (RCP, RR, APSR_RR, I8191), cx1d),
+ ToC ("cx1da", fe000040, 4, (RCP, RR, APSR_RR, I8191), cx1da),
+
+ ToC ("cx2", ee400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2),
+ ToC ("cx2a", fe400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2a),
+ ToC ("cx2d", ee400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2d),
+ ToC ("cx2da", fe400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2da),
+
+ ToC ("cx3", ee800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3),
+ ToC ("cx3a", fe800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3a),
+ ToC ("cx3d", ee800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3d),
+ ToC ("cx3da", fe800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3da),
 };
 #undef ARM_VARIANT
 #undef THUMB_VARIANT
@@ -31278,12 +31579,23 @@ static const struct arm_ext_table armv86a_ext_table[] =
   { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
 };
 
+#define CDE_EXTENSIONS \
+  ARM_ADD ("cdecp0", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE0)), \
+  ARM_ADD ("cdecp1", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE1)), \
+  ARM_ADD ("cdecp2", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE2)), \
+  ARM_ADD ("cdecp3", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE3)), \
+  ARM_ADD ("cdecp4", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE4)), \
+  ARM_ADD ("cdecp5", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE5)), \
+  ARM_ADD ("cdecp6", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE6)), \
+  ARM_ADD ("cdecp7", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE7))
+
 static const struct arm_ext_table armv8m_main_ext_table[] =
 {
   ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
 		  ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
   ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
   ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
+  CDE_EXTENSIONS,
   { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
 };
 
@@ -31303,9 +31615,12 @@ static const struct arm_ext_table armv8_1m_main_ext_table[] =
   ARM_ADD ("mve.fp",
 	   ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_MVE | ARM_EXT2_MVE_FP,
 			FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
+  CDE_EXTENSIONS,
   { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
 };
 
+#undef CDE_EXTENSIONS
+
 static const struct arm_ext_table armv8r_ext_table[] =
 {
   ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index e19d2a83aad437c9d4779a9dc16513554c904567..91803605775418bcc795e163f42b0beaec880967 100644
--- a/gas/doc/c-arm.texi
+++ b/gas/doc/c-arm.texi
@@ -359,6 +359,14 @@ For @code{armv8-m.main}:
 @code{+fp}: Enables single-precision only VFPv5 instructions with 16
 double-word registers.
 @code{+fp.dp}: Enables VFPv5 instructions with 16 double-word registers.
+@code{+cdecp0} (CDE extensions for v8-m architecture with coprocessor 0),
+@code{+cdecp1} (CDE extensions for v8-m architecture with coprocessor 1),
+@code{+cdecp2} (CDE extensions for v8-m architecture with coprocessor 2),
+@code{+cdecp3} (CDE extensions for v8-m architecture with coprocessor 3),
+@code{+cdecp4} (CDE extensions for v8-m architecture with coprocessor 4),
+@code{+cdecp5} (CDE extensions for v8-m architecture with coprocessor 5),
+@code{+cdecp6} (CDE extensions for v8-m architecture with coprocessor 6),
+@code{+cdecp7} (CDE extensions for v8-m architecture with coprocessor 7),
 @code{+nofp}: Disables all FPU instructions.
 @code{+nodsp}: Disables DSP Extension.
 
diff --git a/gas/testsuite/gas/arm/cde-scalar.d b/gas/testsuite/gas/arm/cde-scalar.d
new file mode 100644
index 0000000000000000000000000000000000000000..36260128f4189746e621419f7b495479013d2a2e
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-scalar.d
@@ -0,0 +1,117 @@
+#name: Custom Datapath Extension Scalar bits (CDE)
+#source: cde-scalar.s
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp7 -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7 -I$srcdir/$subdir
+#objdump: -M force-thumb -dr --show-raw-insn -marmv8-m.main -M coproc0=cde -M coproc7=cde
+#...
+00000000 <\.text>:
+ *[0-9a-f]+:	ee00 0000 	cx1	p0, r0, #0
+ *[0-9a-f]+:	ee3f 0000 	cx1	p0, r0, #8064
+ *[0-9a-f]+:	ee00 0080 	cx1	p0, r0, #64
+ *[0-9a-f]+:	ee00 003f 	cx1	p0, r0, #63
+ *[0-9a-f]+:	ee00 0700 	cx1	p7, r0, #0
+ *[0-9a-f]+:	ee00 f000 	cx1	p0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee00 9000 	cx1	p0, r9, #0
+ *[0-9a-f]+:	fe00 0000 	cx1a	p0, r0, #0
+ *[0-9a-f]+:	fe3f 0000 	cx1a	p0, r0, #8064
+ *[0-9a-f]+:	fe00 0080 	cx1a	p0, r0, #64
+ *[0-9a-f]+:	fe00 003f 	cx1a	p0, r0, #63
+ *[0-9a-f]+:	fe00 0700 	cx1a	p7, r0, #0
+ *[0-9a-f]+:	fe00 f000 	cx1a	p0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe00 9000 	cx1a	p0, r9, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe00 0000 	cx1a	p0, r0, #0
+ *[0-9a-f]+:	ee00 0040 	cx1d	p0, r0, r1, #0
+ *[0-9a-f]+:	ee3f 0040 	cx1d	p0, r0, r1, #8064
+ *[0-9a-f]+:	ee00 00c0 	cx1d	p0, r0, r1, #64
+ *[0-9a-f]+:	ee00 007f 	cx1d	p0, r0, r1, #63
+ *[0-9a-f]+:	ee00 0740 	cx1d	p7, r0, r1, #0
+ *[0-9a-f]+:	ee00 a040 	cx1d	p0, sl, fp, #0
+ *[0-9a-f]+:	fe00 0040 	cx1da	p0, r0, r1, #0
+ *[0-9a-f]+:	fe3f 0040 	cx1da	p0, r0, r1, #8064
+ *[0-9a-f]+:	fe00 00c0 	cx1da	p0, r0, r1, #64
+ *[0-9a-f]+:	fe00 007f 	cx1da	p0, r0, r1, #63
+ *[0-9a-f]+:	fe00 0740 	cx1da	p7, r0, r1, #0
+ *[0-9a-f]+:	fe00 a040 	cx1da	p0, sl, fp, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe00 0040 	cx1da	p0, r0, r1, #0
+ *[0-9a-f]+:	ee40 0000 	cx2	p0, r0, r0, #0
+ *[0-9a-f]+:	ee70 0000 	cx2	p0, r0, r0, #384
+ *[0-9a-f]+:	ee40 0080 	cx2	p0, r0, r0, #64
+ *[0-9a-f]+:	ee40 003f 	cx2	p0, r0, r0, #63
+ *[0-9a-f]+:	ee40 0700 	cx2	p7, r0, r0, #0
+ *[0-9a-f]+:	ee40 f000 	cx2	p0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	ee40 9000 	cx2	p0, r9, r0, #0
+ *[0-9a-f]+:	ee4f 0000 	cx2	p0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee49 0000 	cx2	p0, r0, r9, #0
+ *[0-9a-f]+:	fe40 0000 	cx2a	p0, r0, r0, #0
+ *[0-9a-f]+:	fe70 0000 	cx2a	p0, r0, r0, #384
+ *[0-9a-f]+:	fe40 0080 	cx2a	p0, r0, r0, #64
+ *[0-9a-f]+:	fe40 003f 	cx2a	p0, r0, r0, #63
+ *[0-9a-f]+:	fe40 0700 	cx2a	p7, r0, r0, #0
+ *[0-9a-f]+:	fe40 f000 	cx2a	p0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	fe40 9000 	cx2a	p0, r9, r0, #0
+ *[0-9a-f]+:	fe4f 0000 	cx2a	p0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe49 0000 	cx2a	p0, r0, r9, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe40 0000 	cx2a	p0, r0, r0, #0
+ *[0-9a-f]+:	ee40 0040 	cx2d	p0, r0, r1, r0, #0
+ *[0-9a-f]+:	ee70 0040 	cx2d	p0, r0, r1, r0, #384
+ *[0-9a-f]+:	ee40 00c0 	cx2d	p0, r0, r1, r0, #64
+ *[0-9a-f]+:	ee40 007f 	cx2d	p0, r0, r1, r0, #63
+ *[0-9a-f]+:	ee40 0740 	cx2d	p7, r0, r1, r0, #0
+ *[0-9a-f]+:	ee40 a040 	cx2d	p0, sl, fp, r0, #0
+ *[0-9a-f]+:	ee4f 0040 	cx2d	p0, r0, r1, APSR_nzcv, #0
+ *[0-9a-f]+:	ee49 0040 	cx2d	p0, r0, r1, r9, #0
+ *[0-9a-f]+:	fe40 0040 	cx2da	p0, r0, r1, r0, #0
+ *[0-9a-f]+:	fe70 0040 	cx2da	p0, r0, r1, r0, #384
+ *[0-9a-f]+:	fe40 00c0 	cx2da	p0, r0, r1, r0, #64
+ *[0-9a-f]+:	fe40 007f 	cx2da	p0, r0, r1, r0, #63
+ *[0-9a-f]+:	fe40 0740 	cx2da	p7, r0, r1, r0, #0
+ *[0-9a-f]+:	fe40 a040 	cx2da	p0, sl, fp, r0, #0
+ *[0-9a-f]+:	fe4f 0040 	cx2da	p0, r0, r1, APSR_nzcv, #0
+ *[0-9a-f]+:	fe49 0040 	cx2da	p0, r0, r1, r9, #0
+ *[0-9a-f]+:	ee80 0000 	cx3	p0, r0, r0, r0, #0
+ *[0-9a-f]+:	eef0 0000 	cx3	p0, r0, r0, r0, #56
+ *[0-9a-f]+:	ee80 0080 	cx3	p0, r0, r0, r0, #4
+ *[0-9a-f]+:	ee80 0030 	cx3	p0, r0, r0, r0, #3
+ *[0-9a-f]+:	ee80 0700 	cx3	p7, r0, r0, r0, #0
+ *[0-9a-f]+:	ee80 000f 	cx3	p0, APSR_nzcv, r0, r0, #0
+ *[0-9a-f]+:	ee80 0009 	cx3	p0, r9, r0, r0, #0
+ *[0-9a-f]+:	ee8f 0000 	cx3	p0, r0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	ee89 0000 	cx3	p0, r0, r9, r0, #0
+ *[0-9a-f]+:	ee80 f000 	cx3	p0, r0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee80 9000 	cx3	p0, r0, r0, r9, #0
+ *[0-9a-f]+:	fe80 0000 	cx3a	p0, r0, r0, r0, #0
+ *[0-9a-f]+:	fef0 0000 	cx3a	p0, r0, r0, r0, #56
+ *[0-9a-f]+:	fe80 0080 	cx3a	p0, r0, r0, r0, #4
+ *[0-9a-f]+:	fe80 0030 	cx3a	p0, r0, r0, r0, #3
+ *[0-9a-f]+:	fe80 0700 	cx3a	p7, r0, r0, r0, #0
+ *[0-9a-f]+:	fe80 000f 	cx3a	p0, APSR_nzcv, r0, r0, #0
+ *[0-9a-f]+:	fe80 0009 	cx3a	p0, r9, r0, r0, #0
+ *[0-9a-f]+:	fe8f 0000 	cx3a	p0, r0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	fe89 0000 	cx3a	p0, r0, r9, r0, #0
+ *[0-9a-f]+:	fe80 f000 	cx3a	p0, r0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe80 9000 	cx3a	p0, r0, r0, r9, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe80 0000 	cx3a	p0, r0, r0, r0, #0
+ *[0-9a-f]+:	ee80 0040 	cx3d	p0, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	eef0 0040 	cx3d	p0, r0, r1, r0, r0, #56
+ *[0-9a-f]+:	ee80 00c0 	cx3d	p0, r0, r1, r0, r0, #4
+ *[0-9a-f]+:	ee80 0070 	cx3d	p0, r0, r1, r0, r0, #3
+ *[0-9a-f]+:	ee80 0740 	cx3d	p7, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	ee80 004a 	cx3d	p0, sl, fp, r0, r0, #0
+ *[0-9a-f]+:	ee8f 0040 	cx3d	p0, r0, r1, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	ee89 0040 	cx3d	p0, r0, r1, r9, r0, #0
+ *[0-9a-f]+:	ee80 f040 	cx3d	p0, r0, r1, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee80 9040 	cx3d	p0, r0, r1, r0, r9, #0
+ *[0-9a-f]+:	fe80 0040 	cx3da	p0, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	fef0 0040 	cx3da	p0, r0, r1, r0, r0, #56
+ *[0-9a-f]+:	fe80 00c0 	cx3da	p0, r0, r1, r0, r0, #4
+ *[0-9a-f]+:	fe80 0070 	cx3da	p0, r0, r1, r0, r0, #3
+ *[0-9a-f]+:	fe80 0740 	cx3da	p7, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	fe80 004a 	cx3da	p0, sl, fp, r0, r0, #0
+ *[0-9a-f]+:	fe8f 0040 	cx3da	p0, r0, r1, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	fe89 0040 	cx3da	p0, r0, r1, r9, r0, #0
+ *[0-9a-f]+:	fe80 f040 	cx3da	p0, r0, r1, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe80 9040 	cx3da	p0, r0, r1, r0, r9, #0
diff --git a/gas/testsuite/gas/arm/cde-scalar.s b/gas/testsuite/gas/arm/cde-scalar.s
new file mode 100644
index 0000000000000000000000000000000000000000..ac188a3aa03f9239262b1958417df45d0b635939
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-scalar.s
@@ -0,0 +1,206 @@
+.syntax unified
+# Extra tests everywhere:
+# Ensure that setting the register to something in r[1-12] works.
+
+# cx1{a} Has arguments in the following form
+# 111a111000iiiiiidddd0pppi0iiiiii
+#
+# Variants to test:
+# - Base (everything we can set to zero)
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+#   concatenated)
+# - Each register 9 (0b1001), APSR_nzcv, or all zeros
+# - Coprocessor num set to 7
+# - Everything again with the `a` version (to double check parsing).
+# - Accumulator versions without optional argument (to check parsing)
+#
+# IT blocks:
+#  Non-accumulator versions are UNPREDICTABLE in IT blocks.
+#  Accumulator versions are allowed in IT blocks.
+
+# cx1{a} extra tests.
+# Arm conditional
+cx1 p0, r0, #0
+cx1 p0, r0, #8064
+cx1 p0, r0, #64
+cx1 p0, r0, #63
+cx1 p7, r0, #0
+cx1 p0, APSR_nzcv, #0
+cx1 p0, r9, #0
+cx1a p0, r0, #0
+cx1a p0, r0, #8064
+cx1a p0, r0, #64
+cx1a p0, r0, #63
+cx1a p7, r0, #0
+cx1a p0, APSR_nzcv, #0
+cx1a p0, r9, #0
+
+it ne
+cx1a p0, r0, #0
+
+# cx1d{a} encoding of following form:
+# 111a111000iiiiiidddd0pppi1iiiiii
+#
+# Variants to test:
+# - Base (everything we can set to zero)
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+#   concatenated)
+# - Destination register 10 (0b1010) or all zeros
+# - Coprocessor num set to 7
+# - Everything again with the `a` version (to double check parsing).
+# - Accumulator versions without optional argument (to check parsing)
+cx1d p0, r0, r1, #0
+cx1d p0, r0, r1, #8064
+cx1d p0, r0, r1, #64
+cx1d p0, r0, r1, #63
+cx1d p7, r0, r1, #0
+cx1d p0, r10, r11, #0
+cx1da p0, r0, r1, #0
+cx1da p0, r0, r1, #8064
+cx1da p0, r0, r1, #64
+cx1da p0, r0, r1, #63
+cx1da p7, r0, r1, #0
+cx1da p0, r10, r11, #0
+
+it ne
+cx1da p0, r0, r1, #0
+
+
+# cx2{a} Has arguments of the following form:
+# 111a111001iinnnndddd0pppi0iiiiii
+#
+# Variants to test:
+# - Base (everything we can set to zero)
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+#   concatenated)
+# - Each register 9 (0b1001), APSR_nzcv, or all zeros
+# - Coprocessor num set to 7
+# - Everything again with the `a` version (to double check parsing).
+# - Accumulator versions without optional argument (to check parsing)
+cx2 p0, r0, r0, #0
+cx2 p0, r0, r0, #384
+cx2 p0, r0, r0, #64
+cx2 p0, r0, r0, #63
+cx2 p7, r0, r0, #0
+cx2 p0, APSR_nzcv, r0, #0
+cx2 p0, r9, r0, #0
+cx2 p0, r0, APSR_nzcv, #0
+cx2 p0, r0, r9, #0
+cx2a p0, r0, r0, #0
+cx2a p0, r0, r0, #384
+cx2a p0, r0, r0, #64
+cx2a p0, r0, r0, #63
+cx2a p7, r0, r0, #0
+cx2a p0, APSR_nzcv, r0, #0
+cx2a p0, r9, r0, #0
+cx2a p0, r0, APSR_nzcv, #0
+cx2a p0, r0, r9, #0
+
+it ne
+cx2a p0, r0, r0, #0
+
+# cx2d{a} encoding has following form:
+# 111a111001iinnnndddd0pppi1iiiiii
+#
+# - Base (everything we can set to zero)
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+#   concatenated)
+# - Destination register 10 (0b1010) or all zeros
+# - Coprocessor num set to 7
+# - Everything again with the `a` version (to double check parsing).
+# - Accumulator versions without optional argument (to check parsing)
+cx2d p0, r0, r1, r0, #0
+cx2d p0, r0, r1, r0, #384
+cx2d p0, r0, r1, r0, #64
+cx2d p0, r0, r1, r0, #63
+cx2d p7, r0, r1, r0, #0
+cx2d p0, r10, r11, r0, #0
+cx2d p0, r0, r1, APSR_nzcv, #0
+cx2d p0, r0, r1, r9, #0
+cx2da p0, r0, r1, r0, #0
+cx2da p0, r0, r1, r0, #384
+cx2da p0, r0, r1, r0, #64
+cx2da p0, r0, r1, r0, #63
+cx2da p7, r0, r1, r0, #0
+cx2da p0, r10, r11, r0, #0
+cx2da p0, r0, r1, APSR_nzcv, #0
+cx2da p0, r0, r1, r9, #0
+
+# cx3{a} Has arguments in the following form:
+# 111a11101iiinnnnmmmm0pppi0iidddd
+#
+# Variants to test:
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+# - Base (everything we can set to zero)
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+#   concatenated)
+# - Each register 9 (0b1001), APSR_nzcv, or all zeros
+# - Coprocessor num set to 7
+# - Everything again with the `a` version (to double check parsing).
+# - Accumulator versions without optional argument (to check parsing)
+cx3 p0, r0, r0, r0, #0
+cx3 p0, r0, r0, r0, #56
+cx3 p0, r0, r0, r0, #4
+cx3 p0, r0, r0, r0, #3
+cx3 p7, r0, r0, r0, #0
+cx3 p0, APSR_nzcv, r0, r0, #0
+cx3 p0, r9, r0, r0, #0
+cx3 p0, r0, APSR_nzcv, r0, #0
+cx3 p0, r0, r9, r0, #0
+cx3 p0, r0, r0, APSR_nzcv, #0
+cx3 p0, r0, r0, r9, #0
+cx3a p0, r0, r0, r0, #0
+cx3a p0, r0, r0, r0, #56
+cx3a p0, r0, r0, r0, #4
+cx3a p0, r0, r0, r0, #3
+cx3a p7, r0, r0, r0, #0
+cx3a p0, APSR_nzcv, r0, r0, #0
+cx3a p0, r9, r0, r0, #0
+cx3a p0, r0, APSR_nzcv, r0, #0
+cx3a p0, r0, r9, r0, #0
+cx3a p0, r0, r0, APSR_nzcv, #0
+cx3a p0, r0, r0, r9, #0
+
+it ne
+cx3a p0, r0, r0, r0, #0
+
+# cx3d{a} encoding has following form:
+# 111a11101iiinnnnmmmm0pppi1iidddd
+#
+# Variants to test:
+# - Toggle 'a'
+# - immediates that set each set of `i` to ones in turn.
+#   (imm = op1:op2:op3  , which is each group of `i` from left to write
+#   concatenated)
+# - Destination register 10 (0b1010) or all zeros
+# - Source register 9 (0b1001), APSR_nzcv, or all zeros
+
+# No longer allows APSR_nzcv in destination register
+cx3d p0, r0, r1, r0, r0, #0
+cx3d p0, r0, r1, r0, r0, #56
+cx3d p0, r0, r1, r0, r0, #4
+cx3d p0, r0, r1, r0, r0, #3
+cx3d p7, r0, r1, r0, r0, #0
+cx3d p0, r10, r11, r0, r0, #0
+cx3d p0, r0, r1, APSR_nzcv, r0, #0
+cx3d p0, r0, r1, r9, r0, #0
+cx3d p0, r0, r1, r0, APSR_nzcv, #0
+cx3d p0, r0, r1, r0, r9, #0
+cx3da p0, r0, r1, r0, r0, #0
+cx3da p0, r0, r1, r0, r0, #56
+cx3da p0, r0, r1, r0, r0, #4
+cx3da p0, r0, r1, r0, r0, #3
+cx3da p7, r0, r1, r0, r0, #0
+cx3da p0, r10, r11, r0, r0, #0
+cx3da p0, r0, r1, APSR_nzcv, r0, #0
+cx3da p0, r0, r1, r9, r0, #0
+cx3da p0, r0, r1, r0, APSR_nzcv, #0
+cx3da p0, r0, r1, r0, r9, #0
+
+
diff --git a/gas/testsuite/gas/arm/cde-warnings.d b/gas/testsuite/gas/arm/cde-warnings.d
new file mode 100644
index 0000000000000000000000000000000000000000..1421b998d1cd54b8776651919307f273033fe6a2
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-warnings.d
@@ -0,0 +1,5 @@
+#name: Custom Datapath Extension (CDE) Warnings
+#source: cde-warnings.s
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+mve -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+mve -I$srcdir/$subdir
+#error_output: cde-warnings.l
diff --git a/gas/testsuite/gas/arm/cde-warnings.l b/gas/testsuite/gas/arm/cde-warnings.l
new file mode 100644
index 0000000000000000000000000000000000000000..abbd10aed4af14b96f3dc38a166cbe3ce34bd724
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-warnings.l
@@ -0,0 +1,175 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1 p0,r0,#8192'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1a p0,r0,#8192'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1 p0,r0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1a p0,r0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx1 p8,r0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx1a p8,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1 p0,r16,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1a p0,r16,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx1 p0,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx1a p0,r13,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `cx1 p0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1ne p0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1ane p0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx1 p1,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx1a p1,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx1 p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx1a p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1 p0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1a p0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx1 p0,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx1a p0,r15,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1d p0,r0,r1,#8192'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1da p0,r0,r1,#8192'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1d p0,r0,r1,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx1da p0,r0,r1,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx1d p8,r0,r1,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx1da p8,r0,r1,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx1d p0,r16,r17,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx1da p0,r16,r17,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx1d p0,APSR_nzcv,r15,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx1da p0,APSR_nzcv,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx1d p0,r9,r10,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx1da p0,r9,r10,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx1d p0,r13,r14,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx1da p0,r13,r14,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `cx1d p0,r0,r1,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1dne p0,r0,r1,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1dane p0,r0,r1,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx1d p1,r0,r1,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx1da p1,r0,r1,#0'
+[^ :]+:[0-9]+: Error: cx1d requires consecutive destination registers\. -- `cx1d p0,r0,r2,#0'
+[^ :]+:[0-9]+: Error: cx1d requires consecutive destination registers\. -- `cx1da p0,r0,r2,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx1d p0,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx1da p0,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1d p0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx1da p0,r0,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2 p0,r0,r0,#512'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2a p0,r0,r0,#512'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2 p0,r0,r0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2a p0,r0,r0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx2 p8,r0,r0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx2a p8,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2 p0,r16,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2a p0,r16,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2 p0,r0,r16,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2a p0,r0,r16,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2 p0,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2a p0,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2 p0,r0,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2a p0,r0,r13,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `cx2 p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2ne p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2ane p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx2 p1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx2a p1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx2 p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx2a p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2 p0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2a p0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2 p0,r0,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2a p0,r0,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2 p0,r15,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2a p0,r15,r0,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2d p0,r0,r1,r0,#512'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2da p0,r0,r1,r0,#512'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2d p0,r0,r1,r0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx2da p0,r0,r1,r0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx2d p8,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx2da p8,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx2d p0,r16,r17,r0,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx2da p0,r16,r17,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2d p0,r0,r1,r16,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2da p0,r0,r1,r16,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx2d p0,APSR_nzcv,r15,r0,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx2da p0,APSR_nzcv,r15,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx2d p0,r9,r10,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx2da p0,r9,r10,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx2d p0,r12,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx2da p0,r12,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2d p0,r0,r1,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2da p0,r0,r1,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2d p0,r0,r1,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx2da p0,r0,r1,r15,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `cx2d p0,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2dne p0,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2dane p0,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx2d p1,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx2da p1,r0,r1,r0,#0'
+[^ :]+:[0-9]+: Error: cx2d requires consecutive destination registers\. -- `cx2d p0,r0,r2,r0,#0'
+[^ :]+:[0-9]+: Error: cx2d requires consecutive destination registers\. -- `cx2da p0,r0,r2,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx2d p0,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx2da p0,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2d p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx2da p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3 p0,r0,r0,r0,#64'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3a p0,r0,r0,r0,#64'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3 p0,r0,r0,r0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3a p0,r0,r0,r0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx3 p8,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx3a p8,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3 p0,r16,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3a p0,r16,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3 p0,r0,r16,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3a p0,r0,r16,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3 p0,r0,r0,r16,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3a p0,r0,r0,r16,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3 p0,r13,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3a p0,r13,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3 p0,r0,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3a p0,r0,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3 p0,r0,r0,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3a p0,r0,r0,r13,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `cx3 p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3ne p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3ane p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx3 p1,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx3a p1,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx3 p0,r0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx3a p0,r0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3 p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3a p0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3 p0,r15,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3a p0,r15,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3 p0,r0,r15,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3a p0,r0,r15,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3 p0,r0,r0,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3a p0,r0,r0,r15,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3d p0,r0,r1,r0,r0,#64'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3da p0,r0,r1,r0,r0,#64'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3d p0,r0,r1,r0,r0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `cx3da p0,r0,r1,r0,r0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx3d p8,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `cx3da p8,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx3d p0,r16,r17,r0,r0,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx3da p0,r16,r17,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3d p0,r0,r1,r16,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3da p0,r0,r1,r16,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3d p0,r0,r1,r0,r16,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3da p0,r0,r1,r0,r16,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx3d p0,APSR_nzcv,r15,r0,r0,#0'
+[^ :]+:[0-9]+: Error: ARM register expected -- `cx3da p0,APSR_nzcv,r15,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx3d p0,r9,r10,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx3da p0,r9,r10,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx3d p0,r12,r13,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be an even register between r0-r10\. -- `cx3da p0,r12,r13,r0,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3d p0,r0,r1,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3da p0,r0,r1,r13,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3d p0,r0,r1,r0,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3da p0,r0,r1,r0,r13,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3d p0,r0,r1,r15,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3da p0,r0,r1,r15,r0,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3d p0,r0,r1,r0,r15,#0'
+[^ :]+:[0-9]+: Error: Register must be r0-r14 except r13, or APSR_nzcv\. -- `cx3da p0,r0,r1,r0,r15,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `cx3d p0,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3dne p0,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3dane p0,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx3d p1,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `cx3da p1,r0,r1,r0,r0,#0'
+[^ :]+:[0-9]+: Error: cx3d requires consecutive destination registers\. -- `cx3d p0,r0,r2,r0,r0,#0'
+[^ :]+:[0-9]+: Error: cx3d requires consecutive destination registers\. -- `cx3da p0,r0,r2,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx3d p0,r0,r1,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `cx3da p0,r0,r1,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3d p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: syntax error -- `cx3da p0,r0,r0,r0,#0'
diff --git a/gas/testsuite/gas/arm/cde-warnings.s b/gas/testsuite/gas/arm/cde-warnings.s
new file mode 100644
index 0000000000000000000000000000000000000000..8e5759a64e44980481330cdc043c40d2d6bacbc6
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-warnings.s
@@ -0,0 +1,335 @@
+.syntax unified
+# cx1{a}
+# Immediate out of range.
+# Each register out of range.
+# r13 => constrained unpredictable
+# itblock => constrained unpredictable
+# Error given when using coprocessor number not enabled on command line.
+# Too many arguments
+# Too little arguments
+# r15 instead of APSR_nzcv
+
+cx1 p0, r0, #8192
+cx1a p0, r0, #8192
+cx1 p0, r0, #-1
+cx1a p0, r0, #-1
+
+cx1 p8, r0, #0
+cx1a p8, r0, #0
+
+cx1 p0, r16, #0
+cx1a p0, r16, #0
+
+cx1 p0, r13, #0
+cx1a p0, r13, #0
+
+ittt ne
+cx1 p0, r0, #0
+cx1ne p0, r0, #0
+cx1ane p0, r0, #0
+
+cx1 p1, r0, #0
+cx1a p1, r0, #0
+
+cx1 p0, r0, r0, #0
+cx1a p0, r0, r0, #0
+
+cx1 p0, #0
+cx1a p0, #0
+
+cx1 p0, r15, #0
+cx1a p0, r15, #0
+
+# cx1d{a}
+# Immediate out of range.
+# Each register out of range.
+# APSR_nzcv disallowed as destination register.
+# rd<odd> => constrained unpredictable
+# r< N > 10 > => constrained unpredictable
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Disallow non-incrementing values in destination.
+# Too many arguments
+# Too little arguments
+
+cx1d p0, r0, r1, #8192
+cx1da p0, r0, r1, #8192
+cx1d p0, r0, r1, #-1
+cx1da p0, r0, r1, #-1
+
+cx1d p8, r0, r1, #0
+cx1da p8, r0, r1, #0
+
+cx1d p0, r16, r17, #0
+cx1da p0, r16, r17, #0
+
+cx1d p0, APSR_nzcv, r15, #0
+cx1da p0, APSR_nzcv, r15, #0
+
+cx1d p0, r9, r10, #0
+cx1da p0, r9, r10, #0
+
+cx1d p0, r13, r14, #0
+cx1da p0, r13, r14, #0
+
+ittt ne
+cx1d p0, r0, r1, #0
+cx1dne p0, r0, r1, #0
+cx1dane p0, r0, r1, #0
+
+cx1d p1, r0, r1, #0
+cx1da p1, r0, r1, #0
+
+cx1d p0, r0, r2, #0
+cx1da p0, r0, r2, #0
+
+cx1d p0, r0, r1, r0, #0
+cx1da p0, r0, r1, r0, #0
+
+cx1d p0, r0, #0
+cx1da p0, r0, #0
+
+# cx2{a}
+# Immediate out of range.
+# Each register out of range.
+# rd13 => constrained unpredictable
+# rn13 => constrained unpredictable
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Too many arguments
+# Too little arguments.
+# r15 instead of APSR_nzcv
+
+cx2 p0, r0, r0, #512
+cx2a p0, r0, r0, #512
+cx2 p0, r0, r0, #-1
+cx2a p0, r0, r0, #-1
+
+cx2 p8, r0, r0, #0
+cx2a p8, r0, r0, #0
+
+cx2 p0, r16, r0, #0
+cx2a p0, r16, r0, #0
+
+cx2 p0, r0, r16, #0
+cx2a p0, r0, r16, #0
+
+cx2 p0, r13, r0, #0
+cx2a p0, r13, r0, #0
+
+cx2 p0, r0, r13, #0
+cx2a p0, r0, r13, #0
+
+ittt ne
+cx2 p0, r0, r0, #0
+cx2ne p0, r0, r0, #0
+cx2ane p0, r0, r0, #0
+
+cx2 p1, r0, r0, #0
+cx2a p1, r0, r0, #0
+
+cx2 p0, r0, r0, r0, #0
+cx2a p0, r0, r0, r0, #0
+
+cx2 p0, r0, #0
+cx2a p0, r0, #0
+
+cx2 p0, r0, r15, #0
+cx2a p0, r0, r15, #0
+
+cx2 p0, r15, r0, #0
+cx2a p0, r15, r0, #0
+
+# cx2d{a}
+# Immediate out of range.
+# Each register out of range.
+# APSR_nzcv disallowed as destination register.
+# rd<odd> => constrained unpredictable
+# rd< N > 10 > => constrained unpredictable
+# rn13 => constrained unpredictable
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Disallow non-incrementing values in destination.
+# Too many arguments
+# Too little arguments
+cx2d p0, r0, r1, r0, #512
+cx2da p0, r0, r1, r0, #512
+cx2d p0, r0, r1, r0, #-1
+cx2da p0, r0, r1, r0, #-1
+
+cx2d p8, r0, r1, r0, #0
+cx2da p8, r0, r1, r0, #0
+
+cx2d p0, r16, r17, r0, #0
+cx2da p0, r16, r17, r0, #0
+
+cx2d p0, r0, r1, r16, #0
+cx2da p0, r0, r1, r16, #0
+
+cx2d p0, APSR_nzcv, r15, r0, #0
+cx2da p0, APSR_nzcv, r15, r0, #0
+
+cx2d p0, r9, r10, r0, #0
+cx2da p0, r9, r10, r0, #0
+
+cx2d p0, r12, r13, r0, #0
+cx2da p0, r12, r13, r0, #0
+
+cx2d p0, r0, r1, r13, #0
+cx2da p0, r0, r1, r13, #0
+
+cx2d p0, r0, r1, r15, #0
+cx2da p0, r0, r1, r15, #0
+
+ittt ne
+cx2d p0, r0, r1, r0, #0
+cx2dne p0, r0, r1, r0, #0
+cx2dane p0, r0, r1, r0, #0
+
+cx2d p1, r0, r1, r0, #0
+cx2da p1, r0, r1, r0, #0
+
+cx2d p0, r0, r2, r0, #0
+cx2da p0, r0, r2, r0, #0
+
+cx2d p0, r0, r1, r0, r0, #0
+cx2da p0, r0, r1, r0, r0, #0
+
+cx2d p0, r0, r0, #0
+cx2da p0, r0, r0, #0
+
+# cx2{a}
+# Immediate out of range.
+# Each register out of range.
+# rd13 => constrained unpredictable
+# rn13 => constrained unpredictable
+# rm13 => constrained unpredictable
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Too many arguments
+# Too little arguments.
+# r15 instead of APSR_nzcv
+
+cx3 p0, r0, r0, r0, #64
+cx3a p0, r0, r0, r0, #64
+cx3 p0, r0, r0, r0, #-1
+cx3a p0, r0, r0, r0, #-1
+
+cx3 p8, r0, r0, r0, #0
+cx3a p8, r0, r0, r0, #0
+
+cx3 p0, r16, r0, r0, #0
+cx3a p0, r16, r0, r0, #0
+
+cx3 p0, r0, r16, r0, #0
+cx3a p0, r0, r16, r0, #0
+
+cx3 p0, r0, r0, r16, #0
+cx3a p0, r0, r0, r16, #0
+
+cx3 p0, r13, r0, r0, #0
+cx3a p0, r13, r0, r0, #0
+
+cx3 p0, r0, r13, r0, #0
+cx3a p0, r0, r13, r0, #0
+
+cx3 p0, r0, r0, r13, #0
+cx3a p0, r0, r0, r13, #0
+
+ittt ne
+cx3 p0, r0, r0, r0, #0
+cx3ne p0, r0, r0, r0, #0
+cx3ane p0, r0, r0, r0, #0
+
+cx3 p1, r0, r0, r0, #0
+cx3a p1, r0, r0, r0, #0
+
+cx3 p0, r0, r0, r0, r0, #0
+cx3a p0, r0, r0, r0, r0, #0
+
+cx3 p0, r0, r0, #0
+cx3a p0, r0, r0, #0
+
+cx3 p0, r15, r0, r0, #0
+cx3a p0, r15, r0, r0, #0
+
+cx3 p0, r0, r15, r0, #0
+cx3a p0, r0, r15, r0, #0
+
+cx3 p0, r0, r0, r15, #0
+cx3a p0, r0, r0, r15, #0
+
+# cx3d{a}
+# Immediate out of range.
+# Each register out of range.
+# APSR_nzcv disallowed as destination register.
+# rd<odd> => constrained unpredictable
+# rd< N > 10 > => constrained unpredictable
+# rn13 => constrained unpredictable
+# rm13 => constrained unpredictable
+# rn15 disallowed (pattern matches APSR_nzcv)
+# rm15 disallowed (pattern matches APSR_nzcv)
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Disallow non-incrementing values in destination.
+# Too many arguments
+# Too little arguments
+cx3d p0, r0, r1, r0, r0, #64
+cx3da p0, r0, r1, r0, r0, #64
+cx3d p0, r0, r1, r0, r0, #-1
+cx3da p0, r0, r1, r0, r0, #-1
+
+cx3d p8, r0, r1, r0, r0, #0
+cx3da p8, r0, r1, r0, r0, #0
+
+cx3d p0, r16, r17, r0, r0, #0
+cx3da p0, r16, r17, r0, r0, #0
+
+cx3d p0, r0, r1, r16, r0, #0
+cx3da p0, r0, r1, r16, r0, #0
+
+cx3d p0, r0, r1, r0, r16, #0
+cx3da p0, r0, r1, r0, r16, #0
+
+cx3d p0, APSR_nzcv, r15, r0, r0, #0
+cx3da p0, APSR_nzcv, r15, r0, r0, #0
+
+cx3d p0, r9, r10, r0, r0, #0
+cx3da p0, r9, r10, r0, r0, #0
+
+cx3d p0, r12, r13, r0, r0, #0
+cx3da p0, r12, r13, r0, r0, #0
+
+cx3d p0, r0, r1, r13, r0, #0
+cx3da p0, r0, r1, r13, r0, #0
+
+cx3d p0, r0, r1, r0, r13, #0
+cx3da p0, r0, r1, r0, r13, #0
+
+cx3d p0, r0, r1, r15, r0, #0
+cx3da p0, r0, r1, r15, r0, #0
+
+cx3d p0, r0, r1, r0, r15, #0
+cx3da p0, r0, r1, r0, r15, #0
+
+ittt ne
+cx3d p0, r0, r1, r0, r0, #0
+cx3dne p0, r0, r1, r0, r0, #0
+cx3dane p0, r0, r1, r0, r0, #0
+
+cx3d p1, r0, r1, r0, r0, #0
+cx3da p1, r0, r1, r0, r0, #0
+
+cx3d p0, r0, r2, r0, r0, #0
+cx3da p0, r0, r2, r0, r0, #0
+
+cx3d p0, r0, r1, r0, r0, r0, #0
+cx3da p0, r0, r1, r0, r0, r0, #0
+
+cx3d p0, r0, r0, r0, #0
+cx3da p0, r0, r0, r0, #0
diff --git a/gas/testsuite/gas/arm/cde.d b/gas/testsuite/gas/arm/cde.d
new file mode 100644
index 0000000000000000000000000000000000000000..34de201513b1f89b29397d0663b184ca7d1cdf16
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde.d
@@ -0,0 +1,119 @@
+#name: Custom Datapath Extension (CDE)
+#source: cde.s
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp7+mve.fp -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp7+mve -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+mve.fp -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+mve -I$srcdir/$subdir
+#objdump: -M force-thumb -dr --show-raw-insn -marmv8.1-m.main -M coproc0=cde -M coproc7=cde
+#...
+00000000 <\.text>:
+ *[0-9a-f]+:	ee00 0000 	cx1	p0, r0, #0
+ *[0-9a-f]+:	ee3f 0000 	cx1	p0, r0, #8064
+ *[0-9a-f]+:	ee00 0080 	cx1	p0, r0, #64
+ *[0-9a-f]+:	ee00 003f 	cx1	p0, r0, #63
+ *[0-9a-f]+:	ee00 0700 	cx1	p7, r0, #0
+ *[0-9a-f]+:	ee00 f000 	cx1	p0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee00 9000 	cx1	p0, r9, #0
+ *[0-9a-f]+:	fe00 0000 	cx1a	p0, r0, #0
+ *[0-9a-f]+:	fe3f 0000 	cx1a	p0, r0, #8064
+ *[0-9a-f]+:	fe00 0080 	cx1a	p0, r0, #64
+ *[0-9a-f]+:	fe00 003f 	cx1a	p0, r0, #63
+ *[0-9a-f]+:	fe00 0700 	cx1a	p7, r0, #0
+ *[0-9a-f]+:	fe00 f000 	cx1a	p0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe00 9000 	cx1a	p0, r9, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe00 0000 	cx1a	p0, r0, #0
+ *[0-9a-f]+:	ee00 0040 	cx1d	p0, r0, r1, #0
+ *[0-9a-f]+:	ee3f 0040 	cx1d	p0, r0, r1, #8064
+ *[0-9a-f]+:	ee00 00c0 	cx1d	p0, r0, r1, #64
+ *[0-9a-f]+:	ee00 007f 	cx1d	p0, r0, r1, #63
+ *[0-9a-f]+:	ee00 0740 	cx1d	p7, r0, r1, #0
+ *[0-9a-f]+:	ee00 a040 	cx1d	p0, sl, fp, #0
+ *[0-9a-f]+:	fe00 0040 	cx1da	p0, r0, r1, #0
+ *[0-9a-f]+:	fe3f 0040 	cx1da	p0, r0, r1, #8064
+ *[0-9a-f]+:	fe00 00c0 	cx1da	p0, r0, r1, #64
+ *[0-9a-f]+:	fe00 007f 	cx1da	p0, r0, r1, #63
+ *[0-9a-f]+:	fe00 0740 	cx1da	p7, r0, r1, #0
+ *[0-9a-f]+:	fe00 a040 	cx1da	p0, sl, fp, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe00 0040 	cx1da	p0, r0, r1, #0
+ *[0-9a-f]+:	ee40 0000 	cx2	p0, r0, r0, #0
+ *[0-9a-f]+:	ee70 0000 	cx2	p0, r0, r0, #384
+ *[0-9a-f]+:	ee40 0080 	cx2	p0, r0, r0, #64
+ *[0-9a-f]+:	ee40 003f 	cx2	p0, r0, r0, #63
+ *[0-9a-f]+:	ee40 0700 	cx2	p7, r0, r0, #0
+ *[0-9a-f]+:	ee40 f000 	cx2	p0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	ee40 9000 	cx2	p0, r9, r0, #0
+ *[0-9a-f]+:	ee4f 0000 	cx2	p0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee49 0000 	cx2	p0, r0, r9, #0
+ *[0-9a-f]+:	fe40 0000 	cx2a	p0, r0, r0, #0
+ *[0-9a-f]+:	fe70 0000 	cx2a	p0, r0, r0, #384
+ *[0-9a-f]+:	fe40 0080 	cx2a	p0, r0, r0, #64
+ *[0-9a-f]+:	fe40 003f 	cx2a	p0, r0, r0, #63
+ *[0-9a-f]+:	fe40 0700 	cx2a	p7, r0, r0, #0
+ *[0-9a-f]+:	fe40 f000 	cx2a	p0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	fe40 9000 	cx2a	p0, r9, r0, #0
+ *[0-9a-f]+:	fe4f 0000 	cx2a	p0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe49 0000 	cx2a	p0, r0, r9, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe40 0000 	cx2a	p0, r0, r0, #0
+ *[0-9a-f]+:	ee40 0040 	cx2d	p0, r0, r1, r0, #0
+ *[0-9a-f]+:	ee70 0040 	cx2d	p0, r0, r1, r0, #384
+ *[0-9a-f]+:	ee40 00c0 	cx2d	p0, r0, r1, r0, #64
+ *[0-9a-f]+:	ee40 007f 	cx2d	p0, r0, r1, r0, #63
+ *[0-9a-f]+:	ee40 0740 	cx2d	p7, r0, r1, r0, #0
+ *[0-9a-f]+:	ee40 a040 	cx2d	p0, sl, fp, r0, #0
+ *[0-9a-f]+:	ee4f 0040 	cx2d	p0, r0, r1, APSR_nzcv, #0
+ *[0-9a-f]+:	ee49 0040 	cx2d	p0, r0, r1, r9, #0
+ *[0-9a-f]+:	fe40 0040 	cx2da	p0, r0, r1, r0, #0
+ *[0-9a-f]+:	fe70 0040 	cx2da	p0, r0, r1, r0, #384
+ *[0-9a-f]+:	fe40 00c0 	cx2da	p0, r0, r1, r0, #64
+ *[0-9a-f]+:	fe40 007f 	cx2da	p0, r0, r1, r0, #63
+ *[0-9a-f]+:	fe40 0740 	cx2da	p7, r0, r1, r0, #0
+ *[0-9a-f]+:	fe40 a040 	cx2da	p0, sl, fp, r0, #0
+ *[0-9a-f]+:	fe4f 0040 	cx2da	p0, r0, r1, APSR_nzcv, #0
+ *[0-9a-f]+:	fe49 0040 	cx2da	p0, r0, r1, r9, #0
+ *[0-9a-f]+:	ee80 0000 	cx3	p0, r0, r0, r0, #0
+ *[0-9a-f]+:	eef0 0000 	cx3	p0, r0, r0, r0, #56
+ *[0-9a-f]+:	ee80 0080 	cx3	p0, r0, r0, r0, #4
+ *[0-9a-f]+:	ee80 0030 	cx3	p0, r0, r0, r0, #3
+ *[0-9a-f]+:	ee80 0700 	cx3	p7, r0, r0, r0, #0
+ *[0-9a-f]+:	ee80 000f 	cx3	p0, APSR_nzcv, r0, r0, #0
+ *[0-9a-f]+:	ee80 0009 	cx3	p0, r9, r0, r0, #0
+ *[0-9a-f]+:	ee8f 0000 	cx3	p0, r0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	ee89 0000 	cx3	p0, r0, r9, r0, #0
+ *[0-9a-f]+:	ee80 f000 	cx3	p0, r0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee80 9000 	cx3	p0, r0, r0, r9, #0
+ *[0-9a-f]+:	fe80 0000 	cx3a	p0, r0, r0, r0, #0
+ *[0-9a-f]+:	fef0 0000 	cx3a	p0, r0, r0, r0, #56
+ *[0-9a-f]+:	fe80 0080 	cx3a	p0, r0, r0, r0, #4
+ *[0-9a-f]+:	fe80 0030 	cx3a	p0, r0, r0, r0, #3
+ *[0-9a-f]+:	fe80 0700 	cx3a	p7, r0, r0, r0, #0
+ *[0-9a-f]+:	fe80 000f 	cx3a	p0, APSR_nzcv, r0, r0, #0
+ *[0-9a-f]+:	fe80 0009 	cx3a	p0, r9, r0, r0, #0
+ *[0-9a-f]+:	fe8f 0000 	cx3a	p0, r0, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	fe89 0000 	cx3a	p0, r0, r9, r0, #0
+ *[0-9a-f]+:	fe80 f000 	cx3a	p0, r0, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe80 9000 	cx3a	p0, r0, r0, r9, #0
+ *[0-9a-f]+:	bf18      	it	ne
+ *[0-9a-f]+:	fe80 0000 	cx3a	p0, r0, r0, r0, #0
+ *[0-9a-f]+:	ee80 0040 	cx3d	p0, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	eef0 0040 	cx3d	p0, r0, r1, r0, r0, #56
+ *[0-9a-f]+:	ee80 00c0 	cx3d	p0, r0, r1, r0, r0, #4
+ *[0-9a-f]+:	ee80 0070 	cx3d	p0, r0, r1, r0, r0, #3
+ *[0-9a-f]+:	ee80 0740 	cx3d	p7, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	ee80 004a 	cx3d	p0, sl, fp, r0, r0, #0
+ *[0-9a-f]+:	ee8f 0040 	cx3d	p0, r0, r1, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	ee89 0040 	cx3d	p0, r0, r1, r9, r0, #0
+ *[0-9a-f]+:	ee80 f040 	cx3d	p0, r0, r1, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	ee80 9040 	cx3d	p0, r0, r1, r0, r9, #0
+ *[0-9a-f]+:	fe80 0040 	cx3da	p0, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	fef0 0040 	cx3da	p0, r0, r1, r0, r0, #56
+ *[0-9a-f]+:	fe80 00c0 	cx3da	p0, r0, r1, r0, r0, #4
+ *[0-9a-f]+:	fe80 0070 	cx3da	p0, r0, r1, r0, r0, #3
+ *[0-9a-f]+:	fe80 0740 	cx3da	p7, r0, r1, r0, r0, #0
+ *[0-9a-f]+:	fe80 004a 	cx3da	p0, sl, fp, r0, r0, #0
+ *[0-9a-f]+:	fe8f 0040 	cx3da	p0, r0, r1, APSR_nzcv, r0, #0
+ *[0-9a-f]+:	fe89 0040 	cx3da	p0, r0, r1, r9, r0, #0
+ *[0-9a-f]+:	fe80 f040 	cx3da	p0, r0, r1, r0, APSR_nzcv, #0
+ *[0-9a-f]+:	fe80 9040 	cx3da	p0, r0, r1, r0, r9, #0
diff --git a/gas/testsuite/gas/arm/cde.s b/gas/testsuite/gas/arm/cde.s
new file mode 100644
index 0000000000000000000000000000000000000000..1ee18704941aca9069777511c0feaf2004b592b7
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde.s
@@ -0,0 +1,3 @@
+.syntax unified
+
+.include "cde-scalar.s"
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 6d8c3d00861f2430d2c8478c71f165dc4e625665..979bd20885812504869d39ce374db38fbce429ba 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -79,6 +79,15 @@
 #define ARM_EXT2_CRC	     0x00080000	/* ARMv8 CRC32 */
 #define ARM_EXT2_MVE	     0x00100000	/* MVE Integer extension.	   */
 #define ARM_EXT2_MVE_FP	     0x00200000	/* MVE Floating Point extension.   */
+#define ARM_EXT2_CDE	     0x00400000 /* Custom Datapath Extension.	   */
+#define ARM_EXT2_CDE0	     0x00800000 /* Using CDE coproc 0.	   */
+#define ARM_EXT2_CDE1	     0x01000000 /* Using CDE coproc 1.	   */
+#define ARM_EXT2_CDE2	     0x02000000 /* Using CDE coproc 2.	   */
+#define ARM_EXT2_CDE3	     0x04000000 /* Using CDE coproc 3.	   */
+#define ARM_EXT2_CDE4	     0x08000000 /* Using CDE coproc 4.	   */
+#define ARM_EXT2_CDE5	     0x10000000 /* Using CDE coproc 5.	   */
+#define ARM_EXT2_CDE6	     0x20000000 /* Using CDE coproc 6.	   */
+#define ARM_EXT2_CDE7	     0x40000000 /* Using CDE coproc 7.	   */
 
 /* Co-processor space extensions.  */
 #define ARM_CEXT_XSCALE	     0x00000001	/* Allow MIA etc.	 	   */
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index be2a93253bb5673579780f2053161e281e64cb04..2a29887f1695435d45c1d7bb4a917212588d4315 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -355,6 +355,16 @@ struct opcode32
   const char *  assembler;	/* How to disassemble this insn.  */
 };
 
+struct cdeopcode32
+{
+  arm_feature_set arch;		/* Architecture defining this insn.  */
+  uint8_t coproc_shift;		/* coproc is this far into op.  */
+  uint16_t coproc_mask;		/* Length of coproc field in op.  */
+  unsigned long value;		/* If arch is 0 then value is a sentinel.  */
+  unsigned long mask;		/* Recognise insn if (op & mask) == value.  */
+  const char *  assembler;	/* How to disassemble this insn.  */
+};
+
 /* MVE opcodes.  */
 
 struct mopcode32
@@ -460,6 +470,54 @@ enum opcode_sentinel_enum
 
 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
 
+/* print_insn_cde recognizes the following format control codes:
+
+   %%			%
+
+   %a			print 'a' iff bit 28 is 1
+   %p			print bits 8-10 as coprocessor
+   %<bitfield>d		print as decimal
+   %<bitfield>r		print as an ARM register
+   %<bitfield>n		print as an ARM register but r15 is APSR_nzcv
+   %<bitfield>T		print as an ARM register + 1
+   %<bitfield>R		as %r but r13 is UNPREDICTABLE
+   %<bitfield>S		as %r but rX where X > 10 is UNPREDICTABLE
+   %j			print immediate taken from bits (16..21,7,0..5)
+   %k			print immediate taken from bits (20..21,7,0..5).
+   %l			print immediate taken from bits (20..22,7,4..5).  */
+
+/* At the moment there is only one valid position for the coprocessor number,
+   and hence that's encoded in the macro below.  */
+#define CDE_OPCODE(ARCH, VALUE, MASK, ASM) \
+  { ARCH, 8, 7, VALUE, MASK, ASM }
+static const struct cdeopcode32 cde_opcodes[] =
+{
+  /* Custom Datapath Extension instructions.  */
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xee000000, 0xefc00840,
+	      "cx1%a\t%p, %12-15n, #%0-5,7,16-21d"),
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xee000040, 0xefc00840,
+	      "cx1d%a\t%p, %12-15S, %12-15T, #%0-5,7,16-21d"),
+
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xee400000, 0xefc00840,
+	      "cx2%a\t%p, %12-15n, %16-19n, #%0-5,7,20-21d"),
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xee400040, 0xefc00840,
+	      "cx2d%a\t%p, %12-15S, %12-15T, %16-19n, #%0-5,7,20-21d"),
+
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xee800000, 0xef800840,
+	      "cx3%a\t%p, %0-3n, %16-19n, %12-15n, #%4-5,7,20-22d"),
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xee800040, 0xef800840,
+	     "cx3d%a\t%p, %0-3S, %0-3T, %16-19n, %12-15n, #%4-5,7,20-22d"),
+
+  CDE_OPCODE (ARM_FEATURE_CORE_LOW (0), 0, 0, 0)
+
+};
+
 static const struct sopcode32 coprocessor_opcodes[] =
 {
   /* XScale instructions.  */
@@ -5115,7 +5173,8 @@ static const arm_regname regnames[] =
   { "reg-names-atpcs", N_("Select register names used in the ATPCS"),
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
   { "reg-names-special-atpcs", N_("Select special register names used in the ATPCS"),
-    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
+    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
+  { "coproc<N>=(cde|generic)", N_("Enable CDE extensions for coprocessor N space"), { NULL } }
 };
 
 static const char *const iwmmxt_wwnames[] =
@@ -5195,6 +5254,7 @@ static unsigned int regname_selected = 1;
 #define arm_regnames      regnames[regname_selected].reg_names
 
 static bfd_boolean force_thumb = FALSE;
+static uint16_t cde_coprocs = 0;
 
 /* Current IT instruction state.  This contains the same state as the IT
    bits in the CPSR.  */
@@ -8786,6 +8846,121 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
   return (signed long) offset;
 }
 
+
+/* Print one cde instruction on INFO->STREAM.
+   Return TRUE if the instuction matched, FALSE if this is not a
+   recognised cde instruction.  */
+static bfd_boolean
+print_insn_cde (struct disassemble_info *info, long given, bfd_boolean thumb)
+{
+  const struct cdeopcode32 *insn;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  if (thumb)
+  {
+    /* Manually extract the coprocessor code from a known point.
+       This position is the same across all CDE instructions.  */
+    for (insn = cde_opcodes; insn->assembler; insn++)
+    {
+      uint16_t coproc = (given >> insn->coproc_shift) & insn->coproc_mask;
+      uint16_t coproc_mask = 1 << coproc;
+      if (! (coproc_mask & cde_coprocs))
+	continue;
+
+      if ((given & insn->mask) == insn->value)
+      {
+	bfd_boolean is_unpredictable = FALSE;
+	const char *c;
+
+	for (c = insn->assembler; *c; c++)
+	{
+	  if (*c == '%')
+	  {
+	    switch (*++c)
+	    {
+	      case '%':
+		func (stream, "%%");
+		break;
+
+	      case '0': case '1': case '2': case '3': case '4':
+	      case '5': case '6': case '7': case '8': case '9':
+	      {
+		int width;
+		unsigned long value;
+
+		c = arm_decode_bitfield (c, given, &value, &width);
+
+		switch (*c)
+		{
+		  case 'S':
+		    if (value > 10)
+		      is_unpredictable = TRUE;
+		    /* Fall through.  */
+		  case 'R':
+		    if (value == 13)
+		      is_unpredictable = TRUE;
+		    /* Fall through.  */
+		  case 'r':
+		    func (stream, "%s", arm_regnames[value]);
+		    break;
+
+		  case 'n':
+		    if (value == 15)
+		      func (stream, "%s", "APSR_nzcv");
+		    else
+		      func (stream, "%s", arm_regnames[value]);
+		    break;
+
+		  case 'T':
+		    func (stream, "%s", arm_regnames[value + 1]);
+		    break;
+
+		  case 'd':
+		    func (stream, "%ld", value);
+		    break;
+
+		default:
+		  abort ();
+		}
+	      }
+	    break;
+
+	    case 'p':
+	      {
+		uint8_t proc_number = (given >> 8) & 0x7;
+		func (stream, "p%u", proc_number);
+		break;
+	      }
+
+	    case 'a':
+	      {
+		uint8_t a_offset = 28;
+		if (given & (1 << a_offset))
+		  func (stream, "a");
+		break;
+	      }
+	  default:
+	    abort ();
+	  }
+	}
+	else
+	  func (stream, "%c", *c);
+      }
+
+      if (is_unpredictable)
+	func (stream, UNPREDICTABLE_INSTRUCTION);
+
+      return TRUE;
+      }
+    }
+    return FALSE;
+  }
+  else
+    return FALSE;
+}
+
+
 /* Print one neon instruction on INFO->STREAM.
    Return TRUE if the instuction matched, FALSE if this is not a
    recognised neon instruction.  */
@@ -10587,6 +10762,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
   if (is_mve && print_insn_mve (info, given))
     return;
 
+  if (print_insn_cde (info, given, TRUE))
+    return;
+
   if (print_insn_generic_coprocessor (pc, info, given, TRUE))
     return;
 
@@ -11356,6 +11534,36 @@ parse_arm_disassembler_options (const char *options)
 	force_thumb = 1;
       else if (CONST_STRNEQ (opt, "no-force-thumb"))
 	force_thumb = 0;
+      else if (CONST_STRNEQ (opt, "coproc"))
+	{
+	  const char *procptr = opt + sizeof ("coproc") - 1;
+	  char *endptr;
+	  uint8_t coproc_number = strtol (procptr, &endptr, 10);
+	  if (endptr != procptr + 1 || coproc_number > 7)
+	    {
+	      opcodes_error_handler (_("cde coprocessor not between 0-7: %s"),
+				     opt);
+	      continue;
+	    }
+	  if (*endptr != '=')
+	    {
+	      opcodes_error_handler (_("coproc must have an argument: %s"),
+				     opt);
+	      continue;
+	    }
+	  endptr += 1;
+	  if (CONST_STRNEQ (endptr, "generic"))
+	    cde_coprocs &= ~(1 << coproc_number);
+	  else if (CONST_STRNEQ (endptr, "cde")
+		   || CONST_STRNEQ (endptr, "CDE"))
+	    cde_coprocs |= (1 << coproc_number);
+	  else
+	    {
+	      opcodes_error_handler (
+		  _("coprocN argument takes options \"generic\","
+		    " \"cde\", or \"CDE\": %s"), opt);
+	    }
+	}
       else
 	/* xgettext: c-format */
 	opcodes_error_handler (_("unrecognised disassembler option: %s"), opt);


[-- Attachment #2: cde0.patch.gz --]
[-- Type: application/gzip, Size: 11644 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Patch 2/2] [binutils][arm] Implement Custom Datapath Extensions for MVE
  2020-02-10 11:37 [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Matthew Malcomson
  2020-02-10 11:37 ` [Patch 1/2] [binutils][arm] arm support for ARMv8.m " Matthew Malcomson
@ 2020-02-10 11:37 ` Matthew Malcomson
  2020-02-10 15:11 ` [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Nick Clifton
  2 siblings, 0 replies; 7+ messages in thread
From: Matthew Malcomson @ 2020-02-10 11:37 UTC (permalink / raw)
  To: binutils; +Cc: Richard.Earnshaw, nickc, nd, ramana.radhakrishnan

[-- Attachment #1: Type: text/plain, Size: 77264 bytes --]

Here we implement the custom datapath extensions for MVE.

This required the following changes:

- Adding a new register argument type (that takes either an MVE vector or
  a Neon S or D register).
- Adding two new immediate operands types (0-127 and 0-4095).
- Using the Neon type machinery to distinguish between instruction
  types.  This required the introduction of new neon shapes to account
  for the coprocessor operands to these instructions.
- Adding a new disassembly character to `print_insn_cde` to handle the
  new register types.

Specification can be found at
https://developer.arm.com/docs/ddi0607/latest

Successfully regression tested on arm-none-eabi, and arm-wince-pe.

gas/ChangeLog:

2020-02-10  Matthew Malcomson  <matthew.malcomson@arm.com>

	* config/tc-arm.c (NEON_MAX_TYPE_ELS): Increment to account for
	instructions that can have 5 arguments.
	(enum operand_parse_code): Add new operands.
	(parse_operands): Account for new operands.
	(S5): New macro.
	(enum neon_shape_el): Introduce P suffixes for coprocessor.
	(neon_select_shape): Account for P suffix.
	(LOW1): Move macro to global position.
	(HI4): Move macro to global position.
	(vcx_assign_vec_d): New.
	(vcx_assign_vec_m): New.
	(vcx_assign_vec_n): New.
	(enum vcx_reg_type): New.
	(vcx_get_reg_type): New.
	(vcx_size_pos): New.
	(vcx_vec_pos): New.
	(vcx_handle_shape): New.
	(vcx_ensure_register_in_range): New.
	(vcx_handle_register_arguments): New.
	(vcx_handle_insn_block): New.
	(vcx_handle_common_checks): New.
	(do_vcx1): New.
	(do_vcx2): New.
	(do_vcx3): New.
	* testsuite/gas/arm/cde-missing-fp.d: New test.
	* testsuite/gas/arm/cde-missing-fp.l: New test.
	* testsuite/gas/arm/cde-missing-mve.d: New test.
	* testsuite/gas/arm/cde-missing-mve.l: New test.
	* testsuite/gas/arm/cde-mve-or-neon.d: New test.
	* testsuite/gas/arm/cde-mve-or-neon.s: New test.
	* testsuite/gas/arm/cde-mve.s: New test.
	* testsuite/gas/arm/cde-warnings.l:
	* testsuite/gas/arm/cde-warnings.s:
	* testsuite/gas/arm/cde.d:
	* testsuite/gas/arm/cde.s:

opcodes/ChangeLog:

2020-02-10  Matthew Malcomson  <matthew.malcomson@arm.com>

	* arm-dis.c (print_insn_cde): Define 'V' parse character.
	(cde_opcodes): Add VCX* instructions.



###############     Attachment also inlined for ease of reply    ###############


diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b6a1867d28bfefdfd8035a7f48e287b8cb58ba4e..823a4b90755ee52163152e348d3d825301a6e720 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -339,6 +339,11 @@ static const arm_feature_set mve_ext =
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE);
 static const arm_feature_set mve_fp_ext =
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE_FP);
+/* Note: This has more than one bit set, which means using it with
+   mark_feature_used (which returns if *any* of the bits are set in the current
+   cpu variant) can give surprising results.  */
+static const arm_feature_set armv8m_fp =
+  ARM_FEATURE_COPROC (FPU_VFP_V5_SP_D16);
 #ifdef OBJ_ELF
 static const arm_feature_set fpu_vfp_fp16 =
   ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
@@ -478,7 +483,7 @@ struct neon_type_el
   unsigned size;
 };
 
-#define NEON_MAX_TYPE_ELS 4
+#define NEON_MAX_TYPE_ELS 5
 
 struct neon_type
 {
@@ -7092,6 +7097,7 @@ enum operand_parse_code
   OP_RIWG,	/* iWMMXt wCG register */
   OP_RXA,	/* XScale accumulator register */
 
+  OP_RNSDMQ,	/* Neon single, double or MVE vector register */
   OP_RNSDQMQ,	/* Neon single, double or quad register or MVE vector register
 		 */
   OP_RNSDQMQR,	/* Neon single, double or quad register, MVE vector register or
@@ -7160,8 +7166,10 @@ enum operand_parse_code
   OP_I63s,	/*		 -64 .. 63 */
   OP_I64,	/*		   1 .. 64 */
   OP_I64z,	/*		   0 .. 64 */
+  OP_I127,	/*		   0 .. 127 */
   OP_I255,	/*		   0 .. 255 */
   OP_I511,	/*		   0 .. 511 */
+  OP_I4095,	/*		   0 .. 4095 */
   OP_I8191,	/*		   0 .. 8191 */
   OP_I4b,	/* immediate, prefix optional, 1 .. 4 */
   OP_I7b,	/*			       0 .. 7 */
@@ -7480,6 +7488,12 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_RVSD_COND:
 	  po_reg_or_goto (REG_TYPE_VFSD, try_cond);
 	  break;
+	case OP_RNSDMQ:
+	  po_reg_or_goto (REG_TYPE_NSD, try_mq2);
+	  break;
+	  try_mq2:
+	  po_reg_or_fail (REG_TYPE_MQ);
+	  break;
 	case OP_oRNSDQ:
 	case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ);    break;
 	case OP_RNSDQMQR:
@@ -7676,8 +7690,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_I63:	 po_imm_or_fail (  0,     63, FALSE);   break;
 	case OP_I64:	 po_imm_or_fail (  1,     64, FALSE);   break;
 	case OP_I64z:	 po_imm_or_fail (  0,     64, FALSE);   break;
+	case OP_I127:	 po_imm_or_fail (  0,	 127, FALSE);	break;
 	case OP_I255:	 po_imm_or_fail (  0,	 255, FALSE);	break;
 	case OP_I511:	 po_imm_or_fail (  0,	 511, FALSE);	break;
+	case OP_I4095:	 po_imm_or_fail (  0,	 4095, FALSE);	break;
 	case OP_I8191:   po_imm_or_fail (  0,	 8191, FALSE);	break;
 	case OP_I4b:	 po_imm_or_fail (  1,	   4, TRUE);	break;
 	case OP_oI7b:
@@ -14797,6 +14813,15 @@ NEON_ENC_TAB
   X(2, (Q, R), QUAD),			\
   X(2, (D, I), DOUBLE),			\
   X(2, (Q, I), QUAD),			\
+  X(3, (P, F, I), SINGLE),		\
+  X(3, (P, D, I), DOUBLE),		\
+  X(3, (P, Q, I), QUAD),		\
+  X(4, (P, F, F, I), SINGLE),		\
+  X(4, (P, D, D, I), DOUBLE),		\
+  X(4, (P, Q, Q, I), QUAD),		\
+  X(5, (P, F, F, F, I), SINGLE),	\
+  X(5, (P, D, D, D, I), DOUBLE),	\
+  X(5, (P, Q, Q, Q, I), QUAD),		\
   X(3, (D, L, D), DOUBLE),		\
   X(2, (D, Q), MIXED),			\
   X(2, (Q, D), MIXED),			\
@@ -14845,6 +14870,7 @@ NEON_ENC_TAB
 #define S2(A,B)		NS_##A##B
 #define S3(A,B,C)	NS_##A##B##C
 #define S4(A,B,C,D)	NS_##A##B##C##D
+#define S5(A,B,C,D,E)	NS_##A##B##C##D##E
 
 #define X(N, L, C) S##N L
 
@@ -14858,6 +14884,7 @@ enum neon_shape
 #undef S2
 #undef S3
 #undef S4
+#undef S5
 
 enum neon_shape_class
 {
@@ -14886,7 +14913,8 @@ enum neon_shape_el
   SE_I,
   SE_S,
   SE_R,
-  SE_L
+  SE_L,
+  SE_P
 };
 
 /* Register widths of above.  */
@@ -14899,6 +14927,7 @@ static unsigned neon_shape_el_size[] =
   0,
   32,
   32,
+  0,
   0
 };
 
@@ -14911,6 +14940,7 @@ struct neon_shape_info
 #define S2(A,B)		{ SE_##A, SE_##B }
 #define S3(A,B,C)	{ SE_##A, SE_##B, SE_##C }
 #define S4(A,B,C,D)	{ SE_##A, SE_##B, SE_##C, SE_##D }
+#define S5(A,B,C,D,E)	{ SE_##A, SE_##B, SE_##C, SE_##D, SE_##E }
 
 #define X(N, L, C) { N, S##N L }
 
@@ -14923,6 +14953,7 @@ static struct neon_shape_info neon_shape_tab[] =
 #undef S2
 #undef S3
 #undef S4
+#undef S5
 
 /* Bit masks used in type checking given instructions.
   'N_EQK' means the type must be the same as (or based on in some way) the key
@@ -15112,6 +15143,7 @@ neon_select_shape (enum neon_shape shape, ...)
 		matches = 0;
 	      break;
 
+	    case SE_P:
 	    case SE_L:
 	      break;
 	    }
@@ -15840,6 +15872,8 @@ neon_logbits (unsigned x)
 
 #define LOW4(R) ((R) & 0xf)
 #define HI1(R) (((R) >> 4) & 1)
+#define LOW1(R) ((R) & 0x1)
+#define HI4(R) (((R) >> 1) & 0xf)
 
 static unsigned
 mve_get_vcmp_vpt_cond (struct neon_type_el et)
@@ -19728,8 +19762,6 @@ do_neon_fmac_maybe_scalar_long (int subtype)
   inst.instruction &= 0x00ffffff;
   inst.instruction |= high8;
 
-#define LOW1(R) ((R) & 0x1)
-#define HI4(R) (((R) >> 1) & 0xf)
   /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
      whether the instruction is in Q form and whether Vm is a scalar indexed
      operand.  */
@@ -21840,6 +21872,212 @@ do_cx3da (void)
   return do_custom_instruction_3 (1, 1);
 }
 
+static void
+vcx_assign_vec_d (unsigned regnum)
+{
+  inst.instruction |= HI4 (regnum) << 12;
+  inst.instruction |= LOW1 (regnum) << 22;
+}
+
+static void
+vcx_assign_vec_m (unsigned regnum)
+{
+  inst.instruction |= HI4 (regnum);
+  inst.instruction |= LOW1 (regnum) << 5;
+}
+
+static void
+vcx_assign_vec_n (unsigned regnum)
+{
+  inst.instruction |= HI4 (regnum) << 16;
+  inst.instruction |= LOW1 (regnum) << 7;
+}
+
+enum vcx_reg_type {
+    q_reg,
+    d_reg,
+    s_reg
+};
+
+static enum vcx_reg_type
+vcx_get_reg_type (enum neon_shape ns)
+{
+  gas_assert (ns == NS_PQI
+	      || ns == NS_PDI
+	      || ns == NS_PFI
+	      || ns == NS_PQQI
+	      || ns == NS_PDDI
+	      || ns == NS_PFFI
+	      || ns == NS_PQQQI
+	      || ns == NS_PDDDI
+	      || ns == NS_PFFFI);
+  if (ns == NS_PQI || ns == NS_PQQI || ns == NS_PQQQI)
+    return q_reg;
+  if (ns == NS_PDI || ns == NS_PDDI || ns == NS_PDDDI)
+    return d_reg;
+  return s_reg;
+}
+
+#define vcx_size_pos 24
+#define vcx_vec_pos 6
+static unsigned
+vcx_handle_shape (enum vcx_reg_type reg_type)
+{
+  unsigned mult = 2;
+  if (reg_type == q_reg)
+    inst.instruction |= 1 << vcx_vec_pos;
+  else if (reg_type == d_reg)
+    inst.instruction |= 1 << vcx_size_pos;
+  else
+    mult = 1;
+  /* NOTE:
+     The documentation says that the Q registers are encoded as 2*N in the D:Vd
+     bits (or equivalent for N and M registers).
+     Similarly the D registers are encoded as N in D:Vd bits.
+     While the S registers are encoded as N in the Vd:D bits.
+
+     Taking into account the maximum values of these registers we can see a
+     nicer pattern for calculation:
+       Q -> 7, D -> 15, S -> 31
+
+     If we say that everything is encoded in the Vd:D bits, then we can say
+     that Q is encoded as 4*N, and D is encoded as 2*N.
+     This way the bits will end up the same, and calculation is simpler.
+     (calculation is now:
+	1. Multiply by a number determined by the register letter.
+	2. Encode resulting number in Vd:D bits.)
+
+      This is made a little more complicated by automatic handling of 'Q'
+      registers elsewhere, which means the register number is already 2*N where
+      N is the number the user wrote after the register letter.
+     */
+  return mult;
+}
+#undef vcx_vec_pos
+#undef vcx_size_pos
+
+static void
+vcx_ensure_register_in_range (unsigned R, enum vcx_reg_type reg_type)
+{
+  if (reg_type == q_reg)
+    {
+      gas_assert (R % 2 == 0);
+      constraint (R >= 16, _("'q' register must be in range 0-7"));
+    }
+  else if (reg_type == d_reg)
+    constraint (R >= 16, _("'d' register must be in range 0-15"));
+  else
+    constraint (R >= 32, _("'s' register must be in range 0-31"));
+}
+
+static void (*vcx_assign_vec[3]) (unsigned) = {
+    vcx_assign_vec_d,
+    vcx_assign_vec_m,
+    vcx_assign_vec_n
+};
+
+static void
+vcx_handle_register_arguments (unsigned num_registers,
+			       enum vcx_reg_type reg_type)
+{
+  unsigned R;
+  unsigned reg_mult = vcx_handle_shape (reg_type);
+  for (unsigned i = 0; i < num_registers; i++)
+    {
+      R = inst.operands[i+1].reg;
+      vcx_ensure_register_in_range (R, reg_type);
+      if (num_registers == 3 && i > 0)
+	{
+	  if (i == 2)
+	    vcx_assign_vec[1] (R * reg_mult);
+	  else
+	    vcx_assign_vec[2] (R * reg_mult);
+	  continue;
+	}
+      vcx_assign_vec[i](R * reg_mult);
+    }
+}
+
+static void
+vcx_handle_insn_block (enum vcx_reg_type reg_type)
+{
+  if (reg_type == q_reg)
+    if (inst.cond > COND_ALWAYS)
+      inst.pred_insn_type = INSIDE_VPT_INSN;
+    else
+      inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+  else if (inst.cond == COND_ALWAYS)
+    inst.pred_insn_type = OUTSIDE_PRED_INSN;
+  else
+    inst.error = BAD_NOT_IT;
+}
+
+static void
+vcx_handle_common_checks (unsigned num_args, enum neon_shape rs)
+{
+  constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
+  cde_handle_coproc ();
+  enum vcx_reg_type reg_type = vcx_get_reg_type (rs);
+  vcx_handle_register_arguments (num_args, reg_type);
+  vcx_handle_insn_block (reg_type);
+  if (reg_type == q_reg)
+    constraint (!mark_feature_used (&mve_ext),
+		_("vcx instructions with Q registers require MVE"));
+  else
+    constraint (!(ARM_FSET_CPU_SUBSET (armv8m_fp, cpu_variant)
+		  && mark_feature_used (&armv8m_fp))
+		&& !mark_feature_used (&mve_ext),
+		_("vcx instructions with S or D registers require either MVE"
+		  " or Armv8-M floating point etension."));
+}
+
+static void
+do_vcx1 (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_PQI, NS_PDI, NS_PFI, NS_NULL);
+  vcx_handle_common_checks (1, rs);
+
+  unsigned imm = inst.operands[2].imm;
+  inst.instruction |= (imm & 0x03f);
+  inst.instruction |= (imm & 0x040) << 1;
+  inst.instruction |= (imm & 0x780) << 9;
+  if (rs != NS_PQI)
+    constraint (imm >= 2048,
+		_("vcx1 with S or D registers takes immediate within 0-2047"));
+  inst.instruction |= (imm & 0x800) << 13;
+}
+
+static void
+do_vcx2 (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_PQQI, NS_PDDI, NS_PFFI, NS_NULL);
+  vcx_handle_common_checks (2, rs);
+
+  unsigned imm = inst.operands[3].imm;
+  inst.instruction |= (imm & 0x01) << 4;
+  inst.instruction |= (imm & 0x02) << 6;
+  inst.instruction |= (imm & 0x3c) << 14;
+  if (rs != NS_PQQI)
+    constraint (imm >= 64,
+		_("vcx2 with S or D registers takes immediate within 0-63"));
+  inst.instruction |= (imm & 0x40) << 18;
+}
+
+static void
+do_vcx3 (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_PQQQI, NS_PDDDI, NS_PFFFI, NS_NULL);
+  vcx_handle_common_checks (3, rs);
+
+  unsigned imm = inst.operands[4].imm;
+  inst.instruction |= (imm & 0x1) << 4;
+  inst.instruction |= (imm & 0x6) << 19;
+  if (rs != NS_PQQQI)
+    constraint (imm >= 8,
+		_("vcx2 with S or D registers takes immediate within 0-7"));
+  inst.instruction |= (imm & 0x8) << 21;
+}
+
 /* Crypto v1 instructions.  */
 static void
 do_crypto_2op_1 (unsigned elttype, int op)
@@ -26398,7 +26636,17 @@ static const struct asm_opcode insns[] =
  ToC ("cx3a", fe800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3a),
  ToC ("cx3d", ee800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3d),
  ToC ("cx3da", fe800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3da),
+
+ mToC ("vcx1", ec200000, 3, (RCP, RNSDMQ, I4095), vcx1),
+ mToC ("vcx1a", fc200000, 3, (RCP, RNSDMQ, I4095), vcx1),
+
+ mToC ("vcx2", ec300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
+ mToC ("vcx2a", fc300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
+
+ mToC ("vcx3", ec800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
+ mToC ("vcx3a", fc800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
 };
+
 #undef ARM_VARIANT
 #undef THUMB_VARIANT
 #undef TCE
diff --git a/gas/testsuite/gas/arm/cde-missing-fp.d b/gas/testsuite/gas/arm/cde-missing-fp.d
new file mode 100644
index 0000000000000000000000000000000000000000..de7ebc87d1870f4ef391a11b903f13a6d7cc28ac
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-missing-fp.d
@@ -0,0 +1,5 @@
+#name: Custom Datapath Extension FP missing (CDE)
+#source: cde.s
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp7 -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7 -I$srcdir/$subdir
+#error_output: cde-missing-fp.l
diff --git a/gas/testsuite/gas/arm/cde-missing-fp.l b/gas/testsuite/gas/arm/cde-missing-fp.l
new file mode 100644
index 0000000000000000000000000000000000000000..2fbfa9dd27b1c7c09e531ea8df261c8fe124a8a0
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-missing-fp.l
@@ -0,0 +1,148 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#2048'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#1920'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#63'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q7,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#2048'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#1920'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#63'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q7,#0'
+[^ :]+:[0-9]+: Error: selected processor does not support `vptt\.i8 eq,q0,q0' in Thumb mode
+[^ :]+:[0-9]+: Error: bad instruction `vcx1t p0,q0,#0'
+[^ :]+:[0-9]+: Error: bad instruction `vcx1at p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#60'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#2'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#60'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#2'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: selected processor does not support `vptt\.i8 eq,q0,q0' in Thumb mode
+[^ :]+:[0-9]+: Error: bad instruction `vcx2t p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: bad instruction `vcx2at p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#8'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#6'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p7,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#8'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#6'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p7,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: selected processor does not support `vptt\.i8 eq,q0,q0' in Thumb mode
+[^ :]+:[0-9]+: Error: bad instruction `vcx3t p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: bad instruction `vcx3at p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,s0,#1920'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,s0,#64'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,s0,#63'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p7,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,s1,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,s30,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,d0,#1920'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,d0,#64'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,d0,#63'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p7,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1 p0,d15,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,s0,#1920'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,s0,#64'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,s0,#63'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p7,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,s1,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,s30,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,d0,#1920'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,d0,#64'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,d0,#63'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p7,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx1a p0,d15,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s0,s0,#60'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s0,s0,#2'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s0,s0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p7,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s1,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s30,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s0,s1,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,s0,s30,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,d0,d0,#60'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,d0,d0,#2'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,d0,d0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p7,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,d15,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2 p0,d0,d15,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s0,s0,#60'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s0,s0,#2'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s0,s0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p7,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s1,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s30,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s0,s1,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,s0,s30,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,d0,d0,#60'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,d0,d0,#2'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,d0,d0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p7,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,d15,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx2a p0,d0,d15,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s0,s0,#6'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s0,s0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p7,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s1,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s30,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s1,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s30,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s0,s1,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,s0,s0,s30,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,d0,d0,d0,#6'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,d0,d0,d0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p7,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,d15,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,d0,d15,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3 p0,d0,d0,d15,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s0,s0,#6'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s0,s0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p7,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s1,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s30,s0,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s1,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s30,s0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s0,s1,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,s0,s0,s30,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,d0,d0,d0,#6'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,d0,d0,d0,#1'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p7,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,d15,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,d0,d15,d0,#0'
+[^ :]+:[0-9]+: Error: vcx instructions with S or D registers require either MVE or Armv8-M floating point etension\. -- `vcx3a p0,d0,d0,d15,#0'
diff --git a/gas/testsuite/gas/arm/cde-missing-mve.d b/gas/testsuite/gas/arm/cde-missing-mve.d
new file mode 100644
index 0000000000000000000000000000000000000000..22ac9fec5269954be6cb168bc4f955ab453e568e
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-missing-mve.d
@@ -0,0 +1,7 @@
+#name: Custom Datapath Extension MVE missing (CDE)
+#source: cde.s
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp7+fp -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8.1-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+fp -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp7+fp -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+fp -I$srcdir/$subdir
+#error_output: cde-missing-mve.l
diff --git a/gas/testsuite/gas/arm/cde-missing-mve.l b/gas/testsuite/gas/arm/cde-missing-mve.l
new file mode 100644
index 0000000000000000000000000000000000000000..997fbe40601f384a543817452e2d85dd72ad7cb4
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-missing-mve.l
@@ -0,0 +1,57 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#2048'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#1920'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q0,#63'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,q7,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#2048'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#1920'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q0,#63'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,q7,#0'
+[^ :]+:[0-9]+: Error: selected processor does not support `vptt\.i8 eq,q0,q0' in Thumb mode
+[^ :]+:[0-9]+: Error: bad instruction `vcx1t p0,q0,#0'
+[^ :]+:[0-9]+: Error: bad instruction `vcx1at p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#60'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#2'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#64'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#60'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#2'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: selected processor does not support `vptt\.i8 eq,q0,q0' in Thumb mode
+[^ :]+:[0-9]+: Error: bad instruction `vcx2t p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: bad instruction `vcx2at p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#8'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#6'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p7,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#8'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#6'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q0,#1'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p7,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q7,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q7,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,q7,#0'
+[^ :]+:[0-9]+: Error: selected processor does not support `vptt\.i8 eq,q0,q0' in Thumb mode
+[^ :]+:[0-9]+: Error: bad instruction `vcx3t p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: bad instruction `vcx3at p0,q0,q0,q0,#0'
+
diff --git a/gas/testsuite/gas/arm/cde-mve-or-neon.d b/gas/testsuite/gas/arm/cde-mve-or-neon.d
new file mode 100644
index 0000000000000000000000000000000000000000..7d0a1b8d3d51f60cbb82b2854c6d2d17eeb5be28
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-mve-or-neon.d
@@ -0,0 +1,99 @@
+#name: Custom Datapath Extension (CDE)
+#source: cde-mve-or-neon.s
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp7+fp -I$srcdir/$subdir
+#as: -mno-warn-deprecated -march=armv8-m.main+cdecp0+cdecp1+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+fp -I$srcdir/$subdir
+#objdump: -M force-thumb -dr --show-raw-insn -marmv8-m.main -M coproc0=cde -M coproc7=cde
+#...
+00000000 <\.text>:
+ *[0-9a-f]+:	ec20 0000 	vcx1	p0, s0, #0
+ *[0-9a-f]+:	ec2f 0000 	vcx1	p0, s0, #1920
+ *[0-9a-f]+:	ec20 0080 	vcx1	p0, s0, #64
+ *[0-9a-f]+:	ec20 003f 	vcx1	p0, s0, #63
+ *[0-9a-f]+:	ec20 0700 	vcx1	p7, s0, #0
+ *[0-9a-f]+:	ec60 0000 	vcx1	p0, s1, #0
+ *[0-9a-f]+:	ec20 f000 	vcx1	p0, s30, #0
+ *[0-9a-f]+:	ed20 0000 	vcx1	p0, d0, #0
+ *[0-9a-f]+:	ed2f 0000 	vcx1	p0, d0, #1920
+ *[0-9a-f]+:	ed20 0080 	vcx1	p0, d0, #64
+ *[0-9a-f]+:	ed20 003f 	vcx1	p0, d0, #63
+ *[0-9a-f]+:	ed20 0700 	vcx1	p7, d0, #0
+ *[0-9a-f]+:	ed20 f000 	vcx1	p0, d15, #0
+ *[0-9a-f]+:	fc20 0000 	vcx1a	p0, s0, #0
+ *[0-9a-f]+:	fc2f 0000 	vcx1a	p0, s0, #1920
+ *[0-9a-f]+:	fc20 0080 	vcx1a	p0, s0, #64
+ *[0-9a-f]+:	fc20 003f 	vcx1a	p0, s0, #63
+ *[0-9a-f]+:	fc20 0700 	vcx1a	p7, s0, #0
+ *[0-9a-f]+:	fc60 0000 	vcx1a	p0, s1, #0
+ *[0-9a-f]+:	fc20 f000 	vcx1a	p0, s30, #0
+ *[0-9a-f]+:	fd20 0000 	vcx1a	p0, d0, #0
+ *[0-9a-f]+:	fd2f 0000 	vcx1a	p0, d0, #1920
+ *[0-9a-f]+:	fd20 0080 	vcx1a	p0, d0, #64
+ *[0-9a-f]+:	fd20 003f 	vcx1a	p0, d0, #63
+ *[0-9a-f]+:	fd20 0700 	vcx1a	p7, d0, #0
+ *[0-9a-f]+:	fd20 f000 	vcx1a	p0, d15, #0
+ *[0-9a-f]+:	ec30 0000 	vcx2	p0, s0, s0, #0
+ *[0-9a-f]+:	ec3f 0000 	vcx2	p0, s0, s0, #60
+ *[0-9a-f]+:	ec30 0080 	vcx2	p0, s0, s0, #2
+ *[0-9a-f]+:	ec30 0010 	vcx2	p0, s0, s0, #1
+ *[0-9a-f]+:	ec30 0700 	vcx2	p7, s0, s0, #0
+ *[0-9a-f]+:	ec70 0000 	vcx2	p0, s1, s0, #0
+ *[0-9a-f]+:	ec30 f000 	vcx2	p0, s30, s0, #0
+ *[0-9a-f]+:	ec30 0020 	vcx2	p0, s0, s1, #0
+ *[0-9a-f]+:	ec30 000f 	vcx2	p0, s0, s30, #0
+ *[0-9a-f]+:	ed30 0000 	vcx2	p0, d0, d0, #0
+ *[0-9a-f]+:	ed3f 0000 	vcx2	p0, d0, d0, #60
+ *[0-9a-f]+:	ed30 0080 	vcx2	p0, d0, d0, #2
+ *[0-9a-f]+:	ed30 0010 	vcx2	p0, d0, d0, #1
+ *[0-9a-f]+:	ed30 0700 	vcx2	p7, d0, d0, #0
+ *[0-9a-f]+:	ed30 f000 	vcx2	p0, d15, d0, #0
+ *[0-9a-f]+:	ed30 000f 	vcx2	p0, d0, d15, #0
+ *[0-9a-f]+:	fc30 0000 	vcx2a	p0, s0, s0, #0
+ *[0-9a-f]+:	fc3f 0000 	vcx2a	p0, s0, s0, #60
+ *[0-9a-f]+:	fc30 0080 	vcx2a	p0, s0, s0, #2
+ *[0-9a-f]+:	fc30 0010 	vcx2a	p0, s0, s0, #1
+ *[0-9a-f]+:	fc30 0700 	vcx2a	p7, s0, s0, #0
+ *[0-9a-f]+:	fc70 0000 	vcx2a	p0, s1, s0, #0
+ *[0-9a-f]+:	fc30 f000 	vcx2a	p0, s30, s0, #0
+ *[0-9a-f]+:	fc30 0020 	vcx2a	p0, s0, s1, #0
+ *[0-9a-f]+:	fc30 000f 	vcx2a	p0, s0, s30, #0
+ *[0-9a-f]+:	fd30 0000 	vcx2a	p0, d0, d0, #0
+ *[0-9a-f]+:	fd3f 0000 	vcx2a	p0, d0, d0, #60
+ *[0-9a-f]+:	fd30 0080 	vcx2a	p0, d0, d0, #2
+ *[0-9a-f]+:	fd30 0010 	vcx2a	p0, d0, d0, #1
+ *[0-9a-f]+:	fd30 0700 	vcx2a	p7, d0, d0, #0
+ *[0-9a-f]+:	fd30 f000 	vcx2a	p0, d15, d0, #0
+ *[0-9a-f]+:	fd30 000f 	vcx2a	p0, d0, d15, #0
+ *[0-9a-f]+:	ec80 0000 	vcx3	p0, s0, s0, s0, #0
+ *[0-9a-f]+:	ecb0 0000 	vcx3	p0, s0, s0, s0, #6
+ *[0-9a-f]+:	ec80 0010 	vcx3	p0, s0, s0, s0, #1
+ *[0-9a-f]+:	ec80 0700 	vcx3	p7, s0, s0, s0, #0
+ *[0-9a-f]+:	ecc0 0000 	vcx3	p0, s1, s0, s0, #0
+ *[0-9a-f]+:	ec80 f000 	vcx3	p0, s30, s0, s0, #0
+ *[0-9a-f]+:	ec80 0080 	vcx3	p0, s0, s1, s0, #0
+ *[0-9a-f]+:	ec8f 0000 	vcx3	p0, s0, s30, s0, #0
+ *[0-9a-f]+:	ec80 0020 	vcx3	p0, s0, s0, s1, #0
+ *[0-9a-f]+:	ec80 000f 	vcx3	p0, s0, s0, s30, #0
+ *[0-9a-f]+:	ed80 0000 	vcx3	p0, d0, d0, d0, #0
+ *[0-9a-f]+:	edb0 0000 	vcx3	p0, d0, d0, d0, #6
+ *[0-9a-f]+:	ed80 0010 	vcx3	p0, d0, d0, d0, #1
+ *[0-9a-f]+:	ed80 0700 	vcx3	p7, d0, d0, d0, #0
+ *[0-9a-f]+:	ed80 f000 	vcx3	p0, d15, d0, d0, #0
+ *[0-9a-f]+:	ed8f 0000 	vcx3	p0, d0, d15, d0, #0
+ *[0-9a-f]+:	ed80 000f 	vcx3	p0, d0, d0, d15, #0
+ *[0-9a-f]+:	fc80 0000 	vcx3a	p0, s0, s0, s0, #0
+ *[0-9a-f]+:	fcb0 0000 	vcx3a	p0, s0, s0, s0, #6
+ *[0-9a-f]+:	fc80 0010 	vcx3a	p0, s0, s0, s0, #1
+ *[0-9a-f]+:	fc80 0700 	vcx3a	p7, s0, s0, s0, #0
+ *[0-9a-f]+:	fcc0 0000 	vcx3a	p0, s1, s0, s0, #0
+ *[0-9a-f]+:	fc80 f000 	vcx3a	p0, s30, s0, s0, #0
+ *[0-9a-f]+:	fc80 0080 	vcx3a	p0, s0, s1, s0, #0
+ *[0-9a-f]+:	fc8f 0000 	vcx3a	p0, s0, s30, s0, #0
+ *[0-9a-f]+:	fc80 0020 	vcx3a	p0, s0, s0, s1, #0
+ *[0-9a-f]+:	fc80 000f 	vcx3a	p0, s0, s0, s30, #0
+ *[0-9a-f]+:	fd80 0000 	vcx3a	p0, d0, d0, d0, #0
+ *[0-9a-f]+:	fdb0 0000 	vcx3a	p0, d0, d0, d0, #6
+ *[0-9a-f]+:	fd80 0010 	vcx3a	p0, d0, d0, d0, #1
+ *[0-9a-f]+:	fd80 0700 	vcx3a	p7, d0, d0, d0, #0
+ *[0-9a-f]+:	fd80 f000 	vcx3a	p0, d15, d0, d0, #0
+ *[0-9a-f]+:	fd8f 0000 	vcx3a	p0, d0, d15, d0, #0
+ *[0-9a-f]+:	fd80 000f 	vcx3a	p0, d0, d0, d15, #0
diff --git a/gas/testsuite/gas/arm/cde-mve-or-neon.s b/gas/testsuite/gas/arm/cde-mve-or-neon.s
new file mode 100644
index 0000000000000000000000000000000000000000..ba8bc7263eec1e1f9ba9beb0ef62c794fea45a00
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-mve-or-neon.s
@@ -0,0 +1,96 @@
+.syntax unified
+vcx1 p0, s0, #0
+vcx1 p0, s0, #1920
+vcx1 p0, s0, #64
+vcx1 p0, s0, #63
+vcx1 p7, s0, #0
+vcx1 p0, s1, #0
+vcx1 p0, s30, #0
+vcx1 p0, d0, #0
+vcx1 p0, d0, #1920
+vcx1 p0, d0, #64
+vcx1 p0, d0, #63
+vcx1 p7, d0, #0
+vcx1 p0, d15, #0
+vcx1a p0, s0, #0
+vcx1a p0, s0, #1920
+vcx1a p0, s0, #64
+vcx1a p0, s0, #63
+vcx1a p7, s0, #0
+vcx1a p0, s1, #0
+vcx1a p0, s30, #0
+vcx1a p0, d0, #0
+vcx1a p0, d0, #1920
+vcx1a p0, d0, #64
+vcx1a p0, d0, #63
+vcx1a p7, d0, #0
+vcx1a p0, d15, #0
+
+vcx2 p0, s0, s0, #0
+vcx2 p0, s0, s0, #60
+vcx2 p0, s0, s0, #2
+vcx2 p0, s0, s0, #1
+vcx2 p7, s0, s0, #0
+vcx2 p0, s1, s0, #0
+vcx2 p0, s30, s0, #0
+vcx2 p0, s0, s1, #0
+vcx2 p0, s0, s30, #0
+vcx2 p0, d0, d0, #0
+vcx2 p0, d0, d0, #60
+vcx2 p0, d0, d0, #2
+vcx2 p0, d0, d0, #1
+vcx2 p7, d0, d0, #0
+vcx2 p0, d15, d0, #0
+vcx2 p0, d0, d15, #0
+vcx2a p0, s0, s0, #0
+vcx2a p0, s0, s0, #60
+vcx2a p0, s0, s0, #2
+vcx2a p0, s0, s0, #1
+vcx2a p7, s0, s0, #0
+vcx2a p0, s1, s0, #0
+vcx2a p0, s30, s0, #0
+vcx2a p0, s0, s1, #0
+vcx2a p0, s0, s30, #0
+vcx2a p0, d0, d0, #0
+vcx2a p0, d0, d0, #60
+vcx2a p0, d0, d0, #2
+vcx2a p0, d0, d0, #1
+vcx2a p7, d0, d0, #0
+vcx2a p0, d15, d0, #0
+vcx2a p0, d0, d15, #0
+
+
+vcx3 p0, s0, s0, s0, #0
+vcx3 p0, s0, s0, s0, #6
+vcx3 p0, s0, s0, s0, #1
+vcx3 p7, s0, s0, s0, #0
+vcx3 p0, s1, s0, s0, #0
+vcx3 p0, s30, s0, s0, #0
+vcx3 p0, s0, s1, s0, #0
+vcx3 p0, s0, s30, s0, #0
+vcx3 p0, s0, s0, s1, #0
+vcx3 p0, s0, s0, s30, #0
+vcx3 p0, d0, d0, d0, #0
+vcx3 p0, d0, d0, d0, #6
+vcx3 p0, d0, d0, d0, #1
+vcx3 p7, d0, d0, d0, #0
+vcx3 p0, d15, d0, d0, #0
+vcx3 p0, d0, d15, d0, #0
+vcx3 p0, d0, d0, d15, #0
+vcx3a p0, s0, s0, s0, #0
+vcx3a p0, s0, s0, s0, #6
+vcx3a p0, s0, s0, s0, #1
+vcx3a p7, s0, s0, s0, #0
+vcx3a p0, s1, s0, s0, #0
+vcx3a p0, s30, s0, s0, #0
+vcx3a p0, s0, s1, s0, #0
+vcx3a p0, s0, s30, s0, #0
+vcx3a p0, s0, s0, s1, #0
+vcx3a p0, s0, s0, s30, #0
+vcx3a p0, d0, d0, d0, #0
+vcx3a p0, d0, d0, d0, #6
+vcx3a p0, d0, d0, d0, #1
+vcx3a p7, d0, d0, d0, #0
+vcx3a p0, d15, d0, d0, #0
+vcx3a p0, d0, d15, d0, #0
+vcx3a p0, d0, d0, d15, #0
diff --git a/gas/testsuite/gas/arm/cde-mve.s b/gas/testsuite/gas/arm/cde-mve.s
new file mode 100644
index 0000000000000000000000000000000000000000..04e014cdd9fdd4b5914fe895f226576ec1255add
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde-mve.s
@@ -0,0 +1,62 @@
+.syntax unified
+
+vcx1 p0, q0, #0
+vcx1 p0, q0, #2048
+vcx1 p0, q0, #1920
+vcx1 p0, q0, #64
+vcx1 p0, q0, #63
+vcx1 p7, q0, #0
+vcx1 p0, q7, #0
+vcx1a p0, q0, #0
+vcx1a p0, q0, #2048
+vcx1a p0, q0, #1920
+vcx1a p0, q0, #64
+vcx1a p0, q0, #63
+vcx1a p7, q0, #0
+vcx1a p0, q7, #0
+
+vptt.i8 eq, q0, q0
+vcx1t p0, q0, #0
+vcx1at p0, q0, #0
+
+vcx2 p0, q0, q0, #0
+vcx2 p0, q0, q0, #64
+vcx2 p0, q0, q0, #60
+vcx2 p0, q0, q0, #2
+vcx2 p0, q0, q0, #1
+vcx2 p7, q0, q0, #0
+vcx2 p0, q7, q0, #0
+vcx2 p0, q0, q7, #0
+vcx2a p0, q0, q0, #0
+vcx2a p0, q0, q0, #64
+vcx2a p0, q0, q0, #60
+vcx2a p0, q0, q0, #2
+vcx2a p0, q0, q0, #1
+vcx2a p7, q0, q0, #0
+vcx2a p0, q7, q0, #0
+vcx2a p0, q0, q7, #0
+
+vptt.i8 eq, q0, q0
+vcx2t p0, q0, q0, #0
+vcx2at p0, q0, q0, #0
+
+vcx3 p0, q0, q0, q0, #0
+vcx3 p0, q0, q0, q0, #8
+vcx3 p0, q0, q0, q0, #6
+vcx3 p0, q0, q0, q0, #1
+vcx3 p7, q0, q0, q0, #0
+vcx3 p0, q7, q0, q0, #0
+vcx3 p0, q0, q7, q0, #0
+vcx3 p0, q0, q0, q7, #0
+vcx3a p0, q0, q0, q0, #0
+vcx3a p0, q0, q0, q0, #8
+vcx3a p0, q0, q0, q0, #6
+vcx3a p0, q0, q0, q0, #1
+vcx3a p7, q0, q0, q0, #0
+vcx3a p0, q7, q0, q0, #0
+vcx3a p0, q0, q7, q0, #0
+vcx3a p0, q0, q0, q7, #0
+
+vptt.i8 eq, q0, q0
+vcx3t p0, q0, q0, q0, #0
+vcx3at p0, q0, q0, q0, #0
diff --git a/gas/testsuite/gas/arm/cde-warnings.l b/gas/testsuite/gas/arm/cde-warnings.l
index abbd10aed4af14b96f3dc38a166cbe3ce34bd724..d0380d9d79a647d4c48f92a5524b0073d96bce89 100644
--- a/gas/testsuite/gas/arm/cde-warnings.l
+++ b/gas/testsuite/gas/arm/cde-warnings.l
@@ -173,3 +173,183 @@
 [^ :]+:[0-9]+: Error: constant expression required -- `cx3da p0,r0,r1,r0,r0,r0,#0'
 [^ :]+:[0-9]+: Error: syntax error -- `cx3d p0,r0,r0,r0,#0'
 [^ :]+:[0-9]+: Error: syntax error -- `cx3da p0,r0,r0,r0,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1 p0,q0,#4096'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1a p0,q0,#4096'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1 p0,q0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1a p0,q0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx1 p8,q0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx1a p8,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx1 p0,q8,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx1a p0,q8,#0'
+[^ :]+:[0-9]+: Warning: instruction is UNPREDICTABLE in an IT block
+[^ :]+:[0-9]+: Error: syntax error -- `vcx1ne p0,q0,#0'
+[^ :]+:[0-9]+: Warning: instruction is UNPREDICTABLE in an IT block
+[^ :]+:[0-9]+: Error: syntax error -- `vcx1ane p0,q0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx1 p1,q0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx1a p1,q0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx1 p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx1a p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,#0'
+[^ :]+:[0-9]+: Error: vcx1 with S or D registers takes immediate within 0-2047 -- `vcx1 p0,d0,#2048'
+[^ :]+:[0-9]+: Error: vcx1 with S or D registers takes immediate within 0-2047 -- `vcx1a p0,d0,#2048'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1 p0,d0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1a p0,d0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx1 p8,d0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx1a p8,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx1 p0,d16,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx1a p0,d16,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1 p0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1ne p0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1a p0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1ane p0,d0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx1 p1,d0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx1a p1,d0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx1 p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx1a p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,#0'
+[^ :]+:[0-9]+: Error: vcx1 with S or D registers takes immediate within 0-2047 -- `vcx1 p0,s0,#2048'
+[^ :]+:[0-9]+: Error: vcx1 with S or D registers takes immediate within 0-2047 -- `vcx1a p0,s0,#2048'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1 p0,s0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx1a p0,s0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx1 p8,s0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx1a p8,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,s32,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,s32,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1 p0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1ne p0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1a p0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx1ane p0,s0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx1 p1,s0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx1a p1,s0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx1 p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx1a p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1 p0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx1a p0,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2 p0,q0,q0,#128'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2a p0,q0,q0,#128'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2 p0,q0,q0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2a p0,q0,q0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx2 p8,q0,q0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx2a p8,q0,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx2 p0,q8,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx2a p0,q8,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx2 p0,q0,q8,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx2a p0,q0,q8,#0'
+[^ :]+:[0-9]+: Warning: instruction is UNPREDICTABLE in an IT block
+[^ :]+:[0-9]+: Error: syntax error -- `vcx2ne p0,q0,q0,#0'
+[^ :]+:[0-9]+: Warning: instruction is UNPREDICTABLE in an IT block
+[^ :]+:[0-9]+: Error: syntax error -- `vcx2ane p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx2 p1,q0,q0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx2a p1,q0,q0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx2 p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx2a p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,q0,#0'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-63 -- `vcx2 p0,d0,d0,#64'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-63 -- `vcx2a p0,d0,d0,#64'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2 p0,d0,d0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2a p0,d0,d0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx2 p8,d0,d0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx2a p8,d0,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx2 p0,d16,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx2a p0,d16,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx2 p0,d0,d16,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx2a p0,d0,d16,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2 p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2ne p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2a p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2ane p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx2 p1,d0,d0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx2a p1,d0,d0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx2 p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx2a p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,d0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-63 -- `vcx2 p0,s0,s0,#64'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-63 -- `vcx2a p0,s0,s0,#64'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2 p0,s0,s0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx2a p0,s0,s0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx2 p8,s0,s0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx2a p8,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,s32,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,s32,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,s0,s32,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,s0,s32,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2 p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2ne p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2a p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx2ane p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx2 p1,s0,s0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx2a p1,s0,s0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx2 p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx2a p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2 p0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx2a p0,s0,#0'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3 p0,q0,q0,q0,#16'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3a p0,q0,q0,q0,#16'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3 p0,q0,q0,q0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3a p0,q0,q0,q0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx3 p8,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx3a p8,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx3 p0,q8,q0,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx3a p0,q8,q0,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx3 p0,q8,q0,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx3a p0,q0,q8,q0,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx3 p0,q0,q0,q8,#0'
+[^ :]+:[0-9]+: Error: expected MVE register \[q0\.\.q7\] -- `vcx3a p0,q0,q0,q8,#0'
+[^ :]+:[0-9]+: Warning: instruction is UNPREDICTABLE in an IT block
+[^ :]+:[0-9]+: Error: syntax error -- `vcx3ne p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Warning: instruction is UNPREDICTABLE in an IT block
+[^ :]+:[0-9]+: Error: syntax error -- `vcx3ane p0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx3 p1,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx3a p1,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx3 p0,q0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx3a p0,q0,q0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,q0,q0,#0'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-7 -- `vcx3 p0,d0,d0,d0,#8'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-7 -- `vcx3a p0,d0,d0,d0,#8'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3 p0,d0,d0,d0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3a p0,d0,d0,d0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx3 p8,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx3a p8,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx3 p0,d16,d0,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx3a p0,d16,d0,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx3 p0,d0,d16,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx3a p0,d0,d16,d0,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx3 p0,d0,d0,d16,#0'
+[^ :]+:[0-9]+: Error: 'd' register must be in range 0-15 -- `vcx3a p0,d0,d0,d16,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3 p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3ne p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3a p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3ane p0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx3 p1,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx3a p1,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx3 p0,d0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx3a p0,d0,d0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,d0,d0,#0'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-7 -- `vcx3 p0,s0,s0,s0,#8'
+[^ :]+:[0-9]+: Error: vcx2 with S or D registers takes immediate within 0-7 -- `vcx3a p0,s0,s0,s0,#8'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3 p0,s0,s0,s0,#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range -- `vcx3a p0,s0,s0,s0,#-1'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx3 p8,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: CDE Coprocessor must be in range 0-7 -- `vcx3a p8,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,s32,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,s32,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,s0,s32,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,s0,s32,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,s0,s0,s32,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,s0,s0,s32,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3 p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3ne p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3a p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: instruction not allowed in IT block -- `vcx3ane p0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx3 p1,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: coprocessor for insn is not enabled for cde -- `vcx3a p1,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx3 p0,s0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: constant expression required -- `vcx3a p0,s0,s0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3 p0,s0,s0,#0'
+[^ :]+:[0-9]+: Error: MVE vector register expected -- `vcx3a p0,s0,s0,#0'
diff --git a/gas/testsuite/gas/arm/cde-warnings.s b/gas/testsuite/gas/arm/cde-warnings.s
index 8e5759a64e44980481330cdc043c40d2d6bacbc6..34b923f4e0c5f40aec12132428db60fbadf0c691 100644
--- a/gas/testsuite/gas/arm/cde-warnings.s
+++ b/gas/testsuite/gas/arm/cde-warnings.s
@@ -333,3 +333,272 @@ cx3da p0, r0, r1, r0, r0, r0, #0
 
 cx3d p0, r0, r0, r0, #0
 cx3da p0, r0, r0, r0, #0
+
+# vcx1{a}
+# Immediate out of range.
+# Each register out of range.
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Too many arguments
+# Too little arguments
+
+vcx1 p0, q0, #4096
+vcx1a p0, q0, #4096
+vcx1 p0, q0, #-1
+vcx1a p0, q0, #-1
+
+vcx1 p8, q0, #0
+vcx1a p8, q0, #0
+vcx1 p0, q8, #0
+vcx1a p0, q8, #0
+
+itttt ne
+vcx1 p0, q0, #0
+vcx1ne p0, q0, #0
+vcx1a p0, q0, #0
+vcx1ane p0, q0, #0
+
+vcx1 p1, q0, #0
+vcx1a p1, q0, #0
+
+vcx1 p0, q0, q0, #0
+vcx1a p0, q0, q0, #0
+vcx1 p0, #0
+vcx1a p0, #0
+
+
+vcx1 p0, d0, #2048
+vcx1a p0, d0, #2048
+vcx1 p0, d0, #-1
+vcx1a p0, d0, #-1
+
+vcx1 p8, d0, #0
+vcx1a p8, d0, #0
+vcx1 p0, d16, #0
+vcx1a p0, d16, #0
+
+itttt ne
+vcx1 p0, d0, #0
+vcx1ne p0, d0, #0
+vcx1a p0, d0, #0
+vcx1ane p0, d0, #0
+
+vcx1 p1, d0, #0
+vcx1a p1, d0, #0
+
+vcx1 p0, d0, d0, #0
+vcx1a p0, d0, d0, #0
+vcx1 p0, #0
+vcx1a p0, #0
+
+
+vcx1 p0, s0, #2048
+vcx1a p0, s0, #2048
+vcx1 p0, s0, #-1
+vcx1a p0, s0, #-1
+
+vcx1 p8, s0, #0
+vcx1a p8, s0, #0
+vcx1 p0, s32, #0
+vcx1a p0, s32, #0
+
+itttt ne
+vcx1 p0, s0, #0
+vcx1ne p0, s0, #0
+vcx1a p0, s0, #0
+vcx1ane p0, s0, #0
+
+vcx1 p1, s0, #0
+vcx1a p1, s0, #0
+
+vcx1 p0, s0, s0, #0
+vcx1a p0, s0, s0, #0
+vcx1 p0, #0
+vcx1a p0, #0
+
+
+# vcx2{a}
+# Immediate out of range.
+# Each register out of range.
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Too many arguments
+# Too little arguments
+
+vcx2 p0, q0, q0, #128
+vcx2a p0, q0, q0, #128
+vcx2 p0, q0, q0, #-1
+vcx2a p0, q0, q0, #-1
+
+vcx2 p8, q0, q0, #0
+vcx2a p8, q0, q0, #0
+vcx2 p0, q8, q0, #0
+vcx2a p0, q8, q0, #0
+vcx2 p0, q0, q8, #0
+vcx2a p0, q0, q8, #0
+
+itttt ne
+vcx2 p0, q0, q0, #0
+vcx2ne p0, q0, q0, #0
+vcx2a p0, q0, q0, #0
+vcx2ane p0, q0, q0, #0
+
+vcx2 p1, q0, q0, #0
+vcx2a p1, q0, q0, #0
+
+vcx2 p0, q0, q0, q0, #0
+vcx2a p0, q0, q0, q0, #0
+vcx2 p0, q0, #0
+vcx2a p0, q0, #0
+
+
+vcx2 p0, d0, d0, #64
+vcx2a p0, d0, d0, #64
+vcx2 p0, d0, d0, #-1
+vcx2a p0, d0, d0, #-1
+
+vcx2 p8, d0, d0, #0
+vcx2a p8, d0, d0, #0
+vcx2 p0, d16, d0, #0
+vcx2a p0, d16, d0, #0
+vcx2 p0, d0, d16, #0
+vcx2a p0, d0, d16, #0
+
+itttt ne
+vcx2 p0, d0, d0, #0
+vcx2ne p0, d0, d0, #0
+vcx2a p0, d0, d0, #0
+vcx2ane p0, d0, d0, #0
+
+vcx2 p1, d0, d0, #0
+vcx2a p1, d0, d0, #0
+
+vcx2 p0, d0, d0, d0, #0
+vcx2a p0, d0, d0, d0, #0
+vcx2 p0, d0, #0
+vcx2a p0, d0, #0
+
+
+vcx2 p0, s0, s0, #64
+vcx2a p0, s0, s0, #64
+vcx2 p0, s0, s0, #-1
+vcx2a p0, s0, s0, #-1
+
+vcx2 p8, s0, s0, #0
+vcx2a p8, s0, s0, #0
+vcx2 p0, s32, s0, #0
+vcx2a p0, s32, s0, #0
+vcx2 p0, s0, s32, #0
+vcx2a p0, s0, s32, #0
+
+itttt ne
+vcx2 p0, s0, s0, #0
+vcx2ne p0, s0, s0, #0
+vcx2a p0, s0, s0, #0
+vcx2ane p0, s0, s0, #0
+
+vcx2 p1, s0, s0, #0
+vcx2a p1, s0, s0, #0
+
+vcx2 p0, s0, s0, s0, #0
+vcx2a p0, s0, s0, s0, #0
+vcx2 p0, s0, #0
+vcx2a p0, s0, #0
+
+# vcx3{a}
+# Immediate out of range.
+# Each register out of range.
+# IT block => constrained unpredictable
+#
+# Error given when using coprocessor number not enabled on command line.
+# Too many arguments
+# Too little arguments
+
+vcx3 p0, q0, q0, q0, #16
+vcx3a p0, q0, q0, q0, #16
+vcx3 p0, q0, q0, q0, #-1
+vcx3a p0, q0, q0, q0, #-1
+
+vcx3 p8, q0, q0, q0, #0
+vcx3a p8, q0, q0, q0, #0
+vcx3 p0, q8, q0, q0, #0
+vcx3a p0, q8, q0, q0, #0
+vcx3 p0, q8, q0, q0, #0
+vcx3a p0, q0, q8, q0, #0
+vcx3 p0, q0, q0, q8, #0
+vcx3a p0, q0, q0, q8, #0
+
+itttt ne
+vcx3 p0, q0, q0, q0, #0
+vcx3ne p0, q0, q0, q0, #0
+vcx3a p0, q0, q0, q0, #0
+vcx3ane p0, q0, q0, q0, #0
+
+vcx3 p1, q0, q0, q0, #0
+vcx3a p1, q0, q0, q0, #0
+
+vcx3 p0, q0, q0, q0, q0, #0
+vcx3a p0, q0, q0, q0, q0, #0
+vcx3 p0, q0, q0, #0
+vcx3a p0, q0, q0, #0
+
+
+vcx3 p0, d0, d0, d0, #8
+vcx3a p0, d0, d0, d0, #8
+vcx3 p0, d0, d0, d0, #-1
+vcx3a p0, d0, d0, d0, #-1
+
+vcx3 p8, d0, d0, d0, #0
+vcx3a p8, d0, d0, d0, #0
+vcx3 p0, d16, d0, d0, #0
+vcx3a p0, d16, d0, d0, #0
+vcx3 p0, d0, d16, d0, #0
+vcx3a p0, d0, d16, d0, #0
+vcx3 p0, d0, d0, d16, #0
+vcx3a p0, d0, d0, d16, #0
+
+itttt ne
+vcx3 p0, d0, d0, d0, #0
+vcx3ne p0, d0, d0, d0, #0
+vcx3a p0, d0, d0, d0, #0
+vcx3ane p0, d0, d0, d0, #0
+
+vcx3 p1, d0, d0, d0, #0
+vcx3a p1, d0, d0, d0, #0
+
+vcx3 p0, d0, d0, d0, d0, #0
+vcx3a p0, d0, d0, d0, d0, #0
+vcx3 p0, d0, d0, #0
+vcx3a p0, d0, d0, #0
+
+
+vcx3 p0, s0, s0, s0, #8
+vcx3a p0, s0, s0, s0, #8
+vcx3 p0, s0, s0, s0, #-1
+vcx3a p0, s0, s0, s0, #-1
+
+vcx3 p8, s0, s0, s0, #0
+vcx3a p8, s0, s0, s0, #0
+vcx3 p0, s32, s0, s0, #0
+vcx3a p0, s32, s0, s0, #0
+vcx3 p0, s0, s32, s0, #0
+vcx3a p0, s0, s32, s0, #0
+vcx3 p0, s0, s0, s32, #0
+vcx3a p0, s0, s0, s32, #0
+
+itttt ne
+vcx3 p0, s0, s0, s0, #0
+vcx3ne p0, s0, s0, s0, #0
+vcx3a p0, s0, s0, s0, #0
+vcx3ane p0, s0, s0, s0, #0
+
+vcx3 p1, s0, s0, s0, #0
+vcx3a p1, s0, s0, s0, #0
+
+vcx3 p0, s0, s0, s0, s0, #0
+vcx3a p0, s0, s0, s0, s0, #0
+vcx3 p0, s0, s0, #0
+vcx3a p0, s0, s0, #0
+
diff --git a/gas/testsuite/gas/arm/cde.d b/gas/testsuite/gas/arm/cde.d
index 34de201513b1f89b29397d0663b184ca7d1cdf16..0fa02ad18bcba0fd4c9293eeef6f9a99f9471564 100644
--- a/gas/testsuite/gas/arm/cde.d
+++ b/gas/testsuite/gas/arm/cde.d
@@ -117,3 +117,150 @@
  *[0-9a-f]+:	fe89 0040 	cx3da	p0, r0, r1, r9, r0, #0
  *[0-9a-f]+:	fe80 f040 	cx3da	p0, r0, r1, r0, APSR_nzcv, #0
  *[0-9a-f]+:	fe80 9040 	cx3da	p0, r0, r1, r0, r9, #0
+ *[0-9a-f]+:	ec20 0040 	vcx1	p0, q0, #0
+ *[0-9a-f]+:	ed20 0040 	vcx1	p0, q0, #2048
+ *[0-9a-f]+:	ec2f 0040 	vcx1	p0, q0, #1920
+ *[0-9a-f]+:	ec20 00c0 	vcx1	p0, q0, #64
+ *[0-9a-f]+:	ec20 007f 	vcx1	p0, q0, #63
+ *[0-9a-f]+:	ec20 0740 	vcx1	p7, q0, #0
+ *[0-9a-f]+:	ec20 e040 	vcx1	p0, q7, #0
+ *[0-9a-f]+:	fc20 0040 	vcx1a	p0, q0, #0
+ *[0-9a-f]+:	fd20 0040 	vcx1a	p0, q0, #2048
+ *[0-9a-f]+:	fc2f 0040 	vcx1a	p0, q0, #1920
+ *[0-9a-f]+:	fc20 00c0 	vcx1a	p0, q0, #64
+ *[0-9a-f]+:	fc20 007f 	vcx1a	p0, q0, #63
+ *[0-9a-f]+:	fc20 0740 	vcx1a	p7, q0, #0
+ *[0-9a-f]+:	fc20 e040 	vcx1a	p0, q7, #0
+ *[0-9a-f]+:	fe01 8f00 	vptt\.i8	eq, q0, q0
+ *[0-9a-f]+:	ec20 0040 	vcx1	p0, q0, #0
+ *[0-9a-f]+:	fc20 0040 	vcx1a	p0, q0, #0
+ *[0-9a-f]+:	ec30 0040 	vcx2	p0, q0, q0, #0
+ *[0-9a-f]+:	ed30 0040 	vcx2	p0, q0, q0, #64
+ *[0-9a-f]+:	ec3f 0040 	vcx2	p0, q0, q0, #60
+ *[0-9a-f]+:	ec30 00c0 	vcx2	p0, q0, q0, #2
+ *[0-9a-f]+:	ec30 0050 	vcx2	p0, q0, q0, #1
+ *[0-9a-f]+:	ec30 0740 	vcx2	p7, q0, q0, #0
+ *[0-9a-f]+:	ec30 e040 	vcx2	p0, q7, q0, #0
+ *[0-9a-f]+:	ec30 004e 	vcx2	p0, q0, q7, #0
+ *[0-9a-f]+:	fc30 0040 	vcx2a	p0, q0, q0, #0
+ *[0-9a-f]+:	fd30 0040 	vcx2a	p0, q0, q0, #64
+ *[0-9a-f]+:	fc3f 0040 	vcx2a	p0, q0, q0, #60
+ *[0-9a-f]+:	fc30 00c0 	vcx2a	p0, q0, q0, #2
+ *[0-9a-f]+:	fc30 0050 	vcx2a	p0, q0, q0, #1
+ *[0-9a-f]+:	fc30 0740 	vcx2a	p7, q0, q0, #0
+ *[0-9a-f]+:	fc30 e040 	vcx2a	p0, q7, q0, #0
+ *[0-9a-f]+:	fc30 004e 	vcx2a	p0, q0, q7, #0
+ *[0-9a-f]+:	fe01 8f00 	vptt\.i8	eq, q0, q0
+ *[0-9a-f]+:	ec30 0040 	vcx2	p0, q0, q0, #0
+ *[0-9a-f]+:	fc30 0040 	vcx2a	p0, q0, q0, #0
+ *[0-9a-f]+:	ec80 0040 	vcx3	p0, q0, q0, q0, #0
+ *[0-9a-f]+:	ed80 0040 	vcx3	p0, q0, q0, q0, #8
+ *[0-9a-f]+:	ecb0 0040 	vcx3	p0, q0, q0, q0, #6
+ *[0-9a-f]+:	ec80 0050 	vcx3	p0, q0, q0, q0, #1
+ *[0-9a-f]+:	ec80 0740 	vcx3	p7, q0, q0, q0, #0
+ *[0-9a-f]+:	ec80 e040 	vcx3	p0, q7, q0, q0, #0
+ *[0-9a-f]+:	ec8e 0040 	vcx3	p0, q0, q7, q0, #0
+ *[0-9a-f]+:	ec80 004e 	vcx3	p0, q0, q0, q7, #0
+ *[0-9a-f]+:	fc80 0040 	vcx3a	p0, q0, q0, q0, #0
+ *[0-9a-f]+:	fd80 0040 	vcx3a	p0, q0, q0, q0, #8
+ *[0-9a-f]+:	fcb0 0040 	vcx3a	p0, q0, q0, q0, #6
+ *[0-9a-f]+:	fc80 0050 	vcx3a	p0, q0, q0, q0, #1
+ *[0-9a-f]+:	fc80 0740 	vcx3a	p7, q0, q0, q0, #0
+ *[0-9a-f]+:	fc80 e040 	vcx3a	p0, q7, q0, q0, #0
+ *[0-9a-f]+:	fc8e 0040 	vcx3a	p0, q0, q7, q0, #0
+ *[0-9a-f]+:	fc80 004e 	vcx3a	p0, q0, q0, q7, #0
+ *[0-9a-f]+:	fe01 8f00 	vptt\.i8	eq, q0, q0
+ *[0-9a-f]+:	ec80 0040 	vcx3	p0, q0, q0, q0, #0
+ *[0-9a-f]+:	fc80 0040 	vcx3a	p0, q0, q0, q0, #0
+ *[0-9a-f]+:	ec20 0000 	vcx1	p0, s0, #0
+ *[0-9a-f]+:	ec2f 0000 	vcx1	p0, s0, #1920
+ *[0-9a-f]+:	ec20 0080 	vcx1	p0, s0, #64
+ *[0-9a-f]+:	ec20 003f 	vcx1	p0, s0, #63
+ *[0-9a-f]+:	ec20 0700 	vcx1	p7, s0, #0
+ *[0-9a-f]+:	ec60 0000 	vcx1	p0, s1, #0
+ *[0-9a-f]+:	ec20 f000 	vcx1	p0, s30, #0
+ *[0-9a-f]+:	ed20 0000 	vcx1	p0, d0, #0
+ *[0-9a-f]+:	ed2f 0000 	vcx1	p0, d0, #1920
+ *[0-9a-f]+:	ed20 0080 	vcx1	p0, d0, #64
+ *[0-9a-f]+:	ed20 003f 	vcx1	p0, d0, #63
+ *[0-9a-f]+:	ed20 0700 	vcx1	p7, d0, #0
+ *[0-9a-f]+:	ed20 f000 	vcx1	p0, d15, #0
+ *[0-9a-f]+:	fc20 0000 	vcx1a	p0, s0, #0
+ *[0-9a-f]+:	fc2f 0000 	vcx1a	p0, s0, #1920
+ *[0-9a-f]+:	fc20 0080 	vcx1a	p0, s0, #64
+ *[0-9a-f]+:	fc20 003f 	vcx1a	p0, s0, #63
+ *[0-9a-f]+:	fc20 0700 	vcx1a	p7, s0, #0
+ *[0-9a-f]+:	fc60 0000 	vcx1a	p0, s1, #0
+ *[0-9a-f]+:	fc20 f000 	vcx1a	p0, s30, #0
+ *[0-9a-f]+:	fd20 0000 	vcx1a	p0, d0, #0
+ *[0-9a-f]+:	fd2f 0000 	vcx1a	p0, d0, #1920
+ *[0-9a-f]+:	fd20 0080 	vcx1a	p0, d0, #64
+ *[0-9a-f]+:	fd20 003f 	vcx1a	p0, d0, #63
+ *[0-9a-f]+:	fd20 0700 	vcx1a	p7, d0, #0
+ *[0-9a-f]+:	fd20 f000 	vcx1a	p0, d15, #0
+ *[0-9a-f]+:	ec30 0000 	vcx2	p0, s0, s0, #0
+ *[0-9a-f]+:	ec3f 0000 	vcx2	p0, s0, s0, #60
+ *[0-9a-f]+:	ec30 0080 	vcx2	p0, s0, s0, #2
+ *[0-9a-f]+:	ec30 0010 	vcx2	p0, s0, s0, #1
+ *[0-9a-f]+:	ec30 0700 	vcx2	p7, s0, s0, #0
+ *[0-9a-f]+:	ec70 0000 	vcx2	p0, s1, s0, #0
+ *[0-9a-f]+:	ec30 f000 	vcx2	p0, s30, s0, #0
+ *[0-9a-f]+:	ec30 0020 	vcx2	p0, s0, s1, #0
+ *[0-9a-f]+:	ec30 000f 	vcx2	p0, s0, s30, #0
+ *[0-9a-f]+:	ed30 0000 	vcx2	p0, d0, d0, #0
+ *[0-9a-f]+:	ed3f 0000 	vcx2	p0, d0, d0, #60
+ *[0-9a-f]+:	ed30 0080 	vcx2	p0, d0, d0, #2
+ *[0-9a-f]+:	ed30 0010 	vcx2	p0, d0, d0, #1
+ *[0-9a-f]+:	ed30 0700 	vcx2	p7, d0, d0, #0
+ *[0-9a-f]+:	ed30 f000 	vcx2	p0, d15, d0, #0
+ *[0-9a-f]+:	ed30 000f 	vcx2	p0, d0, d15, #0
+ *[0-9a-f]+:	fc30 0000 	vcx2a	p0, s0, s0, #0
+ *[0-9a-f]+:	fc3f 0000 	vcx2a	p0, s0, s0, #60
+ *[0-9a-f]+:	fc30 0080 	vcx2a	p0, s0, s0, #2
+ *[0-9a-f]+:	fc30 0010 	vcx2a	p0, s0, s0, #1
+ *[0-9a-f]+:	fc30 0700 	vcx2a	p7, s0, s0, #0
+ *[0-9a-f]+:	fc70 0000 	vcx2a	p0, s1, s0, #0
+ *[0-9a-f]+:	fc30 f000 	vcx2a	p0, s30, s0, #0
+ *[0-9a-f]+:	fc30 0020 	vcx2a	p0, s0, s1, #0
+ *[0-9a-f]+:	fc30 000f 	vcx2a	p0, s0, s30, #0
+ *[0-9a-f]+:	fd30 0000 	vcx2a	p0, d0, d0, #0
+ *[0-9a-f]+:	fd3f 0000 	vcx2a	p0, d0, d0, #60
+ *[0-9a-f]+:	fd30 0080 	vcx2a	p0, d0, d0, #2
+ *[0-9a-f]+:	fd30 0010 	vcx2a	p0, d0, d0, #1
+ *[0-9a-f]+:	fd30 0700 	vcx2a	p7, d0, d0, #0
+ *[0-9a-f]+:	fd30 f000 	vcx2a	p0, d15, d0, #0
+ *[0-9a-f]+:	fd30 000f 	vcx2a	p0, d0, d15, #0
+ *[0-9a-f]+:	ec80 0000 	vcx3	p0, s0, s0, s0, #0
+ *[0-9a-f]+:	ecb0 0000 	vcx3	p0, s0, s0, s0, #6
+ *[0-9a-f]+:	ec80 0010 	vcx3	p0, s0, s0, s0, #1
+ *[0-9a-f]+:	ec80 0700 	vcx3	p7, s0, s0, s0, #0
+ *[0-9a-f]+:	ecc0 0000 	vcx3	p0, s1, s0, s0, #0
+ *[0-9a-f]+:	ec80 f000 	vcx3	p0, s30, s0, s0, #0
+ *[0-9a-f]+:	ec80 0080 	vcx3	p0, s0, s1, s0, #0
+ *[0-9a-f]+:	ec8f 0000 	vcx3	p0, s0, s30, s0, #0
+ *[0-9a-f]+:	ec80 0020 	vcx3	p0, s0, s0, s1, #0
+ *[0-9a-f]+:	ec80 000f 	vcx3	p0, s0, s0, s30, #0
+ *[0-9a-f]+:	ed80 0000 	vcx3	p0, d0, d0, d0, #0
+ *[0-9a-f]+:	edb0 0000 	vcx3	p0, d0, d0, d0, #6
+ *[0-9a-f]+:	ed80 0010 	vcx3	p0, d0, d0, d0, #1
+ *[0-9a-f]+:	ed80 0700 	vcx3	p7, d0, d0, d0, #0
+ *[0-9a-f]+:	ed80 f000 	vcx3	p0, d15, d0, d0, #0
+ *[0-9a-f]+:	ed8f 0000 	vcx3	p0, d0, d15, d0, #0
+ *[0-9a-f]+:	ed80 000f 	vcx3	p0, d0, d0, d15, #0
+ *[0-9a-f]+:	fc80 0000 	vcx3a	p0, s0, s0, s0, #0
+ *[0-9a-f]+:	fcb0 0000 	vcx3a	p0, s0, s0, s0, #6
+ *[0-9a-f]+:	fc80 0010 	vcx3a	p0, s0, s0, s0, #1
+ *[0-9a-f]+:	fc80 0700 	vcx3a	p7, s0, s0, s0, #0
+ *[0-9a-f]+:	fcc0 0000 	vcx3a	p0, s1, s0, s0, #0
+ *[0-9a-f]+:	fc80 f000 	vcx3a	p0, s30, s0, s0, #0
+ *[0-9a-f]+:	fc80 0080 	vcx3a	p0, s0, s1, s0, #0
+ *[0-9a-f]+:	fc8f 0000 	vcx3a	p0, s0, s30, s0, #0
+ *[0-9a-f]+:	fc80 0020 	vcx3a	p0, s0, s0, s1, #0
+ *[0-9a-f]+:	fc80 000f 	vcx3a	p0, s0, s0, s30, #0
+ *[0-9a-f]+:	fd80 0000 	vcx3a	p0, d0, d0, d0, #0
+ *[0-9a-f]+:	fdb0 0000 	vcx3a	p0, d0, d0, d0, #6
+ *[0-9a-f]+:	fd80 0010 	vcx3a	p0, d0, d0, d0, #1
+ *[0-9a-f]+:	fd80 0700 	vcx3a	p7, d0, d0, d0, #0
+ *[0-9a-f]+:	fd80 f000 	vcx3a	p0, d15, d0, d0, #0
+ *[0-9a-f]+:	fd8f 0000 	vcx3a	p0, d0, d15, d0, #0
+ *[0-9a-f]+:	fd80 000f 	vcx3a	p0, d0, d0, d15, #0
diff --git a/gas/testsuite/gas/arm/cde.s b/gas/testsuite/gas/arm/cde.s
index 1ee18704941aca9069777511c0feaf2004b592b7..e7ae1ea71b1117dfa8e8e3912a346c4690ba7046 100644
--- a/gas/testsuite/gas/arm/cde.s
+++ b/gas/testsuite/gas/arm/cde.s
@@ -1,3 +1,36 @@
 .syntax unified
 
 .include "cde-scalar.s"
+
+# vcx1{a} encoding has the following form
+# 111a110i0d10iiiidddd0pppi1iiiiii (vector form)
+
+# 111a110s0d10iiiidddd0pppi0iiiiii (S/D register form)
+#
+# Variants to test:
+# - immediates that set each set of `i` to ones in turn.
+# - each register set to something non-zero
+#   (where each block of register sets is set to all-ones if possible)
+# - coprocessor set to 7
+
+# vcx2{a} encoding has the following form
+# 111a110i0d11iiiidddd0pppi1mimmmm (vector form)
+# 111a110s0d11iiiidddd0pppi0mimmmm (S/D register form)
+#
+# Variants to test:
+# - immediates that set each set of `i` to ones in turn.
+# - each register set to something non-zero
+#   (where each block of register sets is set to all-ones if possible)
+# - coprocessor set to 7
+
+# vcx3{a} encoding has the following form
+# 111a110i1diinnnndddd0pppn1mimmmm (vector form)
+# 111a110s1diinnnndddd0pppn0mimmmm (S/D register form)
+#
+# Variants to test:
+# - immediates that set each set of `i` to ones in turn.
+# - each register set to something non-zero
+#   (where each block of register sets is set to all-ones if possible)
+# - coprocessor set to 7
+.include "cde-mve.s"
+.include "cde-mve-or-neon.s"
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 2a29887f1695435d45c1d7bb4a917212588d4315..b926b65d6a23ab5a3a7b543e3b0afefd1b673808 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -514,6 +514,27 @@ static const struct cdeopcode32 cde_opcodes[] =
 	      0xee800040, 0xef800840,
 	     "cx3d%a\t%p, %0-3S, %0-3T, %16-19n, %12-15n, #%4-5,7,20-22d"),
 
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xec200000, 0xeeb00840,
+	      "vcx1%a\t%p, %12-15,22V, #%0-5,7,16-19d"),
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xec200040, 0xeeb00840,
+	      "vcx1%a\t%p, %12-15,22V, #%0-5,7,16-19,24d"),
+
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xec300000, 0xeeb00840,
+	      "vcx2%a\t%p, %12-15,22V, %0-3,5V, #%4,7,16-19d"),
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xec300040, 0xeeb00840,
+	      "vcx2%a\t%p, %12-15,22V, %0-3,5V, #%4,7,16-19,24d"),
+
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xec800000, 0xee800840,
+	      "vcx3%a\t%p, %12-15,22V, %16-19,7V, %0-3,5V, #%4,20-21d"),
+  CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+	      0xec800040, 0xee800840,
+	      "vcx3%a\t%p, %12-15,22V, %16-19,7V, %0-3,5V, #%4,20-21,24d"),
+
   CDE_OPCODE (ARM_FEATURE_CORE_LOW (0), 0, 0, 0)
 
 };
@@ -8920,6 +8941,25 @@ print_insn_cde (struct disassemble_info *info, long given, bfd_boolean thumb)
 		    func (stream, "%ld", value);
 		    break;
 
+		  case 'V':
+		    if (given & (1 << 6))
+		      func (stream, "q%ld", value >> 1);
+		    else if (given & (1 << 24))
+		      func (stream, "d%ld", value);
+		    else
+		      {
+			/* Encoding for S register is different than for D and
+			   Q registers.  S registers are encoded using the top
+			   single bit in position 22 as the lowest bit of the
+			   register number, while for Q and D it represents the
+			   highest bit of the register number.  */
+			uint8_t top_bit = (value >> 4) & 1;
+			uint8_t tmp = (value << 1) & 0x1e;
+			uint8_t res = tmp | top_bit;
+			func (stream, "s%u", res);
+		      }
+		    break;
+
 		default:
 		  abort ();
 		}


[-- Attachment #2: cde1.patch.gz --]
[-- Type: application/gzip, Size: 9961 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension.
@ 2020-02-10 11:37 Matthew Malcomson
  2020-02-10 11:37 ` [Patch 1/2] [binutils][arm] arm support for ARMv8.m " Matthew Malcomson
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Matthew Malcomson @ 2020-02-10 11:37 UTC (permalink / raw)
  To: binutils; +Cc: Richard.Earnshaw, nickc, nd, ramana.radhakrishnan

[-- Attachment #1: Type: text/plain, Size: 710 bytes --]

Hello,

This patch series adds the Custom Datapath Extension to the arm backend.
This extension is currently only for the Thumb ISA.

The specification can be found here:
https://developer.arm.com/docs/ddi0607/latest

The patch is in two parts:
Part 1 enables the scalar instructions, which are predicated on *either*
Armv8-m with the floating point extension *or* Armv8.1-m with the MVE
extension.

Part 2 enables the vector instructions which are dependent on Armv8.1-m with
MVE.

Part 1 was worked on by both me and Stam Markianos-Wright.

The patch series has been successfully regression tested on arm-none-eabi and
arm-wince-pe.

Ok for master?

Regards,
MM

Entire patch series attached to cover letter.

[-- Attachment #2: all-patches.tar.gz --]
[-- Type: application/gzip, Size: 21282 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension.
  2020-02-10 11:37 [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Matthew Malcomson
  2020-02-10 11:37 ` [Patch 1/2] [binutils][arm] arm support for ARMv8.m " Matthew Malcomson
  2020-02-10 11:37 ` [Patch 2/2] [binutils][arm] Implement Custom Datapath Extensions for MVE Matthew Malcomson
@ 2020-02-10 15:11 ` Nick Clifton
  2020-02-10 21:50   ` Christophe Lyon
  2 siblings, 1 reply; 7+ messages in thread
From: Nick Clifton @ 2020-02-10 15:11 UTC (permalink / raw)
  To: Matthew Malcomson, binutils; +Cc: Richard.Earnshaw, nd, ramana.radhakrishnan

Hi Matthew,

> The patch is in two parts:
> Part 1 enables the scalar instructions, which are predicated on *either*
> Armv8-m with the floating point extension *or* Armv8.1-m with the MVE
> extension.
> 
> Part 2 enables the vector instructions which are dependent on Armv8.1-m with
> MVE.
> 
> Part 1 was worked on by both me and Stam Markianos-Wright.
> 
> The patch series has been successfully regression tested on arm-none-eabi and
> arm-wince-pe.
> 
> Ok for master?

Yes - please apply.

Cheers
  Nick


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension.
  2020-02-10 15:11 ` [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Nick Clifton
@ 2020-02-10 21:50   ` Christophe Lyon
  2020-02-11 10:51     ` Matthew Malcomson
  0 siblings, 1 reply; 7+ messages in thread
From: Christophe Lyon @ 2020-02-10 21:50 UTC (permalink / raw)
  To: Matthew Malcomson; +Cc: binutils

On Mon, 10 Feb 2020 at 16:11, Nick Clifton <nickc@redhat.com> wrote:
>
> Hi Matthew,
>
> > The patch is in two parts:
> > Part 1 enables the scalar instructions, which are predicated on *either*
> > Armv8-m with the floating point extension *or* Armv8.1-m with the MVE
> > extension.
> >
> > Part 2 enables the vector instructions which are dependent on Armv8.1-m with
> > MVE.
> >
> > Part 1 was worked on by both me and Stam Markianos-Wright.
> >
> > The patch series has been successfully regression tested on arm-none-eabi and
> > arm-wince-pe.
> >
> > Ok for master?
>
> Yes - please apply.
>

Hi,

One of these two patches causes a build failure for gas. I'm seeing:
../../gas/config/tc-arm.c: In function ‘vcx_handle_register_arguments’:
../../gas/config/tc-arm.c:21985:3: error: ‘for’ loop initial
declarations are only allowed in C99 mode
   for (unsigned i = 0; i < num_registers; i++)
   ^
../../gas/config/tc-arm.c:21985:3: note: use option -std=c99 or
-std=gnu99 to compile your code
make[4]: *** [config/tc-arm.o] Error 1

Can you fix it?
Thanks

Christophe

> Cheers
>   Nick
>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension.
  2020-02-10 21:50   ` Christophe Lyon
@ 2020-02-11 10:51     ` Matthew Malcomson
  2020-02-12  9:48       ` Christophe Lyon
  0 siblings, 1 reply; 7+ messages in thread
From: Matthew Malcomson @ 2020-02-11 10:51 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: binutils

On 10/02/2020 21:50, Christophe Lyon wrote:
> On Mon, 10 Feb 2020 at 16:11, Nick Clifton <nickc@redhat.com> wrote:
>>
>> Hi Matthew,
>>
>>> The patch is in two parts:
>>> Part 1 enables the scalar instructions, which are predicated on *either*
>>> Armv8-m with the floating point extension *or* Armv8.1-m with the MVE
>>> extension.
>>>
>>> Part 2 enables the vector instructions which are dependent on Armv8.1-m with
>>> MVE.
>>>
>>> Part 1 was worked on by both me and Stam Markianos-Wright.
>>>
>>> The patch series has been successfully regression tested on arm-none-eabi and
>>> arm-wince-pe.
>>>
>>> Ok for master?
>>
>> Yes - please apply.
>>
> 
> Hi,
> 
> One of these two patches causes a build failure for gas. I'm seeing:
> ../../gas/config/tc-arm.c: In function ‘vcx_handle_register_arguments’:
> ../../gas/config/tc-arm.c:21985:3: error: ‘for’ loop initial
> declarations are only allowed in C99 mode
>     for (unsigned i = 0; i < num_registers; i++)
>     ^
> ../../gas/config/tc-arm.c:21985:3: note: use option -std=c99 or
> -std=gnu99 to compile your code
> make[4]: *** [config/tc-arm.o] Error 1
> 
> Can you fix it?
> Thanks
> 
> Christophe

Wow!
I'm really sorry about that.

I've committed the fix as obvious, but I'd like to double check what 
went wrong here to ensure I avoid it in the future.

My best guess for the problem is that I compile with gcc 5 which has a 
default standard of gnu11, while you're testing with an earlier gcc 
which has a default standard of gnu89.

Does that fit? (i.e. are you using an older gcc?)

I will use `-std=gnu89` from now on.

Regards, and apologies again:
MM

> 
>> Cheers
>>    Nick
>>
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension.
  2020-02-11 10:51     ` Matthew Malcomson
@ 2020-02-12  9:48       ` Christophe Lyon
  0 siblings, 0 replies; 7+ messages in thread
From: Christophe Lyon @ 2020-02-12  9:48 UTC (permalink / raw)
  To: Matthew Malcomson; +Cc: binutils

On Tue, 11 Feb 2020 at 11:51, Matthew Malcomson
<matthew.malcomson@arm.com> wrote:
>
> On 10/02/2020 21:50, Christophe Lyon wrote:
> > On Mon, 10 Feb 2020 at 16:11, Nick Clifton <nickc@redhat.com> wrote:
> >>
> >> Hi Matthew,
> >>
> >>> The patch is in two parts:
> >>> Part 1 enables the scalar instructions, which are predicated on *either*
> >>> Armv8-m with the floating point extension *or* Armv8.1-m with the MVE
> >>> extension.
> >>>
> >>> Part 2 enables the vector instructions which are dependent on Armv8.1-m with
> >>> MVE.
> >>>
> >>> Part 1 was worked on by both me and Stam Markianos-Wright.
> >>>
> >>> The patch series has been successfully regression tested on arm-none-eabi and
> >>> arm-wince-pe.
> >>>
> >>> Ok for master?
> >>
> >> Yes - please apply.
> >>
> >
> > Hi,
> >
> > One of these two patches causes a build failure for gas. I'm seeing:
> > ../../gas/config/tc-arm.c: In function ‘vcx_handle_register_arguments’:
> > ../../gas/config/tc-arm.c:21985:3: error: ‘for’ loop initial
> > declarations are only allowed in C99 mode
> >     for (unsigned i = 0; i < num_registers; i++)
> >     ^
> > ../../gas/config/tc-arm.c:21985:3: note: use option -std=c99 or
> > -std=gnu99 to compile your code
> > make[4]: *** [config/tc-arm.o] Error 1
> >
> > Can you fix it?
> > Thanks
> >
> > Christophe
>
> Wow!
> I'm really sorry about that.
>
> I've committed the fix as obvious, but I'd like to double check what
> went wrong here to ensure I avoid it in the future.
>
> My best guess for the problem is that I compile with gcc 5 which has a
> default standard of gnu11, while you're testing with an earlier gcc
> which has a default standard of gnu89.
>
> Does that fit? (i.e. are you using an older gcc?)
>
Yes, that CI loop is running under Ubuntu Trusty, which has gcc-4.8.

I'm not sure what's the oldest GCC version supported by binutils though.

Thanks

Christophe

> I will use `-std=gnu89` from now on.
>
> Regards, and apologies again:
> MM
>
> >
> >> Cheers
> >>    Nick
> >>
> >>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-02-12  9:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-10 11:37 [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Matthew Malcomson
2020-02-10 11:37 ` [Patch 1/2] [binutils][arm] arm support for ARMv8.m " Matthew Malcomson
2020-02-10 11:37 ` [Patch 2/2] [binutils][arm] Implement Custom Datapath Extensions for MVE Matthew Malcomson
2020-02-10 15:11 ` [Patch 0/2] [binutils][arm] Armv8-M Custom Datapath Extension Nick Clifton
2020-02-10 21:50   ` Christophe Lyon
2020-02-11 10:51     ` Matthew Malcomson
2020-02-12  9:48       ` Christophe Lyon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).