x86: drop VexImmExt
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index f201d1ae9dde38c4a4c9b8ad87dd002d9f328db1..2ddbe195a9ea2688126acda6ea89077ccecf995f 100644 (file)
@@ -225,7 +225,7 @@ static struct Mask_Operation mask_op;
    broadcast factor.  */
 struct Broadcast_Operation
 {
-  /* Type of broadcast: no broadcast, {1to8}, or {1to16}.  */
+  /* Type of broadcast: {1to2}, {1to4}, {1to8}, or {1to16}.  */
   int type;
 
   /* Index of broadcasted operand.  */
@@ -432,7 +432,6 @@ const char extra_symbol_chars[] = "*%-([{}"
         && !defined (TE_GNU)                           \
         && !defined (TE_LINUX)                         \
         && !defined (TE_NACL)                          \
-        && !defined (TE_NETWARE)                       \
         && !defined (TE_FreeBSD)                       \
         && !defined (TE_DragonFly)                     \
         && !defined (TE_NetBSD)))
@@ -1026,6 +1025,10 @@ static const arch_entry cpu_arch[] =
     CPU_WBNOINVD_FLAGS, 0 },
   { STRING_COMMA_LEN (".pconfig"), PROCESSOR_UNKNOWN,
     CPU_PCONFIG_FLAGS, 0 },
+  { STRING_COMMA_LEN (".waitpkg"), PROCESSOR_UNKNOWN,
+    CPU_WAITPKG_FLAGS, 0 },
+  { STRING_COMMA_LEN (".cldemote"), PROCESSOR_UNKNOWN,
+    CPU_CLDEMOTE_FLAGS, 0 },
 };
 
 static const noarch_entry cpu_noarch[] =
@@ -5048,43 +5051,60 @@ check_VecOperands (const insn_template *t)
      to the memory operand.  */
   if (i.broadcast)
     {
-      int broadcasted_opnd_size;
+      i386_operand_type type, overlap;
 
       /* Check if specified broadcast is supported in this instruction,
-        and it's applied to memory operand of DWORD or QWORD type,
-        depending on VecESize.  */
+        and it's applied to memory operand of DWORD or QWORD type.  */
       op = i.broadcast->operand;
-      if (i.broadcast->type != t->opcode_modifier.broadcast
+      if (!t->opcode_modifier.broadcast
          || !i.types[op].bitfield.mem
-         || (t->opcode_modifier.vecesize == 0
-             && !i.types[op].bitfield.dword
-             && !i.types[op].bitfield.unspecified)
-         || (t->opcode_modifier.vecesize == 1
-             && !i.types[op].bitfield.qword
-             && !i.types[op].bitfield.unspecified))
-       goto bad_broadcast;
-
-      broadcasted_opnd_size = t->opcode_modifier.vecesize ? 64 : 32;
-      if (i.broadcast->type == BROADCAST_1TO16)
-       broadcasted_opnd_size <<= 4; /* Broadcast 1to16.  */
-      else if (i.broadcast->type == BROADCAST_1TO8)
-       broadcasted_opnd_size <<= 3; /* Broadcast 1to8.  */
-      else if (i.broadcast->type == BROADCAST_1TO4)
-       broadcasted_opnd_size <<= 2; /* Broadcast 1to4.  */
-      else if (i.broadcast->type == BROADCAST_1TO2)
-       broadcasted_opnd_size <<= 1; /* Broadcast 1to2.  */
-      else
-       goto bad_broadcast;
-
-      if ((broadcasted_opnd_size == 256
-          && !t->operand_types[op].bitfield.ymmword)
-         || (broadcasted_opnd_size == 512
-             && !t->operand_types[op].bitfield.zmmword))
+         || (!i.types[op].bitfield.unspecified
+             && (t->operand_types[op].bitfield.dword
+                 ? !i.types[op].bitfield.dword
+                 : !i.types[op].bitfield.qword)))
        {
        bad_broadcast:
          i.error = unsupported_broadcast;
          return 1;
        }
+
+      operand_type_set (&type, 0);
+      switch ((t->operand_types[op].bitfield.dword ? 4 : 8) * i.broadcast->type)
+       {
+       case 8:
+         type.bitfield.qword = 1;
+         break;
+       case 16:
+         type.bitfield.xmmword = 1;
+         break;
+       case 32:
+         type.bitfield.ymmword = 1;
+         break;
+       case 64:
+         type.bitfield.zmmword = 1;
+         break;
+       default:
+         goto bad_broadcast;
+       }
+
+      overlap = operand_type_and (type, t->operand_types[op]);
+      if (operand_type_all_zero (&overlap))
+         goto bad_broadcast;
+
+      if (t->opcode_modifier.checkregsize)
+       {
+         unsigned int j;
+
+         for (j = 0; j < i.operands; ++j)
+           {
+             if (j != op
+                 && !operand_type_register_match(i.types[j],
+                                                 t->operand_types[j],
+                                                 type,
+                                                 t->operand_types[op]))
+               goto bad_broadcast;
+           }
+       }
     }
   /* If broadcast is supported in this instruction, we need to check if
      operand of one-element size isn't specified without broadcast.  */
