[25/57,Arm,GAS] Add support for MVE instruction: vmvn, vqabs and vqneg

Message ID 896349a0-1937-cf79-8813-bc8014d719ec@arm.com
State New
Headers show
Series
  • : Add support for Armv8.1-M Mainline MVE instructions
Related show

Commit Message

Andre Vieira (lists) May 1, 2019, 5:16 p.m.
Hi,

This patch adds support for MVE instructions VMVN, VQABS, and VQNEG.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_neon_mvn): Change to accept MVE
         variants.
	(do_neon_sat_abs_neg): Likewise.
         (insns): Likewise.
	* testsuite/gas/arm/mve-vmvn-bad.d: New test.
	* testsuite/gas/arm/mve-vmvn-bad.l: New test.
	* testsuite/gas/arm/mve-vmvn-bad.s: New test.
	* testsuite/gas/arm/mve-vqabsneg-bad.d: New test.
	* testsuite/gas/arm/mve-vqabsneg-bad.l: New test.
	* testsuite/gas/arm/mve-vqabsneg-bad.s: New test.

Patch

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1819b7bf078721aecd44a7a4c429b357b478657b..4615f10246ca227257d76962a0e86557d9d9186f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -18489,9 +18489,16 @@  neon_move_immediate (void)
 static void
 do_neon_mvn (void)
 {
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+    return;
+
   if (inst.operands[1].isreg)
     {
-      enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+      enum neon_shape rs;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	rs = neon_select_shape (NS_QQ, NS_NULL);
+      else
+	rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
 
       NEON_ENCODE (INTEGER, inst);
       inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
@@ -18507,6 +18514,13 @@  do_neon_mvn (void)
     }
 
   neon_dp_fixup (&inst);
+
+  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"));
+    }
 }
 
 /* Encode instructions of form:
@@ -19453,7 +19467,14 @@  do_neon_zip_uzp (void)
 static void
 do_neon_sat_abs_neg (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+    return;
+
+  enum neon_shape rs;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    rs = neon_select_shape (NS_QQ, NS_NULL);
+  else
+    rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
   struct neon_type_el et = neon_check_type (2, rs,
     N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
   neon_two_same (neon_quad (rs), 1, et.size);
@@ -24060,7 +24081,6 @@  static const struct asm_opcode insns[] =
   /* CVT with optional immediate for fixed-point variant.  */
  nUF(vcvtq,     _vcvt,    3, (RNQ, RNQ, oI32b), neon_cvt),
 
- nUF(vmvn,      _vmvn,    2, (RNDQ, RNDQ_Ibig), neon_mvn),
  nUF(vmvnq,     _vmvn,    2, (RNQ,  RNDQ_Ibig), neon_mvn),
 
   /* Data processing, three registers of different lengths.  */
@@ -24114,9 +24134,7 @@  static const struct asm_opcode insns[] =
  NUF(vuzp,      1b20100, 2, (RNDQ, RNDQ),     neon_zip_uzp),
  NUF(vuzpq,     1b20100, 2, (RNQ,  RNQ),      neon_zip_uzp),
   /* VQABS / VQNEG. Types S8 S16 S32.  */
- NUF(vqabs,     1b00700, 2, (RNDQ, RNDQ),     neon_sat_abs_neg),
  NUF(vqabsq,    1b00700, 2, (RNQ,  RNQ),      neon_sat_abs_neg),
- NUF(vqneg,     1b00780, 2, (RNDQ, RNDQ),     neon_sat_abs_neg),
  NUF(vqnegq,    1b00780, 2, (RNQ,  RNQ),      neon_sat_abs_neg),
   /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32.  */
  NUF(vpadal,    1b00600, 2, (RNDQ, RNDQ),     neon_pair_long),
