[Arm] <spec_reg> changes for VMRS and VMSR instructions for Armv8.1-M Mainline

Message ID ce3d0e70-7da8-510d-195c-4ec623f49792@arm.com
State New
Headers show
Series
  • [Arm] <spec_reg> changes for VMRS and VMSR instructions for Armv8.1-M Mainline
Related show

Commit Message

Sudakshina Das May 21, 2019, 10:11 a.m.
Hi

This patch makes changes to the <spec_reg> operand for VMRS and VMSR 
instructions as per the Armv8.1-M Mainline.
New <spec_reg> options to support are:

0b0010: FPSCR_nzcvqc, access to FPSCR condition and saturation flags.
0b1100: VPR, privileged only access to the VPR register.
0b1101: P0, access to VPR.P0 predicate fields
0b1110: FPCXT_NS, enables saving and restoring of Non-secure floating 
point context.
0b1111: FPCXT_S, enables saving and restoring of Secure floating point 
context.

Testing: Added new test for the valid instruction operands. Testsuite 
shows no regression when run for arm-none-eabi targets.

Thanks
Sudi


ChangeLog entries are as follows :

*** gas/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

     * config/tc-arm.c (parse_operands): Update case OP_RVC to
     parse p0 and P0.
     (do_vmrs): Add checks for valid operands with respect to
     cpu and fpu options.
     (do_vmsr): Likewise.
     (reg_names): New reg_names for FPSCR_nzcvqc, VPR, FPCXT_NS
     and FPCXT_S.
     * testsuite/gas/arm/armv8_1-m-spec-reg.d: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg.s: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg-bad1.d: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg-bad2.d: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg-bad3.d: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg-bad1.l: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg-bad2.l: New.
     * testsuite/gas/arm/armv8_1-m-spec-reg-bad3.l: New.
     * testsuite/gas/arm/vfp1xD.d: Updated to allow new valid values.
     * testsuite/gas/arm/vfp1xD_t2.d: Likewise.

*** opcodes/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

     * arm-dis.c (coprocessor_opcodes): New instructions for VMRS
     and VMSR with the new operands.

Comments

Nick Clifton May 21, 2019, 1:38 p.m. | #1
Hi Sudi,

> *** gas/ChangeLog ***

> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

> 

>      * config/tc-arm.c (parse_operands): Update case OP_RVC to

>      parse p0 and P0.

>      (do_vmrs): Add checks for valid operands with respect to

>      cpu and fpu options.

>      (do_vmsr): Likewise.

>      (reg_names): New reg_names for FPSCR_nzcvqc, VPR, FPCXT_NS

>      and FPCXT_S.

>      * testsuite/gas/arm/armv8_1-m-spec-reg.d: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg.s: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg-bad1.d: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg-bad2.d: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg-bad3.d: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg-bad1.l: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg-bad2.l: New.

>      * testsuite/gas/arm/armv8_1-m-spec-reg-bad3.l: New.

>      * testsuite/gas/arm/vfp1xD.d: Updated to allow new valid values.

>      * testsuite/gas/arm/vfp1xD_t2.d: Likewise.

> 

> *** opcodes/ChangeLog ***

> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

> 

>      * arm-dis.c (coprocessor_opcodes): New instructions for VMRS

>      and VMSR with the new operands.


Approved - please apply.

Cheers
  Nick
Sudakshina Das May 21, 2019, 5:26 p.m. | #2
Hi Nick

On 21/05/2019 14:38, Nick Clifton wrote:
> Hi Sudi,

> 

>> *** gas/ChangeLog ***

>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>>

>>       * config/tc-arm.c (parse_operands): Update case OP_RVC to

>>       parse p0 and P0.

>>       (do_vmrs): Add checks for valid operands with respect to

>>       cpu and fpu options.

>>       (do_vmsr): Likewise.

>>       (reg_names): New reg_names for FPSCR_nzcvqc, VPR, FPCXT_NS

>>       and FPCXT_S.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg.d: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg.s: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg-bad1.d: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg-bad2.d: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg-bad3.d: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg-bad1.l: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg-bad2.l: New.

