Support Intel SHA
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index 8bbf9db483165f3f57585a6e4f3b6b98cf23050b..a5e014af5e4de3a7e31b7bc4e33401f504143f49 100644 (file)
@@ -1,6 +1,7 @@
 /* tc-i386.c -- Assemble code for the Intel 80386
    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 /* tc-i386.c -- Assemble code for the Intel 80386
    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+   2012
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
    WAIT_PREFIX must be the first prefix since FWAIT is really is an
    instruction, and so must come before any prefixes.
    The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX,
    WAIT_PREFIX must be the first prefix since FWAIT is really is an
    instruction, and so must come before any prefixes.
    The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX,
-   REP_PREFIX, LOCK_PREFIX.  */
+   REP_PREFIX/HLE_PREFIX, LOCK_PREFIX.  */
 #define WAIT_PREFIX    0
 #define SEG_PREFIX     1
 #define ADDR_PREFIX    2
 #define DATA_PREFIX    3
 #define REP_PREFIX     4
 #define WAIT_PREFIX    0
 #define SEG_PREFIX     1
 #define ADDR_PREFIX    2
 #define DATA_PREFIX    3
 #define REP_PREFIX     4
+#define HLE_PREFIX     REP_PREFIX
+#define BND_PREFIX     REP_PREFIX
 #define LOCK_PREFIX    5
 #define REX_PREFIX     6       /* must come last.  */
 #define MAX_PREFIXES   7       /* max prefixes per opcode */
 #define LOCK_PREFIX    5
 #define REX_PREFIX     6       /* must come last.  */
 #define MAX_PREFIXES   7       /* max prefixes per opcode */
@@ -142,7 +145,7 @@ static void set_16bit_gcc_code_flag (int);
 static void set_intel_syntax (int);
 static void set_intel_mnemonic (int);
 static void set_allow_index_reg (int);
 static void set_intel_syntax (int);
 static void set_intel_mnemonic (int);
 static void set_allow_index_reg (int);
-static void set_sse_check (int);
+static void set_check (int);
 static void set_cpu_arch (int);
 #ifdef TE_PE
 static void pe_directive_secrel (int);
 static void set_cpu_arch (int);
 #ifdef TE_PE
 static void pe_directive_secrel (int);
@@ -182,7 +185,6 @@ static void s_bss (int);
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 static void handle_large_common (int small ATTRIBUTE_UNUSED);
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 static void handle_large_common (int small ATTRIBUTE_UNUSED);
-static void handle_quad (int);
 #endif
 
 static const char *default_arch = DEFAULT_ARCH;
 #endif
 
 static const char *default_arch = DEFAULT_ARCH;
@@ -218,7 +220,10 @@ enum i386_error
     old_gcc_only,
     unsupported_with_intel_mnemonic,
     unsupported_syntax,
     old_gcc_only,
     unsupported_with_intel_mnemonic,
     unsupported_syntax,
-    unsupported
+    unsupported,
+    invalid_vsib_address,
+    invalid_vector_register_set,
+    unsupported_vector_index_register
   };
 
 struct _i386_insn
   };
 
 struct _i386_insn
@@ -278,8 +283,22 @@ struct _i386_insn
     /* Swap operand in encoding.  */
     unsigned int swap_operand;
 
     /* Swap operand in encoding.  */
     unsigned int swap_operand;
 
-    /* Force 32bit displacement in encoding.  */
-    unsigned int disp32_encoding;
+    /* Prefer 8bit or 32bit displacement in encoding.  */
+    enum
+      {
+       disp_encoding_default = 0,
+       disp_encoding_8bit,
+       disp_encoding_32bit
+      } disp_encoding;
+
+    /* REP prefix.  */
+    const char *rep_prefix;
+
+    /* HLE prefix.  */
+    const char *hle_prefix;
+
+    /* Have BND prefix.  */
+    const char *bnd_prefix;
 
     /* Error message.  */
     enum i386_error error;
 
     /* Error message.  */
     enum i386_error error;
@@ -302,7 +321,8 @@ const char extra_symbol_chars[] = "*%-(["
      || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))        \
         && !defined (TE_GNU)                           \
         && !defined (TE_LINUX)                         \
      || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))        \
         && !defined (TE_GNU)                           \
         && !defined (TE_LINUX)                         \
-        && !defined (TE_NETWARE)                       \
+        && !defined (TE_NACL)                          \
+        && !defined (TE_NETWARE)                       \
         && !defined (TE_FreeBSD)                       \
         && !defined (TE_DragonFly)                     \
         && !defined (TE_NetBSD)))
         && !defined (TE_FreeBSD)                       \
         && !defined (TE_DragonFly)                     \
         && !defined (TE_NetBSD)))
@@ -409,14 +429,6 @@ enum x86_elf_abi
 static enum x86_elf_abi x86_elf_abi = I386_ABI;
 #endif
 
 static enum x86_elf_abi x86_elf_abi = I386_ABI;
 #endif
 
-/* The names used to print error messages.  */
-static const char *flag_code_names[] =
-  {
-    "32",
-    "16",
-    "64"
-  };
-
 /* 1 for intel syntax,
    0 if att syntax.  */
 static int intel_syntax = 0;
 /* 1 for intel syntax,
    0 if att syntax.  */
 static int intel_syntax = 0;
@@ -434,16 +446,21 @@ static int allow_pseudo_reg = 0;
 /* 1 if register prefix % not required.  */
 static int allow_naked_reg = 0;
 
 /* 1 if register prefix % not required.  */
 static int allow_naked_reg = 0;
 
+/* 1 if the assembler should add BND prefix for all control-tranferring
+   instructions supporting it, even if this prefix wasn't specified
+   explicitly.  */
+static int add_bnd_prefix = 0;
+
 /* 1 if pseudo index register, eiz/riz, is allowed .  */
 static int allow_index_reg = 0;
 
 /* 1 if pseudo index register, eiz/riz, is allowed .  */
 static int allow_index_reg = 0;
 
-static enum
+static enum check_kind
   {
   {
-    sse_check_none = 0,
-    sse_check_warning,
-    sse_check_error
+    check_none = 0,
+    check_warning,
+    check_error
   }
   }
-sse_check;
+sse_check, operand_check = check_warning;
 
 /* Register prefix used for error message.  */
 static const char *register_prefix = "%";
 
 /* Register prefix used for error message.  */
 static const char *register_prefix = "%";
@@ -631,6 +648,8 @@ static const arch_entry cpu_arch[] =
     CPU_COREI7_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("l1om"), PROCESSOR_L1OM,
     CPU_L1OM_FLAGS, 0, 0 },
     CPU_COREI7_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("l1om"), PROCESSOR_L1OM,
     CPU_L1OM_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN ("k1om"), PROCESSOR_K1OM,
+    CPU_K1OM_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("k6"), PROCESSOR_K6,
     CPU_K6_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6,
   { STRING_COMMA_LEN ("k6"), PROCESSOR_K6,
     CPU_K6_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6,
@@ -649,6 +668,12 @@ static const arch_entry cpu_arch[] =
     CPU_BDVER1_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("bdver2"), PROCESSOR_BD,
     CPU_BDVER2_FLAGS, 0, 0 },
     CPU_BDVER1_FLAGS, 0, 0 },
   { STRING_COMMA_LEN ("bdver2"), PROCESSOR_BD,
     CPU_BDVER2_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN ("bdver3"), PROCESSOR_BD,
+    CPU_BDVER3_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN ("btver1"), PROCESSOR_BT,
+    CPU_BTVER1_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN ("btver2"), PROCESSOR_BT,
+    CPU_BTVER2_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".8087"), PROCESSOR_UNKNOWN,
     CPU_8087_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".287"), PROCESSOR_UNKNOWN,
   { STRING_COMMA_LEN (".8087"), PROCESSOR_UNKNOWN,
     CPU_8087_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".287"), PROCESSOR_UNKNOWN,
@@ -679,10 +704,14 @@ static const arch_entry cpu_arch[] =
     CPU_ANY_SSE_FLAGS, 0, 1 },
   { STRING_COMMA_LEN (".avx"), PROCESSOR_UNKNOWN,
     CPU_AVX_FLAGS, 0, 0 },
     CPU_ANY_SSE_FLAGS, 0, 1 },
   { STRING_COMMA_LEN (".avx"), PROCESSOR_UNKNOWN,
     CPU_AVX_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".avx2"), PROCESSOR_UNKNOWN,
+    CPU_AVX2_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".noavx"), PROCESSOR_UNKNOWN,
     CPU_ANY_AVX_FLAGS, 0, 1 },
   { STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN,
     CPU_VMX_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".noavx"), PROCESSOR_UNKNOWN,
     CPU_ANY_AVX_FLAGS, 0, 1 },
   { STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN,
     CPU_VMX_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".vmfunc"), PROCESSOR_UNKNOWN,
+    CPU_VMFUNC_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".smx"), PROCESSOR_UNKNOWN,
     CPU_SMX_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".xsave"), PROCESSOR_UNKNOWN,
   { STRING_COMMA_LEN (".smx"), PROCESSOR_UNKNOWN,
     CPU_SMX_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".xsave"), PROCESSOR_UNKNOWN,
@@ -701,6 +730,8 @@ static const arch_entry cpu_arch[] =
     CPU_RDRND_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".f16c"), PROCESSOR_UNKNOWN,
     CPU_F16C_FLAGS, 0, 0 },
     CPU_RDRND_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".f16c"), PROCESSOR_UNKNOWN,
     CPU_F16C_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".bmi2"), PROCESSOR_UNKNOWN,
+    CPU_BMI2_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".fma"), PROCESSOR_UNKNOWN,
     CPU_FMA_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".fma4"), PROCESSOR_UNKNOWN,
   { STRING_COMMA_LEN (".fma"), PROCESSOR_UNKNOWN,
     CPU_FMA_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".fma4"), PROCESSOR_UNKNOWN,
@@ -711,8 +742,18 @@ static const arch_entry cpu_arch[] =
     CPU_LWP_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".movbe"), PROCESSOR_UNKNOWN,
     CPU_MOVBE_FLAGS, 0, 0 },
     CPU_LWP_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".movbe"), PROCESSOR_UNKNOWN,
     CPU_MOVBE_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".cx16"), PROCESSOR_UNKNOWN,
+    CPU_CX16_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".ept"), PROCESSOR_UNKNOWN,
     CPU_EPT_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".ept"), PROCESSOR_UNKNOWN,
     CPU_EPT_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".lzcnt"), PROCESSOR_UNKNOWN,
+    CPU_LZCNT_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".hle"), PROCESSOR_UNKNOWN,
+    CPU_HLE_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".rtm"), PROCESSOR_UNKNOWN,
+    CPU_RTM_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".invpcid"), PROCESSOR_UNKNOWN,
+    CPU_INVPCID_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".clflush"), PROCESSOR_UNKNOWN,
     CPU_CLFLUSH_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".nop"), PROCESSOR_UNKNOWN,
   { STRING_COMMA_LEN (".clflush"), PROCESSOR_UNKNOWN,
     CPU_CLFLUSH_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".nop"), PROCESSOR_UNKNOWN,
@@ -739,6 +780,18 @@ static const arch_entry cpu_arch[] =
     CPU_BMI_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".tbm"), PROCESSOR_UNKNOWN,
     CPU_TBM_FLAGS, 0, 0 },
     CPU_BMI_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".tbm"), PROCESSOR_UNKNOWN,
     CPU_TBM_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".adx"), PROCESSOR_UNKNOWN,
