aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog44
-rw-r--r--gas/config/tc-arm.c321
-rw-r--r--gas/doc/c-arm.texi8
-rw-r--r--gas/testsuite/gas/arm/cde-scalar.d117
-rw-r--r--gas/testsuite/gas/arm/cde-scalar.s206
-rw-r--r--gas/testsuite/gas/arm/cde-warnings.d5
-rw-r--r--gas/testsuite/gas/arm/cde-warnings.l175
-rw-r--r--gas/testsuite/gas/arm/cde-warnings.s335
-rw-r--r--gas/testsuite/gas/arm/cde.d119
-rw-r--r--gas/testsuite/gas/arm/cde.s3
10 files changed, 1330 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d7d91a4..6df870a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,47 @@
+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.
+
2020-02-10 H.J. Lu <hongjiu.lu@intel.com>
PR gas/25516
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 26a76f3..93d04ee 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. */
@@ -26099,6 +26382,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
@@ -31280,12 +31581,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_AEXT_V8M_MAIN_DSP),
ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_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 }
};
@@ -31307,9 +31619,12 @@ static const struct arm_ext_table armv8_1m_main_ext_table[] =
ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP,
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 e19d2a8..9180360 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 0000000..3626012
--- /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 0000000..ac188a3
--- /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 0000000..1421b99
--- /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 0000000..abbd10a
--- /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 0000000..8e5759a
--- /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 0000000..34de201
--- /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 0000000..1ee1870
--- /dev/null
+++ b/gas/testsuite/gas/arm/cde.s
@@ -0,0 +1,3 @@
+.syntax unified
+
+.include "cde-scalar.s"