[47/57,Arm,OBJDUMP] Add support for MVE instructions: vaddv, vmlaldav, vmladav, vmlas, vrmlsldavh, vmlsldav, vmlsdav, vrmlaldavh, vqdmlah, vqrdmlash, vqrdmlash, vqdmlsdh, vqrdmlsdh, vqdmulh and vqrdmulh

Message ID 74e4023d-475a-4982-67ae-e401a3733335@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:45 p.m.
Hello,

This patch adds support for MVE instructions: VADDV, VMLALDAV, VMLADAV, 
VMLAS, VRMLSLDAVH, VLSLDAV, VLSDAV, VRMLALDAVH, VQDLAH, VQRDMLASH, 
VQRDMLASH, VQDMLSDH, VQRDMLSDH, VQDMULH, and VQRDMULH.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_undefined): Add new reasons.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

Patch

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index e6383355496aa2ef8dc8dd5f5fc3bd1ffcb67905..006475d40046fc75df94ce29b595f220fda1c3ee 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -152,6 +152,29 @@  enum mve_instructions
   MVE_VQDMULL_T2,
   MVE_VQMOVN,
   MVE_VQMOVUN,
+  MVE_VADDV,
+  MVE_VMLADAV_T1,
+  MVE_VMLADAV_T2,
+  MVE_VMLALDAV,
+  MVE_VMLAS,
+  MVE_VADDLV,
+  MVE_VMLSDAV_T1,
+  MVE_VMLSDAV_T2,
+  MVE_VMLSLDAV,
+  MVE_VRMLALDAVH,
+  MVE_VRMLSLDAVH,
+  MVE_VQDMLADH,
+  MVE_VQRDMLADH,
+  MVE_VQDMLAH,
+  MVE_VQRDMLAH,
+  MVE_VQDMLASH,
+  MVE_VQRDMLASH,
+  MVE_VQDMLSDH,
+  MVE_VQRDMLSDH,
+  MVE_VQDMULH_T1,
+  MVE_VQRDMULH_T2,
+  MVE_VQDMULH_T3,
+  MVE_VQRDMULH_T4,
   MVE_NONE
 };
 
@@ -203,6 +226,7 @@  enum mve_undefined
 				   op2 == 0 and op1 == (0 or 1).  */
   UNDEF_OP_0_BAD_CMODE,		/* undefined because op == 0 and cmode
 				   in {0xx1, x0x1}.  */