>>       * testsuite/gas/arm/armv8_1-m-spec-reg-bad3.l: New.

>>       * testsuite/gas/arm/vfp1xD.d: Updated to allow new valid values.

>>       * testsuite/gas/arm/vfp1xD_t2.d: Likewise.

>>

>> *** opcodes/ChangeLog ***

>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>>

>>       * arm-dis.c (coprocessor_opcodes): New instructions for VMRS

>>       and VMSR with the new operands.

> 

> Approved - please apply.

> 


Thanks! Applied all 3 patches.

Sudi

> Cheers

>    Nick

> 

>

Patch

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 0a2e42c48e66de1167e23ca3ee7e9fed56301e45..ee5f807da9cf646c7d7c41bb11d1f9ce64aa74c3 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -7236,7 +7236,20 @@  parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  break;
 	  /* Also accept generic coprocessor regs for unknown registers.  */
 	  coproc_reg:
-	  po_reg_or_fail (REG_TYPE_CN);
+	  po_reg_or_goto (REG_TYPE_CN, vpr_po);
+	  break;
+	  /* Also accept P0 or p0 for VPR.P0.  Since P0 is already an
+	     existing register with a value of 0, this seems like the
+	     best way to parse P0.  */
+	  vpr_po:
+	  if (strncasecmp (str, "P0", 2) == 0)
+	    {
+	      str += 2;
+	      inst.operands[i].isreg = 1;
+	      inst.operands[i].reg = 13;
+	    }
+	  else
+	    goto failure;
 	  break;
 	case OP_RMF:   po_reg_or_fail (REG_TYPE_MVF);	  break;
 	case OP_RMD:   po_reg_or_fail (REG_TYPE_MVD);	  break;
@@ -9831,10 +9844,42 @@  do_vmrs (void)
       return;
     }
 
-  /* MVFR2 is only valid at ARMv8-A.  */
-  if (inst.operands[1].reg == 5)
-    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
-		_(BAD_FPU));
+  switch (inst.operands[1].reg)
+    {
+    /* MVFR2 is only valid for Armv8-A.  */
+    case 5:
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
+		  _(BAD_FPU));
+      break;
+
+    /* Check for new Armv8.1-M Mainline changes to <spec_reg>.  */
+    case 1: /* fpscr.  */
+      constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+		    || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
+		  _(BAD_FPU));
+      break;
+
+    case 14: /* fpcxt_ns.  */
+    case 15: /* fpcxt_s.  */
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
+		  _("selected processor does not support instruction"));
+      break;
+
+    case  2: /* fpscr_nzcvqc.  */
+    case 12: /* vpr.  */
+    case 13: /* p0.  */
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
+		  || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+		      && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
+		  _("selected processor does not support instruction"));
+      if (inst.operands[0].reg != 2
+	  && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
+      break;
+
+    default:
+      break;
+    }
 
   /* APSR_ sets isvec. All other refs to PC are illegal.  */
   if (!inst.operands[0].isvec && Rt == REG_PC)
@@ -9862,10 +9907,42 @@  do_vmsr (void)
       return;
     }
 
-  /* MVFR2 is only valid for ARMv8-A.  */
-  if (inst.operands[0].reg == 5)
-    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
-		_(BAD_FPU));
+  switch (inst.operands[0].reg)
+    {
+    /* MVFR2 is only valid for Armv8-A.  */
+    case 5:
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
+		  _(BAD_FPU));
+      break;
+
+    /* Check for new Armv8.1-M Mainline changes to <spec_reg>.  */
+    case  1: /* fpcr.  */
+      constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+		    || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
+		  _(BAD_FPU));
+      break;
+
+    case 14: /* fpcxt_ns.  */
+    case 15: /* fpcxt_s.  */
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
+		  _("selected processor does not support instruction"));
+      break;
+
+    case  2: /* fpscr_nzcvqc.  */
+    case 12: /* vpr.  */
+    case 13: /* p0.  */
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
+		  || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+		      && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
+		  _("selected processor does not support instruction"));
+      if (inst.operands[0].reg != 2
+	  && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
+      break;
+
+    default:
+      break;
+    }
 
   /* If we get through parsing the register name, we just insert the number
      generated into the instruction without further validation.  */
