Add support for AVX512BW instructions and their AVX512VL versions.
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index f6283a685e5f0179644d6335b1ccda09c61abab8..b1d3c0fb3709d132e1431c389cda3b978bbdac17 100644 (file)
@@ -513,6 +513,11 @@ enum x86_elf_abi
 static enum x86_elf_abi x86_elf_abi = I386_ABI;
 #endif
 
+#if defined (TE_PE) || defined (TE_PEP)
+/* Use big object file format.  */
+static int use_big_obj = 0;
+#endif
+
 /* 1 for intel syntax,
    0 if att syntax.  */
 static int intel_syntax = 0;
@@ -909,6 +914,12 @@ static const arch_entry cpu_arch[] =
     CPU_XSAVES_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".prefetchwt1"), PROCESSOR_UNKNOWN,
     CPU_PREFETCHWT1_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".se1"), PROCESSOR_UNKNOWN,
+    CPU_SE1_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".avx512bw"), PROCESSOR_UNKNOWN,
+    CPU_AVX512BW_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".avx512vl"), PROCESSOR_UNKNOWN,
+    CPU_AVX512VL_FLAGS, 0, 0 },
 };
 
 #ifdef I386COFF
@@ -2839,9 +2850,12 @@ reloc (unsigned int size,
       if (other == BFD_RELOC_SIZE32)
        {
          if (size == 8)
-           return BFD_RELOC_SIZE64;
+           other = BFD_RELOC_SIZE64;
          if (pcrel)
-           as_bad (_("there are no pc-relative size relocations"));
+           {
+             as_bad (_("there are no pc-relative size relocations"));
+             return NO_RELOC;
+           }
        }
 #endif
 
@@ -3153,14 +3167,8 @@ build_vex_prefix (const insn_template *t)
 
       /* Check the REX.W bit.  */
       w = (i.rex & REX_W) ? 1 : 0;
-      if (i.tm.opcode_modifier.vexw)
-       {
-         if (w)
-           abort ();
-
-         if (i.tm.opcode_modifier.vexw == VEXW1)
-           w = 1;
-       }
+      if (i.tm.opcode_modifier.vexw == VEXW1)
+       w = 1;
 
       i.vex.bytes[2] = (w << 7
                        | register_specifier << 3
@@ -4440,6 +4448,10 @@ check_VecOperands (const insn_template *t)
        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;
 
@@ -7327,16 +7339,13 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off)
 \f
 /* x86_cons_fix_new is called via the expression parsing code when a
    reloc is needed.  We use this hook to get the correct .got reloc.  */
-static enum bfd_reloc_code_real got_reloc = NO_RELOC;
 static int cons_sign = -1;
 
 void
 x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
-                 expressionS *exp)
+                 expressionS *exp, bfd_reloc_code_real_type r)
 {
-  enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, 0, got_reloc);
-
-  got_reloc = NO_RELOC;
+  r = reloc (len, 0, cons_sign, 0, r);
 
 #ifdef TE_PE
   if (exp->X_op == O_secrel)
@@ -7632,9 +7641,11 @@ lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
 
 #endif /* TE_PE */
 
-void
+bfd_reloc_code_real_type
 x86_cons (expressionS *exp, int size)
 {
+  bfd_reloc_code_real_type got_reloc = NO_RELOC;
+
   intel_syntax = -intel_syntax;
 
   exp->X_md = 0;
@@ -7681,6 +7692,8 @@ x86_cons (expressionS *exp, int size)
 
   if (intel_syntax)
     i386_intel_simplify (exp);
+
+  return got_reloc;
 }
 
 static void
@@ -7741,6 +7754,10 @@ check_VecOperations (char *op_string, char *op_end)
              op_string += 3;
              if (*op_string == '8')
                bcst_type = BROADCAST_1TO8;
+             else if (*op_string == '4')
+               bcst_type = BROADCAST_1TO4;
+             else if (*op_string == '2')
+               bcst_type = BROADCAST_1TO2;
              else if (*op_string == '1'
                       && *(op_string+1) == '6')
                {
@@ -9138,8 +9155,21 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 #endif
     }
 #if defined (OBJ_COFF) && defined (TE_PE)
-  if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
-    {
+  if (fixP->fx_addsy != NULL
+      && S_IS_WEAK (fixP->fx_addsy)
+      /* PR 16858: Do not modify weak function references.  */
+      && ! fixP->fx_pcrel)
+    {
+#if !defined (TE_PEP)
+      /* For x86 PE weak function symbols are neither PC-relative
+        nor do they set S_IS_FUNCTION.  So the only reliable way
+        to detect them is to check the flags of their containing
+        section.  */
+      if (S_GET_SEGMENT (fixP->fx_addsy) != NULL
+         && S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_CODE)
+       ;
+      else
+#endif
       value -= S_GET_VALUE (fixP->fx_addsy);
     }
 #endif
@@ -9404,6 +9434,8 @@ parse_register (char *reg_string, char **end_op)
          know (e->X_add_number >= 0
                && (valueT) e->X_add_number < i386_regtab_size);
          r = i386_regtab + e->X_add_number;
+         if ((r->reg_flags & RegVRex))
+           i.need_vrex = 1;
          *end_op = input_line_pointer;
        }
       *input_line_pointer = c;
@@ -9497,6 +9529,7 @@ const char *md_shortopts = "qn";
 #define OPTION_MADD_BND_PREFIX (OPTION_MD_BASE + 15)
 #define OPTION_MEVEXLIG (OPTION_MD_BASE + 16)
 #define OPTION_MEVEXWIG (OPTION_MD_BASE + 17)
+#define OPTION_MBIG_OBJ (OPTION_MD_BASE + 18)
 
 struct option md_longopts[] =
 {
@@ -9523,6 +9556,9 @@ struct option md_longopts[] =
   {"madd-bnd-prefix", no_argument, NULL, OPTION_MADD_BND_PREFIX},
   {"mevexlig", required_argument, NULL, OPTION_MEVEXLIG},
   {"mevexwig", required_argument, NULL, OPTION_MEVEXWIG},
+# if defined (TE_PE) || defined (TE_PEP)
+  {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ},
+#endif
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
@@ -9804,6 +9840,12 @@ md_parse_option (int c, char *arg)
        as_fatal (_("invalid -mevexwig= option: `%s'"), arg);
       break;
 
+# if defined (TE_PE) || defined (TE_PEP)
+    case OPTION_MBIG_OBJ:
+      use_big_obj = 1;
+      break;
+#endif
+
     default:
       return 0;
     }
@@ -9956,6 +9998,10 @@ md_show_usage (FILE *stream)
   -mold-gcc               support old (<= 2.8.1) versions of gcc\n"));
   fprintf (stream, _("\
   -madd-bnd-prefix        add BND prefix for all valid branches\n"));
+# if defined (TE_PE) || defined (TE_PEP)
+  fprintf (stream, _("\
+  -mbig-obj               generate big object files\n"));
+#endif
 }
 
 #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
@@ -9994,7 +10040,10 @@ i386_target_format (void)
 #if defined (OBJ_MAYBE_COFF) || defined (OBJ_COFF)
 # if defined (TE_PE) || defined (TE_PEP)
     case bfd_target_coff_flavour:
-      return flag_code == CODE_64BIT ? "pe-x86-64" : "pe-i386";
+      if (flag_code == CODE_64BIT)
+       return use_big_obj ? "pe-bigobj-x86-64" : "pe-x86-64";
+      else
+       return "pe-i386";
 # elif defined (TE_GO32)
     case bfd_target_coff_flavour:
       return "coff-go32";
This page took 0.026474 seconds and 4 git commands to generate.