+    CPU_ADX_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".rdseed"), PROCESSOR_UNKNOWN,
+    CPU_RDSEED_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".prfchw"), PROCESSOR_UNKNOWN,
+    CPU_PRFCHW_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".smap"), PROCESSOR_UNKNOWN,
+    CPU_SMAP_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".mpx"), PROCESSOR_UNKNOWN,
+    CPU_MPX_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".sha"), PROCESSOR_UNKNOWN,
+    CPU_SHA_FLAGS, 0, 0 },
 };
 
 #ifdef I386COFF
 };
 
 #ifdef I386COFF
@@ -813,10 +866,10 @@ const pseudo_typeS md_pseudo_table[] =
   {"att_mnemonic", set_intel_mnemonic, 0},
   {"allow_index_reg", set_allow_index_reg, 1},
   {"disallow_index_reg", set_allow_index_reg, 0},
   {"att_mnemonic", set_intel_mnemonic, 0},
   {"allow_index_reg", set_allow_index_reg, 1},
   {"disallow_index_reg", set_allow_index_reg, 0},
-  {"sse_check", set_sse_check, 0},
+  {"sse_check", set_check, 0},
+  {"operand_check", set_check, 1},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
-  {"quad", handle_quad, 8},
 #else
   {"file", (void (*) (int)) dwarf2_directive_file, 0},
   {"loc", dwarf2_directive_loc, 0},
 #else
   {"file", (void (*) (int)) dwarf2_directive_file, 0},
   {"loc", dwarf2_directive_loc, 0},
@@ -1025,7 +1078,7 @@ i386_align_code (fragS *fragP, int count)
      PROCESSOR_CORE, PROCESSOR_CORE2, PROCESSOR_COREI7, and
      PROCESSOR_GENERIC64, alt_long_patt will be used.
      3. For PROCESSOR_ATHLON, PROCESSOR_K6, PROCESSOR_K8 and
      PROCESSOR_CORE, PROCESSOR_CORE2, PROCESSOR_COREI7, and
      PROCESSOR_GENERIC64, alt_long_patt will be used.
      3. For PROCESSOR_ATHLON, PROCESSOR_K6, PROCESSOR_K8 and
-     PROCESSOR_AMDFAM10, and PROCESSOR_BD, alt_short_patt
+     PROCESSOR_AMDFAM10, PROCESSOR_BD and PROCESSOR_BT, alt_short_patt
      will be used.
 
      When -mtune= isn't used, alt_long_patt will be used if
      will be used.
 
      When -mtune= isn't used, alt_long_patt will be used if
@@ -1071,6 +1124,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_CORE2:
            case PROCESSOR_COREI7:
            case PROCESSOR_L1OM:
            case PROCESSOR_CORE2:
            case PROCESSOR_COREI7:
            case PROCESSOR_L1OM:
+           case PROCESSOR_K1OM:
            case PROCESSOR_GENERIC64:
              patt = alt_long_patt;
              break;
            case PROCESSOR_GENERIC64:
              patt = alt_long_patt;
              break;
@@ -1079,6 +1133,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_K8:
            case PROCESSOR_AMDFAM10:
            case PROCESSOR_BD:
            case PROCESSOR_K8:
            case PROCESSOR_AMDFAM10:
            case PROCESSOR_BD:
+           case PROCESSOR_BT:
              patt = alt_short_patt;
              break;
            case PROCESSOR_I386:
              patt = alt_short_patt;
              break;
            case PROCESSOR_I386:
@@ -1108,6 +1163,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_K8:
            case PROCESSOR_AMDFAM10:
            case PROCESSOR_BD:
            case PROCESSOR_K8:
            case PROCESSOR_AMDFAM10:
            case PROCESSOR_BD:
+           case PROCESSOR_BT:
            case PROCESSOR_GENERIC32:
              /* We use cpu_arch_isa_flags to check if we CAN optimize
                 with nops.  */
            case PROCESSOR_GENERIC32:
              /* We use cpu_arch_isa_flags to check if we CAN optimize
                 with nops.  */
@@ -1123,6 +1179,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_CORE2:
            case PROCESSOR_COREI7:
            case PROCESSOR_L1OM:
            case PROCESSOR_CORE2:
            case PROCESSOR_COREI7:
            case PROCESSOR_L1OM:
+           case PROCESSOR_K1OM:
              if (fragP->tc_frag_data.isa_flags.bitfield.cpunop)
                patt = alt_long_patt;
              else
              if (fragP->tc_frag_data.isa_flags.bitfield.cpunop)
                patt = alt_long_patt;
              else
@@ -1496,6 +1553,7 @@ static const i386_operand_type imm16_32 = OPERAND_TYPE_IMM16_32;
 static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S;
 static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S;
 static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4;
 static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S;
 static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S;
 static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4;
+static const i386_operand_type regbnd = OPERAND_TYPE_REGBND;
 
 enum operand_type
 {
 
 enum operand_type
 {
@@ -1722,6 +1780,17 @@ operand_type_register_match (i386_operand_type m0,
   return 0;
 }
 
   return 0;
 }
 
+static INLINE unsigned int
+register_number (const reg_entry *r)
+{
+  unsigned int nr = r->reg_num;
+
+  if (r->reg_flags & RegRex)
+    nr += 8;
+
+  return nr;
+}
+
 static INLINE unsigned int
 mode_from_disp_size (i386_operand_type t)
 {
 static INLINE unsigned int
 mode_from_disp_size (i386_operand_type t)
 {
@@ -2065,8 +2134,22 @@ set_allow_index_reg (int flag)
 }
 
 static void
 }
 
 static void
-set_sse_check (int dummy ATTRIBUTE_UNUSED)
+set_check (int what)
 {
 {
+  enum check_kind *kind;
+  const char *str;
+
+  if (what)
+    {
+      kind = &operand_check;
+      str = "operand";
+    }
+  else
+    {
+      kind = &sse_check;
+      str = "sse";
+    }
+
   SKIP_WHITESPACE ();
 
   if (!is_end_of_line[(unsigned char) *input_line_pointer])
   SKIP_WHITESPACE ();
 
   if (!is_end_of_line[(unsigned char) *input_line_pointer])
@@ -2075,17 +2158,17 @@ set_sse_check (int dummy ATTRIBUTE_UNUSED)
       int e = get_symbol_end ();
 
       if (strcmp (string, "none") == 0)
       int e = get_symbol_end ();
 
       if (strcmp (string, "none") == 0)
-       sse_check = sse_check_none;
+       *kind = check_none;
       else if (strcmp (string, "warning") == 0)
       else if (strcmp (string, "warning") == 0)
-       sse_check = sse_check_warning;
+       *kind = check_warning;
       else if (strcmp (string, "error") == 0)
       else if (strcmp (string, "error") == 0)
-       sse_check = sse_check_error;
+       *kind = check_error;
       else
       else
-       as_bad (_("bad argument to sse_check directive."));
+       as_bad (_("bad argument to %s_check directive."), str);
       *input_line_pointer = e;
     }
   else
       *input_line_pointer = e;
     }
   else
-    as_bad (_("missing argument for sse_check directive"));
+    as_bad (_("missing argument for %s_check directive"), str);
 
   demand_empty_rest_of_line ();
 }
 
   demand_empty_rest_of_line ();
 }
@@ -2115,6 +2198,11 @@ check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED,
       || new_flag.bitfield.cpul1om)
     return;
 
       || new_flag.bitfield.cpul1om)
     return;
 
+  /* If we are targeting Intel K1OM, we must enable it.  */
+  if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_K1OM
+      || new_flag.bitfield.cpuk1om)
+    return;
+
   as_bad (_("`%s' is not supported on `%s'"), name, arch);
 #endif
 }
   as_bad (_("`%s' is not supported on `%s'"), name, arch);
 #endif
 }
@@ -2226,12 +2314,19 @@ i386_arch (void)
        as_fatal (_("Intel L1OM is 64bit ELF only"));
       return bfd_arch_l1om;
     }
        as_fatal (_("Intel L1OM is 64bit ELF only"));
       return bfd_arch_l1om;
     }
+  else if (cpu_arch_isa == PROCESSOR_K1OM)
+    {
+      if (OUTPUT_FLAVOR != bfd_target_elf_flavour
+         || flag_code != CODE_64BIT)
+       as_fatal (_("Intel K1OM is 64bit ELF only"));
+      return bfd_arch_k1om;
+    }
   else
     return bfd_arch_i386;
 }
 
 unsigned long
   else
     return bfd_arch_i386;
 }
 
 unsigned long
-i386_mach ()
+i386_mach (void)
 {
   if (!strncmp (default_arch, "x86_64", 6))
     {
 {
   if (!strncmp (default_arch, "x86_64", 6))
     {
@@ -2242,6 +2337,13 @@ i386_mach ()
            as_fatal (_("Intel L1OM is 64bit ELF only"));
          return bfd_mach_l1om;
        }
            as_fatal (_("Intel L1OM is 64bit ELF only"));
          return bfd_mach_l1om;
        }
+      else if (cpu_arch_isa == PROCESSOR_K1OM)
+       {
+         if (OUTPUT_FLAVOR != bfd_target_elf_flavour
+             || default_arch[6] != '\0')
+           as_fatal (_("Intel K1OM is 64bit ELF only"));
+         return bfd_mach_k1om;
+       }
       else if (default_arch[6] == '\0')
        return bfd_mach_x86_64;
       else
       else if (default_arch[6] == '\0')
        return bfd_mach_x86_64;
       else
@@ -2254,7 +2356,7 @@ i386_mach ()
 }
 \f
 void
 }
 \f
 void
-md_begin ()
+md_begin (void)
 {
   const char *hash_err;
 
 {
   const char *hash_err;
 
@@ -2284,7 +2386,7 @@ md_begin ()
                                    (void *) core_optab);
            if (hash_err)
              {
                                    (void *) core_optab);
            if (hash_err)
              {
-               as_fatal (_("internal Error:  Can't hash %s: %s"),
+               as_fatal (_("can't hash %s: %s"),
                          (optab - 1)->name,
                          hash_err);
              }
                          (optab - 1)->name,
                          hash_err);
              }
@@ -2306,7 +2408,7 @@ md_begin ()
       {
        hash_err = hash_insert (reg_hash, regtab->reg_name, (void *) regtab);
        if (hash_err)
       {
        hash_err = hash_insert (reg_hash, regtab->reg_name, (void *) regtab);
        if (hash_err)
-         as_fatal (_("internal Error:  Can't hash %s: %s"),
+         as_fatal (_("can't hash %s: %s"),
                    regtab->reg_name,
                    hash_err);
       }
                    regtab->reg_name,
                    hash_err);
       }
@@ -2366,15 +2468,6 @@ md_begin ()
       operand_chars[(unsigned char) *p] = *p;
   }
 
       operand_chars[(unsigned char) *p] = *p;
   }
 
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
-  if (IS_ELF)
-    {
-      record_alignment (text_section, 2);
-      record_alignment (data_section, 2);
-      record_alignment (bss_section, 2);
-    }
-#endif
-
   if (flag_code == CODE_64BIT)
     {
 #if defined (OBJ_COFF) && defined (TE_PE)
   if (flag_code == CODE_64BIT)
     {
 #if defined (OBJ_COFF) && defined (TE_PE)
@@ -2595,6 +2688,16 @@ reloc (unsigned int size,
            break;
          }
 
            break;
          }
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+      if (other == BFD_RELOC_SIZE32)
+       {
+         if (size == 8)
+           return BFD_RELOC_SIZE64;
+         if (pcrel)
+           as_bad (_("there are no pc-relative size relocations"));
+       }
+#endif
+
       /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless.  */
       if (size == 4 && (flag_code != CODE_64BIT || disallow_64bit_reloc))
        sign = -1;
       /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless.  */
       if (size == 4 && (flag_code != CODE_64BIT || disallow_64bit_reloc))
        sign = -1;
@@ -2678,8 +2781,11 @@ tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED)
       && fixP->fx_r_type == BFD_RELOC_32_PCREL)
     return 0;
 
       && fixP->fx_r_type == BFD_RELOC_32_PCREL)
     return 0;
 