@@ -22808,6 +22885,10 @@  static const struct reg_entry reg_names[] =
   REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
   REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
   REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
+  REGDEF(fpscr_nzcvqc,2,VFC), REGDEF(FPSCR_nzcvqc,2,VFC),
+  REGDEF(vpr,12,VFC), REGDEF(VPR,12,VFC),
+  REGDEF(fpcxt_ns,14,VFC), REGDEF(FPCXT_NS,14,VFC),
+  REGDEF(fpcxt_s,15,VFC), REGDEF(FPCXT_S,15,VFC),
 
   /* Maverick DSP coprocessor registers.  */
   REGSET(mvf,MVF),  REGSET(mvd,MVD),  REGSET(mvfx,MVFX),  REGSET(mvdx,MVDX),
@@ -24435,11 +24516,14 @@  static const struct asm_opcode insns[] =
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1xd  /* VFP V1xD (single precision).  */
+#undef THUMB_VARIANT
+#define THUMB_VARIANT  & arm_ext_v6t2
+ mcCE(vmrs,	ef00a10, 2, (APSR_RR, RVC),   vmrs),
+ mcCE(vmsr,	ee00a10, 2, (RVC, RR),        vmsr),
+#undef THUMB_VARIANT
 
   /* Moves and type conversions.  */
  cCE("fmstat",	ef1fa10, 0, (),		      noargs),
