This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24]


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=04d54ace12e77deb8b1d26541de0f2cbc11880f5

commit 04d54ace12e77deb8b1d26541de0f2cbc11880f5
Author: Andre Vieira <andre.simoesdiasvieira@arm.com>
Date:   Thu May 16 14:04:35 2019 +0100

    [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24]
    
    opcodes/ChangeLog:
    2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
    	    Michael Collison <michael.collison@arm.com>
    
    	* arm-dis.c (enum mve_instructions): Add new instructions.
    	(enum mve_unpredictable): Add new reasons.
    	(is_mve_encoding_conflict): Handle new instructions.
    	(is_mve_unpredictable): Likewise.
    	(mve_opcodes): Add new instructions.
    	(print_mve_unpredictable): Handle new reasons.
    	(print_mve_register_blocks): New print function.
    	(print_mve_size): Handle new instructions.
    	(print_insn_mve): Likewise.

Diff:
---
 opcodes/ChangeLog |  13 ++++
 opcodes/arm-dis.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 191 insertions(+)

diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index ef6d3e8..25a86e2 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -3,6 +3,19 @@
 
 	* arm-dis.c (enum mve_instructions): Add new instructions.
 	(enum mve_unpredictable): Add new reasons.
+	(is_mve_encoding_conflict): Handle new instructions.
+	(is_mve_unpredictable): Likewise.
+	(mve_opcodes): Add new instructions.
+	(print_mve_unpredictable): Handle new reasons.
+	(print_mve_register_blocks): New print function.
+	(print_mve_size): Handle new instructions.
+	(print_insn_mve): Likewise.
+
+2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+	    Michael Collison <michael.collison@arm.com>
+
+	* arm-dis.c (enum mve_instructions): Add new instructions.
+	(enum mve_unpredictable): Add new reasons.
 	(enum mve_undefined): Likewise.
 	(is_mve_encoding_conflict): Handle new instructions.
 	(is_mve_undefined): Likewise.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 75cc27b..8ebf227 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -98,6 +98,10 @@ enum mve_instructions
   MVE_VHSUB_T1,
   MVE_VHSUB_T2,
   MVE_VRHADD,
+  MVE_VLD2,
+  MVE_VLD4,
+  MVE_VST2,
+  MVE_VST4,
   MVE_NONE
 };
 
@@ -110,6 +114,12 @@ enum mve_unpredictable
   UNPRED_R13,			/* Unpredictable because r13 (sp) or
 				   r15 (sp) used.  */
   UNPRED_R15,			/* Unpredictable because r15 (pc) is used.  */