-  /* adjust_reloc_syms doesn't know about the GOT.  */
-  if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
+  /* Adjust_reloc_syms doesn't know about the GOT.  Need to keep symbol
+     for size relocations.  */
+  if (fixP->fx_r_type == BFD_RELOC_SIZE32
+      || fixP->fx_r_type == BFD_RELOC_SIZE64
+      || fixP->fx_r_type == BFD_RELOC_386_GOTOFF
       || fixP->fx_r_type == BFD_RELOC_386_PLT32
       || fixP->fx_r_type == BFD_RELOC_386_GOT32
       || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
       || fixP->fx_r_type == BFD_RELOC_386_PLT32
       || fixP->fx_r_type == BFD_RELOC_386_GOT32
       || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
@@ -2776,12 +2882,7 @@ build_vex_prefix (const insn_template *t)
 
   /* Check register specifier.  */
   if (i.vex.register_specifier)
 
   /* Check register specifier.  */
   if (i.vex.register_specifier)
-    {
-      register_specifier = i.vex.register_specifier->reg_num;
-      if ((i.vex.register_specifier->reg_flags & RegRex))
-       register_specifier += 8;
-      register_specifier = ~register_specifier & 0xf;
-    }
+    register_specifier = ~register_number (i.vex.register_specifier) & 0xf;
   else
     register_specifier = 0xf;
 
   else
     register_specifier = 0xf;
 
@@ -2920,16 +3021,17 @@ process_immext (void)
 {
   expressionS *exp;
 
 {
   expressionS *exp;
 
-  if (i.tm.cpu_flags.bitfield.cpusse3 && i.operands > 0)
+  if ((i.tm.cpu_flags.bitfield.cpusse3 || i.tm.cpu_flags.bitfield.cpusvme)
+      && i.operands > 0)
     {
     {
-      /* SSE3 Instructions have the fixed operands with an opcode
-        suffix which is coded in the same place as an 8-bit immediate
-        field would be.  Here we check those operands and remove them
-        afterwards.  */
+      /* MONITOR/MWAIT as well as SVME instructions have fixed operands
+        with an opcode suffix which is coded in the same place as an
+        8-bit immediate field would be.
+        Here we check those operands and remove them afterwards.  */
       unsigned int x;
 
       for (x = 0; x < i.operands; x++)
       unsigned int x;
 
       for (x = 0; x < i.operands; x++)
-       if (i.op[x].regs->reg_num != x)
+       if (register_number (i.op[x].regs) != x)
          as_bad (_("can't use register '%s%s' as operand %d in '%s'."),
                  register_prefix, i.op[x].regs->reg_name, x + 1,
                  i.tm.name);
          as_bad (_("can't use register '%s%s' as operand %d in '%s'."),
                  register_prefix, i.op[x].regs->reg_name, x + 1,
                  i.tm.name);
@@ -2959,6 +3061,43 @@ process_immext (void)
   i.tm.extension_opcode = None;
 }
 
   i.tm.extension_opcode = None;
 }
 
+
+static int
+check_hle (void)
+{
+  switch (i.tm.opcode_modifier.hleprefixok)
+    {
+    default:
+      abort ();
+    case HLEPrefixNone:
+      as_bad (_("invalid instruction `%s' after `%s'"),
+             i.tm.name, i.hle_prefix);
+      return 0;
+    case HLEPrefixLock:
+      if (i.prefix[LOCK_PREFIX])
+       return 1;
+      as_bad (_("missing `lock' with `%s'"), i.hle_prefix);
+      return 0;
+    case HLEPrefixAny:
+      return 1;
+    case HLEPrefixRelease:
+      if (i.prefix[HLE_PREFIX] != XRELEASE_PREFIX_OPCODE)
+       {
+         as_bad (_("instruction `%s' after `xacquire' not allowed"),
+                 i.tm.name);
+         return 0;
+       }
+      if (i.mem_operands == 0
+         || !operand_type_check (i.types[i.operands - 1], anymem))
+       {
+         as_bad (_("memory destination needed for instruction `%s'"
+                   " after `xrelease'"), i.tm.name);
+         return 0;
+       }
+      return 1;
+    }
+}
+
 /* This is the guts of the machine-dependent assembler.  LINE points to a
    machine dependent instruction.  This function is supposed to emit
    the frags/bytes it assembles to.  */
 /* This is the guts of the machine-dependent assembler.  LINE points to a
    machine dependent instruction.  This function is supposed to emit
    the frags/bytes it assembles to.  */
@@ -3019,7 +3158,7 @@ md_assemble (char *line)
   /* Don't optimize displacement for movabs since it only takes 64bit
      displacement.  */
   if (i.disp_operands
   /* Don't optimize displacement for movabs since it only takes 64bit
      displacement.  */
   if (i.disp_operands
-      && !i.disp32_encoding
+      && i.disp_encoding != disp_encoding_32bit
       && (flag_code != CODE_64BIT
          || strcmp (mnemonic, "movabs") != 0))
     optimize_disp ();
       && (flag_code != CODE_64BIT
          || strcmp (mnemonic, "movabs") != 0))
     optimize_disp ();
@@ -3031,7 +3170,7 @@ md_assemble (char *line)
   if (!(t = match_template ()))
     return;
 
   if (!(t = match_template ()))
     return;
 
-  if (sse_check != sse_check_none
+  if (sse_check != check_none
       && !i.tm.opcode_modifier.noavx
       && (i.tm.cpu_flags.bitfield.cpusse
          || i.tm.cpu_flags.bitfield.cpusse2
       && !i.tm.opcode_modifier.noavx
       && (i.tm.cpu_flags.bitfield.cpusse
          || i.tm.cpu_flags.bitfield.cpusse2
@@ -3040,7 +3179,7 @@ md_assemble (char *line)
          || i.tm.cpu_flags.bitfield.cpusse4_1
          || i.tm.cpu_flags.bitfield.cpusse4_2))
     {
          || i.tm.cpu_flags.bitfield.cpusse4_1
          || i.tm.cpu_flags.bitfield.cpusse4_2))
     {
-      (sse_check == sse_check_warning
+      (sse_check == check_warning
        ? as_warn
        : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
     }
        ? as_warn
        : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
     }
@@ -3065,6 +3204,14 @@ md_assemble (char *line)
     if (!add_prefix (FWAIT_OPCODE))
       return;
 
     if (!add_prefix (FWAIT_OPCODE))
       return;
 
+  /* Check if REP prefix is OK.  */
+  if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok)
+    {
+      as_bad (_("invalid instruction `%s' after `%s'"),
+               i.tm.name, i.rep_prefix);
+      return;
+    }
+
   /* Check for lock without a lockable instruction.  Destination operand
      must be memory unless it is xchg (0x86).  */
   if (i.prefix[LOCK_PREFIX]
   /* Check for lock without a lockable instruction.  Destination operand
      must be memory unless it is xchg (0x86).  */
   if (i.prefix[LOCK_PREFIX]
@@ -3077,6 +3224,25 @@ md_assemble (char *line)
       return;
     }
 
       return;
     }
 
+  /* Check if HLE prefix is OK.  */
+  if (i.hle_prefix && !check_hle ())
+    return;
+
+  /* Check BND prefix.  */
+  if (i.bnd_prefix && !i.tm.opcode_modifier.bndprefixok)
+    as_bad (_("expecting valid branch instruction after `bnd'"));
+
+  if (i.tm.cpu_flags.bitfield.cpumpx
+      && flag_code == CODE_64BIT
+      && i.prefix[ADDR_PREFIX])
+    as_bad (_("32-bit address isn't allowed in 64-bit MPX instructions."));
+
+  /* Insert BND prefix.  */
+  if (add_bnd_prefix
+      && i.tm.opcode_modifier.bndprefixok
+      && !i.prefix[BND_PREFIX])
+    add_prefix (BND_PREFIX_OPCODE);
+
   /* Check string instruction segment overrides.  */
   if (i.tm.opcode_modifier.isstring && i.mem_operands != 0)
     {
   /* Check string instruction segment overrides.  */
   if (i.tm.opcode_modifier.isstring && i.mem_operands != 0)
     {
@@ -3209,9 +3375,6 @@ parse_insn (char *line, char *mnemonic)
   const insn_template *t;
   char *dot_p = NULL;
 
   const insn_template *t;
   char *dot_p = NULL;
 
-  /* Non-zero if we found a prefix only acceptable with string insns.  */
-  const char *expecting_string_instruction = NULL;
-
   while (1)
     {
       mnem_p = mnemonic;
   while (1)
     {
       mnem_p = mnemonic;
@@ -3280,7 +3443,12 @@ parse_insn (char *line, char *mnemonic)
            case PREFIX_EXIST:
              return NULL;
            case PREFIX_REP:
            case PREFIX_EXIST:
              return NULL;
            case PREFIX_REP:
-             expecting_string_instruction = current_templates->start->name;
+             if (current_templates->start->cpu_flags.bitfield.cpuhle)
+               i.hle_prefix = current_templates->start->name;
+             else if (current_templates->start->cpu_flags.bitfield.cpumpx)
+               i.bnd_prefix = current_templates->start->name;
+             else
+               i.rep_prefix = current_templates->start->name;
              break;
            default:
              break;
              break;
            default:
              break;
@@ -3298,11 +3466,15 @@ parse_insn (char *line, char *mnemonic)
         encoding.  */
       if (mnem_p - 2 == dot_p && dot_p[1] == 's')
        i.swap_operand = 1;
         encoding.  */
       if (mnem_p - 2 == dot_p && dot_p[1] == 's')
        i.swap_operand = 1;
-      else if (mnem_p - 4 == dot_p 
+      else if (mnem_p - 3 == dot_p
+              && dot_p[1] == 'd'
+              && dot_p[2] == '8')
+       i.disp_encoding = disp_encoding_8bit;
+      else if (mnem_p - 4 == dot_p
               && dot_p[1] == 'd'
               && dot_p[2] == '3'
               && dot_p[3] == '2')
               && dot_p[1] == 'd'
               && dot_p[2] == '3'
               && dot_p[3] == '2')
-       i.disp32_encoding = 1;
+       i.disp_encoding = disp_encoding_32bit;
       else
        goto check_suffix;
       mnem_p = dot_p;
       else
        goto check_suffix;
       mnem_p = dot_p;
@@ -3425,27 +3597,6 @@ skip:
       as_warn (_("use .code16 to ensure correct addressing mode"));
     }
 
       as_warn (_("use .code16 to ensure correct addressing mode"));
     }
 
-  /* Check for rep/repne without a string instruction.  */
-  if (expecting_string_instruction)
-    {
-      static templates override;
-
-      for (t = current_templates->start; t < current_templates->end; ++t)
-       if (t->opcode_modifier.isstring)
-         break;
-      if (t >= current_templates->end)
-       {
-         as_bad (_("expecting string instruction after `%s'"),
-                 expecting_string_instruction);
-         return NULL;
-       }
-      for (override.start = t; t < current_templates->end; ++t)
-       if (!t->opcode_modifier.isstring)
-         break;
-      override.end = t;
-      current_templates = &override;
-    }
-
   return l;
 }
 
   return l;
 }
 
@@ -3834,6 +3985,58 @@ optimize_disp (void)
       }
 }
 
       }
 }
 