- cCE("vmrs",	ef00a10, 2, (APSR_RR, RVC),   vmrs),
- cCE("vmsr",	ee00a10, 2, (RVC, RR),        vmsr),
  cCE("fsitos",	eb80ac0, 2, (RVS, RVS),	      vfp_sp_monadic),
  cCE("fuitos",	eb80a40, 2, (RVS, RVS),	      vfp_sp_monadic),
  cCE("ftosis",	ebd0a40, 2, (RVS, RVS),	      vfp_sp_monadic),
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad1.d b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad1.d
new file mode 100644
index 0000000000000000000000000000000000000000..a8936142599693f08bc3e1440b0998d327cd15f1
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad1.d
@@ -0,0 +1,4 @@ 
+#name: Invalid VMSR/VMRS no mve or fp
+#source: armv8_1-m-spec-reg.s
+#as: -march=armv8.1-m.main
+#error_output: armv8_1-m-spec-reg-bad1.l
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad1.l b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad1.l
new file mode 100644
index 0000000000000000000000000000000000000000..0b139ef13583875f88fc41b3bdd00ba337e7f468
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad1.l
@@ -0,0 +1,9 @@ 
+.*: Assembler messages:
+.*: selected FPU does not support instruction -- `vmrs r0,FPSCR'
+.*: selected processor does not support instruction -- `vmrs r1,FPSCR_nzcvqc'
+.*: selected processor does not support instruction -- `vmrs r2,VPR'
+.*: selected processor does not support instruction -- `vmrs r3,P0'
+.*: selected FPU does not support instruction -- `vmsr fpscr,r0'
+.*: selected processor does not support instruction -- `vmsr fpscr_nzcvqc,r1'
+.*: selected processor does not support instruction -- `vmsr vpr,r2'
+.*: selected processor does not support instruction -- `vmsr p0,r3'
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad2.d b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad2.d
new file mode 100644
index 0000000000000000000000000000000000000000..a02beea7382984abaa65fe98fead451602b2c01d
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad2.d
@@ -0,0 +1,4 @@ 
+#name: Invalid VMSR/VMRS no mve
+#source: armv8_1-m-spec-reg.s
+#as: -march=armv8.1-m.main+fp
+#warning_output: armv8_1-m-spec-reg-bad2.l
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad2.l b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad2.l
new file mode 100644
index 0000000000000000000000000000000000000000..d04fe775ccde680049804760960e9ee431eb453e
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad2.l
@@ -0,0 +1,5 @@ 
+.*: Assembler messages:
+.*: Warning: accessing MVE system register without MVE is UNPREDICTABLE
+.*: Warning: accessing MVE system register without MVE is UNPREDICTABLE
+.*: Warning: accessing MVE system register without MVE is UNPREDICTABLE
+.*: Warning: accessing MVE system register without MVE is UNPREDICTABLE
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad3.d b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad3.d
new file mode 100644
index 0000000000000000000000000000000000000000..1e897884203d92d2bbb2cd44e63677c1ab94af47
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad3.d
@@ -0,0 +1,4 @@ 
+#name: Invalid VMSR/VMRS Only FPSCR allowed
+#source: armv8_1-m-spec-reg.s
+#as: -march=armv6t2 -mfpu=vfpxd
+#error_output: armv8_1-m-spec-reg-bad3.l
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad3.l b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad3.l
new file mode 100644
index 0000000000000000000000000000000000000000..0f4d3cc6fcedb893fba43a0b7b3c0980618793b3
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg-bad3.l
@@ -0,0 +1,11 @@ 
+.*: Assembler messages:
+.*: selected processor does not support instruction -- `vmrs r1,FPSCR_nzcvqc'
+.*: selected processor does not support instruction -- `vmrs r2,VPR'
+.*: selected processor does not support instruction -- `vmrs r3,P0'
+.*: selected processor does not support instruction -- `vmrs r4,FPCXT_NS'
+.*: selected processor does not support instruction -- `vmrs r5,FPCXT_S'
+.*: selected processor does not support instruction -- `vmsr fpscr_nzcvqc,r1'
+.*: selected processor does not support instruction -- `vmsr vpr,r2'
+.*: selected processor does not support instruction -- `vmsr p0,r3'
+.*: selected processor does not support instruction -- `vmsr fpcxt_ns,r4'
+.*: selected processor does not support instruction -- `vmsr fpcxt_s,r5'
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg.d b/gas/testsuite/gas/arm/armv8_1-m-spec-reg.d
new file mode 100644
index 0000000000000000000000000000000000000000..35a6e172fadaaf6b241b60550359743c0634b15c
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg.d
@@ -0,0 +1,20 @@ 
+#name: Valid Armv8.1-M Mainline <spec_reg> change
+#source: armv8_1-m-spec-reg.s
+#as: -march=armv8.1-m.main+mve
+#objdump: -dr --prefix-addresses --show-raw-insn -marmv8.1-m.main
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> eef1 0a10 	vmrs	r0, fpscr
+0[0-9a-f]+ <[^>]+> eef2 1a10 	vmrs	r1, fpscr_nzcvqc
+0[0-9a-f]+ <[^>]+> eefc 2a10 	vmrs	r2, vpr
+0[0-9a-f]+ <[^>]+> eefd 3a10 	vmrs	r3, p0
+0[0-9a-f]+ <[^>]+> eefe 4a10 	vmrs	r4, fpcxt_ns
+0[0-9a-f]+ <[^>]+> eeff 5a10 	vmrs	r5, fpcxt_s
+0[0-9a-f]+ <[^>]+> eee1 0a10 	vmsr	fpscr, r0
+0[0-9a-f]+ <[^>]+> eee2 1a10 	vmsr	fpscr_nzcvqc, r1
+0[0-9a-f]+ <[^>]+> eeec 2a10 	vmsr	vpr, r2
+0[0-9a-f]+ <[^>]+> eeed 3a10 	vmsr	p0, r3
+0[0-9a-f]+ <[^>]+> eeee 4a10 	vmsr	fpcxt_ns, r4
+0[0-9a-f]+ <[^>]+> eeef 5a10 	vmsr	fpcxt_s, r5
diff --git a/gas/testsuite/gas/arm/armv8_1-m-spec-reg.s b/gas/testsuite/gas/arm/armv8_1-m-spec-reg.s
new file mode 100644
index 0000000000000000000000000000000000000000..37157658b1e69d0f8b9e4f1fa9684449b18cfe95
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-spec-reg.s
@@ -0,0 +1,15 @@ 
+	.syntax unified
+func:
+	vmrs r0, FPSCR
+	vmrs r1, FPSCR_nzcvqc
+	vmrs r2, VPR
+	vmrs r3, P0
+	vmrs r4, FPCXT_NS
+	vmrs r5, FPCXT_S
+
+	vmsr fpscr, r0
+	vmsr fpscr_nzcvqc, r1
+	vmsr vpr, r2
+	vmsr p0, r3
+	vmsr fpcxt_ns, r4
+	vmsr fpcxt_s, r5
diff --git a/gas/testsuite/gas/arm/vfp1xD.d b/gas/testsuite/gas/arm/vfp1xD.d
index 8eaf9ae290de34dd286de20990503bcbd17397b8..079f7a17e597c7155a844e39b9837fad93e877d5 100644
--- a/gas/testsuite/gas/arm/vfp1xD.d
+++ b/gas/testsuite/gas/arm/vfp1xD.d
@@ -243,12 +243,12 @@  Disassembly of section .text:
 0+3a4 <[^>]*> eefa0a10 	(vmrs|fmrx)	r0, fpinst2	@ Impl def
 0+3a8 <[^>]*> eef70a10 	(vmrs|fmrx)	r0, mvfr0
 0+3ac <[^>]*> eef60a10 	(vmrs|fmrx)	r0, mvfr1
