Add startswith function and use it instead of CONST_STRNEQ.
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index 60b2fea3265b5d5eb8e0ae7febf9010efcd2d9d3..84a3f292656fc93e4cc87f08aba035275f4e62c6 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-i386.c -- Assemble code for the Intel 80386
-   Copyright (C) 1989-2020 Free Software Foundation, Inc.
+   Copyright (C) 1989-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -374,7 +374,9 @@ struct _i386_insn
        /* Use ZMM state.  */
        xstate_zmm = 1 << 3 | xstate_ymm,
        /* Use TMM state.  */
-       xstate_tmm = 1 << 4
+       xstate_tmm = 1 << 4,
+       /* Use MASK state.  */
+       xstate_mask = 1 << 5
       } xstate;
 
     /* Has GOTPC or TLS relocation.  */
@@ -1012,6 +1014,8 @@ static const arch_entry cpu_arch[] =
     CPU_ZNVER1_FLAGS, 0 },
   { STRING_COMMA_LEN ("znver2"), PROCESSOR_ZNVER,
     CPU_ZNVER2_FLAGS, 0 },
+  { STRING_COMMA_LEN ("znver3"), PROCESSOR_ZNVER,
+    CPU_ZNVER3_FLAGS, 0 },
   { STRING_COMMA_LEN ("btver1"), PROCESSOR_BT,
     CPU_BTVER1_FLAGS, 0 },
   { STRING_COMMA_LEN ("btver2"), PROCESSOR_BT,
@@ -1178,6 +1182,8 @@ static const arch_entry cpu_arch[] =
     CPU_AVX512_VNNI_FLAGS, 0 },
   { STRING_COMMA_LEN (".avx512_bitalg"), PROCESSOR_UNKNOWN,
     CPU_AVX512_BITALG_FLAGS, 0 },
+  { STRING_COMMA_LEN (".avx_vnni"), PROCESSOR_UNKNOWN,
+    CPU_AVX_VNNI_FLAGS, 0 },
   { STRING_COMMA_LEN (".clzero"), PROCESSOR_UNKNOWN,
     CPU_CLZERO_FLAGS, 0 },
   { STRING_COMMA_LEN (".mwaitx"), PROCESSOR_UNKNOWN,
@@ -1220,6 +1226,8 @@ static const arch_entry cpu_arch[] =
     CPU_AVX512_BF16_FLAGS, 0 },
   { STRING_COMMA_LEN (".avx512_vp2intersect"), PROCESSOR_UNKNOWN,
     CPU_AVX512_VP2INTERSECT_FLAGS, 0 },
+  { STRING_COMMA_LEN (".tdx"), PROCESSOR_UNKNOWN,
+    CPU_TDX_FLAGS, 0 },
   { STRING_COMMA_LEN (".enqcmd"), PROCESSOR_UNKNOWN,
     CPU_ENQCMD_FLAGS, 0 },
   { STRING_COMMA_LEN (".serialize"), PROCESSOR_UNKNOWN,
@@ -1236,6 +1244,10 @@ static const arch_entry cpu_arch[] =
     CPU_KL_FLAGS, 0 },
   { STRING_COMMA_LEN (".widekl"), PROCESSOR_UNKNOWN,
     CPU_WIDEKL_FLAGS, 0 },
+  { STRING_COMMA_LEN (".uintr"), PROCESSOR_UNKNOWN,
+    CPU_UINTR_FLAGS, 0 },
+  { STRING_COMMA_LEN (".hreset"), PROCESSOR_UNKNOWN,
+    CPU_HRESET_FLAGS, 0 },
 };
 
 static const noarch_entry cpu_noarch[] =
@@ -1272,6 +1284,7 @@ static const noarch_entry cpu_noarch[] =
   { 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 },
+  { STRING_COMMA_LEN ("noavx_vnni"), CPU_ANY_AVX_VNNI_FLAGS },
   { STRING_COMMA_LEN ("noibt"), CPU_ANY_IBT_FLAGS },
   { STRING_COMMA_LEN ("noshstk"), CPU_ANY_SHSTK_FLAGS },
   { STRING_COMMA_LEN ("noamx_int8"), CPU_ANY_AMX_INT8_FLAGS },
@@ -1282,11 +1295,14 @@ static const noarch_entry cpu_noarch[] =
   { STRING_COMMA_LEN ("noavx512_bf16"), CPU_ANY_AVX512_BF16_FLAGS },
   { STRING_COMMA_LEN ("noavx512_vp2intersect"),
     CPU_ANY_AVX512_VP2INTERSECT_FLAGS },