+/* Check if operands are valid for the instruction.  */
+
+static int
+check_VecOperands (const insn_template *t)
+{
+  /* Without VSIB byte, we can't have a vector register for index.  */
+  if (!t->opcode_modifier.vecsib
+      && i.index_reg
+      && (i.index_reg->reg_type.bitfield.regxmm
+         || i.index_reg->reg_type.bitfield.regymm))
+    {
+      i.error = unsupported_vector_index_register;
+      return 1;
+    }
+
+  /* For VSIB byte, we need a vector register for index, and all vector
+     registers must be distinct.  */
+  if (t->opcode_modifier.vecsib)
+    {
+      if (!i.index_reg
+         || !((t->opcode_modifier.vecsib == VecSIB128
+               && i.index_reg->reg_type.bitfield.regxmm)
+              || (t->opcode_modifier.vecsib == VecSIB256
+                  && i.index_reg->reg_type.bitfield.regymm)))
+      {
+       i.error = invalid_vsib_address;
+       return 1;
+      }
+
+      gas_assert (i.reg_operands == 2);
+      gas_assert (i.types[0].bitfield.regxmm
+                 || i.types[0].bitfield.regymm);
+      gas_assert (i.types[2].bitfield.regxmm
+                 || i.types[2].bitfield.regymm);
+
+      if (operand_check == check_none)
+       return 0;
+      if (register_number (i.op[0].regs) != register_number (i.index_reg)
+         && register_number (i.op[2].regs) != register_number (i.index_reg)
+         && register_number (i.op[0].regs) != register_number (i.op[2].regs))
+       return 0;
+      if (operand_check == check_error)
+       {
+         i.error = invalid_vector_register_set;
+         return 1;
+       }
+      as_warn (_("mask, index, and destination registers should be distinct"));
+    }
+
+  return 0;
+}
+
 /* Check if operands are valid for the instruction.  Update VEX
    operand types.  */
 
 /* Check if operands are valid for the instruction.  Update VEX
    operand types.  */
 
@@ -3874,6 +4077,7 @@ match_template (void)
   unsigned int j;
   unsigned int found_cpu_match;
   unsigned int check_register;
   unsigned int j;
   unsigned int found_cpu_match;
   unsigned int check_register;
+  enum i386_error specific_error = 0;
 
 #if MAX_OPERANDS != 5
 # error "MAX_OPERANDS must be 5."
 
 #if MAX_OPERANDS != 5
 # error "MAX_OPERANDS must be 5."
@@ -4170,9 +4374,12 @@ check_reverse:
          continue;
        }
 
          continue;
        }
 
-      /* Check if VEX operands are valid.  */
-      if (VEX_check_operands (t))
-       continue;
+      /* Check if vector and VEX operands are valid.  */
+      if (check_VecOperands (t) || VEX_check_operands (t))
+       {
+         specific_error = i.error;
+         continue;
+       }
 
       /* We've found a match; break out of loop.  */
       break;
 
       /* We've found a match; break out of loop.  */
       break;