+  UNPRED_Q_GT_4,		/* Unpredictable because
+				   vec reg start > 4 (vld4/st4).  */
+  UNPRED_Q_GT_6,		/* Unpredictable because
+				   vec reg start > 6 (vld2/st2).  */
+  UNPRED_R13_AND_WB,		/* Unpredictable becase gp reg = r13
+				   and WB bit = 1.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
@@ -1823,7 +1833,11 @@ static const struct opcode32 neon_opcodes[] =
    %n			print vector comparison code for predicated instruction
    %v			print vector predicate for instruction in predicated
 			block
+   %w			print writeback mode for MVE v{st,ld}[24]
+   %B			print v{st,ld}[24] any one operands
+
    %<bitfield>r		print as an ARM register
+   %<bitfield>d		print the bitfield in decimal
    %<bitfield>Q		print as a MVE Q register
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
 			UNPREDICTABLE
@@ -1997,6 +2011,42 @@ static const struct mopcode32 mve_opcodes[] =
    0xef000140, 0xef811f51,
    "vrhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VLD2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLD2,
+   0xfc901e00, 0xff901e5f,
+   "vld2%5d.%7-8s\t%B, [%16-19r]%w"},
+
+  /* Vector VLD4.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLD4,
+   0xfc901e01, 0xff901e1f,
+   "vld4%5-6d.%7-8s\t%B, [%16-19r]%w"},
+
+  /* Vector VST2 no writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST2,
+   0xfc801e00, 0xffb01e5f,
+   "vst2%5d.%7-8s\t%B, [%16-19r]"},
+
+  /* Vector VST2 writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST2,
+   0xfca01e00, 0xffb01e5f,
+   "vst2%5d.%7-8s\t%B, [%16-19r]!"},
+
+  /* Vector VST4 no writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST4,
+   0xfc801e01, 0xffb01e1f,
+   "vst4%5-6d.%7-8s\t%B, [%16-19r]"},
+
+  /* Vector VST4 writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST4,
+   0xfca01e01, 0xffb01e1f,
+   "vst4%5-6d.%7-8s\t%B, [%16-19r]!"},
+
   {ARM_FEATURE_CORE_LOW (0),
    MVE_NONE,
    0x00000000, 0x00000000, 0}
@@ -4015,6 +4065,15 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VLD2:
+    case MVE_VLD4:
+    case MVE_VST2:
+    case MVE_VST4:
+      if (arm_decode_field (given, 7, 8) == 3)
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -4132,6 +4191,58 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VLD2:
+    case MVE_VST2:
+      {
+	unsigned long rn = arm_decode_field (given, 16, 19);
+
+	if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1))
+	  {
+	    *unpredictable_code = UNPRED_R13_AND_WB;
+	    return TRUE;
+	  }
+
+	if (rn == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	if (arm_decode_field_multiple (given, 13, 15, 22, 22) > 6)
+	  {
+	    *unpredictable_code = UNPRED_Q_GT_6;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VLD4:
+    case MVE_VST4:
+      {
+	unsigned long rn = arm_decode_field (given, 16, 19);
+
+	if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1))
+	  {
+	    *unpredictable_code = UNPRED_R13_AND_WB;
+	    return TRUE;
+	  }
+
+	if (rn == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	if (arm_decode_field_multiple (given, 13, 15, 22, 22) > 4)
+	  {
+	    *unpredictable_code = UNPRED_Q_GT_4;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4185,11 +4296,61 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "use of r15 (pc)");
       break;
 
+    case UNPRED_Q_GT_4:
+      func (stream, "start register block > r4");
+      break;
+
+    case UNPRED_Q_GT_6:
+      func (stream, "start register block > r6");
+      break;
+
+    case UNPRED_R13_AND_WB:
+      func (stream, "use of r13 and write back");
+      break;
+
     case UNPRED_NONE:
       break;
     }
 }
 
+/* Print register block operand for mve vld2/vld4/vst2/vld4.  */
+
+static void
+print_mve_register_blocks (struct disassemble_info *info,
+			   unsigned long given,
+			   enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  unsigned long q_reg_start = arm_decode_field_multiple (given,
+							 13, 15,
+							 22, 22);
+  switch (matched_insn)
+    {
+    case MVE_VLD2:
+    case MVE_VST2:
+      if (q_reg_start <= 6)
+	func (stream, "{q%ld, q%ld}", q_reg_start, q_reg_start + 1);
+      else
+	func (stream, "<illegal reg q%ld>", q_reg_start);
+      break;
+
+    case MVE_VLD4:
+    case MVE_VST4:
+      if (q_reg_start <= 4)
+	func (stream, "{q%ld, q%ld, q%ld, q%ld}", q_reg_start,
+	      q_reg_start + 1, q_reg_start + 2,
+	      q_reg_start + 3);
+      else
+	func (stream, "<illegal reg q%ld>", q_reg_start);
+      break;
+
+    default:
+      break;
+    }
+}
+
 static void
 print_instruction_predicate (struct disassemble_info *info)
 {
@@ -4222,6 +4383,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VHADD_T2:
     case MVE_VHSUB_T1:
     case MVE_VHSUB_T2:
+    case MVE_VLD2:
+    case MVE_VLD4:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
@@ -4229,6 +4392,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
     case MVE_VRHADD:
+    case MVE_VST2:
+    case MVE_VST4:
       if (size <= 3)
 	func (stream, "%s", mve_vec_sizename[size]);
       else
@@ -5721,6 +5886,15 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      print_instruction_predicate (info);
 		      break;
 
+		    case 'w':
+		      if (arm_decode_field (given, 21, 21) == 1)
+			func (stream, "!");
+		      break;
+
+		    case 'B':
+		      print_mve_register_blocks (info, given, insn->mve_op);
+		      break;
+
 		    case '0': case '1': case '2': case '3': case '4':
 		    case '5': case '6': case '7': case '8': case '9':
 		      {
@@ -5747,6 +5921,10 @@ print_insn_mve (struct disassemble_info *info, long given)
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;
+			  case 'd':
+			    func (stream, "%ld", value);
+			    value_in_comment = value;
+			    break;
 			  case 'Q':
 			    if (value & 0x8)
 			      func (stream, "<illegal reg q%ld.5>", value);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]