x86: reject further invalid AVX-512 masking constructs
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index f4b86f6bf10b609584d42fdf7bd68f12cf9e68d7..4b5b2e5881b56f5259dc4c4895f96f4dacfcd9ae 100644 (file)
@@ -984,6 +984,10 @@ static const arch_entry cpu_arch[] =
     CPU_AVX512_VPOPCNTDQ_FLAGS, 0 },
   { STRING_COMMA_LEN (".avx512_vbmi2"), PROCESSOR_UNKNOWN,
     CPU_AVX512_VBMI2_FLAGS, 0 },
+  { STRING_COMMA_LEN (".avx512_vnni"), PROCESSOR_UNKNOWN,
+    CPU_AVX512_VNNI_FLAGS, 0 },
+  { STRING_COMMA_LEN (".avx512_bitalg"), PROCESSOR_UNKNOWN,
+    CPU_AVX512_BITALG_FLAGS, 0 },
   { STRING_COMMA_LEN (".clzero"), PROCESSOR_UNKNOWN,
     CPU_CLZERO_FLAGS, 0 },
   { STRING_COMMA_LEN (".mwaitx"), PROCESSOR_UNKNOWN,
@@ -1033,6 +1037,8 @@ static const noarch_entry cpu_noarch[] =
   { STRING_COMMA_LEN ("noavx512_4vnniw"), CPU_ANY_AVX512_4VNNIW_FLAGS },
   { STRING_COMMA_LEN ("noavx512_vpopcntdq"), CPU_ANY_AVX512_VPOPCNTDQ_FLAGS },
   { STRING_COMMA_LEN ("noavx512_vbmi2"), CPU_ANY_AVX512_VBMI2_FLAGS },
+  { STRING_COMMA_LEN ("noavx512_vnni"), CPU_ANY_AVX512_VNNI_FLAGS },
+  { STRING_COMMA_LEN ("noavx512_bitalg"), CPU_ANY_AVX512_BITALG_FLAGS },
 };
 
 #ifdef I386COFF
@@ -1100,7 +1106,9 @@ const pseudo_typeS md_pseudo_table[] =
   {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT},
   {"code16", set_code_flag, CODE_16BIT},
   {"code32", set_code_flag, CODE_32BIT},
+#ifdef BFD64
   {"code64", set_code_flag, CODE_64BIT},
+#endif
   {"intel_syntax", set_intel_syntax, 1},
   {"att_syntax", set_intel_syntax, 0},
   {"intel_mnemonic", set_intel_mnemonic, 1},