@@ -4182,7 +4389,7 @@ check_reverse:
     {
       /* We found no match.  */
       const char *err_msg;
     {
       /* We found no match.  */
       const char *err_msg;
-      switch (i.error)
+      switch (specific_error ? specific_error : i.error)
        {
        default:
          abort ();
        {
        default:
          abort ();
@@ -4202,7 +4409,7 @@ check_reverse:
          err_msg = _("invalid instruction suffix");
          break;
        case bad_imm4:
          err_msg = _("invalid instruction suffix");
          break;
        case bad_imm4:
-         err_msg = _("Imm4 isn't the first operand");
+         err_msg = _("constant doesn't fit in 4 bits");
          break;
        case old_gcc_only:
          err_msg = _("only supported with old gcc");
          break;
        case old_gcc_only:
          err_msg = _("only supported with old gcc");
@@ -4214,7 +4421,17 @@ check_reverse:
          err_msg = _("unsupported syntax");
          break;
        case unsupported:
          err_msg = _("unsupported syntax");
          break;
        case unsupported:
-         err_msg = _("unsupported");
+         as_bad (_("unsupported instruction `%s'"),
+                 current_templates->start->name);
+         return NULL;
+       case invalid_vsib_address:
+         err_msg = _("invalid VSIB address");
+         break;
+       case invalid_vector_register_set:
+         err_msg = _("mask, index, and destination registers must be distinct");
+         break;
+       case unsupported_vector_index_register:
+         err_msg = _("unsupported vector index register");
          break;
        }
       as_bad (_("%s for `%s'"), err_msg,
          break;
        }
       as_bad (_("%s for `%s'"), err_msg,
@@ -4582,6 +4799,10 @@ check_byte_reg (void)
       if (i.types[op].bitfield.reg8)
        continue;
 
       if (i.types[op].bitfield.reg8)
        continue;
 
+      /* I/O port address operands are OK too.  */
+      if (i.tm.operand_types[op].bitfield.inoutportreg)
+       continue;
+
       /* crc32 doesn't generate this warning.  */
       if (i.tm.base_opcode == 0xf20f38f0)
        continue;
       /* crc32 doesn't generate this warning.  */
       if (i.tm.base_opcode == 0xf20f38f0)
        continue;
@@ -4589,21 +4810,13 @@ check_byte_reg (void)
       if ((i.types[op].bitfield.reg16
           || i.types[op].bitfield.reg32
           || i.types[op].bitfield.reg64)
       if ((i.types[op].bitfield.reg16
           || i.types[op].bitfield.reg32
           || i.types[op].bitfield.reg64)
-         && i.op[op].regs->reg_num < 4)
+         && i.op[op].regs->reg_num < 4
+         /* Prohibit these changes in 64bit mode, since the lowering
+            would be more complicated.  */
+         && flag_code != CODE_64BIT)
        {
        {
-         /* Prohibit these changes in the 64bit mode, since the
-            lowering is more complicated.  */
-         if (flag_code == CODE_64BIT
-             && !i.tm.operand_types[op].bitfield.inoutportreg)
-           {
-             as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
-                     register_prefix, i.op[op].regs->reg_name,
-                     i.suffix);
-             return 0;
-           }
 #if REGISTER_WARNINGS
 #if REGISTER_WARNINGS
-         if (!quiet_warnings
-             && !i.tm.operand_types[op].bitfield.inoutportreg)
+         if (!quiet_warnings)
            as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
                     register_prefix,
                     (i.op[op].regs + (i.types[op].bitfield.reg16
            as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
                     register_prefix,
                     (i.op[op].regs + (i.types[op].bitfield.reg16
@@ -4923,7 +5136,7 @@ process_operands (void)
        {
          /* The first operand is implicit and must be xmm0.  */
          gas_assert (operand_type_equal (&i.types[0], &regxmm));
        {
          /* The first operand is implicit and must be xmm0.  */
          gas_assert (operand_type_equal (&i.types[0], &regxmm));
-         if (i.op[0].regs->reg_num != 0)
+         if (register_number (i.op[0].regs) != 0)
            return bad_implicit_operand (1);
 
          if (i.tm.opcode_modifier.vexsources == VEX3SOURCES)
            return bad_implicit_operand (1);
 
          if (i.tm.opcode_modifier.vexsources == VEX3SOURCES)
@@ -4997,7 +5210,7 @@ duplicate:
       gas_assert (i.reg_operands
                  && (operand_type_equal (&i.types[0], &regxmm)
                      || operand_type_equal (&i.types[0], &regymm)));
       gas_assert (i.reg_operands
                  && (operand_type_equal (&i.types[0], &regxmm)
                      || operand_type_equal (&i.types[0], &regymm)));
-      if (i.op[0].regs->reg_num != 0)
+      if (register_number (i.op[0].regs) != 0)
        return bad_implicit_operand (i.types[0].bitfield.regxmm);
 
       for (j = 1; j < i.operands; j++)
        return bad_implicit_operand (i.types[0].bitfield.regxmm);
 
       for (j = 1; j < i.operands; j++)
@@ -5200,10 +5413,7 @@ build_modrm_byte (void)
                       || operand_type_equal (&i.tm.operand_types[reg_slot],
                                              &regymm));
           exp->X_op = O_constant;
                       || operand_type_equal (&i.tm.operand_types[reg_slot],
                                              &regymm));
           exp->X_op = O_constant;
-          exp->X_add_number
-              = ((i.op[reg_slot].regs->reg_num
-                  + ((i.op[reg_slot].regs->reg_flags & RegRex) ? 8 : 0))
-                << 4);
+          exp->X_add_number = register_number (i.op[reg_slot].regs) << 4;
         }
       else
         {
         }
       else
         {
@@ -5247,9 +5457,7 @@ build_modrm_byte (void)
                      || operand_type_equal (&i.tm.operand_types[reg_slot],
                                             &regymm));
           i.op[imm_slot].imms->X_add_number
                      || operand_type_equal (&i.tm.operand_types[reg_slot],
                                             &regymm));
           i.op[imm_slot].imms->X_add_number
-              |= ((i.op[reg_slot].regs->reg_num
-                   + ((i.op[reg_slot].regs->reg_flags & RegRex) ? 8 : 0))
-                 << 4);
+              |= register_number (i.op[reg_slot].regs) << 4;
         }
 
       gas_assert (operand_type_equal (&i.tm.operand_types[nds], &regxmm)
         }
 
       gas_assert (operand_type_equal (&i.tm.operand_types[nds], &regxmm)
@@ -5412,15 +5620,53 @@ build_modrm_byte (void)
              break;
          gas_assert (op < i.operands);
 
              break;
          gas_assert (op < i.operands);
 
+         if (i.tm.opcode_modifier.vecsib)
+           {
+             if (i.index_reg->reg_num == RegEiz
+                 || i.index_reg->reg_num == RegRiz)
+               abort ();
+
+             i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+             if (!i.base_reg)
+               {
+                 i.sib.base = NO_BASE_REGISTER;
+                 i.sib.scale = i.log2_scale_factor;
+                 i.types[op].bitfield.disp8 = 0;
+                 i.types[op].bitfield.disp16 = 0;
+                 i.types[op].bitfield.disp64 = 0;
+                 if (flag_code != CODE_64BIT)
+                   {
+                     /* Must be 32 bit */
+                     i.types[op].bitfield.disp32 = 1;
+                     i.types[op].bitfield.disp32s = 0;
+                   }
+                 else
+                   {
+                     i.types[op].bitfield.disp32 = 0;
+                     i.types[op].bitfield.disp32s = 1;
+                   }
+               }
+             i.sib.index = i.index_reg->reg_num;
+             if ((i.index_reg->reg_flags & RegRex) != 0)
+               i.rex |= REX_X;
+           }
+
          default_seg = &ds;
 
          if (i.base_reg == 0)
            {
              i.rm.mode = 0;
              if (!i.disp_operands)
          default_seg = &ds;
 
          if (i.base_reg == 0)
            {
              i.rm.mode = 0;
              if (!i.disp_operands)
-               fake_zero_displacement = 1;
+               {
+                 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;
+               }
              if (i.index_reg == 0)
                {
              if (i.index_reg == 0)
                {
+                 gas_assert (!i.tm.opcode_modifier.vecsib);
                  /* Operand is just <disp>  */
                  if (flag_code == CODE_64BIT)
                    {
                  /* Operand is just <disp>  */
                  if (flag_code == CODE_64BIT)
                    {
@@ -5446,8 +5692,9 @@ build_modrm_byte (void)
                      i.types[op] = disp32;
                    }
                }
                      i.types[op] = disp32;
                    }
                }
-             else /* !i.base_reg && i.index_reg  */
+             else if (!i.tm.opcode_modifier.vecsib)
                {
                {
+                 /* !i.base_reg && i.index_reg  */
                  if (i.index_reg->reg_num == RegEiz
                      || i.index_reg->reg_num == RegRiz)
                    i.sib.index = NO_INDEX_REGISTER;
                  if (i.index_reg->reg_num == RegEiz
                      || i.index_reg->reg_num == RegRiz)
                    i.sib.index = NO_INDEX_REGISTER;
@@ -5478,6 +5725,7 @@ build_modrm_byte (void)
          else if (i.base_reg->reg_num == RegRip ||
                   i.base_reg->reg_num == RegEip)
            {
          else if (i.base_reg->reg_num == RegRip ||
                   i.base_reg->reg_num == RegEip)
            {
+             gas_assert (!i.tm.opcode_modifier.vecsib);
              i.rm.regmem = NO_BASE_REGISTER;
              i.types[op].bitfield.disp8 = 0;
              i.types[op].bitfield.disp16 = 0;
              i.rm.regmem = NO_BASE_REGISTER;
              i.types[op].bitfield.disp8 = 0;
              i.types[op].bitfield.disp16 = 0;
@@ -5490,6 +5738,7 @@ build_modrm_byte (void)
            }
          else if (i.base_reg->reg_type.bitfield.reg16)
            {
            }
          else if (i.base_reg->reg_type.bitfield.reg16)
            {
+             gas_assert (!i.tm.opcode_modifier.vecsib);
              switch (i.base_reg->reg_num)
                {
                case 3: /* (%bx)  */
              switch (i.base_reg->reg_num)
                {
                case 3: /* (%bx)  */
@@ -5533,28 +5782,26 @@ build_modrm_byte (void)
                    i.types[op].bitfield.disp32 = 1;
                }
 
                    i.types[op].bitfield.disp32 = 1;
                }
 
-             i.rm.regmem = i.base_reg->reg_num;
+             if (!i.tm.opcode_modifier.vecsib)
+               i.rm.regmem = i.base_reg->reg_num;
              if ((i.base_reg->reg_flags & RegRex) != 0)
                i.rex |= REX_B;
              i.sib.base = i.base_reg->reg_num;
              /* x86-64 ignores REX prefix bit here to avoid decoder
                 complications.  */
              if ((i.base_reg->reg_flags & RegRex) != 0)
                i.rex |= REX_B;
              i.sib.base = i.base_reg->reg_num;
              /* x86-64 ignores REX prefix bit here to avoid decoder
                 complications.  */
-             if ((i.base_reg->reg_num & 7) == EBP_REG_NUM)
-               {
+             if (!(i.base_reg->reg_flags & RegRex)
+                 && (i.base_reg->reg_num == EBP_REG_NUM
+                  || i.base_reg->reg_num == ESP_REG_NUM))
                  default_seg = &ss;
                  default_seg = &ss;
-                 if (i.disp_operands == 0)
-                   {
-                     fake_zero_displacement = 1;
-                     i.types[op].bitfield.disp8 = 1;
-                   }
-               }
-             else if (i.base_reg->reg_num == ESP_REG_NUM)
+             if (i.base_reg->reg_num == 5 && i.disp_operands == 0)
                {
                {
-                 default_seg = &ss;
+                 fake_zero_displacement = 1;
+                 i.types[op].bitfield.disp8 = 1;
                }
              i.sib.scale = i.log2_scale_factor;
              if (i.index_reg == 0)
                {
                }
              i.sib.scale = i.log2_scale_factor;
              if (i.index_reg == 0)
                {
+                 gas_assert (!i.tm.opcode_modifier.vecsib);
                  /* <disp>(%esp) becomes two byte modrm with no index
                     register.  We've already stored the code for esp
                     in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING.
                  /* <disp>(%esp) becomes two byte modrm with no index
                     register.  We've already stored the code for esp
                     in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING.
@@ -5562,7 +5809,7 @@ build_modrm_byte (void)
                     extra modrm byte.  */
                  i.sib.index = NO_INDEX_REGISTER;
                }
                     extra modrm byte.  */
                  i.sib.index = NO_INDEX_REGISTER;
                }
-             else
+             else if (!i.tm.opcode_modifier.vecsib)
                {
                  if (i.index_reg->reg_num == RegEiz
                      || i.index_reg->reg_num == RegRiz)
                {
                  if (i.index_reg->reg_num == RegEiz
                      || i.index_reg->reg_num == RegRiz)
@@ -5579,7 +5826,19 @@ build_modrm_byte (void)
                      || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL))
                i.rm.mode = 0;
              else
                      || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL))
                i.rm.mode = 0;
              else
-               i.rm.mode = mode_from_disp_size (i.types[op]);
+               {
+                 if (!fake_zero_displacement
+                     && !i.disp_operands
+                     && i.disp_encoding)
+                   {
+                     fake_zero_displacement = 1;
+                     if (i.disp_encoding == disp_encoding_8bit)
+                       i.types[op].bitfield.disp8 = 1;
+                     else
+                       i.types[op].bitfield.disp32 = 1;
+                   }
+                 i.rm.mode = mode_from_disp_size (i.types[op]);
+               }
            }
 
          if (fake_zero_displacement)
            }
 
          if (fake_zero_displacement)
@@ -5664,6 +5923,7 @@ build_modrm_byte (void)
                || i.types[op].bitfield.regmmx
                || i.types[op].bitfield.regxmm
                || i.types[op].bitfield.regymm
                || i.types[op].bitfield.regmmx
                || i.types[op].bitfield.regxmm
                || i.types[op].bitfield.regymm
+               || i.types[op].bitfield.regbnd
                || i.types[op].bitfield.sreg2
                || i.types[op].bitfield.sreg3
                || i.types[op].bitfield.control
                || i.types[op].bitfield.sreg2
                || i.types[op].bitfield.sreg3
                || i.types[op].bitfield.control
@@ -5714,7 +5974,7 @@ build_modrm_byte (void)
                  vex_reg = op + 1;
                }
              else
                  vex_reg = op + 1;
                }
              else
-               { 
+               {
                  /* There are only 2 operands.  */
                  gas_assert (op < 2 && i.operands == 2);
                  vex_reg = 1;
                  /* There are only 2 operands.  */
                  gas_assert (op < 2 && i.operands == 2);
                  vex_reg = 1;
@@ -5781,7 +6041,7 @@ output_branch (void)
   offsetT off;
 
   code16 = flag_code == CODE_16BIT ? CODE16 : 0;
   offsetT off;
 
   code16 = flag_code == CODE_16BIT ? CODE16 : 0;
-  size = i.disp32_encoding ? BIG : SMALL;
+  size = i.disp_encoding == disp_encoding_32bit ? BIG : SMALL;
 
   prefix = 0;
   if (i.prefix[DATA_PREFIX] != 0)
 
   prefix = 0;
   if (i.prefix[DATA_PREFIX] != 0)
@@ -5803,6 +6063,13 @@ output_branch (void)
       i.prefixes--;
     }
 
       i.prefixes--;
     }
 
+  /* BND prefixed jump.  */
+  if (i.prefix[BND_PREFIX] != 0)
+    {
+      FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
+      i.prefixes -= 1;
+    }
+
   if (i.prefixes != 0 && !intel_syntax)
     as_warn (_("skipping prefixes on this instruction"));
 
   if (i.prefixes != 0 && !intel_syntax)
     as_warn (_("skipping prefixes on this instruction"));
 
@@ -5897,11 +6164,27 @@ output_jump (void)
       i.prefixes -= 1;
     }
 
       i.prefixes -= 1;
     }
 
+  /* BND prefixed jump.  */
+  if (i.prefix[BND_PREFIX] != 0)
+    {
+      FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
+      i.prefixes -= 1;
+    }
+
   if (i.prefixes != 0 && !intel_syntax)
     as_warn (_("skipping prefixes on this instruction"));
 
   if (i.prefixes != 0 && !intel_syntax)
     as_warn (_("skipping prefixes on this instruction"));
 
-  p = frag_more (1 + size);
-  *p++ = i.tm.base_opcode;
+  p = frag_more (i.tm.opcode_length + size);
+  switch (i.tm.opcode_length)
+    {
+    case 2:
+      *p++ = i.tm.base_opcode >> 8;
+    case 1:
+      *p++ = i.tm.base_opcode;
+      break;
+    default:
+      abort ();
+    }
 
   fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
                      i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
 
   fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
                      i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
@@ -6008,7 +6291,7 @@ output_insn (void)
       unsigned int prefix;
 
       /* Since the VEX prefix contains the implicit prefix, we don't
       unsigned int prefix;
 
       /* Since the VEX prefix contains the implicit prefix, we don't
-         need the explicit prefix.  */
+        need the explicit prefix.  */
       if (!i.tm.opcode_modifier.vex)
        {
          switch (i.tm.opcode_length)
       if (!i.tm.opcode_modifier.vex)
        {
          switch (i.tm.opcode_length)
@@ -6047,8 +6330,7 @@ check_prefix:
            if (*q)
              FRAG_APPEND_1_CHAR (*q);
        }
            if (*q)
              FRAG_APPEND_1_CHAR (*q);
        }
-
-      if (i.tm.opcode_modifier.vex)
+      else
        {
          for (j = 0, q = i.prefix; j < ARRAY_SIZE (i.prefix); j++, q++)
            if (*q)
        {
          for (j = 0, q = i.prefix; j < ARRAY_SIZE (i.prefix); j++, q++)
            if (*q)
@@ -6410,7 +6692,19 @@ x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
   fix_new_exp (frag, off, len, exp, 0, r);
 }
 
   fix_new_exp (frag, off, len, exp, 0, r);
 }
 
-#if (!defined (OBJ_ELF) && !defined (OBJ_MAYBE_ELF)) || defined (LEX_AT)
+/* Export the ABI address size for use by TC_ADDRESS_BYTES for the
+   purpose of the `.dc.a' internal pseudo-op.  */
+
+int
+x86_address_bytes (void)
+{
+  if ((stdoutput->arch_info->mach & bfd_mach_x64_32))
+    return 4;
+  return stdoutput->arch_info->bits_per_address / 8;
+}
+
+#if !(defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (OBJ_MACH_O)) \
+    || defined (LEX_AT)
 # define lex_got(reloc, adjust, types) NULL
 #else
 /* Parse operands of the form
 # define lex_got(reloc, adjust, types) NULL
 #else
 /* Parse operands of the form
@@ -6438,6 +6732,11 @@ lex_got (enum bfd_reloc_code_real *rel,
     const enum bfd_reloc_code_real rel[2];
     const i386_operand_type types64;
   } gotrel[] = {
     const enum bfd_reloc_code_real rel[2];
     const i386_operand_type types64;
   } gotrel[] = {
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+    { STRING_COMMA_LEN ("SIZE"),      { BFD_RELOC_SIZE32,
+                                       BFD_RELOC_SIZE32 },
+      OPERAND_TYPE_IMM32_64 },
+#endif
     { STRING_COMMA_LEN ("PLTOFF"),   { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_PLTOFF64 },
       OPERAND_TYPE_IMM64 },
     { STRING_COMMA_LEN ("PLTOFF"),   { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_PLTOFF64 },
       OPERAND_TYPE_IMM64 },
@@ -6493,8 +6792,10 @@ lex_got (enum bfd_reloc_code_real *rel,
   char *cp;
   unsigned int j;
 
   char *cp;
   unsigned int j;
 
+#if defined (OBJ_MAYBE_ELF)
   if (!IS_ELF)
     return NULL;
   if (!IS_ELF)
     return NULL;
+#endif
 
   for (cp = input_line_pointer; *cp != '@'; cp++)
     if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
 
   for (cp = input_line_pointer; *cp != '@'; cp++)
     if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
@@ -6511,8 +6812,6 @@ lex_got (enum bfd_reloc_code_real *rel,
              char *tmpbuf, *past_reloc;
 
              *rel = gotrel[j].rel[object_64bit];
              char *tmpbuf, *past_reloc;
 
              *rel = gotrel[j].rel[object_64bit];
-             if (adjust)
-               *adjust = len;
 
              if (types)
                {
 
              if (types)
                {
@@ -6525,7 +6824,7 @@ lex_got (enum bfd_reloc_code_real *rel,
                    *types = gotrel[j].types64;
                }
 
                    *types = gotrel[j].types64;
                }
 
-             if (GOT_symbol == NULL)
+             if (j != 0 && GOT_symbol == NULL)
                GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
 
              /* The length of the first part of our input line.  */
                GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
 
              /* The length of the first part of our input line.  */
@@ -6547,6 +6846,12 @@ lex_got (enum bfd_reloc_code_real *rel,
                /* Replace the relocation token with ' ', so that
                   errors like foo@GOTOFF1 will be detected.  */
                tmpbuf[first++] = ' ';
                /* Replace the relocation token with ' ', so that
                   errors like foo@GOTOFF1 will be detected.  */
                tmpbuf[first++] = ' ';
+             else
+               /* Increment length by 1 if the relocation token is
+                  removed.  */
+               len++;
+             if (adjust)
+               *adjust = len;
              memcpy (tmpbuf + first, past_reloc, second);
              tmpbuf[first + second] = '\0';
              return tmpbuf;
              memcpy (tmpbuf + first, past_reloc, second);
              tmpbuf[first + second] = '\0';
              return tmpbuf;
@@ -6563,6 +6868,109 @@ lex_got (enum bfd_reloc_code_real *rel,
 }
 #endif
 
 }
 #endif
 
+#ifdef TE_PE
+#ifdef lex_got
+#undef lex_got
+#endif
+/* Parse operands of the form
+   <symbol>@SECREL32+<nnn>
+
+   If we find one, set up the correct relocation in RELOC and copy the
+   input string, minus the `@SECREL32' into a malloc'd buffer for
+   parsing by the calling routine.  Return this buffer, and if ADJUST
+   is non-null set it to the length of the string we removed from the
+   input line.  Otherwise return NULL.
+
+   This function is copied from the ELF version above adjusted for PE targets.  */
+
+static char *
+lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
+        int *adjust ATTRIBUTE_UNUSED,
+        i386_operand_type *types ATTRIBUTE_UNUSED)
+{
+  static const struct
+  {
+    const char *str;
+    int len;
+    const enum bfd_reloc_code_real rel[2];
+    const i386_operand_type types64;
+  }
+  gotrel[] =
+  {
+    { STRING_COMMA_LEN ("SECREL32"),    { BFD_RELOC_32_SECREL,
+                                         BFD_RELOC_32_SECREL },
+      OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
+  };
+
+  char *cp;
+  unsigned j;
+
+  for (cp = input_line_pointer; *cp != '@'; cp++)
+    if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
+      return NULL;
+
+  for (j = 0; j < ARRAY_SIZE (gotrel); j++)
+    {
+      int len = gotrel[j].len;
+
+      if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
+       {
+         if (gotrel[j].rel[object_64bit] != 0)
+           {
+             int first, second;
+             char *tmpbuf, *past_reloc;
+
+             *rel = gotrel[j].rel[object_64bit];
+             if (adjust)
+               *adjust = len;
+
+             if (types)
+               {
+                 if (flag_code != CODE_64BIT)
+                   {
+                     types->bitfield.imm32 = 1;
+                     types->bitfield.disp32 = 1;
+                   }
+                 else
+                   *types = gotrel[j].types64;
+               }
+
+             /* The length of the first part of our input line.  */
+             first = cp - input_line_pointer;
+
+             /* The second part goes from after the reloc token until
+                (and including) an end_of_line char or comma.  */
+             past_reloc = cp + 1 + len;
+             cp = past_reloc;
+             while (!is_end_of_line[(unsigned char) *cp] && *cp != ',')
+               ++cp;
+             second = cp + 1 - past_reloc;
+
+             /* Allocate and copy string.  The trailing NUL shouldn't
+                be necessary, but be safe.  */
+             tmpbuf = (char *) xmalloc (first + second + 2);
+             memcpy (tmpbuf, input_line_pointer, first);
+             if (second != 0 && *past_reloc != ' ')
+               /* Replace the relocation token with ' ', so that
+                  errors like foo@SECLREL321 will be detected.  */
+               tmpbuf[first++] = ' ';
+             memcpy (tmpbuf + first, past_reloc, second);
+             tmpbuf[first + second] = '\0';
+             return tmpbuf;
+           }
+
+         as_bad (_("@%s reloc is not supported with %d-bit output format"),
+                 gotrel[j].str, 1 << (5 + object_64bit));
+         return NULL;
+       }
+    }
+
+  /* Might be a symbol version string.  Don't as_bad here.  */
+  return NULL;
+}
+
+#endif /* TE_PE */
+
 void
 x86_cons (expressionS *exp, int size)
 {
 void
 x86_cons (expressionS *exp, int size)
 {
@@ -6625,8 +7033,7 @@ signed_cons (int size)
 
 #ifdef TE_PE
 static void
 
 #ifdef TE_PE
 static void
-pe_directive_secrel (dummy)
-     int dummy ATTRIBUTE_UNUSED;
+pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
 {
   expressionS exp;
 
 {
   expressionS exp;
 
@@ -7042,14 +7449,55 @@ i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
 static int
 i386_index_check (const char *operand_string)
 {
 static int
 i386_index_check (const char *operand_string)
 {
-  int ok;
   const char *kind = "base/index";
   const char *kind = "base/index";
+  enum flag_code addr_mode;
+
+  if (i.prefix[ADDR_PREFIX])
+    addr_mode = flag_code == CODE_32BIT ? CODE_16BIT : CODE_32BIT;
+  else
+    {
+      addr_mode = flag_code;
+
 #if INFER_ADDR_PREFIX
 #if INFER_ADDR_PREFIX
-  int fudged = 0;
+      if (i.mem_operands == 0)
+       {
+         /* Infer address prefix from the first memory operand.  */
+         const reg_entry *addr_reg = i.base_reg;
 
 
- tryprefix:
+         if (addr_reg == NULL)
+           addr_reg = i.index_reg;
+
+         if (addr_reg)
+           {
+             if (addr_reg->reg_num == RegEip
+                 || addr_reg->reg_num == RegEiz
+                 || addr_reg->reg_type.bitfield.reg32)
+               addr_mode = CODE_32BIT;
+             else if (flag_code != CODE_64BIT
+                      && addr_reg->reg_type.bitfield.reg16)
+               addr_mode = CODE_16BIT;
+
+             if (addr_mode != flag_code)
+               {
+                 i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
+                 i.prefixes += 1;
+                 /* Change the size of any displacement too.  At most one
+                    of Disp16 or Disp32 is set.
+                    FIXME.  There doesn't seem to be any real need for
+                    separate Disp16 and Disp32 flags.  The same goes for
+                    Imm16 and Imm32.  Removing them would probably clean
+                    up the code quite a lot.  */
+                 if (flag_code != CODE_64BIT
+                     && (i.types[this_operand].bitfield.disp16
+                         || i.types[this_operand].bitfield.disp32))
+                   i.types[this_operand]
+                     = operand_type_xor (i.types[this_operand], disp16_32);
+               }
+           }
+       }
 #endif
 #endif
-  ok = 1;
+    }
+
   if (current_templates->start->opcode_modifier.isstring
       && !current_templates->start->opcode_modifier.immext
       && (current_templates->end[-1].opcode_modifier.isstring
   if (current_templates->start->opcode_modifier.isstring
       && !current_templates->start->opcode_modifier.immext
       && (current_templates->end[-1].opcode_modifier.isstring
@@ -7057,7 +7505,14 @@ i386_index_check (const char *operand_string)
     {
       /* Memory operands of string insns are special in that they only allow
         a single register (rDI, rSI, or rBX) as their memory address.  */
     {
       /* Memory operands of string insns are special in that they only allow
         a single register (rDI, rSI, or rBX) as their memory address.  */
-      unsigned int expected;
+      const reg_entry *expected_reg;
+      static const char *di_si[][2] =
+       {
+         { "esi", "edi" },
+         { "si", "di" },
+         { "rsi", "rdi" }
+       };
+      static const char *bx[] = { "ebx", "bx", "rbx" };
 
       kind = "string address";
 
 
       kind = "string address";
 
@@ -7070,75 +7525,70 @@ i386_index_check (const char *operand_string)
                  && current_templates->end[-1].operand_types[1]
                     .bitfield.baseindex))
            type = current_templates->end[-1].operand_types[1];
                  && current_templates->end[-1].operand_types[1]
                     .bitfield.baseindex))
            type = current_templates->end[-1].operand_types[1];
-         expected = type.bitfield.esseg ? 7 /* rDI */ : 6 /* rSI */;
+         expected_reg = hash_find (reg_hash,
+                                   di_si[addr_mode][type.bitfield.esseg]);
+
        }
       else
        }
       else
-       expected = 3 /* rBX */;
+       expected_reg = hash_find (reg_hash, bx[addr_mode]);
 
 
-      if (!i.base_reg || i.index_reg
+      if (i.base_reg != expected_reg
+         || i.index_reg
          || operand_type_check (i.types[this_operand], disp))
          || operand_type_check (i.types[this_operand], disp))
-       ok = -1;
-      else if (!(flag_code == CODE_64BIT
-                ? i.prefix[ADDR_PREFIX]
-                  ? i.base_reg->reg_type.bitfield.reg32
-                  : i.base_reg->reg_type.bitfield.reg64
-                : (flag_code == CODE_16BIT) ^ !i.prefix[ADDR_PREFIX]
-                  ? i.base_reg->reg_type.bitfield.reg32
-                  : i.base_reg->reg_type.bitfield.reg16))
-       ok = 0;
-      else if (i.base_reg->reg_num != expected)
-       ok = -1;
-
-      if (ok < 0)
-       {
-         unsigned int j;
-
-         for (j = 0; j < i386_regtab_size; ++j)
-           if ((flag_code == CODE_64BIT
-                ? i.prefix[ADDR_PREFIX]
-                  ? i386_regtab[j].reg_type.bitfield.reg32
-                  : i386_regtab[j].reg_type.bitfield.reg64
-                : (flag_code == CODE_16BIT) ^ !i.prefix[ADDR_PREFIX]
-                  ? i386_regtab[j].reg_type.bitfield.reg32
-                  : i386_regtab[j].reg_type.bitfield.reg16)
-               && i386_regtab[j].reg_num == expected)
-             break;
-         gas_assert (j < i386_regtab_size);
+       {
+         /* The second memory operand must have the same size as
+            the first one.  */
+         if (i.mem_operands
+             && i.base_reg
+             && !((addr_mode == CODE_64BIT
+                   && i.base_reg->reg_type.bitfield.reg64)
+                  || (addr_mode == CODE_32BIT
+                      ? i.base_reg->reg_type.bitfield.reg32
+                      : i.base_reg->reg_type.bitfield.reg16)))
+           goto bad_address;
+
          as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"),
                   operand_string,
                   intel_syntax ? '[' : '(',
                   register_prefix,
          as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"),
                   operand_string,
                   intel_syntax ? '[' : '(',
                   register_prefix,
-                  i386_regtab[j].reg_name,
+                  expected_reg->reg_name,
                   intel_syntax ? ']' : ')');
                   intel_syntax ? ']' : ')');
-         ok = 1;
-       }
-    }
-  else if (flag_code == CODE_64BIT)
-    {
-      if ((i.base_reg
-          && ((i.prefix[ADDR_PREFIX] == 0
-               && !i.base_reg->reg_type.bitfield.reg64)
-              || (i.prefix[ADDR_PREFIX]
-                  && !i.base_reg->reg_type.bitfield.reg32))
-          && (i.index_reg
-              || i.base_reg->reg_num !=
-                 (i.prefix[ADDR_PREFIX] == 0 ? RegRip : RegEip)))
-         || (i.index_reg
-             && (!i.index_reg->reg_type.bitfield.baseindex
-                 || (i.prefix[ADDR_PREFIX] == 0
-                     && i.index_reg->reg_num != RegRiz
-                     && !i.index_reg->reg_type.bitfield.reg64
-                     )
-                 || (i.prefix[ADDR_PREFIX]
-                     && i.index_reg->reg_num != RegEiz
-                     && !i.index_reg->reg_type.bitfield.reg32))))
-       ok = 0;
+         return 1;
+       }
+      else
+       return 1;
+
+bad_address:
+      as_bad (_("`%s' is not a valid %s expression"),
+             operand_string, kind);
+      return 0;
     }
   else
     {
     }
   else
     {
-      if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
+      if (addr_mode != CODE_16BIT)
        {
        {
-         /* 16bit checks.  */
+         /* 32-bit/64-bit checks.  */
+         if ((i.base_reg
+              && (addr_mode == CODE_64BIT
+                  ? !i.base_reg->reg_type.bitfield.reg64
+                  : !i.base_reg->reg_type.bitfield.reg32)
+              && (i.index_reg
+                  || (i.base_reg->reg_num
+                      != (addr_mode == CODE_64BIT ? RegRip : RegEip))))
+             || (i.index_reg
+                 && !i.index_reg->reg_type.bitfield.regxmm
+                 && !i.index_reg->reg_type.bitfield.regymm
+                 && ((addr_mode == CODE_64BIT
+                      ? !(i.index_reg->reg_type.bitfield.reg64
+                          || i.index_reg->reg_num == RegRiz)
+                      : !(i.index_reg->reg_type.bitfield.reg32
+                          || i.index_reg->reg_num == RegEiz))
+                     || !i.index_reg->reg_type.bitfield.baseindex)))
+           goto bad_address;
+       }
+      else
+       {
+         /* 16-bit checks.  */
          if ((i.base_reg
               && (!i.base_reg->reg_type.bitfield.reg16
                   || !i.base_reg->reg_type.bitfield.baseindex))
          if ((i.base_reg
               && (!i.base_reg->reg_type.bitfield.reg16
                   || !i.base_reg->reg_type.bitfield.baseindex))
@@ -7149,56 +7599,10 @@ i386_index_check (const char *operand_string)
                           && i.base_reg->reg_num < 6
                           && i.index_reg->reg_num >= 6
                           && i.log2_scale_factor == 0))))
                           && i.base_reg->reg_num < 6
                           && i.index_reg->reg_num >= 6
                           && i.log2_scale_factor == 0))))
-           ok = 0;
-       }
-      else
-       {
-         /* 32bit checks.  */
-         if ((i.base_reg
-              && !i.base_reg->reg_type.bitfield.reg32)
-             || (i.index_reg
-                 && ((!i.index_reg->reg_type.bitfield.reg32
-                      && i.index_reg->reg_num != RegEiz)
-                     || !i.index_reg->reg_type.bitfield.baseindex)))
-           ok = 0;
+           goto bad_address;
        }
     }
        }
     }
-  if (!ok)
-    {
-#if INFER_ADDR_PREFIX
-      if (!i.mem_operands && !i.prefix[ADDR_PREFIX])
-       {
-         i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
-         i.prefixes += 1;
-         /* Change the size of any displacement too.  At most one of
-            Disp16 or Disp32 is set.
-            FIXME.  There doesn't seem to be any real need for separate
-            Disp16 and Disp32 flags.  The same goes for Imm16 and Imm32.
-            Removing them would probably clean up the code quite a lot.  */
-         if (flag_code != CODE_64BIT
-             && (i.types[this_operand].bitfield.disp16
-                 || i.types[this_operand].bitfield.disp32))
-           i.types[this_operand]
-             = operand_type_xor (i.types[this_operand], disp16_32);
-         fudged = 1;
-         goto tryprefix;
-       }
-      if (fudged)
-       as_bad (_("`%s' is not a valid %s expression"),
-               operand_string,
-               kind);
-      else
-#endif
-       as_bad (_("`%s' is not a valid %s-bit %s expression"),
-               operand_string,
-               flag_code_names[i.prefix[ADDR_PREFIX]
-                                        ? flag_code == CODE_32BIT
-                                          ? CODE_16BIT
-                                          : CODE_32BIT
-                                        : flag_code],
-               kind);
-    }
-  return ok;
+  return 1;
 }
 
 /* Parse OPERAND_STRING into the i386_insn structure I.  Returns zero
 }
 
 /* Parse OPERAND_STRING into the i386_insn structure I.  Returns zero
@@ -7414,6 +7818,9 @@ i386_att_operand (char *operand_string)
                    }
                  else if (*base_string == REGISTER_PREFIX)
                    {
                    }
                  else if (*base_string == REGISTER_PREFIX)
                    {
+                     end_op = strchr (base_string, ',');
+                     if (end_op)
+                       *end_op = '\0';
                      as_bad (_("bad register name `%s'"), base_string);
                      return 0;
                    }
                      as_bad (_("bad register name `%s'"), base_string);
                      return 0;
                    }
@@ -7455,6 +7862,9 @@ i386_att_operand (char *operand_string)
            }
          else if (*base_string == REGISTER_PREFIX)
            {
            }
          else if (*base_string == REGISTER_PREFIX)
            {
+             end_op = strchr (base_string, ',');
+             if (end_op)
+               *end_op = '\0';
              as_bad (_("bad register name `%s'"), base_string);
              return 0;
            }
              as_bad (_("bad register name `%s'"), base_string);
              return 0;
            }
@@ -7500,6 +7910,18 @@ i386_att_operand (char *operand_string)
   return 1;                    /* Normal return.  */
 }
 \f
   return 1;                    /* Normal return.  */
 }
 \f