@@ -5096,15 +5116,16 @@ check_VecOperands (const insn_template *t)
          break;
       gas_assert (op < i.operands);
       /* Check size of the memory operand.  */
-      if ((t->opcode_modifier.vecesize == 0
-          && i.types[op].bitfield.dword)
-         || (t->opcode_modifier.vecesize == 1
-             && i.types[op].bitfield.qword))
+      if (t->operand_types[op].bitfield.dword
+         ? i.types[op].bitfield.dword
+         : i.types[op].bitfield.qword)
        {
          i.error = broadcast_needed;
          return 1;
        }
     }
+  else
+    op = MAX_OPERANDS - 1; /* Avoid uninitialized variable warning.  */
 
   /* Check if requested masking is supported.  */
   if (i.mask
@@ -5151,7 +5172,7 @@ check_VecOperands (const insn_template *t)
       && i.disp_encoding != disp_encoding_32bit)
     {
       if (i.broadcast)
-       i.memshift = t->opcode_modifier.vecesize ? 3 : 2;
+       i.memshift = t->operand_types[op].bitfield.dword ? 2 : 3;
       else
        i.memshift = t->opcode_modifier.disp8memshift;
 
@@ -6546,22 +6567,13 @@ build_modrm_byte (void)
   unsigned int source, dest;
   int vex_3_sources;
 
-  /* The first operand of instructions with VEX prefix and 3 sources
-     must be VEX_Imm4.  */
   vex_3_sources = i.tm.opcode_modifier.vexsources == VEX3SOURCES;
   if (vex_3_sources)
     {
       unsigned int nds, reg_slot;
       expressionS *exp;
 
-      if (i.tm.opcode_modifier.veximmext
-          && i.tm.opcode_modifier.immext)
-        {
-          dest = i.operands - 2;
-          gas_assert (dest == 3);
-        }
-      else
-        dest = i.operands - 1;
+      dest = i.operands - 1;
       nds = dest - 1;
 
       /* There are 2 kinds of instructions:
@@ -6570,16 +6582,12 @@ build_modrm_byte (void)
          VexW0 or VexW1.  The destination must be either XMM, YMM or
         ZMM register.
          2. 4 operands: 4 register operands or 3 register operands
-         plus 1 memory operand, VexXDS, and VexImmExt  */
+        plus 1 memory operand, with VexXDS.  */
       gas_assert ((i.reg_operands == 4
                    || (i.reg_operands == 3 && i.mem_operands == 1))
                   && i.tm.opcode_modifier.vexvvvv == VEXXDS
-                  && (i.tm.opcode_modifier.veximmext
-                      || (i.imm_operands == 1
-                          && i.types[0].bitfield.vec_imm4
-                          && (i.tm.opcode_modifier.vexw == VEXW0
-                              || i.tm.opcode_modifier.vexw == VEXW1)
-                          && i.tm.operand_types[dest].bitfield.regsimd)));
+                 && i.tm.opcode_modifier.vexw
+                 && i.tm.operand_types[dest].bitfield.regsimd);
 
       if (i.imm_operands == 0)
         {
@@ -6602,15 +6610,6 @@ build_modrm_byte (void)
               reg_slot = 0;
             }
 
-          /* FMA swaps REG and NDS.  */
-          if (i.tm.cpu_flags.bitfield.cpufma)
-            {
-              unsigned int tmp;
-              tmp = reg_slot;
-              reg_slot = nds;
-              nds = tmp;
-            }
-
           gas_assert (i.tm.operand_types[reg_slot].bitfield.regsimd);
           exp->X_op = O_constant;
           exp->X_add_number = register_number (i.op[reg_slot].regs) << 4;
@@ -6620,6 +6619,8 @@ build_modrm_byte (void)
         {
           unsigned int imm_slot;
 
+         gas_assert (i.imm_operands == 1 && i.types[0].bitfield.vec_imm4);
+
           if (i.tm.opcode_modifier.vexw == VEXW0)
             {
               /* If VexW0 is set, the third operand is the source and
@@ -8445,15 +8446,15 @@ check_VecOperations (char *op_string, char *op_end)
 
              op_string += 3;
              if (*op_string == '8')
-               bcst_type = BROADCAST_1TO8;
+               bcst_type = 8;
              else if (*op_string == '4')
-               bcst_type = BROADCAST_1TO4;
+               bcst_type = 4;
              else if (*op_string == '2')
-               bcst_type = BROADCAST_1TO2;
+               bcst_type = 2;
              else if (*op_string == '1'
                       && *(op_string+1) == '6')
                {
-                 bcst_type = BROADCAST_1TO16;
+                 bcst_type = 16;
                  op_string++;
                }
              else
This page took 0.030639 seconds and 4 git commands to generate.