+  { STRING_COMMA_LEN ("notdx"), CPU_ANY_TDX_FLAGS },
   { STRING_COMMA_LEN ("noenqcmd"), CPU_ANY_ENQCMD_FLAGS },
   { STRING_COMMA_LEN ("noserialize"), CPU_ANY_SERIALIZE_FLAGS },
   { STRING_COMMA_LEN ("notsxldtrk"), CPU_ANY_TSXLDTRK_FLAGS },
   { STRING_COMMA_LEN ("nokl"), CPU_ANY_KL_FLAGS },
   { STRING_COMMA_LEN ("nowidekl"), CPU_ANY_WIDEKL_FLAGS },
+  { STRING_COMMA_LEN ("nouintr"), CPU_ANY_UINTR_FLAGS },
+  { STRING_COMMA_LEN ("nohreset"), CPU_ANY_HRESET_FLAGS },
 };
 
 #ifdef I386COFF
@@ -3583,7 +3599,7 @@ build_vex_prefix (const insn_template *t)
       && i.dir_encoding == dir_encoding_default
       && i.operands == i.reg_operands
       && operand_type_equal (&i.types[0], &i.types[i.operands - 1])
-      && i.tm.opcode_modifier.vexopcode == VEX0F
+      && i.tm.opcode_modifier.opcodeprefix == VEX0F
       && (i.tm.opcode_modifier.load || i.tm.opcode_modifier.d)
       && i.rex == REX_B)
     {
@@ -3628,7 +3644,7 @@ build_vex_prefix (const insn_template *t)
       union i386_op temp_op;
       i386_operand_type temp_type;
 
-      gas_assert (i.tm.opcode_modifier.vexopcode == VEX0F);
+      gas_assert (i.tm.opcode_modifier.opcodeprefix == VEX0F);
       gas_assert (!i.tm.opcode_modifier.sae);
       gas_assert (operand_type_equal (&i.types[i.operands - 2],
                                       &i.types[i.operands - 3]));
@@ -3699,7 +3715,7 @@ build_vex_prefix (const insn_template *t)
   /* Use 2-byte VEX prefix if possible.  */
   if (w == 0
       && i.vec_encoding != vex_encoding_vex3
-      && i.tm.opcode_modifier.vexopcode == VEX0F
+      && i.tm.opcode_modifier.opcodeprefix == VEX0F
       && (i.rex & (REX_W | REX_X | REX_B)) == 0)
     {
       /* 2-byte VEX prefix.  */
@@ -3722,7 +3738,7 @@ build_vex_prefix (const insn_template *t)
 
       i.vex.length = 3;
 
-      switch (i.tm.opcode_modifier.vexopcode)
+      switch (i.tm.opcode_modifier.opcodeprefix)
        {
        case VEX0F:
          m = 0x1;
@@ -3774,8 +3790,7 @@ is_evex_encoding (const insn_template *t)
 static INLINE bfd_boolean
 is_any_vex_encoding (const insn_template *t)
 {
-  return t->opcode_modifier.vex || t->opcode_modifier.vexopcode
-        || is_evex_encoding (t);
+  return t->opcode_modifier.vex || is_evex_encoding (t);
 }
 
 /* Build the EVEX prefix.  */
@@ -3837,7 +3852,7 @@ build_evex_prefix (void)
   i.vex.bytes[0] = 0x62;
 
   /* mmmm bits.  */
-  switch (i.tm.opcode_modifier.vexopcode)
+  switch (i.tm.opcode_modifier.opcodeprefix)
     {
     case VEX0F:
       m = 1;
@@ -4023,22 +4038,25 @@ process_immext (void)
 static int
 check_hle (void)
 {
-  switch (i.tm.opcode_modifier.hleprefixok)
+  switch (i.tm.opcode_modifier.prefixok)
     {
     default:
       abort ();
-    case HLEPrefixNone:
+    case PrefixLock:
+    case PrefixNone:
+    case PrefixNoTrack:
+    case PrefixRep:
       as_bad (_("invalid instruction `%s' after `%s'"),
              i.tm.name, i.hle_prefix);
       return 0;
-    case HLEPrefixLock:
+    case PrefixHLELock:
       if (i.prefix[LOCK_PREFIX])
        return 1;
       as_bad (_("missing `lock' with `%s'"), i.hle_prefix);
       return 0;
-    case HLEPrefixAny:
+    case PrefixHLEAny:
       return 1;
-    case HLEPrefixRelease:
+    case PrefixHLERelease:
       if (i.prefix[HLE_PREFIX] != XRELEASE_PREFIX_OPCODE)
        {
          as_bad (_("instruction `%s' after `xacquire' not allowed"),
@@ -4398,7 +4416,7 @@ load_insn_p (void)
       /* vldmxcsr.  */
       if (i.tm.base_opcode == 0xae
          && i.tm.opcode_modifier.vex
-         && i.tm.opcode_modifier.vexopcode == VEX0F
+         && i.tm.opcode_modifier.opcodeprefix == VEX0F
          && i.tm.extension_opcode == 2)
        return 1;
     }
@@ -4430,6 +4448,7 @@ load_insn_p (void)
 
       /* cmpxchg8b, cmpxchg16b, xrstors.  */
       if (i.tm.base_opcode == 0xfc7
+         && i.tm.opcode_modifier.opcodeprefix == 0
          && (i.tm.extension_opcode == 1 || i.tm.extension_opcode == 3))
        return 1;
 
@@ -4449,6 +4468,7 @@ load_insn_p (void)
 
       /* vmptrld */
       if (i.tm.base_opcode == 0xfc7
+         && i.tm.opcode_modifier.opcodeprefix == 0
          && i.tm.extension_opcode == 6)
        return 1;
 
@@ -4775,7 +4795,7 @@ md_assemble (char *line)
       return;
 
   /* Check if REP prefix is OK.  */
-  if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok)
+  if (i.rep_prefix && i.tm.opcode_modifier.prefixok != PrefixRep)
     {
       as_bad (_("invalid instruction `%s' after `%s'"),
                i.tm.name, i.rep_prefix);
@@ -4785,7 +4805,7 @@ md_assemble (char *line)
   /* Check for lock without a lockable instruction.  Destination operand
      must be memory unless it is xchg (0x86).  */
   if (i.prefix[LOCK_PREFIX]
-      && (!i.tm.opcode_modifier.islockable
+      && (i.tm.opcode_modifier.prefixok < PrefixLock
          || i.mem_operands == 0
          || (i.tm.base_opcode != 0x86
              && !(i.flags[i.operands - 1] & Operand_Mem))))
@@ -4813,7 +4833,7 @@ md_assemble (char *line)
     as_bad (_("expecting valid branch instruction after `bnd'"));
 
   /* Check NOTRACK prefix.  */
-  if (i.notrack_prefix && !i.tm.opcode_modifier.notrackprefixok)
+  if (i.notrack_prefix && i.tm.opcode_modifier.prefixok != PrefixNoTrack)
     as_bad (_("expecting indirect branch instruction after `notrack'"));
 
   if (i.tm.cpu_flags.bitfield.cpumpx)
@@ -4865,7 +4885,7 @@ md_assemble (char *line)
          i.xstate |= xstate_mmx;
          break;
        case RegMask:
-         i.xstate |= xstate_zmm;
+         i.xstate |= xstate_mask;
          break;
        case RegSIMD:
          if (i.tm.operand_types[j].bitfield.tmmword)
@@ -6243,6 +6263,13 @@ match_template (char mnem_suffix)
       if (cpu_flags_match (t) != CPU_FLAGS_PERFECT_MATCH)
        continue;
 
+      /* Check Pseudo Prefix.  */
+      i.error = unsupported;
+      if (t->opcode_modifier.pseudovexprefix
+         && !(i.vec_encoding == vex_encoding_vex
+             || i.vec_encoding == vex_encoding_vex3))
+       continue;
+
       /* Check AT&T mnemonic.   */
       i.error = unsupported_with_intel_mnemonic;
       if (intel_mnemonic && t->opcode_modifier.attmnemonic)
@@ -6309,8 +6336,9 @@ match_template (char mnem_suffix)
       j = i.imm_operands + (t->operands > i.imm_operands + 1);
       if (((i.suffix == QWORD_MNEM_SUFFIX
            && flag_code != CODE_64BIT
-           && (t->base_opcode != 0x0fc7
-               || t->extension_opcode != 1 /* cmpxchg8b */))
+           && !(t->base_opcode == 0xfc7
+                && i.tm.opcode_modifier.opcodeprefix == 0
+                && t->extension_opcode == 1) /* cmpxchg8b */)
           || (i.suffix == LONG_MNEM_SUFFIX
               && !cpu_arch_flags.bitfield.cpui386))
          && (intel_syntax
@@ -6755,6 +6783,8 @@ check_string (void)
 static int
 process_suffix (void)
 {
+  bfd_boolean is_crc32 = FALSE;
+
   /* If matched instruction specifies an explicit instruction mnemonic
      suffix, use it.  */
   if (i.tm.opcode_modifier.size == SIZE16)
@@ -6768,6 +6798,9 @@ process_suffix (void)
           && !i.tm.opcode_modifier.addrprefixopreg)
     {
       unsigned int numop = i.operands;
+      /* CRC32 */
+      is_crc32 = (i.tm.base_opcode == 0xf38f0
+                 && i.tm.opcode_modifier.opcodeprefix == PREFIX_0XF2);
 
       /* movsx/movzx want only their source operand considered here, for the
         ambiguity checking below.  The suffix will be replaced afterwards
@@ -6777,8 +6810,7 @@ process_suffix (void)
        --i.operands;
 
       /* crc32 needs REX.W set regardless of suffix / source operand size.  */
-      if (i.tm.base_opcode == 0xf20f38f0
-          && i.tm.operand_types[1].bitfield.qword)
+      if (is_crc32 && i.tm.operand_types[1].bitfield.qword)
         i.rex |= REX_W;
 
       /* If there's no instruction mnemonic suffix we try to invent one
@@ -6789,7 +6821,7 @@ process_suffix (void)
             Destination register type is more significant than source
             register type.  crc32 in SSE4.2 prefers source register
             type. */
-         unsigned int op = i.tm.base_opcode != 0xf20f38f0 ? i.operands : 1;
+         unsigned int op = is_crc32 ? 1 : i.operands;
 
          while (op--)
            if (i.tm.operand_types[op].bitfield.instance == InstanceNone
@@ -7127,7 +7159,7 @@ process_suffix (void)
       break;
 
     case 0:
-      /* Select word/dword/qword operation with explict data sizing prefix
+      /* Select word/dword/qword operation with explicit data sizing prefix
         when there are no suitable register operands.  */
       if (i.tm.opcode_modifier.w
          && (i.prefix[DATA_PREFIX] || (i.prefix[REX_PREFIX] & REX_W))
@@ -7139,7 +7171,7 @@ process_suffix (void)
                      || i.tm.operand_types[0].bitfield.instance == RegD
                      || i.tm.operand_types[1].bitfield.instance == RegD
                      /* CRC32 */
-                     || i.tm.base_opcode == 0xf20f38f0))))
+                     || is_crc32))))
        i.tm.base_opcode |= 1;
       break;
     }
@@ -7175,6 +7207,23 @@ process_suffix (void)
          unsigned int op;
          enum { need_word, need_dword, need_qword } need;
 
+         /* Check the register operand for the address size prefix if
+            the memory operand has no real registers, like symbol, DISP
+            or symbol(%rip).  */
+         if (i.mem_operands == 1
+             && i.reg_operands == 1
+             && i.operands == 2
+             && i.types[1].bitfield.class == Reg
+             && (flag_code == CODE_32BIT
+                 ? i.op[1].regs->reg_type.bitfield.word
+                 : i.op[1].regs->reg_type.bitfield.dword)
+             && ((i.base_reg == NULL && i.index_reg == NULL)
+                 || (i.base_reg
+                     && i.base_reg->reg_num == RegIP
+                     && i.base_reg->reg_type.bitfield.qword))
+             && !add_prefix (ADDR_PREFIX_OPCODE))
+           return 0;
+
          if (flag_code == CODE_32BIT)
            need = i.prefix[ADDR_PREFIX] ? need_word : need_dword;
          else if (i.prefix[ADDR_PREFIX])
@@ -7236,7 +7285,9 @@ check_byte_reg (void)
        continue;
 
       /* crc32 only wants its source operand checked here.  */
-      if (i.tm.base_opcode == 0xf20f38f0 && op)
+      if (i.tm.base_opcode == 0xf38f0
+         && i.tm.opcode_modifier.opcodeprefix == PREFIX_0XF2
+         && op != 0)
        continue;
 
       /* Any other register is bad.  */
@@ -8580,6 +8631,9 @@ need_plt32_p (symbolS *s)
   if (!object_64bit)
     return FALSE;
 
+  if (s == NULL)
+    return FALSE;
+
   /* Weak or undefined symbol need PLT32 relocation.  */
   if (S_IS_WEAK (s) || !S_IS_DEFINED (s))
     return TRUE;
@@ -8756,10 +8810,13 @@ output_interseg_jump (void)
   else
     fix_new_exp (frag_now, p - frag_now->fr_literal, size,
                 i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
-  if (i.op[0].imms->X_op != O_constant)
-    as_bad (_("can't handle non absolute segment in `%s'"),
-           i.tm.name);
-  md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
+
+  p += size;
+  if (i.op[0].imms->X_op == O_constant)
+    md_number_to_chars (p, (valueT) i.op[0].imms->X_add_number, 2);
+  else
+    fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
+                i.op[0].imms, 0, reloc (2, 0, 0, i.reloc[0]));
 }
 
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
@@ -9144,56 +9201,9 @@ output_insn (void)
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   if (IS_ELF && x86_used_note && now_seg != absolute_section)
     {
-      if (i.tm.cpu_flags.bitfield.cpucmov)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_CMOV;
-      if (i.tm.cpu_flags.bitfield.cpusse)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_SSE;
-      if (i.tm.cpu_flags.bitfield.cpusse2)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_SSE2;
-      if (i.tm.cpu_flags.bitfield.cpusse3)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_SSE3;
-      if (i.tm.cpu_flags.bitfield.cpussse3)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_SSSE3;
-      if (i.tm.cpu_flags.bitfield.cpusse4_1)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_SSE4_1;
-      if (i.tm.cpu_flags.bitfield.cpusse4_2)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_SSE4_2;
-      if (i.tm.cpu_flags.bitfield.cpuavx)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX;
-      if (i.tm.cpu_flags.bitfield.cpuavx2)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX2;
-      if (i.tm.cpu_flags.bitfield.cpufma)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_FMA;
-      if (i.tm.cpu_flags.bitfield.cpuavx512f)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512F;
-      if (i.tm.cpu_flags.bitfield.cpuavx512cd)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512CD;
-      if (i.tm.cpu_flags.bitfield.cpuavx512er)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512ER;
-      if (i.tm.cpu_flags.bitfield.cpuavx512pf)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512PF;
-      if (i.tm.cpu_flags.bitfield.cpuavx512vl)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512VL;
-      if (i.tm.cpu_flags.bitfield.cpuavx512dq)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512DQ;
-      if (i.tm.cpu_flags.bitfield.cpuavx512bw)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512BW;
-      if (i.tm.cpu_flags.bitfield.cpuavx512_4fmaps)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS;
-      if (i.tm.cpu_flags.bitfield.cpuavx512_4vnniw)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW;
-      if (i.tm.cpu_flags.bitfield.cpuavx512_bitalg)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_BITALG;
-      if (i.tm.cpu_flags.bitfield.cpuavx512ifma)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_IFMA;
-      if (i.tm.cpu_flags.bitfield.cpuavx512vbmi)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_VBMI;
-      if (i.tm.cpu_flags.bitfield.cpuavx512_vbmi2)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2;
-      if (i.tm.cpu_flags.bitfield.cpuavx512_vnni)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_VNNI;
-      if (i.tm.cpu_flags.bitfield.cpuavx512_bf16)
-       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_AVX512_BF16;
+      if ((i.xstate & xstate_tmm) == xstate_tmm
+         || i.tm.cpu_flags.bitfield.cpuamx_tile)
+       x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_TMM;
 
       if (i.tm.cpu_flags.bitfield.cpu8087
          || i.tm.cpu_flags.bitfield.cpu287
@@ -9201,18 +9211,41 @@ output_insn (void)
          || i.tm.cpu_flags.bitfield.cpu687
          || i.tm.cpu_flags.bitfield.cpufisttp)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_X87;
+
       if ((i.xstate & xstate_mmx)
          || i.tm.base_opcode == 0xf77 /* emms */
          || i.tm.base_opcode == 0xf0e /* femms */)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MMX;
+
+      if (i.index_reg)
+       {
+         if (i.index_reg->reg_type.bitfield.zmmword)
+           i.xstate |= xstate_zmm;
+         else if (i.index_reg->reg_type.bitfield.ymmword)
+           i.xstate |= xstate_ymm;
+         else if (i.index_reg->reg_type.bitfield.xmmword)
+           i.xstate |= xstate_xmm;
+       }
+
+      /* vzeroall / vzeroupper */
+      if (i.tm.base_opcode == 0x77 && i.tm.cpu_flags.bitfield.cpuavx)
+       i.xstate |= xstate_ymm;
+
       if ((i.xstate & xstate_xmm)
+         /* ldmxcsr / stmxcsr */
+         || (i.tm.base_opcode == 0xfae && i.tm.cpu_flags.bitfield.cpusse)
+         /* vldmxcsr / vstmxcsr */
+         || (i.tm.base_opcode == 0xae && i.tm.cpu_flags.bitfield.cpuavx)
          || i.tm.cpu_flags.bitfield.cpuwidekl
          || i.tm.cpu_flags.bitfield.cpukl)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XMM;
+
       if ((i.xstate & xstate_ymm) == xstate_ymm)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_YMM;
       if ((i.xstate & xstate_zmm) == xstate_zmm)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_ZMM;
+      if (i.mask || (i.xstate & xstate_mask) == xstate_mask)
+       x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MASK;
       if (i.tm.cpu_flags.bitfield.cpufxsr)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_FXSR;
       if (i.tm.cpu_flags.bitfield.cpuxsave)
@@ -9222,9 +9255,55 @@ output_insn (void)
       if (i.tm.cpu_flags.bitfield.cpuxsavec)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XSAVEC;
 
-      if ((i.xstate & xstate_tmm) == xstate_tmm
-         || i.tm.cpu_flags.bitfield.cpuamx_tile)
-       x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_TMM;
+      if (x86_feature_2_used
+         || i.tm.cpu_flags.bitfield.cpucmov
+         || i.tm.cpu_flags.bitfield.cpusyscall
+         || (i.tm.base_opcode == 0xfc7
+             && i.tm.opcode_modifier.opcodeprefix == 0
+             && i.tm.extension_opcode == 1) /* cmpxchg8b */)
+       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_BASELINE;
+      if (i.tm.cpu_flags.bitfield.cpusse3
+         || i.tm.cpu_flags.bitfield.cpussse3
+         || i.tm.cpu_flags.bitfield.cpusse4_1
+         || i.tm.cpu_flags.bitfield.cpusse4_2
+         || i.tm.cpu_flags.bitfield.cpucx16
+         || i.tm.cpu_flags.bitfield.cpupopcnt
+         /* LAHF-SAHF insns in 64-bit mode.  */
+         || (flag_code == CODE_64BIT
+             && (i.tm.base_opcode | 1) == 0x9f))
+       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V2;
+      if (i.tm.cpu_flags.bitfield.cpuavx
+         || i.tm.cpu_flags.bitfield.cpuavx2
+         /* Any VEX encoded insns execpt for CpuAVX512F, CpuAVX512BW,
+            CpuAVX512DQ, LPW, TBM and AMX.  */
+         || (i.tm.opcode_modifier.vex
+             && !i.tm.cpu_flags.bitfield.cpuavx512f
+             && !i.tm.cpu_flags.bitfield.cpuavx512bw
+             && !i.tm.cpu_flags.bitfield.cpuavx512dq
+             && !i.tm.cpu_flags.bitfield.cpulwp
+             && !i.tm.cpu_flags.bitfield.cputbm
+             && !(x86_feature_2_used & GNU_PROPERTY_X86_FEATURE_2_TMM))
+         || i.tm.cpu_flags.bitfield.cpuf16c
+         || i.tm.cpu_flags.bitfield.cpufma
+         || i.tm.cpu_flags.bitfield.cpulzcnt
+         || i.tm.cpu_flags.bitfield.cpumovbe
+         || i.tm.cpu_flags.bitfield.cpuxsaves
+         || (x86_feature_2_used
+             & (GNU_PROPERTY_X86_FEATURE_2_XSAVE
+                | GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT
+                | GNU_PROPERTY_X86_FEATURE_2_XSAVEC)) != 0)
+       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V3;
+      if (i.tm.cpu_flags.bitfield.cpuavx512f
+         || i.tm.cpu_flags.bitfield.cpuavx512bw
+         || i.tm.cpu_flags.bitfield.cpuavx512dq
+         || i.tm.cpu_flags.bitfield.cpuavx512vl
+         /* Any EVEX encoded insns except for AVX512ER, AVX512PF and
+            VNNIW.  */
+         || (i.tm.opcode_modifier.evex
+             && !i.tm.cpu_flags.bitfield.cpuavx512er
+             && !i.tm.cpu_flags.bitfield.cpuavx512pf
+             && !i.tm.cpu_flags.bitfield.cpuavx512_4vnniw))
+       x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V4;
     }
 #endif
 
@@ -9276,7 +9355,6 @@ output_insn (void)
       char *p;
       unsigned char *q;
       unsigned int j;
-      unsigned int prefix;
       enum mf_cmp_kind mf_cmp;
 
       if (avoid_fence
@@ -9347,33 +9425,36 @@ output_insn (void)
         don't need the explicit prefix.  */
       if (!i.tm.opcode_modifier.vex && !i.tm.opcode_modifier.evex)
        {
-         switch (i.tm.opcode_length)
+         switch (i.tm.opcode_modifier.opcodeprefix)
            {
-           case 3:
-             if (i.tm.base_opcode & 0xff000000)
-               {
-                 prefix = (i.tm.base_opcode >> 24) & 0xff;
-                 if (!i.tm.cpu_flags.bitfield.cpupadlock
-                     || prefix != REPE_PREFIX_OPCODE
-                     || (i.prefix[REP_PREFIX] != REPE_PREFIX_OPCODE))
-                   add_prefix (prefix);
-               }
+           case PREFIX_0X66:
+             add_prefix (0x66);
              break;
-           case 2:
-             if ((i.tm.base_opcode & 0xff0000) != 0)
+           case PREFIX_0XF2:
+             add_prefix (0xf2);
+             break;
+           case PREFIX_0XF3:
+             if (!i.tm.cpu_flags.bitfield.cpupadlock
+                 || (i.prefix[REP_PREFIX] != 0xf3))
+               add_prefix (0xf3);
+             break;
+           case PREFIX_NONE:
+             switch (i.tm.opcode_length)
                {
-                 prefix = (i.tm.base_opcode >> 16) & 0xff;
-                 add_prefix (prefix);
+               case 3:
+               case 2:
+               case 1:
+                 break;
+               case 0:
+                 /* Check for pseudo prefixes.  */
+                 as_bad_where (insn_start_frag->fr_file,
+                               insn_start_frag->fr_line,
+                               _("pseudo prefix without instruction"));
+                 return;
+               default:
+                 abort ();
                }
              break;
-           case 1:
-             break;
-           case 0:
-             /* Check for pseudo prefixes.  */
-             as_bad_where (insn_start_frag->fr_file,
-                           insn_start_frag->fr_line,
-                            _("pseudo prefix without instruction"));
-             return;
            default:
              abort ();
            }
@@ -9955,63 +10036,64 @@ lex_got (enum bfd_reloc_code_real *rel,
     int len;
     const enum bfd_reloc_code_real rel[2];
     const i386_operand_type types64;
+    bfd_boolean need_GOT_symbol;
   } gotrel[] = {
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
     { STRING_COMMA_LEN ("SIZE"),      { BFD_RELOC_SIZE32,
                                        BFD_RELOC_SIZE32 },
-      OPERAND_TYPE_IMM32_64 },
+      OPERAND_TYPE_IMM32_64, FALSE },
 #endif
     { STRING_COMMA_LEN ("PLTOFF"),   { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_PLTOFF64 },
-      OPERAND_TYPE_IMM64 },
+      OPERAND_TYPE_IMM64, TRUE },
     { STRING_COMMA_LEN ("PLT"),      { BFD_RELOC_386_PLT32,
                                       BFD_RELOC_X86_64_PLT32    },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, FALSE },
     { STRING_COMMA_LEN ("GOTPLT"),   { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_GOTPLT64 },
-      OPERAND_TYPE_IMM64_DISP64 },
+      OPERAND_TYPE_IMM64_DISP64, TRUE },
     { STRING_COMMA_LEN ("GOTOFF"),   { BFD_RELOC_386_GOTOFF,
                                       BFD_RELOC_X86_64_GOTOFF64 },
-      OPERAND_TYPE_IMM64_DISP64 },
+      OPERAND_TYPE_IMM64_DISP64, TRUE },
     { STRING_COMMA_LEN ("GOTPCREL"), { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_GOTPCREL },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
     { STRING_COMMA_LEN ("TLSGD"),    { BFD_RELOC_386_TLS_GD,
                                       BFD_RELOC_X86_64_TLSGD    },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
     { STRING_COMMA_LEN ("TLSLDM"),   { BFD_RELOC_386_TLS_LDM,
                                       _dummy_first_bfd_reloc_code_real },
-      OPERAND_TYPE_NONE },
+      OPERAND_TYPE_NONE, TRUE },
     { STRING_COMMA_LEN ("TLSLD"),    { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_TLSLD    },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
     { STRING_COMMA_LEN ("GOTTPOFF"), { BFD_RELOC_386_TLS_IE_32,
                                       BFD_RELOC_X86_64_GOTTPOFF },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
     { STRING_COMMA_LEN ("TPOFF"),    { BFD_RELOC_386_TLS_LE_32,
                                       BFD_RELOC_X86_64_TPOFF32  },
-      OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
+      OPERAND_TYPE_IMM32_32S_64_DISP32_64, TRUE },
     { STRING_COMMA_LEN ("NTPOFF"),   { BFD_RELOC_386_TLS_LE,
                                       _dummy_first_bfd_reloc_code_real },
-      OPERAND_TYPE_NONE },
+      OPERAND_TYPE_NONE, TRUE },
     { STRING_COMMA_LEN ("DTPOFF"),   { BFD_RELOC_386_TLS_LDO_32,
                                       BFD_RELOC_X86_64_DTPOFF32 },
-      OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
+      OPERAND_TYPE_IMM32_32S_64_DISP32_64, TRUE },
     { STRING_COMMA_LEN ("GOTNTPOFF"),{ BFD_RELOC_386_TLS_GOTIE,
                                       _dummy_first_bfd_reloc_code_real },
-      OPERAND_TYPE_NONE },
+      OPERAND_TYPE_NONE, TRUE },
     { STRING_COMMA_LEN ("INDNTPOFF"),{ BFD_RELOC_386_TLS_IE,
                                       _dummy_first_bfd_reloc_code_real },
-      OPERAND_TYPE_NONE },
+      OPERAND_TYPE_NONE, TRUE },
     { STRING_COMMA_LEN ("GOT"),      { BFD_RELOC_386_GOT32,
                                       BFD_RELOC_X86_64_GOT32    },
-      OPERAND_TYPE_IMM32_32S_64_DISP32 },
+      OPERAND_TYPE_IMM32_32S_64_DISP32, TRUE },
     { STRING_COMMA_LEN ("TLSDESC"),  { BFD_RELOC_386_TLS_GOTDESC,
                                       BFD_RELOC_X86_64_GOTPC32_TLSDESC },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
     { STRING_COMMA_LEN ("TLSCALL"),  { BFD_RELOC_386_TLS_DESC_CALL,
                                       BFD_RELOC_X86_64_TLSDESC_CALL },
-      OPERAND_TYPE_IMM32_32S_DISP32 },
+      OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
   };
   char *cp;
   unsigned int j;