@@ -4650,7 +4658,8 @@ check_VecOperands (const insn_template *t)
        }
       else if (i.reg_operands == 1 && i.mask)
        {
-         if ((i.types[1].bitfield.regymm
+         if ((i.types[1].bitfield.regxmm
+              || i.types[1].bitfield.regymm
               || i.types[1].bitfield.regzmm)
              && (register_number (i.op[1].regs)
                  == register_number (i.index_reg)))
@@ -4789,12 +4798,8 @@ check_VecOperands (const insn_template *t)
                  i.types[op].bitfield.vec_disp8 = 1;
                else
                  {
-                   /* Vector insn can only have Vec_Disp8/Disp32 in
-                      32/64bit modes, and Vec_Disp8/Disp16 in 16bit
-                      mode.  */
+                   /* Vector insn doesn't allow plain Disp8.  */
                    i.types[op].bitfield.disp8 = 0;
-                   if (flag_code != CODE_16BIT)
-                     i.types[op].bitfield.disp16 = 0;
                  }
              }
            else if (flag_code != CODE_16BIT)
@@ -5422,7 +5427,8 @@ process_suffix (void)
                }
 
              for (op = i.operands; --op >= 0;)
-               if (!i.tm.operand_types[op].bitfield.inoutportreg)
+               if (!i.tm.operand_types[op].bitfield.inoutportreg
+                   && !i.tm.operand_types[op].bitfield.shiftcount)
                  {
                    if (i.types[op].bitfield.reg8)
                      {
@@ -5555,7 +5561,7 @@ process_suffix (void)
            suffixes |= 1 << 3;
          if (!i.tm.opcode_modifier.no_ssuf)
            suffixes |= 1 << 4;
-         if (!i.tm.opcode_modifier.no_qsuf)
+         if (flag_code == CODE_64BIT && !i.tm.opcode_modifier.no_qsuf)
            suffixes |= 1 << 5;
 
          /* There are more than suffix matches.  */
@@ -6556,7 +6562,7 @@ build_modrm_byte (void)
                  i.types[op].bitfield.disp8 = 0;
                  i.types[op].bitfield.disp16 = 0;
                  i.types[op].bitfield.disp64 = 0;
-                 if (flag_code != CODE_64BIT)
+                 if (flag_code != CODE_64BIT || i.prefix[ADDR_PREFIX])
                    {
                      /* Must be 32 bit */
                      i.types[op].bitfield.disp32 = 1;
@@ -6581,13 +6587,7 @@ build_modrm_byte (void)
            {
              i.rm.mode = 0;
              if (!i.disp_operands)
-               {
-                 fake_zero_displacement = 1;
-                 /* Instructions with VSIB byte need 32bit displacement
-                    if there is no base register.  */
-                 if (i.tm.opcode_modifier.vecsib)
-                   i.types[op].bitfield.disp32 = 1;
-               }
+               fake_zero_displacement = 1;
              if (i.index_reg == 0)
                {
                  gas_assert (!i.tm.opcode_modifier.vecsib);
@@ -6632,7 +6632,7 @@ build_modrm_byte (void)
                  i.types[op].bitfield.disp8 = 0;
                  i.types[op].bitfield.disp16 = 0;
                  i.types[op].bitfield.disp64 = 0;
-                 if (flag_code != CODE_64BIT)
+                 if (flag_code != CODE_64BIT || i.prefix[ADDR_PREFIX])
                    {
                      /* Must be 32 bit */
                      i.types[op].bitfield.disp32 = 1;
@@ -8138,10 +8138,10 @@ check_VecOperations (char *op_string, char *op_end)
          else if ((mask = parse_register (op_string, &end_op)) != NULL)
            {
              /* k0 can't be used for write mask.  */
-             if (mask->reg_num == 0)
+             if (!mask->reg_type.bitfield.regmask || mask->reg_num == 0)
                {
-                 as_bad (_("`%s' can't be used for write mask"),
-                         op_string);
+                 as_bad (_("`%s%s' can't be used for write mask"),
+                         register_prefix, mask->reg_name);
                  return NULL;
                }
 
@@ -8220,6 +8220,12 @@ check_VecOperations (char *op_string, char *op_end)
       return NULL;
     }
 
+  if (i.mask && i.mask->zeroing && !i.mask->mask)
+    {
+      as_bad (_("zeroing-masking only allowed with write mask"));
+      return NULL;
+    }
+
   return op_string;
 }
 
@@ -8624,13 +8630,13 @@ i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
   return ret;
 }
 
-/* Make sure the memory operand we've been dealt is valid.
-   Return 1 on success, 0 on a failure.  */
+/* Return the active addressing mode, taking address override and
+   registers forming the address into consideration.  Update the
+   address override prefix if necessary.  */
 
-static int
-i386_index_check (const char *operand_string)
+static enum flag_code
+i386_addressing_mode (void)
 {
-  const char *kind = "base/index";
   enum flag_code addr_mode;
 
   if (i.prefix[ADDR_PREFIX])
@@ -8679,6 +8685,18 @@ i386_index_check (const char *operand_string)
 #endif
     }
 
+  return addr_mode;
+}
+
+/* Make sure the memory operand we've been dealt is valid.
+   Return 1 on success, 0 on a failure.  */
+
+static int
+i386_index_check (const char *operand_string)
+{
+  const char *kind = "base/index";
+  enum flag_code addr_mode = i386_addressing_mode ();
+
   if (current_templates->start->opcode_modifier.isstring
       && !current_templates->start->opcode_modifier.immext
       && (current_templates->end[-1].opcode_modifier.isstring
This page took 0.046824 seconds and 4 git commands to generate.