aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--include/ChangeLog13
-rw-r--r--include/opcode/arm.h9
-rw-r--r--opcodes/ChangeLog12
-rw-r--r--opcodes/arm-dis.c210
14 files changed, 1573 insertions, 4 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"
diff --git a/include/ChangeLog b/include/ChangeLog
index 6facd28..9c0b5d2 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,16 @@
+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.
+
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 6d8c3d0..979bd20 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/ChangeLog b/opcodes/ChangeLog
index d8f84c8..fb4f262 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,15 @@
+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.
+
2020-02-10 H.J. Lu <hongjiu.lu@intel.com>
PR gas/25516
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index be2a932..2a29887 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);