[49/57,Arm,OBJDUMP] Add support for MVE complex number instructions

Message ID d7151f3c-7122-110d-bf7c-b3dc96b7661b@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:46 p.m.
Hello,

This patch adds support for MVE instructions: VCADD, VHCADD, VCMLA, and 
VCMUL.

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.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_unpredictable): Likewise.
	(print_mve_rotate): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

Patch

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 1dae51d8a0889e288e85876be280bfaea2a4c785..f2e244d104cdb1938ea2a9b8066647b485aaaa1f 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -179,6 +179,11 @@  enum mve_instructions
   MVE_VDWDUP,
   MVE_VIWDUP,
   MVE_VIDUP,
+  MVE_VCADD_FP,
+  MVE_VCADD_VEC,
+  MVE_VHCADD,
+  MVE_VCMLA_FP,
+  MVE_VCMUL_FP,
   MVE_NONE
 };
 
@@ -1964,6 +1969,7 @@  static const struct opcode32 neon_opcodes[] =
    %<bitfield>h		print high half of 64-bit destination reg
    %<bitfield>k		print immediate for vector conversion instruction
    %<bitfield>l		print low half of 64-bit destination reg
+   %<bitfield>o		print rotate value for vcmul
    %<bitfield>u		print immediate value for vddup/vdwdup
    %<bitfield>x		print the bitfield in hex.
   */
@@ -2044,6 +2050,24 @@  static const struct mopcode32 mve_opcodes[] =
    0xeef10f00, 0xeff31fd1,
    "vaddv%5A%v.%u%18-19s\t%13-15l, %1-3Q"},
 
+  /* Vector VCADD floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCADD_FP,
+   0xfc800840, 0xfea11f51,
+   "vcadd%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%24o"},
+
+  /* Vector VCADD.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCADD_VEC,
+   0xfe000f00, 0xff810f51,
+   "vcadd%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%12o"},
+
+  /* Vector VCMLA.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCMLA_FP,
+   0xfc200840, 0xfe211f51,
+   "vcmla%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%23-24o"},
+
   /* Vector VCMP floating point T1.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCMP_FP_T1,
@@ -2147,6 +2171,12 @@  static const struct mopcode32 mve_opcodes[] =
    0xee001f40, 0xef811f70,
    "vhsub%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
 
+  /* Vector VCMUL.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCMUL_FP,
+   0xee300e00, 0xefb10f50,
+   "vcmul%v.f%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%0,12o"},
+
   /* Vector VDUP.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VDUP,
@@ -2201,6 +2231,12 @@  static const struct mopcode32 mve_opcodes[] =
    0xee011f60, 0xff811f70,
    "vdwdup%v.u%20-21s\t%13-15,22Q, %17-19l, %1-3h, #%0,7u"},
 
+  /* Vector VHCADD.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VHCADD,
+   0xee000f00, 0xff810f51,
+   "vhcadd%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%12o"},
+
   /* Vector VIWDUP.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VIWDUP,
@@ -4698,6 +4734,8 @@  is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VCADD_VEC:
+    case MVE_VHCADD:
     case MVE_VDDUP:
     case MVE_VIDUP:
     case MVE_VQRDMLADH:
@@ -5521,6 +5559,7 @@  is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	  return FALSE;
       }
 
+    case MVE_VCMUL_FP:
     case MVE_VQDMULL_T1:
       {
 	unsigned long Qd;
@@ -5599,6 +5638,58 @@  is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VCADD_VEC:
+    case MVE_VHCADD:
+      {
+	unsigned long Qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	if ((Qd == Qm) && arm_decode_field (given, 20, 21) == 2)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_2;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VCADD_FP:
+      {
+	unsigned long Qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	if ((Qd == Qm) && arm_decode_field (given, 20, 20) == 1)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VCMLA_FP:
+      {
+	unsigned long Qda;
+	unsigned long Qm;
+	unsigned long Qn;
+
+	if (arm_decode_field (given, 20, 20) == 1)
+	  {
+	    Qda = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	    Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	    Qn = arm_decode_field_multiple (given, 17, 19, 7, 7);
+
+	    if ((Qda == Qn) || (Qda == Qm))
+	      {
+		*unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+	else
+	  return FALSE;
+
+      }
+
     default:
       return FALSE;
     }
@@ -6206,6 +6297,49 @@  print_mve_vcvt_size (struct disassemble_info *info,
     }
 }
 
+static void
+print_mve_rotate (struct disassemble_info *info, unsigned long rot,
+		  unsigned long rot_width)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  if (rot_width == 1)
+    {
+      switch (rot)
+	{
+	case 0:
+	  func (stream, "90");
+	  break;
+	case 1:
+	  func (stream, "270");
+	  break;
+	default:
+	  break;
+	}
+    }
+  else if (rot_width == 2)
+    {
+      switch (rot)
+	{
+	case 0:
+	  func (stream, "0");
+	  break;
+	case 1:
+	  func (stream, "90");
+	  break;
+	case 2:
+	  func (stream, "180");
+	  break;
+	case 3:
+	  func (stream, "270");
+	  break;
+	default:
+	  break;
+	}
+    }
+}
+
 static void
 print_instruction_predicate (struct disassemble_info *info)
 {
@@ -6229,6 +6363,7 @@  print_mve_size (struct disassemble_info *info,
   switch (matched_insn)
     {
     case MVE_VADDV:
+    case MVE_VCADD_VEC:
     case MVE_VCMP_VEC_T1:
     case MVE_VCMP_VEC_T2:
     case MVE_VCMP_VEC_T3:
@@ -6239,6 +6374,7 @@  print_mve_size (struct disassemble_info *info,
     case MVE_VDWDUP:
     case MVE_VHADD_T1:
     case MVE_VHADD_T2:
+    case MVE_VHCADD:
     case MVE_VHSUB_T1:
     case MVE_VHSUB_T2:
     case MVE_VIDUP:
@@ -6299,6 +6435,9 @@  print_mve_size (struct disassemble_info *info,
 	func (stream, "16");
       break;
 
+    case MVE_VCADD_FP:
+    case MVE_VCMLA_FP:
+    case MVE_VCMUL_FP:
     case MVE_VMLADAV_T1:
     case MVE_VMLALDAV:
     case MVE_VMLSDAV_T1:
@@ -8064,6 +8203,9 @@  print_insn_mve (struct disassemble_info *info, long given)
 				break;
 			      }
 			    break;
+			  case 'o':
+			    print_mve_rotate (info, value, width);
+			    break;
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;