+/* Calculate the maximum variable size (i.e., excluding fr_fix)
+   that an rs_machine_dependent frag may reach.  */
+
+unsigned int
+i386_frag_max_var (fragS *frag)
+{
+  /* The only relaxable frags are for jumps.
+     Unconditional jumps can grow by 4 bytes and others by 5 bytes.  */
+  gas_assert (frag->fr_type == rs_machine_dependent);
+  return TYPE_FROM_RELAX_STATE (frag->fr_subtype) == UNCOND_JUMP ? 4 : 5;
+}
+
 /* md_estimate_size_before_relax()
 
    Called just before relax() for rs_machine_dependent frags.  The x86
 /* md_estimate_size_before_relax()
 
    Called just before relax() for rs_machine_dependent frags.  The x86
@@ -7514,9 +7936,7 @@ i386_att_operand (char *operand_string)
    returned value.  */
 
 int
    returned value.  */
 
 int
-md_estimate_size_before_relax (fragP, segment)
-     fragS *fragP;
-     segT segment;
+md_estimate_size_before_relax (fragS *fragP, segT segment)
 {
   /* We've already got fragP->fr_subtype right;  all we have to do is
      check for un-relaxable symbols.  On an ELF system, we can't relax
 {
   /* We've already got fragP->fr_subtype right;  all we have to do is
      check for un-relaxable symbols.  On an ELF system, we can't relax
@@ -7639,10 +8059,8 @@ md_estimate_size_before_relax (fragP, segment)
        Caller will turn frag into a ".space 0".  */
 
 void
        Caller will turn frag into a ".space 0".  */
 
 void
-md_convert_frag (abfd, sec, fragP)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     segT sec ATTRIBUTE_UNUSED;
-     fragS *fragP;
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
+                 fragS *fragP)
 {
   unsigned char *opcode;
   unsigned char *where_to_put_displacement = NULL;
 {
   unsigned char *opcode;
   unsigned char *where_to_put_displacement = NULL;
@@ -7739,21 +8157,17 @@ md_convert_frag (abfd, sec, fragP)
   fragP->fr_fix += extension;
 }
 \f
   fragP->fr_fix += extension;
 }
 \f
