[arm] Update the decoding of MVE VMOV, VMVN

Message ID 5dc2b8c5.1c69fb81.6c79a.35b7SMTPIN_ADDED_MISSING@mx.google.com
State New
Headers show
Series
  • [arm] Update the decoding of MVE VMOV, VMVN
Related show

Commit Message

Mihail Ionescu Nov. 6, 2019, 11:37 a.m.
Hi,

This patch updates the decoding of the VMOV and VMVN instructions which depend on cmode.
Previously VMOV and VMVN with cmode 1101 were not allowed.
The cmode changes also required updating of the MVE conflict checking.
Now instructions with opcodes 0xef800d50 and 0xef800e70 correctly get decoded as VMOV
and VMVN, respectively.

Tested on arm-none-eabi, no additional regressions were introduced.

opcodes/ChangeLog:

2019-11-06  Mihail Ionescu  <mihail.ionescu@arm.com>

	* opcodes/arm-dis.c (mve_opcodes): Enable VMOV imm to vec with cmode 1101.
	(is_mve_encoding_conflict): Update cmode conflict checks for MVE_VMVN_IMM.


gas/ChangeLog:

2019-11-06  Mihail Ionescu  <mihail.ionescu@arm.com>

	* gas/config/tc-arm.c (do_neon_mvn): Allow mve_ext cmode=0xd.
	* testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s: New test.
	* testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d: Likewise.



Ok for master?

Regards,
Mihail

###############     Attachment also inlined for ease of reply    ###############
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1f462307ed9129d8aca8a4bd371965c4b2f0c0ca..db668fc135fe36ce86db325733cabe24b209dcb0 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -19372,8 +19372,6 @@ do_neon_mvn (void)
   if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
     {
       constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
-      constraint ((inst.instruction & 0xd00) == 0xd00,
-		  _("immediate value out of range"));
     }
 }
 