@@ -24777,6 +24795,9 @@  static const struct asm_opcode insns[] =
  mnUF(vmax,      _vmax,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
  MNUF(vqadd,     0000010,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
  MNUF(vqsub,     0000210,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
+ mnUF(vmvn,      _vmvn,    2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
+ MNUF(vqabs,     1b00700,  2, (RNDQMQ, RNDQMQ),     neon_sat_abs_neg),
+ MNUF(vqneg,     1b00780,  2, (RNDQMQ, RNDQMQ),     neon_sat_abs_neg),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vmvn-bad.d b/gas/testsuite/gas/arm/mve-vmvn-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..3b06d63fcc1b807c81ea2bb7312cb8677187c73e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmvn-bad.d
@@ -0,0 +1,5 @@ 
+#name: bad MVE VMVN instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmvn-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmvn-bad.l b/gas/testsuite/gas/arm/mve-vmvn-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..8073a68ea80cfc39a6d92dba7637fc174de47be2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmvn-bad.l
@@ -0,0 +1,20 @@ 
+[^:]*: Assembler messages:
+[^:]*:10: Error: invalid instruction shape -- `vmvn.i16 d0,d1'
+[^:]*:11: Error: immediate out of range -- `vmvn.i32 q0,#0x1ef'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: syntax error -- `vmvneq q0,q1'
+[^:]*:16: Error: syntax error -- `vmvneq q0,q1'
+[^:]*:18: Error: syntax error -- `vmvneq q0,q1'
+[^:]*:19: Error: vector predicated instruction should be in VPT/VPST block -- `vmvnt q0,q1'
+[^:]*:21: Error: instruction missing MVE vector predication code -- `vmvn q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vmvn-bad.s b/gas/testsuite/gas/arm/mve-vmvn-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..5b8f127abf1e57a45caabef0f888de4a84514a8a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmvn-bad.s
@@ -0,0 +1,21 @@ 
+.macro cond lastop
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vmvn.i16 q0, \lastop
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmvn.i16 d0, d1
+vmvn.i32 q0, #0x1ef
+cond q1
+cond #0
+it eq
+vmvneq q0, q1
+vmvneq q0, q1
+vpst
+vmvneq q0, q1
+vmvnt q0, q1
+vpst
+vmvn q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vqabsneg-bad.d b/gas/testsuite/gas/arm/mve-vqabsneg-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..30c9cd6c6477c2584c597a9db7c4d49992b20d85
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqabsneg-bad.d
@@ -0,0 +1,5 @@ 
+#name: bad MVE VQABS and VQNEG instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqabsneg-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqabsneg-bad.l b/gas/testsuite/gas/arm/mve-vqabsneg-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..ea9891e317cf80c319bda84389e3ee0cec41fb50
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqabsneg-bad.l
@@ -0,0 +1,27 @@ 
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqabs.u8 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqneg.u16 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqabs.s64 q0,q1'
+[^:]*:13: Error: bad instruction `vqnegs.s64 q0,q1'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vqabseq.s32 q0,q1'
+[^:]*:18: Error: syntax error -- `vqabseq.s32 q0,q1'
+[^:]*:19: Error: syntax error -- `vqabseq.s32 q0,q1'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vqabst.s32 q0,q1'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vqabs.s32 q0,q1'
+[^:]*:24: Error: syntax error -- `vqnegeq.s32 q0,q1'
+[^:]*:25: Error: syntax error -- `vqnegeq.s32 q0,q1'
+[^:]*:26: Error: syntax error -- `vqnegeq.s32 q0,q1'
+[^:]*:27: Error: vector predicated instruction should be in VPT/VPST block -- `vqnegt.s32 q0,q1'
+[^:]*:29: Error: instruction missing MVE vector predication code -- `vqneg.s32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vqabsneg-bad.s b/gas/testsuite/gas/arm/mve-vqabsneg-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..af760904b2489614df19508e3bae817b22ebec6a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqabsneg-bad.s
@@ -0,0 +1,29 @@ 
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqabs.u8 q0, q1
+vqneg.u16 q0, q1
+vqabs.s64 q0, q1
+vqnegs.s64 q0, q1
+cond vqabs
+cond vqneg
+it eq
+vqabseq.s32 q0, q1
+vqabseq.s32 q0, q1
+vqabseq.s32 q0, q1
+vqabst.s32 q0, q1
+vpst
+vqabs.s32 q0, q1
+it eq
+vqnegeq.s32 q0, q1
+vqnegeq.s32 q0, q1
+vqnegeq.s32 q0, q1
+vqnegt.s32 q0, q1
+vpst
+vqneg.s32 q0, q1