-/* Apply a fixup (fixS) to segment data, once it has been determined
+/* Apply a fixup (fixP) to segment data, once it has been determined
    by our caller that we have all the info we need to fix it up.
 
    by our caller that we have all the info we need to fix it up.
 
+   Parameter valP is the pointer to the value of the bits.
+
    On the 386, immediates, displacements, and data pointers are all in
    the same (little-endian) format, so we don't need to care about which
    we are handling.  */
 
 void
    On the 386, immediates, displacements, and data pointers are all in
    the same (little-endian) format, so we don't need to care about which
    we are handling.  */
 
 void
-md_apply_fix (fixP, valP, seg)
-     /* The fix we're to put in.  */
-     fixS *fixP;
-     /* Pointer to the value of the bits.  */
-     valueT *valP;
-     /* Segment fix is from.  */
-     segT seg ATTRIBUTE_UNUSED;
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
   valueT value = *valP;
 {
   char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
   valueT value = *valP;
@@ -8165,14 +8579,16 @@ const char *md_shortopts = "qn";
 #define OPTION_MOLD_GCC (OPTION_MD_BASE + 9)
 #define OPTION_MSSE2AVX (OPTION_MD_BASE + 10)
 #define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11)
 #define OPTION_MOLD_GCC (OPTION_MD_BASE + 9)
 #define OPTION_MSSE2AVX (OPTION_MD_BASE + 10)
 #define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11)
-#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 12)
-#define OPTION_X32 (OPTION_MD_BASE + 13)
+#define OPTION_MOPERAND_CHECK (OPTION_MD_BASE + 12)
+#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 13)
+#define OPTION_X32 (OPTION_MD_BASE + 14)
+#define OPTION_MADD_BND_PREFIX (OPTION_MD_BASE + 15)
 
 struct option md_longopts[] =
 {
   {"32", no_argument, NULL, OPTION_32},
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
 
 struct option md_longopts[] =
 {
   {"32", no_argument, NULL, OPTION_32},
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
-     || defined (TE_PE) || defined (TE_PEP))
+     || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
   {"64", no_argument, NULL, OPTION_64},
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"64", no_argument, NULL, OPTION_64},
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
@@ -8188,7 +8604,9 @@ struct option md_longopts[] =
   {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
   {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
   {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
   {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
   {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
   {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
+  {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK},
   {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR},
   {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR},
+  {"madd-bnd-prefix", no_argument, NULL, OPTION_MADD_BND_PREFIX},
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
@@ -8230,7 +8648,7 @@ md_parse_option (int c, char *arg)
       break;
 #endif
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
       break;
 #endif
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
-     || defined (TE_PE) || defined (TE_PEP))
+     || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
     case OPTION_64:
       {
        const char **list, **l;
     case OPTION_64:
       {
        const char **list, **l;
@@ -8240,7 +8658,8 @@ md_parse_option (int c, char *arg)
          if (CONST_STRNEQ (*l, "elf64-x86-64")
              || strcmp (*l, "coff-x86-64") == 0
              || strcmp (*l, "pe-x86-64") == 0
          if (CONST_STRNEQ (*l, "elf64-x86-64")
              || strcmp (*l, "coff-x86-64") == 0
              || strcmp (*l, "pe-x86-64") == 0
-             || strcmp (*l, "pei-x86-64") == 0)
+             || strcmp (*l, "pei-x86-64") == 0
+             || strcmp (*l, "mach-o-x86-64") == 0)
            {
              default_arch = "x86_64";
              break;
            {
              default_arch = "x86_64";
              break;
@@ -8416,15 +8835,26 @@ md_parse_option (int c, char *arg)
 
     case OPTION_MSSE_CHECK:
       if (strcasecmp (arg, "error") == 0)
 
     case OPTION_MSSE_CHECK:
       if (strcasecmp (arg, "error") == 0)
-       sse_check = sse_check_error;
+       sse_check = check_error;
       else if (strcasecmp (arg, "warning") == 0)
       else if (strcasecmp (arg, "warning") == 0)
-       sse_check = sse_check_warning;
+       sse_check = check_warning;
       else if (strcasecmp (arg, "none") == 0)
       else if (strcasecmp (arg, "none") == 0)
-       sse_check = sse_check_none;
+       sse_check = check_none;
       else
        as_fatal (_("invalid -msse-check= option: `%s'"), arg);
       break;
 
       else
        as_fatal (_("invalid -msse-check= option: `%s'"), arg);
       break;
 
+    case OPTION_MOPERAND_CHECK:
+      if (strcasecmp (arg, "error") == 0)
+       operand_check = check_error;
+      else if (strcasecmp (arg, "warning") == 0)
+       operand_check = check_warning;
+      else if (strcasecmp (arg, "none") == 0)
+       operand_check = check_none;
+      else
+       as_fatal (_("invalid -moperand-check= option: `%s'"), arg);
+      break;
+
     case OPTION_MAVXSCALAR:
       if (strcasecmp (arg, "128") == 0)
        avxscalar = vex128;
     case OPTION_MAVXSCALAR:
       if (strcasecmp (arg, "128") == 0)
        avxscalar = vex128;
@@ -8434,6 +8864,10 @@ md_parse_option (int c, char *arg)
        as_fatal (_("invalid -mavxscalar= option: `%s'"), arg);
       break;
 
        as_fatal (_("invalid -mavxscalar= option: `%s'"), arg);
       break;
 
+    case OPTION_MADD_BND_PREFIX:
+      add_bnd_prefix = 1;
+      break;
+
     default:
       return 0;
     }
     default:
       return 0;
     }
@@ -8508,7 +8942,7 @@ show_arch (FILE *stream, int ext, int check)
          fprintf (stream, "%s\n", message);
          p = start;
          left = size - (start - message) - len - 2;
          fprintf (stream, "%s\n", message);
          p = start;
          left = size - (start - message) - len - 2;
-         
+
          gas_assert (left >= 0);
 
          p = mempcpy (p, name, len);
          gas_assert (left >= 0);
 
          p = mempcpy (p, name, len);
@@ -8563,6 +8997,9 @@ md_show_usage (FILE *stream)
   -msse-check=[none|error|warning]\n\
                           check SSE instructions\n"));
   fprintf (stream, _("\
   -msse-check=[none|error|warning]\n\
                           check SSE instructions\n"));
   fprintf (stream, _("\
+  -moperand-check=[none|error|warning]\n\
+                          check operand combinations for validity\n"));
+  fprintf (stream, _("\
   -mavxscalar=[128|256]   encode scalar AVX instructions with specific vector\n\
                            length\n"));
   fprintf (stream, _("\
   -mavxscalar=[128|256]   encode scalar AVX instructions with specific vector\n\
                            length\n"));
   fprintf (stream, _("\
@@ -8575,6 +9012,8 @@ md_show_usage (FILE *stream)
   -mnaked-reg             don't require `%%' prefix for registers\n"));
   fprintf (stream, _("\
   -mold-gcc               support old (<= 2.8.1) versions of gcc\n"));
   -mnaked-reg             don't require `%%' prefix for registers\n"));
   fprintf (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 (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
 }
 
 #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
@@ -8650,13 +9089,26 @@ i386_target_format (void)
              as_fatal (_("Intel L1OM is 64bit only"));
            return ELF_TARGET_L1OM_FORMAT;
          }
              as_fatal (_("Intel L1OM is 64bit only"));
            return ELF_TARGET_L1OM_FORMAT;
          }
+       if (cpu_arch_isa == PROCESSOR_K1OM)
+         {
+           if (x86_elf_abi != X86_64_ABI)
+             as_fatal (_("Intel K1OM is 64bit only"));
+           return ELF_TARGET_K1OM_FORMAT;
+         }
        else
          return format;
       }
 #endif
 #if defined (OBJ_MACH_O)
     case bfd_target_mach_o_flavour:
        else
          return format;
       }
 #endif
 #if defined (OBJ_MACH_O)
     case bfd_target_mach_o_flavour:
-      return flag_code == CODE_64BIT ? "mach-o-x86-64" : "mach-o-i386";
+      if (flag_code == CODE_64BIT)
+       {
+         use_rela_relocations = 1;
+         object_64bit = 1;
+         return "mach-o-x86-64";
+       }
+      else
+       return "mach-o-i386";
 #endif
     default:
       abort ();
 #endif
     default:
       abort ();
@@ -8709,8 +9161,7 @@ i386_elf_emit_arch_note (void)
 #endif
 \f
 symbolS *
 #endif
 \f
 symbolS *
-md_undefined_symbol (name)
-     char *name;
+md_undefined_symbol (char *name)
 {
   if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0]
       && name[1] == GLOBAL_OFFSET_TABLE_NAME[1]
 {
   if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0]
       && name[1] == GLOBAL_OFFSET_TABLE_NAME[1]
@@ -8732,9 +9183,7 @@ md_undefined_symbol (name)
 /* Round up a section size to the appropriate boundary.  */
 
 valueT
 /* Round up a section size to the appropriate boundary.  */
 
 valueT
-md_section_align (segment, size)
-     segT segment ATTRIBUTE_UNUSED;
-     valueT size;
+md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
 {
 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
   if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
 {
 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
   if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
@@ -8805,15 +9254,33 @@ i386_validate_fix (fixS *fixp)
 }
 
 arelent *
 }
 
 arelent *
-tc_gen_reloc (section, fixp)
-     asection *section ATTRIBUTE_UNUSED;
-     fixS *fixp;
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 {
   arelent *rel;
   bfd_reloc_code_real_type code;
 
   switch (fixp->fx_r_type)
     {
 {
   arelent *rel;
   bfd_reloc_code_real_type code;
 
   switch (fixp->fx_r_type)
     {
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+    case BFD_RELOC_SIZE32:
+    case BFD_RELOC_SIZE64:
+      if (S_IS_DEFINED (fixp->fx_addsy)
+         && !S_IS_EXTERNAL (fixp->fx_addsy))
+       {
+         /* Resolve size relocation against local symbol to size of
+            the symbol plus addend.  */
+         valueT value = S_GET_SIZE (fixp->fx_addsy) + fixp->fx_offset;
+         if (fixp->fx_r_type == BFD_RELOC_SIZE32
+             && !fits_in_unsigned_long (value))
+           as_bad_where (fixp->fx_file, fixp->fx_line,
+                         _("symbol size computation overflow"));
+         fixp->fx_addsy = NULL;
+         fixp->fx_subsy = NULL;
+         md_apply_fix (fixp, (valueT *) &value, NULL);
+         return NULL;
+       }
+#endif
+
     case BFD_RELOC_X86_64_PLT32:
     case BFD_RELOC_X86_64_GOT32:
     case BFD_RELOC_X86_64_GOTPCREL:
     case BFD_RELOC_X86_64_PLT32:
     case BFD_RELOC_X86_64_GOT32:
     case BFD_RELOC_X86_64_GOTPCREL:
@@ -8945,7 +9412,6 @@ tc_gen_reloc (section, fixp)
       if (disallow_64bit_reloc)
        switch (code)
          {
       if (disallow_64bit_reloc)
        switch (code)
          {
-         case BFD_RELOC_64:
          case BFD_RELOC_X86_64_DTPOFF64:
          case BFD_RELOC_X86_64_TPOFF64:
          case BFD_RELOC_64_PCREL:
          case BFD_RELOC_X86_64_DTPOFF64:
          case BFD_RELOC_X86_64_TPOFF64:
          case BFD_RELOC_64_PCREL:
@@ -9054,6 +9520,16 @@ tc_x86_frame_initial_instructions (void)
   cfi_add_CFA_offset (x86_dwarf2_return_column, x86_cie_data_alignment);
 }
 
   cfi_add_CFA_offset (x86_dwarf2_return_column, x86_cie_data_alignment);
 }
 
+int
+x86_dwarf2_addr_size (void)
+{
+#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
+  if (x86_elf_abi == X86_64_X32_ABI)
+    return 4;
+#endif
+  return bfd_arch_bits_per_address (stdoutput) / 8;
+}
+
 int
 i386_elf_section_type (const char *str, size_t len)
 {
 int
 i386_elf_section_type (const char *str, size_t len)
 {
@@ -9153,50 +9629,4 @@ handle_large_common (int small ATTRIBUTE_UNUSED)
       bss_section = saved_bss_section;
     }
 }
       bss_section = saved_bss_section;
     }
 }
-
-static void
-handle_quad (int nbytes)
-{
-  expressionS exp;
-
-  if (x86_elf_abi != X86_64_X32_ABI)
-    {
-      cons (nbytes);
-      return;
-    }
-
-  if (is_it_end_of_statement ())
-    {
-      demand_empty_rest_of_line ();
-      return;
-    }
-
-  do
-    {
-      if (*input_line_pointer == '"')
-       {
-         as_bad (_("unexpected `\"' in expression"));
-         ignore_rest_of_line ();
-         return;
-       }
-      x86_cons (&exp, nbytes);
-      /* Output 4 bytes if not constant.  */
-      if (exp.X_op != O_constant)
-       nbytes = 4;
-      emit_expr (&exp, (unsigned int) nbytes);
-      /* Zero-extends to 8 bytes if not constant.  */
-      if (nbytes == 4)
-       {
-         memset (&exp, '\0', sizeof (exp));
-         exp.X_op = O_constant;
-         emit_expr (&exp, nbytes);
-       }
-      nbytes = 8;
-    }
-  while (*input_line_pointer++ == ',');
-
-  input_line_pointer--;                /* Put terminator back into stream.  */
-
-  demand_empty_rest_of_line ();
-}
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
This page took 0.06554 seconds and 4 git commands to generate.