+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
 
   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;
    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.  */
 #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")
 #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 " \
   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 */
        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;
 
 }
 
+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)
            gas_assert (0);
        case IF_INSIDE_IT_LAST_INSN:
        case NEUTRAL_IT_INSN:
+       case NEUTRAL_IT_NO_VPT_INSN:
          break;
 
        case VPT_INSN:
            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;
              }
            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.  */
  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
   { 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 }
 };
 
           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)),
 
 @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.
 
 
--- /dev/null
+#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
 
--- /dev/null
+.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
+
+
 
--- /dev/null
+#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
 
--- /dev/null
+[^ :]+: 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'
 
--- /dev/null
+.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
 
--- /dev/null
+#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
 
--- /dev/null
+.syntax unified
+
+.include "cde-scalar.s"
 
+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
 
 #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.                  */
 
+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
 
   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
 
 /* 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.  */
   { "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[] =
 #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.  */
   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.  */
   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;
 
        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);