-0+3b0 <[^>]*> eefc0a10 	(vmrs|fmrx)	r0, <impl def 0xc>
+0+3b0 <[^>]*> eefc0a10 	(vmrs|fmrx)	r0, (vpr|<impl def 0xc>)
 0+3b4 <[^>]*> eee90a10 	(vmsr|fmxr)	fpinst, r0	@ Impl def
 0+3b8 <[^>]*> eeea0a10 	(vmsr|fmxr)	fpinst2, r0	@ Impl def
 0+3bc <[^>]*> eee70a10 	(vmsr|fmxr)	mvfr0, r0
 0+3c0 <[^>]*> eee60a10 	(vmsr|fmxr)	mvfr1, r0
-0+3c4 <[^>]*> eeec0a10 	(vmsr|fmxr)	<impl def 0xc>, r0
+0+3c4 <[^>]*> eeec0a10 	(vmsr|fmxr)	(vpr|<impl def 0xc>), r0
 0+3c8 <[^>]*> eef10a10 	vmrs	r0, fpscr
 0+3cc <[^>]*> eef11a10 	vmrs	r1, fpscr
 0+3d0 <[^>]*> eef12a10 	vmrs	r2, fpscr
@@ -282,14 +282,14 @@  Disassembly of section .text:
 0+440 <[^>]*> eee82a10 	vmsr	fpexc, r2
 0+444 <[^>]*> eee93a10 	vmsr	fpinst, r3	@ Impl def
 0+448 <[^>]*> eeea4a10 	vmsr	fpinst2, r4	@ Impl def
-0+44c <[^>]*> eeef5a10 	vmsr	(c15|<impl def 0xf>), r5
+0+44c <[^>]*> eeef5a10 	vmsr	(c15|<impl def 0xf>|fpcxt_s), r5
 0+450 <[^>]*> eef03a10 	vmrs	r3, fpsid
 0+454 <[^>]*> eef64a10 	vmrs	r4, mvfr1
 0+458 <[^>]*> eef75a10 	vmrs	r5, mvfr0
 0+45c <[^>]*> eef86a10 	vmrs	r6, fpexc
 0+460 <[^>]*> eef97a10 	vmrs	r7, fpinst	@ Impl def
 0+464 <[^>]*> eefa8a10 	vmrs	r8, fpinst2	@ Impl def
-0+468 <[^>]*> eeff9a10 	vmrs	r9, (c15|<impl def 0xf>)
+0+468 <[^>]*> eeff9a10 	vmrs	r9, (c15|<impl def 0xf>|fpcxt_s)
 0+46c <[^>]*> e1a00000 	nop			; \(mov r0, r0\)
 0+470 <[^>]*> e1a00000 	nop			; \(mov r0, r0\)
 0+474 <[^>]*> e1a00000 	nop			; \(mov r0, r0\)
