[PATCH 15/57][Arm][GAS] Add support for MVE instructions: vcls, vclz and vfmas
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Wed, 15 May 2019 17:31:38 +0000 (18:31 +0100)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 16 May 2019 15:35:52 +0000 (16:35 +0100)
gas/ChangeLog:
2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>

* config/tc-arm.c (do_mve_vfmas): New encoding function.
(do_neon_cls): Change to support MVE variants.
(do_neon_clz): Change to support MVE variants.
(insns): Change to support MVE variants and add new.
* testsuite/gas/arm/mve-vcls-bad.d: New test.
* testsuite/gas/arm/mve-vcls-bad.l: New test.
* testsuite/gas/arm/mve-vcls-bad.s: New test.
* testsuite/gas/arm/mve-vclz-bad.d: New test.
* testsuite/gas/arm/mve-vclz-bad.l: New test.
* testsuite/gas/arm/mve-vclz-bad.s: New test.
* testsuite/gas/arm/mve-vfmas-bad.d: New test.
* testsuite/gas/arm/mve-vfmas-bad.l: New test.
* testsuite/gas/arm/mve-vfmas-bad.s: New test.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/gas/arm/mve-vcls-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vcls-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vcls-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vclz-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vclz-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vclz-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vfmas-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vfmas-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vfmas-bad.s [new file with mode: 0644]

index 216d17ede7f8ac2a8956d49a4dc34a0f4dbb4950..1ac53fc189368553765dd80b835b8d49fabe00b7 100644 (file)
@@ -1,3 +1,19 @@
+2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+       * config/tc-arm.c (do_mve_vfmas): New encoding function.
+       (do_neon_cls): Change to support MVE variants.
+       (do_neon_clz): Change to support MVE variants.
+       (insns): Change to support MVE variants and add new.
+       * testsuite/gas/arm/mve-vcls-bad.d: New test.
+       * testsuite/gas/arm/mve-vcls-bad.l: New test.
+       * testsuite/gas/arm/mve-vcls-bad.s: New test.
+       * testsuite/gas/arm/mve-vclz-bad.d: New test.
+       * testsuite/gas/arm/mve-vclz-bad.l: New test.
+       * testsuite/gas/arm/mve-vclz-bad.s: New test.
+       * testsuite/gas/arm/mve-vfmas-bad.d: New test.
+       * testsuite/gas/arm/mve-vfmas-bad.l: New test.
+       * testsuite/gas/arm/mve-vfmas-bad.s: New test.
+
 2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * config/tc-arm.c (enum operand_parse_code): New operands.
index 7cd88d3363e973c1c085407d1083f0bfb2686483..504fe1d4bd9bf1b363a83664fb9dc9e74e47b368 100644 (file)
@@ -15579,6 +15579,32 @@ do_mve_vcmp (void)
   return;
 }
 