diff --git a/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d
new file mode 100644
index 0000000000000000000000000000000000000000..dc6bf0ccd8553a073c49b6fccb86cdb6c08f9001
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d
@@ -0,0 +1,40 @@
+# name: MVE vmov, vmvn, vbic, vorr aliases
+# 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:
+[^>]*> ff80 0d70 	vmvn.i32	q0, #8454143	; 0x0080ffff
+[^>]*> ff80 0f70 			; <UNDEFINED> instruction: 0xff800f70
+[^>]*> ef80 0e70 	vmov.i64	q0, #0x0000000000000000
+[^>]*> ef80 0070 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0270 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0470 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0670 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0870 	vmvn.i16	q0, #0	; 0x0000
+[^>]*> ef80 0a70 	vmvn.i16	q0, #0	; 0x0000
+[^>]*> ef80 0c70 	vmvn.i32	q0, #255	; 0x000000ff
+[^>]*> ef80 0150 	vorr.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0350 	vorr.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0550 	vorr.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0950 	vorr.i16	q0, #0	; 0x0000
+[^>]*> ef80 0b50 	vorr.i16	q0, #0	; 0x0000
+[^>]*> ef80 0170 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0370 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0570 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0770 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0970 	vbic.i16	q0, #0	; 0x0000
+[^>]*> ef80 0b70 	vbic.i16	q0, #0	; 0x0000
+[^>]*> ef80 0050 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0250 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0450 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0650 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0850 	vmov.i16	q0, #0	; 0x0000
+[^>]*> ef80 0a50 	vmov.i16	q0, #0	; 0x0000
+[^>]*> ef80 0c50 	vmov.i32	q0, #255	; 0x000000ff
+[^>]*> ef80 0e50 	vmov.i8	q0, #0	; 0x00
+[^>]*> ef80 0d50 	vmov.i32	q0, #65535	; 0x0000ffff
+[^>]*> ef80 0f50 	vmov.f32	q0, #2	; 0x40000000
+[^>]*> ff80 0d70 	vmvn.i32	q0, #8454143	; 0x0080ffff
+[^>]*> ff80 0d50 	vmov.i32	q0, #8454143	; 0x0080ffff
diff --git a/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s
new file mode 100644
index 0000000000000000000000000000000000000000..7f5bba482f3eda1e468fd97d73779805f9c69360
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s
@@ -0,0 +1,47 @@
+.syntax unified
+.text
+@ VMVN with cmode = d
+.inst 0xff800d70
+
+@ VMVN with cmode = f, should be undefined
+.inst 0xff800f70
+
+@ VBIC
+.inst 0xef800e70 @VMOV
+.inst 0xef800070 @VMVN
+.inst 0xef800270 @VMVN
+.inst 0xef800470 @VMVN
+.inst 0xef800670 @VMVN
+.inst 0xef800870 @VMVN
+.inst 0xef800a70 @VMVN
+.inst 0xef800c70 @VMVN
+
+@ VMOV
+.inst 0xef800150 @VORR
+.inst 0xef800350 @VORR
+.inst 0xef800550 @VORR
+.inst 0xef800950 @VORR
+.inst 0xef800b50 @VORR
+.inst 0xef800170 @VBIC
+.inst 0xef800370 @VBIC
+.inst 0xef800570 @VBIC
+.inst 0xef800770 @VBIC
+.inst 0xef800970 @VBIC
+.inst 0xef800b70 @VBIC
+
+@ VMVN same as VMOV -> VBIC
+@ VORR
+.inst 0xef800050 @VMOV
+.inst 0xef800250 @VMOV
+.inst 0xef800450 @VMOV
+.inst 0xef800650 @VMOV
+.inst 0xef800850 @VMOV
+.inst 0xef800a50 @VMOV
+.inst 0xef800c50 @VMOV
+.inst 0xef800e50 @VMOV
+.inst 0xef800d50 @VMOV
+.inst 0xef800f50 @VMOV
+
+
+vmvn.i32 q0,#0x80ffff
+vmov.i32 q0,#0x80ffff
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 8ff86bf4d62ff69ed9a4a5f3f5bc5c81b3abbe85..48e6109bf335d10d5b435db3600c36abbbd68251 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2801,10 +2801,15 @@ static const struct mopcode32 mve_opcodes[] =
    "vsri%v.%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
 
   /* Vector VMOV immediate to vector,
-     cmode == 11x1 -> VMVN which is UNDEFINED
-     for such a cmode.  */
+     undefinded for cmode == 1111 */
   {ARM_FEATURE_COPROC (FPU_MVE),
-   MVE_VMVN_IMM, 0xef800d50, 0xefb81dd0, UNDEFINED_INSTRUCTION},
+   MVE_VMVN_IMM, 0xef800f70, 0xefb81ff0, UNDEFINED_INSTRUCTION},
+
+  /* Vector VMOV immediate to vector,
+     cmode == 1101 */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV_IMM_TO_VEC, 0xef800d50, 0xefb81fd0,
+   "vmov%v.%5,8-11s\t%13-15,22Q, %E"},
 
   /* Vector VMOV immediate to vector.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
@@ -5623,11 +5628,11 @@ is_mve_encoding_conflict (unsigned long given,
       {
 	unsigned long cmode = arm_decode_field (given, 8, 11);
 
-	if ((cmode & 9) == 1)
+	if (cmode == 0xe)
 	  return TRUE;
-	else if ((cmode & 5) == 1)
+	else if ((cmode & 0x9) == 1)
 	  return TRUE;
-	else if ((cmode & 0xe) == 0xe)
+	else if ((cmode & 0xd) == 9)
 	  return TRUE;
 	else
 	  return FALSE;

Patch

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1f462307ed9129d8aca8a4bd371965c4b2f0c0ca..db668fc135fe36ce86db325733cabe24b209dcb0 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -19372,8 +19372,6 @@  do_neon_mvn (void)
   if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
     {
       constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
-      constraint ((inst.instruction & 0xd00) == 0xd00,
-		  _("immediate value out of range"));
     }
 }
 
diff --git a/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d
new file mode 100644
index 0000000000000000000000000000000000000000..dc6bf0ccd8553a073c49b6fccb86cdb6c08f9001
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.d
@@ -0,0 +1,40 @@ 
+# name: MVE vmov, vmvn, vbic, vorr aliases
+# 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:
+[^>]*> ff80 0d70 	vmvn.i32	q0, #8454143	; 0x0080ffff
+[^>]*> ff80 0f70 			; <UNDEFINED> instruction: 0xff800f70
+[^>]*> ef80 0e70 	vmov.i64	q0, #0x0000000000000000
+[^>]*> ef80 0070 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0270 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0470 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0670 	vmvn.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0870 	vmvn.i16	q0, #0	; 0x0000
+[^>]*> ef80 0a70 	vmvn.i16	q0, #0	; 0x0000
+[^>]*> ef80 0c70 	vmvn.i32	q0, #255	; 0x000000ff
+[^>]*> ef80 0150 	vorr.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0350 	vorr.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0550 	vorr.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0950 	vorr.i16	q0, #0	; 0x0000
+[^>]*> ef80 0b50 	vorr.i16	q0, #0	; 0x0000
+[^>]*> ef80 0170 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0370 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0570 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0770 	vbic.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0970 	vbic.i16	q0, #0	; 0x0000
+[^>]*> ef80 0b70 	vbic.i16	q0, #0	; 0x0000
+[^>]*> ef80 0050 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0250 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0450 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0650 	vmov.i32	q0, #0	; 0x00000000
+[^>]*> ef80 0850 	vmov.i16	q0, #0	; 0x0000
+[^>]*> ef80 0a50 	vmov.i16	q0, #0	; 0x0000
+[^>]*> ef80 0c50 	vmov.i32	q0, #255	; 0x000000ff
+[^>]*> ef80 0e50 	vmov.i8	q0, #0	; 0x00
+[^>]*> ef80 0d50 	vmov.i32	q0, #65535	; 0x0000ffff
+[^>]*> ef80 0f50 	vmov.f32	q0, #2	; 0x40000000
+[^>]*> ff80 0d70 	vmvn.i32	q0, #8454143	; 0x0080ffff
+[^>]*> ff80 0d50 	vmov.i32	q0, #8454143	; 0x0080ffff
diff --git a/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s
new file mode 100644
index 0000000000000000000000000000000000000000..7f5bba482f3eda1e468fd97d73779805f9c69360
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-vmvn-vorr-vbic.s
@@ -0,0 +1,47 @@ 
+.syntax unified
+.text
+@ VMVN with cmode = d
+.inst 0xff800d70
+
+@ VMVN with cmode = f, should be undefined
+.inst 0xff800f70
+
+@ VBIC
+.inst 0xef800e70 @VMOV
+.inst 0xef800070 @VMVN
+.inst 0xef800270 @VMVN
+.inst 0xef800470 @VMVN
+.inst 0xef800670 @VMVN
+.inst 0xef800870 @VMVN
+.inst 0xef800a70 @VMVN
+.inst 0xef800c70 @VMVN
+
+@ VMOV
+.inst 0xef800150 @VORR
+.inst 0xef800350 @VORR
+.inst 0xef800550 @VORR
+.inst 0xef800950 @VORR
+.inst 0xef800b50 @VORR
+.inst 0xef800170 @VBIC
+.inst 0xef800370 @VBIC
+.inst 0xef800570 @VBIC
+.inst 0xef800770 @VBIC
+.inst 0xef800970 @VBIC
+.inst 0xef800b70 @VBIC
+
+@ VMVN same as VMOV -> VBIC
+@ VORR
+.inst 0xef800050 @VMOV
+.inst 0xef800250 @VMOV
+.inst 0xef800450 @VMOV
+.inst 0xef800650 @VMOV
+.inst 0xef800850 @VMOV
+.inst 0xef800a50 @VMOV
+.inst 0xef800c50 @VMOV
+.inst 0xef800e50 @VMOV
+.inst 0xef800d50 @VMOV
+.inst 0xef800f50 @VMOV
+
+
+vmvn.i32 q0,#0x80ffff
+vmov.i32 q0,#0x80ffff
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 8ff86bf4d62ff69ed9a4a5f3f5bc5c81b3abbe85..48e6109bf335d10d5b435db3600c36abbbd68251 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2801,10 +2801,15 @@  static const struct mopcode32 mve_opcodes[] =
    "vsri%v.%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
 
   /* Vector VMOV immediate to vector,
-     cmode == 11x1 -> VMVN which is UNDEFINED
-     for such a cmode.  */
+     undefinded for cmode == 1111 */
   {ARM_FEATURE_COPROC (FPU_MVE),
-   MVE_VMVN_IMM, 0xef800d50, 0xefb81dd0, UNDEFINED_INSTRUCTION},
+   MVE_VMVN_IMM, 0xef800f70, 0xefb81ff0, UNDEFINED_INSTRUCTION},
+
+  /* Vector VMOV immediate to vector,
+     cmode == 1101 */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV_IMM_TO_VEC, 0xef800d50, 0xefb81fd0,
+   "vmov%v.%5,8-11s\t%13-15,22Q, %E"},
 
   /* Vector VMOV immediate to vector.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
@@ -5623,11 +5628,11 @@  is_mve_encoding_conflict (unsigned long given,
       {
 	unsigned long cmode = arm_decode_field (given, 8, 11);
 
-	if ((cmode & 9) == 1)
+	if (cmode == 0xe)
 	  return TRUE;
-	else if ((cmode & 5) == 1)
+	else if ((cmode & 0x9) == 1)
 	  return TRUE;
-	else if ((cmode & 0xe) == 0xe)
+	else if ((cmode & 0xd) == 9)
 	  return TRUE;
 	else
 	  return FALSE;