[binutils-gdb] x86: Determine vector length from the last vector operand

H.J.Lu hjl@sourceware.org
Sun Jul 22 19:02:00 GMT 2018


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

commit c7213af9b3e47d3341f95fe24549681029a53853
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sun Jul 22 12:00:39 2018 -0700

    x86: Determine vector length from the last vector operand
    
    Determine VEX/EVEXE vector length from the last multi-length vector
    operand.
    
    	* config/tc-i386.c (build_vex_prefix): Determine vector
    	length from the last multi-length vector operand.
    	(build_evex_prefix): Likewise.

Diff:
---
 gas/ChangeLog        |  6 ++++++
 gas/config/tc-i386.c | 35 +++++++++++++++++++++++++----------
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 3253a9f..5df35569 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* config/tc-i386.c (build_vex_prefix): Determine vector
+	length from the last multi-length vector operand.
+	(build_evex_prefix): Likewise.
+
 2018-07-20  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config/tc-i386.c (match_simd_size): Break long line.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index c4ccffc..575b017 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -3363,10 +3363,12 @@ build_vex_prefix (const insn_template *t)
     vector_length = 1;
   else
     {
-      unsigned int op;
+      int op;
 
+      /* Determine vector length from the last multi-length vector
+	 operand.  */
       vector_length = 0;
-      for (op = 0; op < t->operands; ++op)
+      for (op = t->operands - 1; op >= 0; op--)
 	if (t->operand_types[op].bitfield.xmmword
 	    && t->operand_types[op].bitfield.ymmword
 	    && i.types[op].bitfield.ymmword)
@@ -3611,20 +3613,31 @@ build_evex_prefix (void)
       if (!i.tm.opcode_modifier.evex
 	  || i.tm.opcode_modifier.evex == EVEXDYN)
 	{
-	  unsigned int op;
+	  int op;
 
+	  /* Determine vector length from the last multi-length vector
+	     operand.  */
 	  vec_length = 0;
-	  for (op = 0; op < i.tm.operands; ++op)
+	  for (op = i.operands - 1; op >= 0; op--)
 	    if (i.tm.operand_types[op].bitfield.xmmword
 		+ i.tm.operand_types[op].bitfield.ymmword
 		+ i.tm.operand_types[op].bitfield.zmmword > 1)
 	      {
 		if (i.types[op].bitfield.zmmword)
-		  i.tm.opcode_modifier.evex = EVEX512;
+		  {
+		    i.tm.opcode_modifier.evex = EVEX512;
+		    break;
+		  }
 		else if (i.types[op].bitfield.ymmword)
-		  i.tm.opcode_modifier.evex = EVEX256;
+		  {
+		    i.tm.opcode_modifier.evex = EVEX256;
+		    break;
+		  }
 		else if (i.types[op].bitfield.xmmword)
-		  i.tm.opcode_modifier.evex = EVEX128;
+		  {
+		    i.tm.opcode_modifier.evex = EVEX128;
+		    break;
+		  }
 		else if (i.broadcast && (int) op == i.broadcast->operand)
 		  {
 		    switch ((i.tm.operand_types[op].bitfield.dword ? 4 : 8)
@@ -3640,12 +3653,14 @@ build_evex_prefix (void)
 			  i.tm.opcode_modifier.evex = EVEX128;
 			  break;
 			default:
-			  continue;
+			  abort ();
 		      }
+		    break;
 		  }
-		  continue;
-		break;
 	      }
+
+	  if (op < 0)
+	    abort ();
 	}
 
       switch (i.tm.opcode_modifier.evex)



More information about the Binutils-cvs mailing list