@@ -10048,7 +10130,7 @@ lex_got (enum bfd_reloc_code_real *rel,
                    *types = gotrel[j].types64;
                }
 
-             if (j != 0 && GOT_symbol == NULL)
+             if (gotrel[j].need_GOT_symbol && GOT_symbol == NULL)
                GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
 
              /* The length of the first part of our input line.  */
@@ -10968,7 +11050,7 @@ i386_index_check (const char *operand_string)
 
       kind = "string address";
 
-      if (current_templates->start->opcode_modifier.repprefixok)
+      if (current_templates->start->opcode_modifier.prefixok == PrefixRep)
        {
          int es_op = current_templates->end[-1].opcode_modifier.isstring
                      - IS_STRING_ES_OP0;
@@ -12934,7 +13016,7 @@ md_parse_option (int c, const char *arg)
 
        list = bfd_target_list ();
        for (l = list; *l != NULL; l++)
-         if (CONST_STRNEQ (*l, "elf64-x86-64")
+         if (startswith (*l, "elf64-x86-64")
              || strcmp (*l, "coff-x86-64") == 0
              || strcmp (*l, "pe-x86-64") == 0
              || strcmp (*l, "pei-x86-64") == 0
@@ -12958,7 +13040,7 @@ md_parse_option (int c, const char *arg)
 
          list = bfd_target_list ();
          for (l = list; *l != NULL; l++)
-           if (CONST_STRNEQ (*l, "elf32-x86-64"))
+           if (startswith (*l, "elf32-x86-64"))
              {
                default_arch = "x86_64:32";
                break;
@@ -14284,7 +14366,7 @@ x86_64_section_letter (int letter, const char **ptr_msg)
 bfd_vma
 x86_64_section_word (char *str, size_t len)
 {
-  if (len == 5 && flag_code == CODE_64BIT && CONST_STRNEQ (str, "large"))
+  if (len == 5 && flag_code == CODE_64BIT && startswith (str, "large"))
     return SHF_X86_64_LARGE;
 
   return -1;
This page took 0.033672 seconds and 4 git commands to generate.