diff mbox

[AARCH64] Remove Cn register for coprocessor CRn, CRm field

Message ID 5846EA93.7080009@foss.arm.com
State New
Headers show

Commit Message

Renlin Li Dec. 6, 2016, 4:42 p.m. UTC
Hi all,

This is a patch to remove the internal CN register representation for
coprocessor filed used in aarch64 sys, sysl instruction.

SYS #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>}
SYSL <Xt>, #<op1>, <Cn>, <Cm>, #<op2>

Cn, Cm filed are represented as as register in binutils. However, they are not.
They are just value encoded in CRn and CRm field. And they are used as immediate
instead of register number to access it's content.

So in this patch, the register representation is removed. The field is rename to
CRn and CRm, and constrained by immediate value range. AARCH64_OPND_QLF_CR qualifier
is also added for CRn, CRm filed to further guard the range of those immediate.

There will be two types of errors.

For example,
sysl x7, #1, x15, c3, #1
sysl x7, #1, c15, c16, #1

The first one is wrong type of operand. CRn operand should be used instead of x15 register.
Previously, this case is not properly handled. The following message will be given:
'''Fatal error: unhandled type 11'''

After the change. This case is also caught. And proper error message is printed.
'''operand 3 must be a 4-bit opcode field named for historical reasons C0 - C15 -- `sysl 
x7,#1,x15,C3,#1'

The second case is that c16 is out of range. The error message remains the same as before.

A new test instruction is added into diagnostic.s.
aarch64 binutils regression checked Okay without new regression. Okay to commit?

Regards,
Renlin Li

opcodes/ChangeLog:

2016-12-06 Renlin Li <renlin.li@arm.com>

	* aarch64-opc.c (aarch64_opnd_qualifiers): New CR value range
	qualifier.
	(operand_general_constraint_met_p): Remove case for CP_REG.
	(aarch64_print_operand): Print CRn, CRm operand using imm field.
	* aarch64-tbl.h (QL_SYS): Use CR qualifier.
	(QL_SYSL): Likewise.
	(aarch64_opcode_table): Change CRn, CRm operand class and type.
	* aarch64-opc-2.c : Regenerate.
	* aarch64-asm-2.c : Likewise.
	* aarch64-dis-2.c : Likewise.

include/ChangeLog:

2016-12-06 Renlin Li <renlin.li@arm.com>

	* opcode/aarch64.h (aarch64_operand_class): Remove
	AARCH64_OPND_CLASS_CP_REG.
	(enum aarch64_opnd): Change AARCH64_OPND_Cn to AARCH64_OPND_CRn,
	AARCH64_OPND_Cm to AARCH64_OPND_CRm.
	(aarch64_opnd_qualifier): Define AARCH64_OPND_QLF_CR qualifier.

gas/ChangeLog:

2016-12-06 Renlin Li <renlin.li@arm.com>

	* config/tc-aarch64.c (AARCH64_REG_TYPES): Remove CN register.
	(get_reg_expected_msg): Remove CN register case.
	(parse_operands): rewrite parser for CRn, CRm operand.
	(reg_names): Remove CN register.
	* testsuite/gas/aarch64/diagnostic.s: Add a new test case.
	* testsuite/gas/aarch64/diagnostic.l: Adjust error message.

Comments

Nick Clifton Dec. 9, 2016, 10:02 a.m. UTC | #1
Hi Renlin,

> opcodes/ChangeLog:

> 

> 2016-12-06 Renlin Li <renlin.li@arm.com>

> 

>     * aarch64-opc.c (aarch64_opnd_qualifiers): New CR value range

>     qualifier.

>     (operand_general_constraint_met_p): Remove case for CP_REG.

>     (aarch64_print_operand): Print CRn, CRm operand using imm field.

>     * aarch64-tbl.h (QL_SYS): Use CR qualifier.

>     (QL_SYSL): Likewise.

>     (aarch64_opcode_table): Change CRn, CRm operand class and type.

>     * aarch64-opc-2.c : Regenerate.

>     * aarch64-asm-2.c : Likewise.

>     * aarch64-dis-2.c : Likewise.

> 

> include/ChangeLog:

> 

> 2016-12-06 Renlin Li <renlin.li@arm.com>

> 

>     * opcode/aarch64.h (aarch64_operand_class): Remove

>     AARCH64_OPND_CLASS_CP_REG.

>     (enum aarch64_opnd): Change AARCH64_OPND_Cn to AARCH64_OPND_CRn,

>     AARCH64_OPND_Cm to AARCH64_OPND_CRm.

>     (aarch64_opnd_qualifier): Define AARCH64_OPND_QLF_CR qualifier.

> 

> gas/ChangeLog:

> 

> 2016-12-06 Renlin Li <renlin.li@arm.com>

> 

>     * config/tc-aarch64.c (AARCH64_REG_TYPES): Remove CN register.

>     (get_reg_expected_msg): Remove CN register case.

>     (parse_operands): rewrite parser for CRn, CRm operand.

>     (reg_names): Remove CN register.

>     * testsuite/gas/aarch64/diagnostic.s: Add a new test case.

>     * testsuite/gas/aarch64/diagnostic.l: Adjust error message.


Approved - please apply.

Cheers
  Nick
diff mbox

Patch

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index c71b32b..b0e8fc7 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -266,7 +266,6 @@  struct reloc_entry
   BASIC_REG_TYPE(FP_S)	/* s[0-31] */	\
   BASIC_REG_TYPE(FP_D)	/* d[0-31] */	\
   BASIC_REG_TYPE(FP_Q)	/* q[0-31] */	\
-  BASIC_REG_TYPE(CN)	/* c[0-7]  */	\
   BASIC_REG_TYPE(VN)	/* v[0-31] */	\
   BASIC_REG_TYPE(ZN)	/* z[0-31] */	\
   BASIC_REG_TYPE(PN)	/* p[0-15] */	\
@@ -407,9 +406,6 @@  get_reg_expected_msg (aarch64_reg_type reg_type)
       msg = N_("128-bit SIMD scalar or floating-point quad precision "
 	       "register expected");
       break;
-    case REG_TYPE_CN:
-      msg = N_("C0 - C15 expected");
-      break;
     case REG_TYPE_R_Z_BHSDQ_V:
     case REG_TYPE_R_Z_BHSDQ_VZP:
       msg = N_("register expected");
@@ -5520,16 +5516,23 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 	    goto failure;
 	  break;
 
-	case AARCH64_OPND_Cn:
-	case AARCH64_OPND_Cm:
-	  po_reg_or_fail (REG_TYPE_CN);
-	  if (val > 15)
+	case AARCH64_OPND_CRn:
+	case AARCH64_OPND_CRm:
 	    {
-	      set_fatal_syntax_error (_(get_reg_expected_msg (REG_TYPE_CN)));
-	      goto failure;
+	      char prefix = *(str++);
+	      if (prefix != 'c' && prefix != 'C')
+		goto failure;
+
+	      po_imm_nc_or_fail ();
+	      if (val > 15)
+		{
+		  set_fatal_syntax_error (_(N_ ("C0 - C15 expected")));
+		  goto failure;
+		}
+	      info->qualifier = AARCH64_OPND_QLF_CR;
+	      info->imm.value = val;
+	      break;
 	    }
-	  inst.base.operands[i].reg.regno = val;
-	  break;
 
 	case AARCH64_OPND_SHLL_IMM:
 	case AARCH64_OPND_IMM_VLSR:
@@ -6780,9 +6783,6 @@  static const reg_entry reg_names[] = {
   REGDEF (wzr, 31, Z_32), REGDEF (WZR, 31, Z_32),
   REGDEF (xzr, 31, Z_64), REGDEF (XZR, 31, Z_64),
 
-  /* Coprocessor register numbers.  */
-  REGSET (c, CN), REGSET (C, CN),
-
   /* Floating-point single precision registers.  */
   REGSET (s, FP_S), REGSET (S, FP_S),
 
diff --git a/gas/testsuite/gas/aarch64/diagnostic.l b/gas/testsuite/gas/aarch64/diagnostic.l
index 427a36a..6a2563e 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.l
+++ b/gas/testsuite/gas/aarch64/diagnostic.l
@@ -64,111 +64,112 @@ 
 [^:]*:66: Error: invalid addressing mode at operand 2 -- `ldrb w0,x1,x2,sxtx'
 [^:]*:67: Error: invalid shift amount at operand 2 -- `prfm PLDL3KEEP,\[x9,x15,sxtx#2\]'
 [^:]*:68: Error: C0 - C15 expected at operand 3 -- `sysl x7,#1,C16,C30,#1'
-[^:]*:69: Error: operand 4 must be a 4-bit opcode field named for historical reasons C0 - C15 -- `sysl x7,#1,C15,C77,#1'
-[^:]*:70: Error: extending shift is not permitted at operand 3 -- `add x0,xzr,x7,uxtx#5'
-[^:]*:71: Error: bad expression at operand 2 -- `mov x0,##5'
-[^:]*:72: Error: unknown mnemonic `bad' -- `bad expression'
-[^:]*:73: Error: unknown mnemonic `mockup' -- `mockup-op'
-[^:]*:74: Error: comma expected between operands at operand 2 -- `orr x0. x0,#0xff,lsl#1'
-[^:]*:75: Error: the specified relocation type is not allowed for MOVK at operand 2 -- `movk x1,#:abs_g1_s:s12'
-[^:]*:76: Error: can't mix relocation modifier with explicit shift at operand 2 -- `movz x1,#:abs_g1_s:s12,lsl#16'
-[^:]*:77: Error: register offset not allowed in pre-indexed addressing mode at operand 2 -- `prfm pldl3strm,\[sp,w0,sxtw#3\]!'
-[^:]*:78: Error: immediate value out of range 0 to 31 at operand 1 -- `prfm 0x2f,LABEL1'
-[^:]*:79: Error: immediate value out of range 0 to 15 at operand 1 -- `dmb #16'
-[^:]*:80: Error: immediate value out of range 0 to 31 at operand 2 -- `tbz w0,#40,0x17c'
-[^:]*:81: Error: invalid number of registers in the list; 2 registers are expected at operand 1 -- `st2 \{v4.2d,v5.2d,v6.2d\},\[x3\]'
-[^:]*:82: Error: invalid register list at operand 1 -- `ld2 \{v1.4h,v0.4h\},\[x1\]'
-[^:]*:83: Error: the specified option is not accepted in ISB at operand 1 -- `isb osh'
-[^:]*:84: Error: invalid address at operand 2 -- `st2 \{v4.2d,v5.2d,v6.2d\},\\\[x3\\\]'
-[^:]*:85: Error: immediate value must be a multiple of 4 at operand 3 -- `ldnp w7,w15,\[x3,#3\]'
-[^:]*:86: Error: unexpected address writeback at operand 3 -- `stnp x7,x15,\[x3,#32\]!'
-[^:]*:87: Error: immediate offset out of range -256 to 252 at operand 3 -- `ldnp w7,w15,\[x3,#256\]'
-[^:]*:88: Error: shift is not permitted at operand 2 -- `movi v1.2d,4294967295,lsl#0'
-[^:]*:89: Error: shift amount must be 0 at operand 2 -- `movi v1.8b,97,lsl#8'
-[^:]*:90: Error: unknown or missing system register name at operand 1 -- `msr dummy,x1'
-[^:]*:91: Error: invalid floating-point constant at operand 2 -- `fmov s0,0x42000000'
-[^:]*:92: Error: immediate value must be a multiple of 8 at operand 3 -- `ldp x0,x1,\[x2,#4\]'
-[^:]*:93: Error: immediate value must be a multiple of 8 at operand 3 -- `ldp x0,x1,\[x2,#4\]!'
-[^:]*:94: Error: immediate value must be a multiple of 8 at operand 3 -- `ldp x0,x1,\[x2\],#4'
-[^:]*:95: Error: immediate value must be a multiple of 4 at operand 3 -- `stp w0,w1,\[x2,#3\]'
-[^:]*:96: Error: immediate value must be a multiple of 4 at operand 3 -- `stp w0,w1,\[x2,#2\]!'
-[^:]*:97: Error: immediate value must be a multiple of 4 at operand 3 -- `stp w0,w1,\[x2\],#1'
-[^:]*:98: Error: operand 3 must be one of the standard conditions, excluding AL and NV. -- `cinc w0,w1,al'
-[^:]*:99: Error: operand 3 must be one of the standard conditions, excluding AL and NV. -- `cinc w0,w1,nv'
-[^:]*:100: Error: operand 2 must be one of the standard conditions, excluding AL and NV. -- `cset w0,al'
-[^:]*:101: Error: operand 2 must be one of the standard conditions, excluding AL and NV. -- `cset w0,nv'
-[^:]*:104: Error: operand 1 must be an integer register -- `ret lr'
-[^:]*:105: Error: operand 1 must be an integer register -- `ret kk'
-[^:]*:106: Error: immediate operand required at operand 1 -- `clrex x0'
-[^:]*:107: Error: immediate operand required at operand 1 -- `clrex w0'
-[^:]*:108: Error: constant expression required at operand 1 -- `clrex kk'
-[^:]*:109: Error: operand 5 must be an integer register -- `sys #0,c0,c0,#0,kk'
-[^:]*:110: Error: unexpected comma before the omitted optional operand at operand 5 -- `sys #0,c0,c0,#0,'
-[^:]*:112: Error: selected processor does not support `casp w0,w1,w2,w3,\[x4\]'
-[^:]*:115: Warning: unpredictable load of register pair -- `ldp x0,x0,\[sp\]'
-[^:]*:116: Warning: unpredictable load of register pair -- `ldp d0,d0,\[sp\]'
-[^:]*:117: Warning: unpredictable load of register pair -- `ldp x0,x0,\[sp\],#16'
-[^:]*:118: Warning: unpredictable load of register pair -- `ldnp x0,x0,\[sp\]'
-[^:]*:121: Warning: unpredictable transfer with writeback -- `ldr x0,\[x0,#8\]!'
-[^:]*:122: Warning: unpredictable transfer with writeback -- `str x0,\[x0,#8\]!'
-[^:]*:123: Warning: unpredictable transfer with writeback -- `str x1,\[x1\],#8'
-[^:]*:124: Warning: unpredictable transfer with writeback -- `stp x0,x1,\[x0,#16\]!'
-[^:]*:125: Warning: unpredictable transfer with writeback -- `ldp x0,x1,\[x1\],#16'
-[^:]*:126: Error: this relocation modifier is not allowed on this instruction at operand 2 -- `adr x2,:got:s1'
-[^:]*:127: Error: this relocation modifier is not allowed on this instruction at operand 2 -- `ldr x0,\[x0,:got:s1\]'
-[^:]*:130: Error: 64-bit integer or SP register expected at operand 2 -- `ldr x1,\[wsp,#8\]!'
-[^:]*:131: Error: 64-bit integer or SP register expected at operand 3 -- `ldp x6,x29,\[w7,#8\]!'
-[^:]*:132: Error: 64-bit integer or SP register expected at operand 2 -- `str x30,\[w11,#8\]!'
-[^:]*:133: Error: 64-bit integer or SP register expected at operand 3 -- `stp x8,x27,\[wsp,#8\]!'
-[^:]*:213: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[-1\]'
-[^:]*:216: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[2\]'
-[^:]*:217: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[64\]'
-[^:]*:219: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[-1\]'
-[^:]*:222: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[4\]'
-[^:]*:223: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[65\]'
-[^:]*:225: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[-1\]'
-[^:]*:228: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[8\]'
-[^:]*:229: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[66\]'
-[^:]*:231: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[-1\]'
-[^:]*:234: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[16\]'
-[^:]*:235: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[67\]'
-[^:]*:237: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[-1\],\[x0\]'
-[^:]*:240: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[2\],\[x0\]'
-[^:]*:241: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[64\],\[x0\]'
-[^:]*:243: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[-1\],\[x0\]'
-[^:]*:246: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[4\],\[x0\]'
-[^:]*:247: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[65\],\[x0\]'
-[^:]*:249: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[-1\],\[x0\]'
-[^:]*:252: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[8\],\[x0\]'
-[^:]*:253: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[66\],\[x0\]'
-[^:]*:255: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[-1\],\[x0\]'
-[^:]*:258: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[16\],\[x0\]'
-[^:]*:259: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[67\],\[x0\]'
-[^:]*:261: Error: invalid floating-point constant at operand 2 -- `fmov d0,#2'
-[^:]*:262: Error: invalid floating-point constant at operand 2 -- `fmov d0,#-2'
-[^:]*:263: Error: invalid floating-point constant at operand 2 -- `fmov s0,2'
-[^:]*:264: Error: invalid floating-point constant at operand 2 -- `fmov s0,-2'
-[^:]*:266: Error: integer 64-bit register expected at operand 2 -- `st2 {v0.4s,v1.4s},\[sp\],xzr'
-[^:]*:267: Error: integer or zero register expected at operand 2 -- `str x1,\[x2,sp\]'
-[^:]*:270: Error: relocation not allowed at operand 3 -- `ldnp x1,x2,\[x3,#:lo12:foo\]'
-[^:]*:271: Error: invalid addressing mode at operand 2 -- `ld1 {v0\.4s},\[x3,#:lo12:foo\]'
-[^:]*:272: Error: the optional immediate offset can only be 0 at operand 2 -- `stuminl x0,\[x3,#:lo12:foo\]'
-[^:]*:273: Error: relocation not allowed at operand 2 -- `prfum pldl1keep,\[x3,#:lo12:foo\]'
-[^:]*:275: Error: invalid addressing mode at operand 2 -- `ldr x0,\[x3\],x4'
-[^:]*:276: Error: invalid addressing mode at operand 3 -- `ldnp x1,x2,\[x3\],x4'
-[^:]*:278: Error: invalid addressing mode at operand 2 -- `stuminl x0,\[x3\],x4'
-[^:]*:279: Error: invalid addressing mode at operand 2 -- `prfum pldl1keep,\[x3\],x4'
-[^:]*:281: Error: '\]' expected at operand 2 -- `ldr x0,\[x1,#1,mul vl\]'
-[^:]*:282: Error: invalid use of 'MUL' at operand 2 -- `ldr x0,\[x1,x2,mul vl\]'
-[^:]*:283: Error: invalid use of 'MUL' at operand 2 -- `ldr x0,\[x1,x2,mul#1\]'
-[^:]*:284: Error: invalid use of 'MUL' at operand 2 -- `ldr x0,\[x1,x2,mul#4\]'
-[^:]*:286: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,x0,mul\]'
-[^:]*:287: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,x0,mul#1\]'
-[^:]*:288: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,w0,mul\]'
-[^:]*:289: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,w0,mul#2\]'
-[^:]*:291: Error: invalid use of 'MUL' at operand 3 -- `adds x1,sp,1,mul#1'
-[^:]*:292: Error: invalid use of 'MUL' at operand 3 -- `adds x1,sp,2,mul#255'
-[^:]*:293: Error: invalid use of 'MUL' at operand 3 -- `adds x1,sp,3,mul#256'
-[^:]*:294: Error: invalid use of 'MUL' at operand 4 -- `orr x0,x0,#0xff,mul#1'
-[^:]*:295: Error: invalid use of 'MUL' at operand 4 -- `orr x0,x0,#0xfe,mul#255'
-[^:]*:296: Error: invalid use of 'MUL' at operand 4 -- `orr x0,x0,#0xfc,mul#256'
+[^:]*:69: Error: C0 - C15 expected at operand 4 -- `sysl x7,#1,C15,C77,#1'
+[^:]*:70: Error: operand 3 must be a 4-bit opcode field named for historical reasons C0 - C15 -- `sysl x7,#1,x15,C1,#1'
+[^:]*:71: Error: extending shift is not permitted at operand 3 -- `add x0,xzr,x7,uxtx#5'
+[^:]*:72: Error: bad expression at operand 2 -- `mov x0,##5'
+[^:]*:73: Error: unknown mnemonic `bad' -- `bad expression'
+[^:]*:74: Error: unknown mnemonic `mockup' -- `mockup-op'
+[^:]*:75: Error: comma expected between operands at operand 2 -- `orr x0. x0,#0xff,lsl#1'
+[^:]*:76: Error: the specified relocation type is not allowed for MOVK at operand 2 -- `movk x1,#:abs_g1_s:s12'
+[^:]*:77: Error: can't mix relocation modifier with explicit shift at operand 2 -- `movz x1,#:abs_g1_s:s12,lsl#16'
+[^:]*:78: Error: register offset not allowed in pre-indexed addressing mode at operand 2 -- `prfm pldl3strm,\[sp,w0,sxtw#3\]!'
+[^:]*:79: Error: immediate value out of range 0 to 31 at operand 1 -- `prfm 0x2f,LABEL1'
+[^:]*:80: Error: immediate value out of range 0 to 15 at operand 1 -- `dmb #16'
+[^:]*:81: Error: immediate value out of range 0 to 31 at operand 2 -- `tbz w0,#40,0x17c'
+[^:]*:82: Error: invalid number of registers in the list; 2 registers are expected at operand 1 -- `st2 \{v4.2d,v5.2d,v6.2d\},\[x3\]'
+[^:]*:83: Error: invalid register list at operand 1 -- `ld2 \{v1.4h,v0.4h\},\[x1\]'
+[^:]*:84: Error: the specified option is not accepted in ISB at operand 1 -- `isb osh'
+[^:]*:85: Error: invalid address at operand 2 -- `st2 \{v4.2d,v5.2d,v6.2d\},\\\[x3\\\]'
+[^:]*:86: Error: immediate value must be a multiple of 4 at operand 3 -- `ldnp w7,w15,\[x3,#3\]'
+[^:]*:87: Error: unexpected address writeback at operand 3 -- `stnp x7,x15,\[x3,#32\]!'
+[^:]*:88: Error: immediate offset out of range -256 to 252 at operand 3 -- `ldnp w7,w15,\[x3,#256\]'
+[^:]*:89: Error: shift is not permitted at operand 2 -- `movi v1.2d,4294967295,lsl#0'
+[^:]*:90: Error: shift amount must be 0 at operand 2 -- `movi v1.8b,97,lsl#8'
+[^:]*:91: Error: unknown or missing system register name at operand 1 -- `msr dummy,x1'
+[^:]*:92: Error: invalid floating-point constant at operand 2 -- `fmov s0,0x42000000'
+[^:]*:93: Error: immediate value must be a multiple of 8 at operand 3 -- `ldp x0,x1,\[x2,#4\]'
+[^:]*:94: Error: immediate value must be a multiple of 8 at operand 3 -- `ldp x0,x1,\[x2,#4\]!'
+[^:]*:95: Error: immediate value must be a multiple of 8 at operand 3 -- `ldp x0,x1,\[x2\],#4'
+[^:]*:96: Error: immediate value must be a multiple of 4 at operand 3 -- `stp w0,w1,\[x2,#3\]'
+[^:]*:97: Error: immediate value must be a multiple of 4 at operand 3 -- `stp w0,w1,\[x2,#2\]!'
+[^:]*:98: Error: immediate value must be a multiple of 4 at operand 3 -- `stp w0,w1,\[x2\],#1'
+[^:]*:99: Error: operand 3 must be one of the standard conditions, excluding AL and NV. -- `cinc w0,w1,al'
+[^:]*:100: Error: operand 3 must be one of the standard conditions, excluding AL and NV. -- `cinc w0,w1,nv'
+[^:]*:101: Error: operand 2 must be one of the standard conditions, excluding AL and NV. -- `cset w0,al'
+[^:]*:102: Error: operand 2 must be one of the standard conditions, excluding AL and NV. -- `cset w0,nv'
+[^:]*:105: Error: operand 1 must be an integer register -- `ret lr'
+[^:]*:106: Error: operand 1 must be an integer register -- `ret kk'
+[^:]*:107: Error: immediate operand required at operand 1 -- `clrex x0'
+[^:]*:108: Error: immediate operand required at operand 1 -- `clrex w0'
+[^:]*:109: Error: constant expression required at operand 1 -- `clrex kk'
+[^:]*:110: Error: operand 5 must be an integer register -- `sys #0,c0,c0,#0,kk'
+[^:]*:111: Error: unexpected comma before the omitted optional operand at operand 5 -- `sys #0,c0,c0,#0,'
+[^:]*:113: Error: selected processor does not support `casp w0,w1,w2,w3,\[x4\]'
+[^:]*:116: Warning: unpredictable load of register pair -- `ldp x0,x0,\[sp\]'
+[^:]*:117: Warning: unpredictable load of register pair -- `ldp d0,d0,\[sp\]'
+[^:]*:118: Warning: unpredictable load of register pair -- `ldp x0,x0,\[sp\],#16'
+[^:]*:119: Warning: unpredictable load of register pair -- `ldnp x0,x0,\[sp\]'
+[^:]*:122: Warning: unpredictable transfer with writeback -- `ldr x0,\[x0,#8\]!'
+[^:]*:123: Warning: unpredictable transfer with writeback -- `str x0,\[x0,#8\]!'
+[^:]*:124: Warning: unpredictable transfer with writeback -- `str x1,\[x1\],#8'
+[^:]*:125: Warning: unpredictable transfer with writeback -- `stp x0,x1,\[x0,#16\]!'
+[^:]*:126: Warning: unpredictable transfer with writeback -- `ldp x0,x1,\[x1\],#16'
+[^:]*:127: Error: this relocation modifier is not allowed on this instruction at operand 2 -- `adr x2,:got:s1'
+[^:]*:128: Error: this relocation modifier is not allowed on this instruction at operand 2 -- `ldr x0,\[x0,:got:s1\]'
+[^:]*:131: Error: 64-bit integer or SP register expected at operand 2 -- `ldr x1,\[wsp,#8\]!'
+[^:]*:132: Error: 64-bit integer or SP register expected at operand 3 -- `ldp x6,x29,\[w7,#8\]!'
+[^:]*:133: Error: 64-bit integer or SP register expected at operand 2 -- `str x30,\[w11,#8\]!'
+[^:]*:134: Error: 64-bit integer or SP register expected at operand 3 -- `stp x8,x27,\[wsp,#8\]!'
+[^:]*:214: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[-1\]'
+[^:]*:217: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[2\]'
+[^:]*:218: Error: register element index out of range 0 to 1 at operand 2 -- `dup v0\.2d,v1\.2d\[64\]'
+[^:]*:220: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[-1\]'
+[^:]*:223: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[4\]'
+[^:]*:224: Error: register element index out of range 0 to 3 at operand 2 -- `dup v0\.4s,v1\.4s\[65\]'
+[^:]*:226: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[-1\]'
+[^:]*:229: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[8\]'
+[^:]*:230: Error: register element index out of range 0 to 7 at operand 2 -- `dup v0\.8h,v1\.8h\[66\]'
+[^:]*:232: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[-1\]'
+[^:]*:235: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[16\]'
+[^:]*:236: Error: register element index out of range 0 to 15 at operand 2 -- `dup v0\.16b,v1\.16b\[67\]'
+[^:]*:238: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[-1\],\[x0\]'
+[^:]*:241: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[2\],\[x0\]'
+[^:]*:242: Error: register element index out of range 0 to 1 at operand 1 -- `ld2 {v0\.d,v1\.d}\[64\],\[x0\]'
+[^:]*:244: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[-1\],\[x0\]'
+[^:]*:247: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[4\],\[x0\]'
+[^:]*:248: Error: register element index out of range 0 to 3 at operand 1 -- `ld2 {v0\.s,v1\.s}\[65\],\[x0\]'
+[^:]*:250: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[-1\],\[x0\]'
+[^:]*:253: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[8\],\[x0\]'
+[^:]*:254: Error: register element index out of range 0 to 7 at operand 1 -- `ld2 {v0\.h,v1\.h}\[66\],\[x0\]'
+[^:]*:256: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[-1\],\[x0\]'
+[^:]*:259: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[16\],\[x0\]'
+[^:]*:260: Error: register element index out of range 0 to 15 at operand 1 -- `ld2 {v0\.b,v1\.b}\[67\],\[x0\]'
+[^:]*:262: Error: invalid floating-point constant at operand 2 -- `fmov d0,#2'
+[^:]*:263: Error: invalid floating-point constant at operand 2 -- `fmov d0,#-2'
+[^:]*:264: Error: invalid floating-point constant at operand 2 -- `fmov s0,2'
+[^:]*:265: Error: invalid floating-point constant at operand 2 -- `fmov s0,-2'
+[^:]*:267: Error: integer 64-bit register expected at operand 2 -- `st2 {v0.4s,v1.4s},\[sp\],xzr'
+[^:]*:268: Error: integer or zero register expected at operand 2 -- `str x1,\[x2,sp\]'
+[^:]*:271: Error: relocation not allowed at operand 3 -- `ldnp x1,x2,\[x3,#:lo12:foo\]'
+[^:]*:272: Error: invalid addressing mode at operand 2 -- `ld1 {v0\.4s},\[x3,#:lo12:foo\]'
+[^:]*:273: Error: the optional immediate offset can only be 0 at operand 2 -- `stuminl x0,\[x3,#:lo12:foo\]'
+[^:]*:274: Error: relocation not allowed at operand 2 -- `prfum pldl1keep,\[x3,#:lo12:foo\]'
+[^:]*:276: Error: invalid addressing mode at operand 2 -- `ldr x0,\[x3\],x4'
+[^:]*:277: Error: invalid addressing mode at operand 3 -- `ldnp x1,x2,\[x3\],x4'
+[^:]*:279: Error: invalid addressing mode at operand 2 -- `stuminl x0,\[x3\],x4'
+[^:]*:280: Error: invalid addressing mode at operand 2 -- `prfum pldl1keep,\[x3\],x4'
+[^:]*:282: Error: '\]' expected at operand 2 -- `ldr x0,\[x1,#1,mul vl\]'
+[^:]*:283: Error: invalid use of 'MUL' at operand 2 -- `ldr x0,\[x1,x2,mul vl\]'
+[^:]*:284: Error: invalid use of 'MUL' at operand 2 -- `ldr x0,\[x1,x2,mul#1\]'
+[^:]*:285: Error: invalid use of 'MUL' at operand 2 -- `ldr x0,\[x1,x2,mul#4\]'
+[^:]*:287: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,x0,mul\]'
+[^:]*:288: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,x0,mul#1\]'
+[^:]*:289: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,w0,mul\]'
+[^:]*:290: Error: invalid use of 'MUL' at operand 2 -- `strb w7,\[x30,w0,mul#2\]'
+[^:]*:292: Error: invalid use of 'MUL' at operand 3 -- `adds x1,sp,1,mul#1'
+[^:]*:293: Error: invalid use of 'MUL' at operand 3 -- `adds x1,sp,2,mul#255'
+[^:]*:294: Error: invalid use of 'MUL' at operand 3 -- `adds x1,sp,3,mul#256'
+[^:]*:295: Error: invalid use of 'MUL' at operand 4 -- `orr x0,x0,#0xff,mul#1'
+[^:]*:296: Error: invalid use of 'MUL' at operand 4 -- `orr x0,x0,#0xfe,mul#255'
+[^:]*:297: Error: invalid use of 'MUL' at operand 4 -- `orr x0,x0,#0xfc,mul#256'
diff --git a/gas/testsuite/gas/aarch64/diagnostic.s b/gas/testsuite/gas/aarch64/diagnostic.s
index 7974bc2..d2b9244 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.s
+++ b/gas/testsuite/gas/aarch64/diagnostic.s
@@ -67,6 +67,7 @@ 
 	prfm	PLDL3KEEP, [x9, x15, sxtx #2]
 	sysl	x7, #1, C16, C30, #1
 	sysl	x7, #1, C15, C77, #1
+	sysl	x7, #1, x15, C1, #1
 	add	x0, xzr, x7, uxtx #5
 	mov	x0, ##5
 	bad expression
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 69645d0..f129a6d 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -113,7 +113,6 @@  enum aarch64_operand_class
   AARCH64_OPND_CLASS_SIMD_ELEMENT,
   AARCH64_OPND_CLASS_SISD_REG,
   AARCH64_OPND_CLASS_SIMD_REGLIST,
-  AARCH64_OPND_CLASS_CP_REG,
   AARCH64_OPND_CLASS_SVE_REG,
   AARCH64_OPND_CLASS_PRED_REG,
   AARCH64_OPND_CLASS_ADDRESS,
@@ -170,8 +169,8 @@  enum aarch64_opnd
 			   structure to all lanes.  */
   AARCH64_OPND_LEt,	/* AdvSIMD Vector Element list.  */
 
-  AARCH64_OPND_Cn,	/* Co-processor register in CRn field.  */
-  AARCH64_OPND_Cm,	/* Co-processor register in CRm field.  */
+  AARCH64_OPND_CRn,	/* Co-processor register in CRn field.  */
+  AARCH64_OPND_CRm,	/* Co-processor register in CRm field.  */
 
   AARCH64_OPND_IDX,	/* AdvSIMD EXT index operand.  */
   AARCH64_OPND_IMM_VLSL,/* Immediate for shifting vector registers left.  */
@@ -394,6 +393,7 @@  enum aarch64_opnd_qualifier
   AARCH64_OPND_QLF_P_M,
 
   /* Constraint on value.  */
+  AARCH64_OPND_QLF_CR,		/* CRn, CRm. */
   AARCH64_OPND_QLF_imm_0_7,
   AARCH64_OPND_QLF_imm_0_15,
   AARCH64_OPND_QLF_imm_0_31,
diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
index 121bde8..5d5ec78 100644
--- a/opcodes/aarch64-asm-2.c
+++ b/opcodes/aarch64-asm-2.c
@@ -611,8 +611,6 @@  aarch64_insert_operand (const aarch64_operand *self,
     case 26:
     case 27:
     case 28:
-    case 36:
-    case 37:
     case 144:
     case 145:
     case 146:
@@ -653,6 +651,8 @@  aarch64_insert_operand (const aarch64_operand *self,
       return aarch64_ins_ldst_reglist_r (self, info, code, inst);
     case 35:
       return aarch64_ins_ldst_elemlist (self, info, code, inst);
+    case 36:
+    case 37:
     case 38:
     case 48:
     case 49:
diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
index 19b3dcf..ffae39e 100644
--- a/opcodes/aarch64-dis-2.c
+++ b/opcodes/aarch64-dis-2.c
@@ -18694,8 +18694,6 @@  aarch64_extract_operand (const aarch64_operand *self,
     case 26:
     case 27:
     case 28:
-    case 36:
-    case 37:
     case 144:
     case 145:
     case 146:
@@ -18740,6 +18738,8 @@  aarch64_extract_operand (const aarch64_operand *self,
       return aarch64_ext_ldst_reglist_r (self, info, code, inst);
     case 35:
       return aarch64_ext_ldst_elemlist (self, info, code, inst);
+    case 36:
+    case 37:
     case 38:
     case 48:
     case 49:
diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
index e1729a8..cfa7467 100644
--- a/opcodes/aarch64-opc-2.c
+++ b/opcodes/aarch64-opc-2.c
@@ -60,8 +60,8 @@  const struct aarch64_operand aarch64_operands[] =
   {AARCH64_OPND_CLASS_SIMD_REGLIST, "LVt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a SIMD vector register list"},
   {AARCH64_OPND_CLASS_SIMD_REGLIST, "LVt_AL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a SIMD vector register list"},
   {AARCH64_OPND_CLASS_SIMD_REGLIST, "LEt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a SIMD vector element list"},
-  {AARCH64_OPND_CLASS_CP_REG, "Cn", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRn}, "a 4-bit opcode field named for historical reasons C0 - C15"},
-  {AARCH64_OPND_CLASS_CP_REG, "Cm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRm}, "a 4-bit opcode field named for historical reasons C0 - C15"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "CRn", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRn}, "a 4-bit opcode field named for historical reasons C0 - C15"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "CRm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRm}, "a 4-bit opcode field named for historical reasons C0 - C15"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "IDX", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm4}, "an immediate as the index of the least significant byte"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "IMM_VLSL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a left shift amount for an AdvSIMD register"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "IMM_VLSR", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a right shift amount for an AdvSIMD register"},
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 5b9eb27..4275d4d 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -711,6 +711,7 @@  struct operand_qualifier_data aarch64_opnd_qualifiers[] =
      First 3 fields:
      Lower bound, higher bound, unused.  */
 
+  {0, 15, 0, "CR",       OQK_VALUE_IN_RANGE},
   {0,  7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
   {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
   {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
@@ -2418,16 +2419,6 @@  operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	}
       break;
 
-    case AARCH64_OPND_CLASS_CP_REG:
-      /* Cn or Cm: 4-bit opcode field named for historical reasons.
-	 valid range: C0 - C15.  */
-      if (opnd->reg.regno > 15)
-	{
-	  set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
-	  return 0;
-	}
-      break;
-
     case AARCH64_OPND_CLASS_SYSTEM:
       switch (type)
 	{
@@ -3187,9 +3178,9 @@  aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 		opnd->reglane.index);
       break;
 
-    case AARCH64_OPND_Cn:
-    case AARCH64_OPND_Cm:
-      snprintf (buf, size, "C%d", opnd->reg.regno);
+    case AARCH64_OPND_CRn:
+    case AARCH64_OPND_CRm:
+      snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
       break;
 
     case AARCH64_OPND_IDX:
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 0efd98e..4fd009f 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -59,13 +59,13 @@ 
 /* e.g. SYS #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>}.  */
 #define QL_SYS			\
 {				\
-  QLF5(NIL,NIL,NIL,NIL,X),	\
+  QLF5(NIL,CR,CR,NIL,X),	\
 }
 
 /* e.g. SYSL <Xt>, #<op1>, <Cn>, <Cm>, #<op2>.  */
 #define QL_SYSL			\
 {				\
-  QLF5(X,NIL,NIL,NIL,NIL),	\
+  QLF5(X,NIL,CR,CR,NIL),	\
 }
 
 /* e.g. ADRP <Xd>, <label>.  */
@@ -3237,13 +3237,13 @@  struct aarch64_opcode aarch64_opcode_table[] =
   CORE_INSN ("dsb", 0xd503309f, 0xfffff0ff, ic_system, 0, OP1 (BARRIER), {}, 0),
   CORE_INSN ("dmb", 0xd50330bf, 0xfffff0ff, ic_system, 0, OP1 (BARRIER), {}, 0),
   CORE_INSN ("isb", 0xd50330df, 0xfffff0ff, ic_system, 0, OP1 (BARRIER_ISB), {}, F_OPD0_OPT | F_DEFAULT (0xF)),
-  CORE_INSN ("sys", 0xd5080000, 0xfff80000, ic_system, 0, OP5 (UIMM3_OP1, Cn, Cm, UIMM3_OP2, Rt), QL_SYS, F_HAS_ALIAS | F_OPD4_OPT | F_DEFAULT (0x1F)),
+  CORE_INSN ("sys", 0xd5080000, 0xfff80000, ic_system, 0, OP5 (UIMM3_OP1, CRn, CRm, UIMM3_OP2, Rt), QL_SYS, F_HAS_ALIAS | F_OPD4_OPT | F_DEFAULT (0x1F)),
   CORE_INSN ("at",  0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_AT, Rt), QL_SRC_X, F_ALIAS),
   CORE_INSN ("dc",  0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_DC, Rt), QL_SRC_X, F_ALIAS),
   CORE_INSN ("ic",  0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_IC, Rt_SYS), QL_SRC_X, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)),
   CORE_INSN ("tlbi",0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_TLBI, Rt_SYS), QL_SRC_X, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)),
   CORE_INSN ("msr", 0xd5000000, 0xffe00000, ic_system, 0, OP2 (SYSREG, Rt), QL_SRC_X, 0),
-  CORE_INSN ("sysl",0xd5280000, 0xfff80000, ic_system, 0, OP5 (Rt, UIMM3_OP1, Cn, Cm, UIMM3_OP2), QL_SYSL, 0),
+  CORE_INSN ("sysl",0xd5280000, 0xfff80000, ic_system, 0, OP5 (Rt, UIMM3_OP1, CRn, CRm, UIMM3_OP2), QL_SYSL, 0),
   CORE_INSN ("mrs", 0xd5200000, 0xffe00000, ic_system, 0, OP2 (Rt, SYSREG), QL_DST_X, 0),
   V8_3_INSN ("paciaz",  0xd503231f, 0xffffffff, ic_system, OP0 (), {}, F_ALIAS),
   V8_3_INSN ("paciasp", 0xd503233f, 0xffffffff, ic_system, OP0 (), {}, F_ALIAS),
@@ -4084,9 +4084,9 @@  struct aarch64_opcode aarch64_opcode_table[] =
       "a SIMD vector register list")					\
     Y(SIMD_REGLIST, ldst_elemlist, "LEt", 0, F(),			\
       "a SIMD vector element list")					\
-    Y(CP_REG, regno, "Cn", 0, F(FLD_CRn),				\
+    Y(IMMEDIATE, imm, "CRn", 0, F(FLD_CRn),				\
       "a 4-bit opcode field named for historical reasons C0 - C15")	\
-    Y(CP_REG, regno, "Cm", 0, F(FLD_CRm),				\
+    Y(IMMEDIATE, imm, "CRm", 0, F(FLD_CRm),				\
       "a 4-bit opcode field named for historical reasons C0 - C15")	\
     Y(IMMEDIATE, imm, "IDX", 0, F(FLD_imm4),				\
       "an immediate as the index of the least significant byte")	\