x86: Determine vector length from the last vector operand
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 22 Jul 2018 19:00:39 +0000 (12:00 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 22 Jul 2018 19:00:39 +0000 (12:00 -0700)
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.

gas/ChangeLog
gas/config/tc-i386.c

index 3253a9fdc676bc62f506717d406a8f6e1ee01470..5df35569f94751b096ac89dd21e9f8689df296d4 100644 (file)
@@ -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.
index c4ccffc75fa65348d02f66f7059c443c06efdfa0..575b017af42a9f6c16f46470495a096a7dbef034 100644 (file)
@@ -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)