+  UNDEF_XCHG_UNS,		/* undefined because X == 1 and U == 1.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1922,9 +1946,11 @@  static const struct opcode32 neon_opcodes[] =
    %E			print vmov, vmvn, vorr, vbic encoded constant
    %N			print generic index for vmov
    %T			print bottom ('b') or top ('t') of source register
+   %X			print exchange field in vmla* instructions
 
    %<bitfield>r		print as an ARM register
    %<bitfield>d		print the bitfield in decimal
+   %<bitfield>A		print accumulate or not
    %<bitfield>Q		print as a MVE Q register
    %<bitfield>F		print as a MVE S register
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
@@ -1999,6 +2025,18 @@  static const struct mopcode32 mve_opcodes[] =
    0xef100150, 0xffb11f51,
    "vbic%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VADDLV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADDLV,
+   0xee890f00, 0xef8f1fd1,
+   "vaddlv%5A%v.%u32\t%13-15l, %20-22h, %1-3Q"},
+
+  /* Vector VADDV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADDV,
+   0xeef10f00, 0xeff31fd1,
+   "vaddv%5A%v.%u%18-19s\t%13-15l, %1-3Q"},
+
   /* Vector VCMP floating point T1.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCMP_FP_T1,
@@ -2222,6 +2260,74 @@  static const struct mopcode32 mve_opcodes[] =
    0xec101f00, 0xfe101f80,
    "vldrw%v.u32\t%13-15,22Q, %d"},
 
+  /* Vector VMLALDAV.  Note must appear before VMLADAV due to instruction
+     opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLALDAV,
+   0xee801e00, 0xef801f51,
+   "vmlaldav%5Ax%v.%u%16s\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLALDAV,
+   0xee800e00, 0xef801f51,
+   "vmlalv%5A%v.%u%16s\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLAV T1 variant, same as VMLADAV but with X == 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T1,
+   0xeef00e00, 0xeff01f51,
+   "vmlav%5A%v.%u%16s\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLAV T2 variant, same as VMLADAV but with X == 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T2,
+   0xeef00f00, 0xeff11f51,
+   "vmlav%5A%v.%u8\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLADAV T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T1,
+   0xeef01e00, 0xeff01f51,
+   "vmladav%5Ax%v.%u%16s\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLADAV T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T2,
+   0xeef01f00, 0xeff11f51,
+   "vmladav%5Ax%v.%u8\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLAS.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLAS,
+   0xee011e40, 0xef811f70,
+   "vmlas%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VRMLSLDAVH.  Note must appear before VMLSDAV due to instruction
+     opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMLSLDAVH,
+   0xfe800e01, 0xff810f51,
+   "vrmlsldavh%5A%X%v.s32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLSLDAV.  Note must appear before VMLSDAV due to instruction
+     opcdoe aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLSLDAV,
+   0xee800e01, 0xff800f51,
+   "vmlsldav%5A%X%v.%u%16s\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLSDAV T1 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLSDAV_T1,
+   0xeef00e01, 0xfff00f51,
+   "vmlsdav%5A%X%v.s%16s\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLSDAV T2 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLSDAV_T2,
+   0xfef00e01, 0xfff10f51,
+   "vmlsdav%5A%X%v.s8\t%13-15l, %17-19,7Q, %1-3Q"},
+
   /* Vector VMOV between gpr and half precision register, op == 0.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VMOV_HFP_TO_GP,
@@ -2367,12 +2473,96 @@  static const struct mopcode32 mve_opcodes[] =
    0xee310e81, 0xffb30fd1,
    "vqmovun%T%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
 
+  /* Vector VQDMLADH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLADH,
+   0xee000e00, 0xff810f51,
+   "vqdmladh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQRDMLADH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLADH,
+   0xee000e01, 0xff810f51,
+   "vqrdmladh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMLAH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLAH,
+   0xee000e60, 0xef811f70,
+   "vqdmlah%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQRDMLAH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLAH,
+   0xee000e40, 0xef811f70,
+   "vqrdmlah%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQDMLASH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLASH,
+   0xee001e60, 0xef811f70,
+   "vqdmlash%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQRDMLASH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLASH,
+   0xee001e40, 0xef811f70,
+   "vqrdmlash%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQDMLSDH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLSDH,
+   0xfe000e00, 0xff810f51,
+   "vqdmlsdh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQRDMLSDH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLSDH,
+   0xfe000e01, 0xff810f51,
+   "vqrdmlsdh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMULH T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMULH_T1,
+   0xef000b40, 0xff811f51,
+   "vqdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQRDMULH T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMULH_T2,
+   0xff000b40, 0xff811f51,
+   "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMULH T3 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMULH_T3,
+   0xee010e60, 0xff811f70,
+   "vqdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQRDMULH T4 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMULH_T4,
+   0xfe010e60, 0xff811f70,
+   "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   /* Vector VRINT floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VRINT_FP,
    0xffb20440, 0xffb31c51,
    "vrint%m%v.f%18-19s\t%13-15,22Q, %1-3,5Q"},
 
+  /* Vector VRMLALDAVH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMLALDAVH,
+   0xee800f00, 0xef811f51,
+   "vrmlalvh%5A%v.%u32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VRMLALDAVH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMLALDAVH,
+   0xee801f00, 0xef811f51,
+   "vrmlaldavh%5Ax%v.%u32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
   /* Vector VST2 no writeback.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VST2,
@@ -4477,6 +4667,17 @@  is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VQRDMLADH:
+    case MVE_VQDMLAH:
+    case MVE_VQRDMLAH:
+    case MVE_VQDMLASH:
+    case MVE_VQRDMLASH:
+    case MVE_VQDMLSDH:
+    case MVE_VQRDMLSDH:
+    case MVE_VQDMULH_T3:
+    case MVE_VQRDMULH_T4:
+    case MVE_VQDMLADH:
+    case MVE_VMLAS:
     case MVE_VMULL_INT:
     case MVE_VHADD_T2:
     case MVE_VHSUB_T2:
@@ -4572,6 +4773,7 @@  is_mve_encoding_conflict (unsigned long given,
 	  return FALSE;
       }
 
+    case MVE_VADDV:
     case MVE_VMOVN:
     case MVE_VQMOVUN:
     case MVE_VQMOVN:
@@ -4580,6 +4782,21 @@  is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VMLSLDAV:
+    case MVE_VRMLSLDAVH:
+    case MVE_VMLALDAV:
+    case MVE_VADDLV:
+      if (arm_decode_field (given, 20, 22) == 7)
+	return TRUE;
+      else
+	return FALSE;
+
+    case MVE_VRMLALDAVH:
+      if ((arm_decode_field (given, 20, 22) & 6) == 6)
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -4681,6 +4898,8 @@  is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VQDMULH_T1:
+    case MVE_VQRDMULH_T2:
     case MVE_VRHADD:
     case MVE_VHADD_T1:
     case MVE_VHSUB_T1:
@@ -4942,6 +5161,19 @@  is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VRMLALDAVH:
+    case MVE_VMLADAV_T1:
+    case MVE_VMLADAV_T2:
+    case MVE_VMLALDAV:
+      if ((arm_decode_field (given, 28, 28) == 1)
+	  && (arm_decode_field (given, 12, 12) == 1))
+	{
+	  *undefined_code = UNDEF_XCHG_UNS;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5001,6 +5233,13 @@  is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VQDMLAH:
+    case MVE_VQRDMLAH:
+    case MVE_VQDMLASH:
+    case MVE_VQRDMLASH:
+    case MVE_VQDMULH_T3:
+    case MVE_VQRDMULH_T4:
+    case MVE_VMLAS:
     case MVE_VFMA_FP_SCALAR:
     case MVE_VFMAS_FP_SCALAR:
     case MVE_VHADD_T2:
@@ -5213,6 +5452,10 @@  is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VQRDMLADH:
+    case MVE_VQDMLSDH:
+    case MVE_VQRDMLSDH:
+    case MVE_VQDMLADH:
     case MVE_VMULL_INT:
       {
 	unsigned long Qd;
@@ -5293,6 +5536,18 @@  is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMLSLDAV:
+    case MVE_VRMLSLDAVH:
+    case MVE_VMLALDAV:
+    case MVE_VADDLV:
+      if (arm_decode_field (given, 20, 22) == 6)
+	{
+	  *unpredictable_code = UNPRED_R13;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5559,6 +5814,10 @@  print_mve_undefined (struct disassemble_info *info,
       func (stream, "op field equal 0 and bad cmode");
       break;
 
+    case UNDEF_XCHG_UNS:
+      func (stream, "exchange and unsigned together");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -5918,6 +6177,7 @@  print_mve_size (struct disassemble_info *info,
 
   switch (matched_insn)
     {
+    case MVE_VADDV:
     case MVE_VCMP_VEC_T1:
     case MVE_VCMP_VEC_T2:
     case MVE_VCMP_VEC_T3:
@@ -5936,12 +6196,25 @@  print_mve_size (struct disassemble_info *info,
     case MVE_VLDRD_GATHER_T4:
     case MVE_VLDRB_T1:
     case MVE_VLDRH_T2:
+    case MVE_VMLAS:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
     case MVE_VPT_VEC_T4:
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
+    case MVE_VQDMLADH:
+    case MVE_VQRDMLADH:
+    case MVE_VQDMLAH:
+    case MVE_VQRDMLAH:
+    case MVE_VQDMLASH:
+    case MVE_VQRDMLASH:
+    case MVE_VQDMLSDH:
+    case MVE_VQRDMLSDH:
+    case MVE_VQDMULH_T1:
+    case MVE_VQRDMULH_T2:
+    case MVE_VQDMULH_T3:
+    case MVE_VQRDMULH_T4:
     case MVE_VRHADD:
     case MVE_VRINT_FP:
     case MVE_VST2:
@@ -5971,6 +6244,10 @@  print_mve_size (struct disassemble_info *info,
 	func (stream, "16");
       break;
 
+    case MVE_VMLADAV_T1:
+    case MVE_VMLALDAV:
+    case MVE_VMLSDAV_T1:
+    case MVE_VMLSLDAV:
     case MVE_VMOVN:
     case MVE_VQDMULL_T1:
     case MVE_VQDMULL_T2:
@@ -7642,6 +7919,11 @@  print_insn_mve (struct disassemble_info *info, long given)
 			func (stream, "t");
 		      break;
 
+		    case 'X':
+		      if (arm_decode_field (given, 12, 12) == 1)
+			func (stream, "x");
+		      break;
+
 		    case '0': case '1': case '2': case '3': case '4':
 		    case '5': case '6': case '7': case '8': case '9':
 		      {
@@ -7665,6 +7947,10 @@  print_insn_mve (struct disassemble_info *info, long given)
 					    value,
 					    insn->mve_op);
 			    break;
+			  case 'A':
+			    if (value == 1)
+			      func (stream, "a");
+			    break;
 			  case 'i':
 			    {
 			      unsigned long imm