diff --git a/gas/testsuite/gas/arm/vfp1xD_t2.d b/gas/testsuite/gas/arm/vfp1xD_t2.d
index 7dd5030f28d6515d9ed2cbe3e11c5ab66be4167d..248185d448621e98303a6f8e04d316a395bb0ec7 100644
--- a/gas/testsuite/gas/arm/vfp1xD_t2.d
+++ b/gas/testsuite/gas/arm/vfp1xD_t2.d
@@ -257,12 +257,12 @@  Disassembly of section .text:
 0+3c0 <[^>]*> eefa 0a10 	(vmrs|fmrx)	r0, fpinst2	@ Impl def
 0+3c4 <[^>]*> eef7 0a10 	(vmrs|fmrx)	r0, mvfr0
 0+3c8 <[^>]*> eef6 0a10 	(vmrs|fmrx)	r0, mvfr1
-0+3cc <[^>]*> eefc 0a10 	(vmrs|fmrx)	r0, <impl def 0xc>
+0+3cc <[^>]*> eefc 0a10 	(vmrs|fmrx)	r0, (<impl def 0xc>|vpr)
 0+3d0 <[^>]*> eee9 0a10 	(vmsr|fmxr)	fpinst, r0	@ Impl def
 0+3d4 <[^>]*> eeea 0a10 	(vmsr|fmxr)	fpinst2, r0	@ Impl def
 0+3d8 <[^>]*> eee7 0a10 	(vmsr|fmxr)	mvfr0, r0
 0+3dc <[^>]*> eee6 0a10 	(vmsr|fmxr)	mvfr1, r0
-0+3e0 <[^>]*> eeec 0a10 	(vmsr|fmxr)	<impl def 0xc>, r0
+0+3e0 <[^>]*> eeec 0a10 	(vmsr|fmxr)	(<impl def 0xc>|vpr), r0
 0+3e4 <[^>]*> bf00      	nop
 0+3e6 <[^>]*> bf00      	nop
 0+3e8 <[^>]*> bf00      	nop
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index ad65ffa99adff1244428f8d2931c51a0dbfa2172..0503d9365d19633d0dacce367ba4acaf2beb6f6a 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -809,8 +809,10 @@  static const struct sopcode32 coprocessor_opcodes[] =
   /* Floating point coprocessor (VFP) instructions.  */
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
-  {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
+  {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD | FPU_MVE),
     0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
+  {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0x0ee20a10, 0x0fff0fff, "vmsr%c\tfpscr_nzcvqc, %12-15r"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
@@ -823,12 +825,22 @@  static const struct sopcode32 coprocessor_opcodes[] =
     0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
+  {ANY, ARM_FEATURE_COPROC (FPU_MVE),
+    0x0eec0a10, 0x0fff0fff, "vmsr%c\tvpr, %12-15r"},
+  {ANY, ARM_FEATURE_COPROC (FPU_MVE),
+    0x0eed0a10, 0x0fff0fff, "vmsr%c\tp0, %12-15r"},
+  {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0x0eee0a10, 0x0fff0fff, "vmsr%c\tfpcxt_ns, %12-15r"},
+  {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0x0eef0a10, 0x0fff0fff, "vmsr%c\tfpcxt_s, %12-15r"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
-  {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
+  {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD | FPU_MVE),
     0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
+  {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0x0ef20a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr_nzcvqc"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
     0x0ef50a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr2"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
@@ -841,6 +853,14 @@  static const struct sopcode32 coprocessor_opcodes[] =
     0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
+  {ANY, ARM_FEATURE_COPROC (FPU_MVE),
+    0x0efc0a10, 0x0fff0fff, "vmrs%c\t%12-15r, vpr"},
+  {ANY, ARM_FEATURE_COPROC (FPU_MVE),
+    0x0efd0a10, 0x0fff0fff, "vmrs%c\t%12-15r, p0"},
+  {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0x0efe0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpcxt_ns"},
+  {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0x0eff0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpcxt_s"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1),
     0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1),