[35/57,Arm,GAS] Add support for MVE instructions: vshlc and vshll

Message ID ece4b845-a4db-1c30-fd2f-686df2666d41@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:36 p.m.
Hi,

This patch adds support for MVE instructions VSHLC, VSHLLT, and VSHLLB.

gas/ChangeLog:

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

	* config/tc-arm.c (do_mve_vshll): New encoding function.
	(do_mve_vshlc): Likewise.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vshlc-bad.d: New test.
	* testsuite/gas/arm/mve-vshlc-bad.l: New test.
	* testsuite/gas/arm/mve-vshlc-bad.s: New test.
	* testsuite/gas/arm/mve-vshll-bad.d: New test.
	* testsuite/gas/arm/mve-vshll-bad.l: New test.
	* testsuite/gas/arm/mve-vshll-bad.s: New test.

Patch

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 53924bd1a76debe9ca9999eefe21a55881541dfb..b3e4228d62f6dd9f3f672dad8f407ef4aed2bf1f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15774,6 +15774,63 @@  do_mve_vmlas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vshll (void)
+{
+  struct neon_type_el et
+    = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  int imm = inst.operands[2].imm;
+  constraint (imm < 1 || (unsigned)imm > et.size,
+	      _("immediate value out of range"));
+
+  if ((unsigned)imm == et.size)
+    {
+      inst.instruction |= neon_logbits (et.size) << 18;
+      inst.instruction |= 0x110001;
+    }
+  else
+    {
+      inst.instruction |= (et.size + imm) << 16;
+      inst.instruction |= 0x800140;
+    }
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
+
+static void
+do_mve_vshlc (void)
+{
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (inst.operands[1].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+  else if (inst.operands[1].reg == REG_SP)
+    as_tsktsk (MVE_BAD_SP);
+
+  int imm = inst.operands[2].imm;
+  constraint (imm < 1 || imm > 32, _("immediate value out of range"));
+
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= (imm & 0x1f) << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= inst.operands[1].reg;
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vshrn (void)
 {
@@ -25182,6 +25239,10 @@  static const struct asm_opcode insns[] =
  mCEF(vqrshrunt,  _vqrshrunt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
  mCEF(vqrshrunb,  _vqrshrunb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
 
+ mToC("vshlc",	    eea00fc0,	   3, (RMQ, RR, I32z),	    mve_vshlc),
+ mToC("vshllt",	    ee201e00,	   3, (RMQ, RMQ, I32),	    mve_vshll),
+ mToC("vshllb",	    ee200e00,	   3, (RMQ, RMQ, I32),	    mve_vshll),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vshlc-bad.d b/gas/testsuite/gas/arm/mve-vshlc-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..fcaafd3abb19f473e0b92537c43645e8bdedf6eb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshlc-bad.d
@@ -0,0 +1,5 @@ 
+#name: bad MVE VSHLC instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshlc-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshlc-bad.l b/gas/testsuite/gas/arm/mve-vshlc-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5aa4ef997b130b54d5968e669ca4109b265dcf11
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshlc-bad.l
@@ -0,0 +1,16 @@ 
+[^:]*: Assembler messages:
+[^:]*:10: Error: immediate value out of range -- `vshlc q0,r1,#0'
+[^:]*:11: Error: immediate value out of range -- `vshlc q0,r1,#33'
+[^:]*:12: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:13: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*: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 -- `vshlceq q0,r1,#2'
+[^:]*:17: Error: syntax error -- `vshlceq q0,r1,#2'
+[^:]*:19: Error: syntax error -- `vshlceq q0,r1,#2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vshlct q0,r1,#2'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vshlc q0,r1,#2'
diff --git a/gas/testsuite/gas/arm/mve-vshlc-bad.s b/gas/testsuite/gas/arm/mve-vshlc-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..777fa76fd8f32a03dbff4a1c08d8a9307af09d23
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshlc-bad.s
@@ -0,0 +1,22 @@ 
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vshlc q0, r1, #2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshlc q0, r1, #0
+vshlc q0, r1, #33
+vshlc q0, sp, #1
+vshlc q0, pc, #1
+cond
+it eq
+vshlceq q0, r1, #2
+vshlceq q0, r1, #2
+vpst
+vshlceq q0, r1, #2
+vshlct q0, r1, #2
+vpst
+vshlc q0, r1, #2
diff --git a/gas/testsuite/gas/arm/mve-vshll-bad.d b/gas/testsuite/gas/arm/mve-vshll-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..df0cfa350e7672bd37c5faefbff9ad792cf3118f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshll-bad.d
@@ -0,0 +1,5 @@ 
+#name: bad MVE VSHLLT and VSHLLB instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshll-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshll-bad.l b/gas/testsuite/gas/arm/mve-vshll-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..42152f48b2f42f926c7d8b9e81124a1f0c8f91d6
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshll-bad.l
@@ -0,0 +1,35 @@ 
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vshllt.s32 q0,q1,#1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vshllt.i8 q0,q1,#1'
+[^:]*:12: Error: immediate value out of range -- `vshllt.u8 q0,q1,#0'
+[^:]*:13: Error: immediate value out of range -- `vshllt.u8 q0,q1,#9'
+[^:]*:14: Error: immediate value out of range -- `vshllt.s16 q0,q1,#0'
+[^:]*:15: Error: immediate value out of range -- `vshllt.s16 q0,q1,#17'
+[^:]*:16: Error: bad type in SIMD instruction -- `vshllb.s32 q0,q1,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vshllb.i8 q0,q1,#1'
+[^:]*:18: Error: immediate value out of range -- `vshllb.u8 q0,q1,#0'
+[^:]*:19: Error: immediate value out of range -- `vshllb.u8 q0,q1,#9'
+[^:]*:20: Error: immediate value out of range -- `vshllb.s16 q0,q1,#0'
+[^:]*:21: Error: immediate value out of range -- `vshllb.s16 q0,q1,#17'
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Error: syntax error -- `vshllteq.s8 q0,q1,#1'
+[^:]*:26: Error: syntax error -- `vshllteq.s8 q0,q1,#1'
+[^:]*:28: Error: syntax error -- `vshllteq.s8 q0,q1,#1'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vshlltt.s8 q0,q1,#1'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vshllt.s8 q0,q1,#1'
+[^:]*:33: Error: syntax error -- `vshllbeq.s8 q0,q1,#1'
+[^:]*:34: Error: syntax error -- `vshllbeq.s8 q0,q1,#1'
+[^:]*:36: Error: syntax error -- `vshllbeq.s8 q0,q1,#1'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vshllbt.s8 q0,q1,#1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vshllb.s8 q0,q1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vshll-bad.s b/gas/testsuite/gas/arm/mve-vshll-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..01d52c65bbe4f8d0a20e2d6fd8cf9be5d16369f9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshll-bad.s
@@ -0,0 +1,39 @@ 
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, #4
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshllt.s32 q0, q1, #1
+vshllt.i8 q0, q1, #1
+vshllt.u8 q0, q1, #0
+vshllt.u8 q0, q1, #9
+vshllt.s16 q0, q1, #0
+vshllt.s16 q0, q1, #17
+vshllb.s32 q0, q1, #1
+vshllb.i8 q0, q1, #1
+vshllb.u8 q0, q1, #0
+vshllb.u8 q0, q1, #9
+vshllb.s16 q0, q1, #0
+vshllb.s16 q0, q1, #17
+cond vshllt
+cond vshllb
+it eq
+vshllteq.s8 q0, q1, #1
+vshllteq.s8 q0, q1, #1
+vpst
+vshllteq.s8 q0, q1, #1
+vshlltt.s8 q0, q1, #1
+vpst
+vshllt.s8 q0, q1, #1
+it eq
+vshllbeq.s8 q0, q1, #1
+vshllbeq.s8 q0, q1, #1
+vpst
+vshllbeq.s8 q0, q1, #1
+vshllbt.s8 q0, q1, #1
+vpst
+vshllb.s8 q0, q1, #1