+static void
+do_mve_vfmas (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (inst.operands[2].reg == REG_SP)
+    as_tsktsk (MVE_BAD_SP);
+  else if (inst.operands[2].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+
+  inst.instruction |= (et.size == 16) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= inst.operands[2].reg;
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vcmul (void)
 {
@@ -19003,7 +19029,15 @@ do_neon_recip_est (void)
 static void
 do_neon_cls (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+    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);
@@ -19012,7 +19046,15 @@ do_neon_cls (void)
 static void
 do_neon_clz (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+    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_I8 | N_I16 | N_I32 | N_KEY);
   neon_two_same (neon_quad (rs), 1, et.size);
@@ -23645,10 +23687,8 @@ static const struct asm_opcode insns[] =
  NUF(vrsqrte,   1b30480, 2, (RNDQ, RNDQ),     neon_recip_est),
  NUF(vrsqrteq,  1b30480, 2, (RNQ,  RNQ),      neon_recip_est),
   /* VCLS. Types S8 S16 S32.  */
- NUF(vcls,      1b00400, 2, (RNDQ, RNDQ),     neon_cls),
  NUF(vclsq,     1b00400, 2, (RNQ,  RNQ),      neon_cls),
   /* VCLZ. Types I8 I16 I32.  */
- NUF(vclz,      1b00480, 2, (RNDQ, RNDQ),     neon_clz),
  NUF(vclzq,     1b00480, 2, (RNQ,  RNQ),      neon_clz),
   /* VCNT. Size 8.  */
  NUF(vcnt,      1b00500, 2, (RNDQ, RNDQ),     neon_cnt),
@@ -24182,6 +24222,7 @@ static const struct asm_opcode insns[] =
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),             mve_vcmul),
+ mToC("vfmas", ee311e40,   3, (RMQ, RMQ, RR),                    mve_vfmas),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
@@ -24237,6 +24278,8 @@ static const struct asm_opcode insns[] =
  mnUF(vorr,      _vorr,                  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
  mnUF(vorn,      _vorn,                  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
  mnUF(veor,      _veor,                  3, (RNDQMQ, oRNDQMQ, RNDQMQ),      neon_logic),
+ MNUF(vcls,      1b00400,        2, (RNDQMQ, RNDQMQ),               neon_cls),
+ MNUF(vclz,      1b00480,        2, (RNDQMQ, RNDQMQ),               neon_clz),
 
 #undef ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vcls-bad.d b/gas/testsuite/gas/arm/mve-vcls-bad.d
new file mode 100644 (file)
index 0000000..0cfdabd
--- /dev/null
@@ -0,0 +1,5 @@
+#name: bad MVE VCLS instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcls-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcls-bad.l b/gas/testsuite/gas/arm/mve-vcls-bad.l
new file mode 100644 (file)
index 0000000..c58d34f
--- /dev/null
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vcls.f32 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vcls.u32 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vcls.32 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vcls.i32 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vcls.s64 q0,q1'
+[^:]*: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 -- `vclseq.s16 q0,q1'
+[^:]*:18: Error: syntax error -- `vclseq.s16 q0,q1'
+[^:]*:20: Error: syntax error -- `vclseq.s16 q0,q1'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vclst.s16 q0,q1'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vcls.s16 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vcls-bad.s b/gas/testsuite/gas/arm/mve-vcls-bad.s
new file mode 100644 (file)
index 0000000..a3cb1be
--- /dev/null
@@ -0,0 +1,24 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcls.s32 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcls.f32 q0, q1
+vcls.u32 q0, q1
+vcls.32 q0, q1
+vcls.i32 q0, q1
+vcls.s64 q0, q1
+cond
+it eq
+vclseq.s16 q0, q1
+vclseq.s16 q0, q1
+vpst
+vclseq.s16 q0, q1
+vclst.s16 q0, q1
+vpst
+vcls.s16 q0, q1
+
diff --git a/gas/testsuite/gas/arm/mve-vclz-bad.d b/gas/testsuite/gas/arm/mve-vclz-bad.d
new file mode 100644 (file)
index 0000000..72f37da
--- /dev/null
@@ -0,0 +1,5 @@
+#name: bad MVE VCLZ instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vclz-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vclz-bad.l b/gas/testsuite/gas/arm/mve-vclz-bad.l
new file mode 100644 (file)
index 0000000..aa68b0f
--- /dev/null
@@ -0,0 +1,14 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vclz.f32 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vclz.i64 q0,q1'
+[^:]*: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
+[^:]*:14: Error: syntax error -- `vclzeq.i16 q0,q1'
+[^:]*:15: Error: syntax error -- `vclzeq.i16 q0,q1'
+[^:]*:17: Error: syntax error -- `vclzeq.i16 q0,q1'
+[^:]*:18: Error: vector predicated instruction should be in VPT/VPST block -- `vclzt.i16 q0,q1'
+[^:]*:20: Error: instruction missing MVE vector predication code -- `vclz.i16 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vclz-bad.s b/gas/testsuite/gas/arm/mve-vclz-bad.s
new file mode 100644 (file)
index 0000000..088e831
--- /dev/null
@@ -0,0 +1,20 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vclz.i32 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vclz.f32 q0, q1
+vclz.i64 q0, q1
+cond
+it eq
+vclzeq.i16 q0, q1
+vclzeq.i16 q0, q1
+vpst
+vclzeq.i16 q0, q1
+vclzt.i16 q0, q1
+vpst
+vclz.i16 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vfmas-bad.d b/gas/testsuite/gas/arm/mve-vfmas-bad.d
new file mode 100644 (file)
index 0000000..dd3510f
--- /dev/null
@@ -0,0 +1,5 @@
+#name: bad MVE FP VFMAS instructions 
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vfmas-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vfmas-bad.l b/gas/testsuite/gas/arm/mve-vfmas-bad.l
new file mode 100644 (file)
index 0000000..6a9b1f4
--- /dev/null
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:11: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:12: Error: bad type in SIMD instruction -- `vfmas.i32 q0,q1,r2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vfmas.f64 q0,q1,r2'
+[^:]*: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
+[^:]*:16: Error: syntax error -- `vfmaseq.f32 q0,q1,r2'
+[^:]*:17: Error: syntax error -- `vfmaseq.f32 q0,q1,r2'
+[^:]*:19: Error: syntax error -- `vfmaseq.f32 q0,q1,r2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vfmast.f32 q0,q1,r2'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vfmas.f32 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vfmas-bad.s b/gas/testsuite/gas/arm/mve-vfmas-bad.s
new file mode 100644 (file)
index 0000000..15f894a
--- /dev/null
@@ -0,0 +1,22 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vfmas.f32 q0, q1, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vfmas.f32 q0, q1, sp
+vfmas.f32 q0, q1, pc
+vfmas.i32 q0, q1, r2
+vfmas.f64 q0, q1, r2
+cond
+it eq
+vfmaseq.f32 q0, q1, r2
+vfmaseq.f32 q0, q1, r2
+vpst
+vfmaseq.f32 q0, q1, r2
+vfmast.f32 q0, q1, r2
+vpst
+vfmas.f32 q0, q1, r2