bfd/
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index cc5b200e2c0cb19151eb4e17e3bb2960471c32f5..c90cadca4c5bdf916c382a29105e05b8eff66dc3 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -81,6 +81,7 @@
 #define LONG_MNEM_SUFFIX  'l'
 #define QWORD_MNEM_SUFFIX  'q'
 #define XMMWORD_MNEM_SUFFIX  'x'
+#define YMMWORD_MNEM_SUFFIX 'y'
 /* Intel Syntax.  Use a non-ascii letter since since it never appears
    in instructions.  */
 #define LONG_DOUBLE_MNEM_SUFFIX '\1'
@@ -113,33 +114,6 @@ modrm_byte;
 /* x86-64 extension prefix.  */
 typedef int rex_byte;
 
-/* The SSE5 instructions have a two bit instruction modifier (OC) that 
-   is stored in two separate bytes in the instruction.  Pick apart OC 
-   into the 2 separate bits for instruction.  */
-#define DREX_OC0(x)    (((x) & 1) != 0)
-#define DREX_OC1(x)    (((x) & 2) != 0)
-
-#define DREX_OC0_MASK  (1 << 3)        /* set OC0 in byte 4 */
-#define DREX_OC1_MASK  (1 << 2)        /* set OC1 in byte 3 */
-
-/* OC mappings */
-#define DREX_XMEM_X1_X2_X2 0   /* 4 op insn, dest = src3, src1 = reg/mem */
-#define DREX_X1_XMEM_X2_X2 1   /* 4 op insn, dest = src3, src2 = reg/mem */
-#define DREX_X1_XMEM_X2_X1 2   /* 4 op insn, dest = src1, src2 = reg/mem */
-#define DREX_X1_X2_XMEM_X1 3   /* 4 op insn, dest = src1, src3 = reg/mem */
-
-#define DREX_XMEM_X1_X2           0    /* 3 op insn, src1 = reg/mem */
-#define DREX_X1_XMEM_X2           1    /* 3 op insn, src1 = reg/mem */
-
-/* Information needed to create the DREX byte in SSE5 instructions.  */
-typedef struct
-{
-  unsigned int reg;            /* register */
-  unsigned int rex;            /* REX flags */
-  unsigned int modrm_reg;      /* which arg goes in the modrm.reg field */
-  unsigned int modrm_regmem;   /* which arg goes in the modrm.regmem field */
-} drex_byte;
-
 /* 386 opcode byte to code indirect addressing.  */
 typedef struct
 {
@@ -149,25 +123,6 @@ typedef struct
 }
 sib_byte;
 
-enum processor_type
-{
-  PROCESSOR_UNKNOWN,
-  PROCESSOR_I386,
-  PROCESSOR_I486,
-  PROCESSOR_PENTIUM,
-  PROCESSOR_PENTIUMPRO,
-  PROCESSOR_PENTIUM4,
-  PROCESSOR_NOCONA,
-  PROCESSOR_CORE,
-  PROCESSOR_CORE2,
-  PROCESSOR_K6,
-  PROCESSOR_ATHLON,
-  PROCESSOR_K8,
-  PROCESSOR_GENERIC32,
-  PROCESSOR_GENERIC64,
-  PROCESSOR_AMDFAM10
-};
-
 /* x86 arch names, types and features */
 typedef struct
 {
@@ -182,14 +137,21 @@ 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_sse_check (int);
 static void set_cpu_arch (int);
 #ifdef TE_PE
 static void pe_directive_secrel (int);
 #endif
 static void signed_cons (int);
 static char *output_invalid (int c);
+static int i386_finalize_immediate (segT, expressionS *, i386_operand_type,
+                                   const char *);
+static int i386_finalize_displacement (segT, expressionS *, i386_operand_type,
+                                      const char *);
 static int i386_att_operand (char *);
 static int i386_intel_operand (char *, int);
+static int i386_intel_simplify (expressionS *);
+static int i386_intel_parse_name (const char *, expressionS *);
 static const reg_entry *parse_register (char *, char **);
 static char *parse_insn (char *, char *);
 static char *parse_operands (char *, const char *);
@@ -197,7 +159,7 @@ static void swap_operands (void);
 static void swap_2_operands (int, int);
 static void optimize_imm (void);
 static void optimize_disp (void);
-static int match_template (void);
+static const template *match_template (void);
 static int check_string (void);
 static int process_suffix (void);
 static int check_byte_reg (void);
@@ -205,7 +167,6 @@ static int check_long_reg (void);
 static int check_qword_reg (void);
 static int check_word_reg (void);
 static int finalize_imm (void);
-static void process_drex (void);
 static int process_operands (void);
 static const seg_entry *build_modrm_byte (void);
 static void output_insn (void);
@@ -220,6 +181,16 @@ static void handle_large_common (int small ATTRIBUTE_UNUSED);
 
 static const char *default_arch = DEFAULT_ARCH;
 
+/* VEX prefix.  */
+typedef struct
+{
+  /* VEX prefix is either 2 byte or 3 byte.  */
+  unsigned char bytes[3];
+  unsigned int length;
+  /* Destination or source register specifier.  */
+  const reg_entry *register_specifier;
+} vex_prefix;
+
 /* 'md_assemble ()' gathers together information and puts it into a
    i386_insn.  */
 
@@ -278,13 +249,14 @@ struct _i386_insn
     unsigned char prefix[MAX_PREFIXES];
 
     /* RM and SIB are the modrm byte and the sib byte where the
-       addressing modes of this insn are encoded.  DREX is the byte
-       added by the SSE5 instructions.  */
-
+       addressing modes of this insn are encoded.  */
     modrm_byte rm;
     rex_byte rex;
     sib_byte sib;
-    drex_byte drex;
+    vex_prefix vex;
+
+    /* Swap operand in encoding.  */
+    unsigned int swap_operand : 1;
   };
 
 typedef struct _i386_insn i386_insn;
@@ -380,7 +352,7 @@ static expressionS disp_expressions[MAX_MEMORY_OPERANDS];
 static expressionS im_expressions[MAX_IMMEDIATE_OPERANDS];
 
 /* Current operand we are working on.  */
-static int this_operand;
+static int this_operand = -1;
 
 /* We support four different modes.  FLAG_CODE variable is used to distinguish
    these.  */
@@ -422,6 +394,14 @@ static int allow_naked_reg = 0;
 /* 1 if pseudo index register, eiz/riz, is allowed .  */
 static int allow_index_reg = 0;
 
+static enum
+  {
+    sse_check_none = 0,
+    sse_check_warning,
+    sse_check_error
+  }
+sse_check;
+
 /* Register prefix used for error message.  */
 static const char *register_prefix = "%";
 
@@ -447,21 +427,24 @@ static i386_cpu_flags cpu_arch_flags = CPU_UNKNOWN_FLAGS;
 static int cpu_arch_tune_set = 0;
 
 /* Cpu we are generating instructions for.  */
-static enum processor_type cpu_arch_tune = PROCESSOR_UNKNOWN;
+enum processor_type cpu_arch_tune = PROCESSOR_UNKNOWN;
 
 /* CPU feature flags of cpu we are generating instructions for.  */
 static i386_cpu_flags cpu_arch_tune_flags;
 
 /* CPU instruction set architecture used.  */
-static enum processor_type cpu_arch_isa = PROCESSOR_UNKNOWN;
+enum processor_type cpu_arch_isa = PROCESSOR_UNKNOWN;
 
 /* CPU feature flags of instruction set architecture used.  */
-static i386_cpu_flags cpu_arch_isa_flags;
+i386_cpu_flags cpu_arch_isa_flags;
 
 /* If set, conditional jumps are not automatically promoted to handle
    larger than a byte offset.  */
 static unsigned int no_cond_jump_promotion = 0;
 
+/* Encode SSE instructions with VEX prefix.  */
+static unsigned int sse2avx;
+
 /* Pre-defined "_GLOBAL_OFFSET_TABLE_".  */
 static symbolS *GOT_symbol;
 
@@ -592,6 +575,10 @@ static const arch_entry cpu_arch[] =
     CPU_CORE2_FLAGS },
   { "core2", PROCESSOR_CORE2,
     CPU_CORE2_FLAGS },
+  { "corei7", PROCESSOR_COREI7,
+    CPU_COREI7_FLAGS },
+  { "l1om", PROCESSOR_GENERIC64,
+    CPU_L1OM_FLAGS },
   { "k6", PROCESSOR_K6,
     CPU_K6_FLAGS },
   { "k6_2", PROCESSOR_K6,
@@ -606,8 +593,18 @@ static const arch_entry cpu_arch[] =
     CPU_K8_FLAGS },
   { "amdfam10", PROCESSOR_AMDFAM10,
     CPU_AMDFAM10_FLAGS },
+  { ".8087", PROCESSOR_UNKNOWN,
+    CPU_8087_FLAGS },
+  { ".287", PROCESSOR_UNKNOWN,
+    CPU_287_FLAGS },
+  { ".387", PROCESSOR_UNKNOWN,
+    CPU_387_FLAGS },
+  { ".no87", PROCESSOR_UNKNOWN,
+    CPU_ANY87_FLAGS },
   { ".mmx", PROCESSOR_UNKNOWN,
     CPU_MMX_FLAGS },
+  { ".nommx", PROCESSOR_UNKNOWN,
+    CPU_3DNOWA_FLAGS },
   { ".sse", PROCESSOR_UNKNOWN,
     CPU_SSE_FLAGS },
   { ".sse2", PROCESSOR_UNKNOWN,
@@ -622,12 +619,38 @@ static const arch_entry cpu_arch[] =
     CPU_SSE4_2_FLAGS },
   { ".sse4", PROCESSOR_UNKNOWN,
     CPU_SSE4_2_FLAGS },
+  { ".nosse", PROCESSOR_UNKNOWN,
+    CPU_ANY_SSE_FLAGS },
+  { ".avx", PROCESSOR_UNKNOWN,
+    CPU_AVX_FLAGS },
+  { ".noavx", PROCESSOR_UNKNOWN,
+    CPU_ANY_AVX_FLAGS },
   { ".vmx", PROCESSOR_UNKNOWN,
     CPU_VMX_FLAGS },
   { ".smx", PROCESSOR_UNKNOWN,
     CPU_SMX_FLAGS },
   { ".xsave", PROCESSOR_UNKNOWN,
     CPU_XSAVE_FLAGS },
+  { ".aes", PROCESSOR_UNKNOWN,
+    CPU_AES_FLAGS },
+  { ".pclmul", PROCESSOR_UNKNOWN,
+    CPU_PCLMUL_FLAGS },
+  { ".clmul", PROCESSOR_UNKNOWN,
+    CPU_PCLMUL_FLAGS },
+  { ".fma", PROCESSOR_UNKNOWN,
+    CPU_FMA_FLAGS },
+  { ".fma4", PROCESSOR_UNKNOWN,
+    CPU_FMA4_FLAGS },
+  { ".movbe", PROCESSOR_UNKNOWN,
+    CPU_MOVBE_FLAGS },
+  { ".ept", PROCESSOR_UNKNOWN,
+    CPU_EPT_FLAGS },
+  { ".clflush", PROCESSOR_UNKNOWN,
+    CPU_CLFLUSH_FLAGS },
+  { ".syscall", PROCESSOR_UNKNOWN,
+    CPU_SYSCALL_FLAGS },
+  { ".rdtscp", PROCESSOR_UNKNOWN,
+    CPU_RDTSCP_FLAGS },
   { ".3dnow", PROCESSOR_UNKNOWN,
     CPU_3DNOW_FLAGS },
   { ".3dnowa", PROCESSOR_UNKNOWN,
@@ -642,10 +665,50 @@ static const arch_entry cpu_arch[] =
     CPU_SSE4A_FLAGS },
   { ".abm", PROCESSOR_UNKNOWN,
     CPU_ABM_FLAGS },
-  { ".sse5", PROCESSOR_UNKNOWN,
-    CPU_SSE5_FLAGS },
 };
 
+#ifdef I386COFF
+/* Like s_lcomm_internal in gas/read.c but the alignment string
+   is allowed to be optional.  */
+
+static symbolS *
+pe_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
+{
+  addressT align = 0;
+
+  SKIP_WHITESPACE ();
+
+  if (needs_align
+      && *input_line_pointer == ',')
+    {
+      align = parse_align (needs_align - 1);
+
+      if (align == (addressT) -1)
+       return NULL;
+    }
+  else
+    {
+      if (size >= 8)
+       align = 3;
+      else if (size >= 4)
+       align = 2;
+      else if (size >= 2)
+       align = 1;
+      else
+       align = 0;
+    }
+
+  bss_alloc (symbolP, size, align);
+  return symbolP;
+}
+
+static void
+pe_lcomm (int needs_align)
+{
+  s_comm_internal (needs_align * 2, pe_lcomm_internal);
+}
+#endif
+
 const pseudo_typeS md_pseudo_table[] =
 {
 #if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO)
@@ -656,6 +719,8 @@ const pseudo_typeS md_pseudo_table[] =
   {"arch", set_cpu_arch, 0},
 #ifndef I386COFF
   {"bss", s_bss, 0},
+#else
+  {"lcomm", pe_lcomm, 1},
 #endif
   {"ffloat", float_cons, 'f'},
   {"dfloat", float_cons, 'd'},
@@ -674,6 +739,7 @@ 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},
+  {"sse_check", set_sse_check, 0},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
 #else
@@ -881,8 +947,8 @@ i386_align_code (fragS *fragP, int count)
      1. For PROCESSOR_I386, PROCESSOR_I486, PROCESSOR_PENTIUM and
      PROCESSOR_GENERIC32, f32_patt will be used.
      2. For PROCESSOR_PENTIUMPRO, PROCESSOR_PENTIUM4, PROCESSOR_NOCONA,
-     PROCESSOR_CORE, PROCESSOR_CORE2, and PROCESSOR_GENERIC64,
-     alt_long_patt will be used.
+     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, alt_short_patt will be used.
 
@@ -910,7 +976,7 @@ i386_align_code (fragS *fragP, int count)
     {
       const char *const *patt = NULL;
 
-      if (cpu_arch_isa == PROCESSOR_UNKNOWN)
+      if (fragP->tc_frag_data.isa == PROCESSOR_UNKNOWN)
        {
          /* PROCESSOR_UNKNOWN means that all ISAs may be used.  */
          switch (cpu_arch_tune)
@@ -918,7 +984,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_UNKNOWN:
              /* We use cpu_arch_isa_flags to check if we SHOULD
                 optimize for Cpu686.  */
-             if (cpu_arch_isa_flags.bitfield.cpui686)
+             if (fragP->tc_frag_data.isa_flags.bitfield.cpui686)
                patt = alt_long_patt;
              else
                patt = f32_patt;
@@ -928,6 +994,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_NOCONA:
            case PROCESSOR_CORE:
            case PROCESSOR_CORE2:
+           case PROCESSOR_COREI7:
            case PROCESSOR_GENERIC64:
              patt = alt_long_patt;
              break;
@@ -947,10 +1014,10 @@ i386_align_code (fragS *fragP, int count)
        }
       else
        {
-         switch (cpu_arch_tune)
+         switch (fragP->tc_frag_data.tune)
            {
            case PROCESSOR_UNKNOWN:
-             /* When cpu_arch_isa is net, cpu_arch_tune shouldn't be
+             /* When cpu_arch_isa is set, cpu_arch_tune shouldn't be
                 PROCESSOR_UNKNOWN.  */
              abort ();
              break;
@@ -965,7 +1032,7 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_GENERIC32:
              /* We use cpu_arch_isa_flags to check if we CAN optimize
                 for Cpu686.  */
-             if (cpu_arch_isa_flags.bitfield.cpui686)
+             if (fragP->tc_frag_data.isa_flags.bitfield.cpui686)
                patt = alt_short_patt;
              else
                patt = f32_patt;
@@ -975,7 +1042,8 @@ i386_align_code (fragS *fragP, int count)
            case PROCESSOR_NOCONA:
            case PROCESSOR_CORE:
            case PROCESSOR_CORE2:
-             if (cpu_arch_isa_flags.bitfield.cpui686)
+           case PROCESSOR_COREI7:
+             if (fragP->tc_frag_data.isa_flags.bitfield.cpui686)
                patt = alt_long_patt;
              else
                patt = f32_patt;
@@ -990,8 +1058,16 @@ i386_align_code (fragS *fragP, int count)
        {
          /* If the padding is less than 15 bytes, we use the normal
             ones.  Otherwise, we use a jump instruction and adjust
-            its offset.  */
-         if (count < 15)
+            its offset.   */
+         int limit;
+         
+         /* For 64bit, the limit is 3 bytes.  */
+         if (flag_code == CODE_64BIT
+             && fragP->tc_frag_data.isa_flags.bitfield.cpulm)
+           limit = 3;
+         else
+           limit = 15;
+         if (count < limit)
            memcpy (fragP->fr_literal + fragP->fr_fix,
                    patt[count - 1], count);
          else
@@ -1024,34 +1100,34 @@ i386_align_code (fragS *fragP, int count)
 }
 
 static INLINE int
-uints_all_zero (const unsigned int *x, unsigned int size)
+operand_type_all_zero (const union i386_operand_type *x)
 {
-  switch (size)
+  switch (ARRAY_SIZE(x->array))
     {
     case 3:
-      if (x[2])
+      if (x->array[2])
        return 0;
     case 2:
-      if (x[1])
+      if (x->array[1])
        return 0;
     case 1:
-      return !x[0];
+      return !x->array[0];
     default:
       abort ();
     }
 }
 
 static INLINE void
-uints_set (unsigned int *x, unsigned int v, unsigned int size)
+operand_type_set (union i386_operand_type *x, unsigned int v)
 {
-  switch (size)
+  switch (ARRAY_SIZE(x->array))
     {
     case 3:
-      x[2] = v;
+      x->array[2] = v;
     case 2:
-      x[1] = v;
+      x->array[1] = v;
     case 1:
-      x[0] = v;
+      x->array[0] = v;
       break;
     default:
       abort ();
@@ -1059,33 +1135,79 @@ uints_set (unsigned int *x, unsigned int v, unsigned int size)
 }
 
 static INLINE int
-uints_equal (const unsigned int *x, const unsigned int *y,
-            unsigned int size)
+operand_type_equal (const union i386_operand_type *x,
+                   const union i386_operand_type *y)
 {
-  switch (size)
+  switch (ARRAY_SIZE(x->array))
     {
     case 3:
-      if (x[2] != y [2])
+      if (x->array[2] != y->array[2])
        return 0;
     case 2:
-      if (x[1] != y [1])
+      if (x->array[1] != y->array[1])
        return 0;
     case 1:
-      return x[0] == y [0];
+      return x->array[0] == y->array[0];
+      break;
+    default:
+      abort ();
+    }
+}
+
+static INLINE int
+cpu_flags_all_zero (const union i386_cpu_flags *x)
+{
+  switch (ARRAY_SIZE(x->array))
+    {
+    case 3:
+      if (x->array[2])
+       return 0;
+    case 2:
+      if (x->array[1])
+       return 0;
+    case 1:
+      return !x->array[0];
+    default:
+      abort ();
+    }
+}
+
+static INLINE void
+cpu_flags_set (union i386_cpu_flags *x, unsigned int v)
+{
+  switch (ARRAY_SIZE(x->array))
+    {
+    case 3:
+      x->array[2] = v;
+    case 2:
+      x->array[1] = v;
+    case 1:
+      x->array[0] = v;
       break;
     default:
       abort ();
     }
 }
 
-#define UINTS_ALL_ZERO(x) \
-  uints_all_zero ((x).array, ARRAY_SIZE ((x).array))
-#define UINTS_SET(x, v) \
-  uints_set ((x).array, v, ARRAY_SIZE ((x).array))
-#define UINTS_CLEAR(x) \
-  uints_set ((x).array, 0, ARRAY_SIZE ((x).array))
-#define UINTS_EQUAL(x, y) \
-  uints_equal ((x).array, (y).array, ARRAY_SIZE ((x).array))
+static INLINE int
+cpu_flags_equal (const union i386_cpu_flags *x,
+                const union i386_cpu_flags *y)
+{
+  switch (ARRAY_SIZE(x->array))
+    {
+    case 3:
+      if (x->array[2] != y->array[2])
+       return 0;
+    case 2:
+      if (x->array[1] != y->array[1])
+       return 0;
+    case 1:
+      return x->array[0] == y->array[0];
+      break;
+    default:
+      abort ();
+    }
+}
 
 static INLINE int
 cpu_flags_check_cpu64 (i386_cpu_flags f)
@@ -1130,29 +1252,89 @@ cpu_flags_or (i386_cpu_flags x, i386_cpu_flags y)
   return x;
 }
 
-/* Return 3 if there is a perfect match, 2 if compatible with 64bit,
-   1 if compatible with arch, 0 if there is no match.  */
+static INLINE i386_cpu_flags
+cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y)
+{
+  switch (ARRAY_SIZE (x.array))
+    {
+    case 3:
+      x.array [2] &= ~y.array [2];
+    case 2:
+      x.array [1] &= ~y.array [1];
+    case 1:
+      x.array [0] &= ~y.array [0];
+      break;
+    default:
+      abort ();
+    }
+  return x;
+}
+
+#define CPU_FLAGS_ARCH_MATCH           0x1
+#define CPU_FLAGS_64BIT_MATCH          0x2
+#define CPU_FLAGS_AES_MATCH            0x4
+#define CPU_FLAGS_PCLMUL_MATCH         0x8
+#define CPU_FLAGS_AVX_MATCH           0x10
+
+#define CPU_FLAGS_32BIT_MATCH \
+  (CPU_FLAGS_ARCH_MATCH | CPU_FLAGS_AES_MATCH \
+   | CPU_FLAGS_PCLMUL_MATCH | CPU_FLAGS_AVX_MATCH)
+#define CPU_FLAGS_PERFECT_MATCH \
+  (CPU_FLAGS_32BIT_MATCH | CPU_FLAGS_64BIT_MATCH)
+
+/* Return CPU flags match bits. */
 
 static int
-cpu_flags_match (i386_cpu_flags x)
+cpu_flags_match (const template *t)
 {
-  int overlap = cpu_flags_check_cpu64 (x) ? 2 : 0;
+  i386_cpu_flags x = t->cpu_flags;
+  int match = cpu_flags_check_cpu64 (x) ? CPU_FLAGS_64BIT_MATCH : 0;
 
   x.bitfield.cpu64 = 0;
   x.bitfield.cpuno64 = 0;
 
-  if (UINTS_ALL_ZERO (x))
-    overlap |= 1;
+  if (cpu_flags_all_zero (&x))
+    {
+      /* This instruction is available on all archs.  */
+      match |= CPU_FLAGS_32BIT_MATCH;
+    }
   else
     {
+      /* This instruction is available only on some archs.  */
       i386_cpu_flags cpu = cpu_arch_flags;
 
       cpu.bitfield.cpu64 = 0;
       cpu.bitfield.cpuno64 = 0;
       cpu = cpu_flags_and (x, cpu);
-      overlap |= UINTS_ALL_ZERO (cpu) ? 0 : 1;
+      if (!cpu_flags_all_zero (&cpu))
+       {
+         if (x.bitfield.cpuavx)
+           {
+             /* We only need to check AES/PCLMUL/SSE2AVX with AVX.  */
+             if (cpu.bitfield.cpuavx)
+               {
+                 /* Check SSE2AVX.  */
+                 if (!t->opcode_modifier.sse2avx|| sse2avx)
+                   {
+                     match |= (CPU_FLAGS_ARCH_MATCH
+                               | CPU_FLAGS_AVX_MATCH);
+                     /* Check AES.  */
+                     if (!x.bitfield.cpuaes || cpu.bitfield.cpuaes)
+                       match |= CPU_FLAGS_AES_MATCH;
+                     /* Check PCLMUL.  */
+                     if (!x.bitfield.cpupclmul
+                         || cpu.bitfield.cpupclmul)
+                       match |= CPU_FLAGS_PCLMUL_MATCH;
+                   }
+               }
+             else
+               match |= CPU_FLAGS_ARCH_MATCH;
+           }
+         else
+           match |= CPU_FLAGS_32BIT_MATCH;
+       }
     }
-  return overlap;
+  return match;
 }
 
 static INLINE i386_operand_type
@@ -1212,6 +1394,8 @@ operand_type_xor (i386_operand_type x, i386_operand_type y)
 static const i386_operand_type acc32 = OPERAND_TYPE_ACC32;
 static const i386_operand_type acc64 = OPERAND_TYPE_ACC64;
 static const i386_operand_type control = OPERAND_TYPE_CONTROL;
+static const i386_operand_type inoutportreg
+  = OPERAND_TYPE_INOUTPORTREG;
 static const i386_operand_type reg16_inoutportreg
   = OPERAND_TYPE_REG16_INOUTPORTREG;
 static const i386_operand_type disp16 = OPERAND_TYPE_DISP16;
@@ -1221,6 +1405,7 @@ static const i386_operand_type disp16_32 = OPERAND_TYPE_DISP16_32;
 static const i386_operand_type anydisp
   = OPERAND_TYPE_ANYDISP;
 static const i386_operand_type regxmm = OPERAND_TYPE_REGXMM;
+static const i386_operand_type regymm = OPERAND_TYPE_REGYMM;
 static const i386_operand_type imm8 = OPERAND_TYPE_IMM8;
 static const i386_operand_type imm8s = OPERAND_TYPE_IMM8S;
 static const i386_operand_type imm16 = OPERAND_TYPE_IMM16;
@@ -1276,6 +1461,8 @@ operand_type_check (i386_operand_type t, enum operand_type c)
     default:
       abort ();
     }
+
+  return 0;
 }
 
 /* Return 1 if there is no conflict in 8bit/16bit/32bit/64bit on
@@ -1308,7 +1495,9 @@ match_mem_size (const template *t, unsigned int j)
               || (i.types[j].bitfield.tbyte
                   && !t->operand_types[j].bitfield.tbyte)
               || (i.types[j].bitfield.xmmword
-                  && !t->operand_types[j].bitfield.xmmword)));
+                  && !t->operand_types[j].bitfield.xmmword)
+              || (i.types[j].bitfield.ymmword
+                  && !t->operand_types[j].bitfield.ymmword)));
 }
 
 /* Return 1 if there is no size conflict on any operands for
@@ -1351,7 +1540,7 @@ operand_size_match (const template *t)
     return match;
 
   /* Check reverse.  */
-  assert (i.operands == 2);
+  gas_assert (i.operands == 2);
 
   match = 1;
   for (j = 0; j < 2; j++)
@@ -1389,7 +1578,8 @@ operand_type_match (i386_operand_type overlap,
   temp.bitfield.qword = 0;
   temp.bitfield.tbyte = 0;
   temp.bitfield.xmmword = 0;
-  if (UINTS_ALL_ZERO (temp))
+  temp.bitfield.ymmword = 0;
+  if (operand_type_all_zero (&temp))
     return 0;
 
   return (given.bitfield.baseindex == overlap.bitfield.baseindex
@@ -1504,8 +1694,8 @@ static i386_operand_type
 smallest_imm_type (offsetT num)
 {
   i386_operand_type t;
-  UINTS_CLEAR (t);
+
+  operand_type_set (&t, 0);
   t.bitfield.imm64 = 1;
 
   if (cpu_arch_tune != PROCESSOR_I486 && num == 1)
@@ -1722,6 +1912,8 @@ set_intel_syntax (int syntax_flag)
   else
     allow_naked_reg = (ask_naked_reg < 0);
 
+  expr_set_rank (O_full_ptr, syntax_flag ? 10 : 0);
+
   identifier_chars['%'] = intel_syntax && allow_naked_reg ? '%' : 0;
   identifier_chars['$'] = intel_syntax ? '$' : 0;
   register_prefix = allow_naked_reg ? "" : "%";
@@ -1739,6 +1931,61 @@ set_allow_index_reg (int flag)
   allow_index_reg = flag;
 }
 
+static void
+set_sse_check (int dummy ATTRIBUTE_UNUSED)
+{
+  SKIP_WHITESPACE ();
+
+  if (!is_end_of_line[(unsigned char) *input_line_pointer])
+    {
+      char *string = input_line_pointer;
+      int e = get_symbol_end ();
+
+      if (strcmp (string, "none") == 0)
+       sse_check = sse_check_none;
+      else if (strcmp (string, "warning") == 0)
+       sse_check = sse_check_warning;
+      else if (strcmp (string, "error") == 0)
+       sse_check = sse_check_error;
+      else
+       as_bad (_("bad argument to sse_check directive."));
+      *input_line_pointer = e;
+    }
+  else
+    as_bad (_("missing argument for sse_check directive"));
+
+  demand_empty_rest_of_line ();
+}
+
+static void
+check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED,
+                          i386_cpu_flags new ATTRIBUTE_UNUSED)
+{
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+  static const char *arch;
+
+  /* Intel LIOM is only supported on ELF.  */
+  if (!IS_ELF)
+    return;
+
+  if (!arch)
+    {
+      /* Use cpu_arch_name if it is set in md_parse_option.  Otherwise
+        use default_arch.  */
+      arch = cpu_arch_name;
+      if (!arch)
+       arch = default_arch;
+    }
+
+  /* If we are targeting Intel L1OM, wm must enable it.  */
+  if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_L1OM
+      || new.bitfield.cpul1om)
+    return;
+  
+  as_bad (_("`%s' is not supported on `%s'"), name, arch);
+#endif
+}
+
 static void
 set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
 {
@@ -1755,6 +2002,8 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
        {
          if (strcmp (string, cpu_arch[i].name) == 0)
            {
+             check_cpu_arch_compatible (string, cpu_arch[i].flags);
+
              if (*string != '.')
                {
                  cpu_arch_name = cpu_arch[i].name;
@@ -1780,9 +2029,13 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
                  break;
                }
 
-             flags = cpu_flags_or (cpu_arch_flags,
-                                   cpu_arch[i].flags);
-             if (!UINTS_EQUAL (flags, cpu_arch_flags))
+             if (strncmp (string + 1, "no", 2))
+               flags = cpu_flags_or (cpu_arch_flags,
+                                     cpu_arch[i].flags);
+             else
+               flags = cpu_flags_and_not (cpu_arch_flags,
+                                          cpu_arch[i].flags);
+             if (!cpu_flags_equal (&flags, &cpu_arch_flags))
                {
                  if (cpu_sub_arch_name)
                    {
@@ -1829,11 +2082,34 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
+enum bfd_architecture
+i386_arch (void)
+{
+  if (cpu_arch_isa_flags.bitfield.cpul1om)
+    {
+      if (OUTPUT_FLAVOR != bfd_target_elf_flavour
+         || flag_code != CODE_64BIT)
+       as_fatal (_("Intel L1OM is 64bit ELF only"));
+      return bfd_arch_l1om;
+    }
+  else
+    return bfd_arch_i386;
+}
+
 unsigned long
 i386_mach ()
 {
   if (!strcmp (default_arch, "x86_64"))
-    return bfd_mach_x86_64;
+    {
+      if (cpu_arch_isa_flags.bitfield.cpul1om)
+       {
+         if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+           as_fatal (_("Intel L1OM is 64bit ELF only"));
+         return bfd_mach_l1om;
+       }
+      else
+       return bfd_mach_x86_64;
+    }
   else if (!strcmp (default_arch, "i386"))
     return bfd_mach_i386_i386;
   else
@@ -1868,7 +2144,7 @@ md_begin ()
            core_optab->end = optab;
            hash_err = hash_insert (op_hash,
                                    (optab - 1)->name,
-                                   (PTR) core_optab);
+                                   (void *) core_optab);
            if (hash_err)
              {
                as_fatal (_("Internal Error:  Can't hash %s: %s"),
@@ -1891,7 +2167,7 @@ md_begin ()
 
     for (regtab = i386_regtab; regtab_size--; regtab++)
       {
-       hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab);
+       hash_err = hash_insert (reg_hash, regtab->reg_name, (void *) regtab);
        if (hash_err)
          as_fatal (_("Internal Error:  Can't hash %s: %s"),
                    regtab->reg_name,
@@ -1943,6 +2219,7 @@ md_begin ()
     operand_chars['?'] = '?';
 #endif
     digit_chars['-'] = '-';
+    mnemonic_chars['_'] = '_';
     mnemonic_chars['-'] = '-';
     mnemonic_chars['.'] = '.';
     identifier_chars['_'] = '_';
@@ -2008,8 +2285,6 @@ pi (char *line, i386_insn *x)
           (x->rex & REX_R) != 0,
           (x->rex & REX_X) != 0,
           (x->rex & REX_B) != 0);
-  fprintf (stdout, "  drex:  reg %d rex 0x%x\n", 
-          x->drex.reg, x->drex.rex);
   for (i = 0; i < x->operands; i++)
     {
       fprintf (stdout, "    #%d:  ", i + 1);
@@ -2021,6 +2296,7 @@ pi (char *line, i386_insn *x)
          || x->types[i].bitfield.reg64
          || x->types[i].bitfield.regmmx
          || x->types[i].bitfield.regxmm
+         || x->types[i].bitfield.regymm
          || x->types[i].bitfield.sreg2
          || x->types[i].bitfield.sreg3
          || x->types[i].bitfield.control
@@ -2121,6 +2397,7 @@ const type_names[] =
   { OPERAND_TYPE_JUMPABSOLUTE, "Jump Absolute" },
   { OPERAND_TYPE_REGMMX, "rMMX" },
   { OPERAND_TYPE_REGXMM, "rXMM" },
+  { OPERAND_TYPE_REGYMM, "rYMM" },
   { OPERAND_TYPE_ESSEG, "es" },
 };
 
@@ -2133,7 +2410,7 @@ pt (i386_operand_type t)
   for (j = 0; j < ARRAY_SIZE (type_names); j++)
     {
       a = operand_type_and (t, type_names[j].mask);
-      if (!UINTS_ALL_ZERO (a))
+      if (!operand_type_all_zero (&a))
        fprintf (stdout, "%s, ",  type_names[j].name);
     }
   fflush (stdout);
@@ -2231,8 +2508,7 @@ reloc (unsigned int size,
              sign > 0 ? "signed" : "unsigned", size);
     }
 
-  abort ();
-  return BFD_RELOC_NONE;
+  return NO_RELOC;
 }
 
 /* Here we decide which fixups can be adjusted to make them relative to
@@ -2290,6 +2566,10 @@ tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED)
       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
     return 0;
+
+  if (fixP->fx_addsy != NULL
+      && symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_GNU_INDIRECT_FUNCTION)
+    return 0;
 #endif
   return 1;
 }
@@ -2347,16 +2627,186 @@ intel_float_operand (const char *mnemonic)
   return 1;
 }
 
+/* Build the VEX prefix.  */
+
+static void
+build_vex_prefix (const template *t)
+{
+  unsigned int register_specifier;
+  unsigned int implied_prefix;
+  unsigned int vector_length;
+
+  /* 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;
+    }
+  else
+    register_specifier = 0xf;
+
+  /* Use 2-byte VEX prefix by swappping destination and source
+     operand.  */
+  if (!i.swap_operand
+      && i.operands == i.reg_operands
+      && i.tm.opcode_modifier.vex0f
+      && i.tm.opcode_modifier.s
+      && i.rex == REX_B)
+    {
+      unsigned int xchg = i.operands - 1;
+      union i386_op temp_op;
+      i386_operand_type temp_type;
+
+      temp_type = i.types[xchg];
+      i.types[xchg] = i.types[0];
+      i.types[0] = temp_type;
+      temp_op = i.op[xchg];
+      i.op[xchg] = i.op[0];
+      i.op[0] = temp_op;
+
+      gas_assert (i.rm.mode == 3);
+
+      i.rex = REX_R;
+      xchg = i.rm.regmem;
+      i.rm.regmem = i.rm.reg;
+      i.rm.reg = xchg;
+
+      /* Use the next insn.  */
+      i.tm = t[1];
+    }
+
+  vector_length = i.tm.opcode_modifier.vex256 ? 1 : 0;
+
+  switch ((i.tm.base_opcode >> 8) & 0xff)
+    {
+    case 0:
+      implied_prefix = 0;
+      break;
+    case DATA_PREFIX_OPCODE:
+      implied_prefix = 1;
+      break;
+    case REPE_PREFIX_OPCODE:
+      implied_prefix = 2;
+      break;
+    case REPNE_PREFIX_OPCODE:
+      implied_prefix = 3;
+      break;
+    default:
+      abort ();
+    }
+
+  /* Use 2-byte VEX prefix if possible.  */
+  if (i.tm.opcode_modifier.vex0f
+      && (i.rex & (REX_W | REX_X | REX_B)) == 0)
+    {
+      /* 2-byte VEX prefix.  */
+      unsigned int r;
+
+      i.vex.length = 2;
+      i.vex.bytes[0] = 0xc5;
+
+      /* Check the REX.R bit.  */
+      r = (i.rex & REX_R) ? 0 : 1;
+      i.vex.bytes[1] = (r << 7
+                       | register_specifier << 3
+                       | vector_length << 2
+                       | implied_prefix);
+    }
+  else
+    {
+      /* 3-byte VEX prefix.  */
+      unsigned int m, w;
+
+      if (i.tm.opcode_modifier.vex0f)
+       m = 0x1;
+      else if (i.tm.opcode_modifier.vex0f38)
+       m = 0x2;
+      else if (i.tm.opcode_modifier.vex0f3a)
+       m = 0x3;
+      else
+       abort ();
+
+      i.vex.length = 3;
+      i.vex.bytes[0] = 0xc4;
+
+      /* The high 3 bits of the second VEX byte are 1's compliment
+        of RXB bits from REX.  */
+      i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m;
+
+      /* Check the REX.W bit.  */
+      w = (i.rex & REX_W) ? 1 : 0;
+      if (i.tm.opcode_modifier.vexw0 || i.tm.opcode_modifier.vexw1)
+       {
+         if (w)
+           abort ();
+
+         if (i.tm.opcode_modifier.vexw1)
+           w = 1;
+       }
+
+      i.vex.bytes[2] = (w << 7
+                       | register_specifier << 3
+                       | vector_length << 2
+                       | implied_prefix);
+    }
+}
+
+static void
+process_immext (void)
+{
+  expressionS *exp;
+
+  if (i.tm.cpu_flags.bitfield.cpusse3 && 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.  */
+      unsigned int x;
+
+      for (x = 0; x < i.operands; x++)
+       if (i.op[x].regs->reg_num != 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);
+
+      i.operands = 0;
+    }
+
+  /* These AMD 3DNow! and SSE2 instructions have an opcode suffix
+     which is coded in the same place as an 8-bit immediate field
+     would be.  Here we fake an 8-bit immediate operand from the
+     opcode suffix stored in tm.extension_opcode.
+
+     AVX instructions also use this encoding, for some of
+     3 argument instructions.  */
+
+  gas_assert (i.imm_operands == 0
+             && (i.operands <= 2
+                 || (i.tm.opcode_modifier.vex
+                     && i.operands <= 4)));
+
+  exp = &im_expressions[i.imm_operands++];
+  i.op[i.operands].imms = exp;
+  i.types[i.operands] = imm8;
+  i.operands++;
+  exp->X_op = O_constant;
+  exp->X_add_number = i.tm.extension_opcode;
+  i.tm.extension_opcode = None;
+}
+
 /* 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.  */
 
 void
-md_assemble (line)
-     char *line;
+md_assemble (char *line)
 {
   unsigned int j;
   char mnemonic[MAX_MNEM_SIZE];
+  const template *t;
 
   /* Initialize globals.  */
   memset (&i, '\0', sizeof (i));
@@ -2375,6 +2825,7 @@ md_assemble (line)
     return;
 
   line = parse_operands (line, mnemonic);
+  this_operand = -1;
   if (line == NULL)
     return;
 
@@ -2414,9 +2865,23 @@ md_assemble (line)
      making sure the overlap of the given operands types is consistent
      with the template operand types.  */
 
-  if (!match_template ())
+  if (!(t = match_template ()))
     return;
 
+  if (sse_check != sse_check_none
+      && !i.tm.opcode_modifier.noavx
+      && (i.tm.cpu_flags.bitfield.cpusse
+         || i.tm.cpu_flags.bitfield.cpusse2
+         || i.tm.cpu_flags.bitfield.cpusse3
+         || i.tm.cpu_flags.bitfield.cpussse3
+         || i.tm.cpu_flags.bitfield.cpusse4_1
+         || i.tm.cpu_flags.bitfield.cpusse4_2))
+    {
+      (sse_check == sse_check_warning
+       ? as_warn
+       : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
+    }
+
   /* Zap movzx and movsx suffix.  The suffix has been set from
      "word ptr" or "byte ptr" on the source operand in Intel syntax
      or extracted from mnemonic in AT&T syntax.  But we'll use
@@ -2427,7 +2892,7 @@ md_assemble (line)
         there is no suffix, the default will be byte extension.  */
       if (i.reg_operands != 2
          && !i.suffix
-         && intel_syntax) 
+         && intel_syntax)
        as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
 
       i.suffix = 0;
@@ -2442,11 +2907,16 @@ md_assemble (line)
     {
       if (!check_string ())
        return;
+      i.disp_operands = 0;
     }
 
   if (!process_suffix ())
     return;
 
+  /* Update operand types.  */
+  for (j = 0; j < i.operands; j++)
+    i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]);
+
   /* Make still unresolved immediate matches conform to size of immediate
      given in i.suffix.  */
   if (!finalize_imm ())
@@ -2455,56 +2925,20 @@ md_assemble (line)
   if (i.types[0].bitfield.imm1)
     i.imm_operands = 0;        /* kludge for shift insns.  */
 
-  for (j = 0; j < 3; j++)
-    if (i.types[j].bitfield.inoutportreg
-       || i.types[j].bitfield.shiftcount
-       || i.types[j].bitfield.acc
-       || i.types[j].bitfield.floatacc)
-      i.reg_operands--;
-
-  if (i.tm.opcode_modifier.immext)
-    {
-      expressionS *exp;
-
-      if (i.tm.cpu_flags.bitfield.cpusse3 && i.operands > 0)
-       {
-         /* Streaming SIMD extensions 3 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.  */
-         unsigned int x;
-
-         for (x = 0; x < i.operands; x++)
-           if (i.op[x].regs->reg_num != 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);
-         i.operands = 0;
-       }
-
-      /* These AMD 3DNow! and Intel Katmai New Instructions have an
-        opcode suffix which is coded in the same place as an 8-bit
-        immediate field would be.  Here we fake an 8-bit immediate
-        operand from the opcode suffix stored in tm.extension_opcode.
-        SSE5 also uses this encoding, for some of its 3 argument
-        instructions.  */
-
-      assert (i.imm_operands == 0
-             && (i.operands <= 2
-                 || (i.tm.cpu_flags.bitfield.cpusse5
-                     && i.operands <= 3)));
-
-      exp = &im_expressions[i.imm_operands++];
-      i.op[i.operands].imms = exp;
-      UINTS_CLEAR (i.types[i.operands]);
-      i.types[i.operands].bitfield.imm8 = 1;
-      i.operands++;
-      exp->X_op = O_constant;
-      exp->X_add_number = i.tm.extension_opcode;
-      i.tm.extension_opcode = None;
-    }
+  /* We only need to check those implicit registers for instructions
+     with 3 operands or less.  */
+  if (i.operands <= 3)
+    for (j = 0; j < i.operands; j++)
+      if (i.types[j].bitfield.inoutportreg
+         || i.types[j].bitfield.shiftcount
+         || i.types[j].bitfield.acc
+         || i.types[j].bitfield.floatacc)
+       i.reg_operands--;
+
+  /* ImmExt should be processed after SSE2AVX.  */
+  if (!i.tm.opcode_modifier.sse2avx
+      && i.tm.opcode_modifier.immext)
+    process_immext ();
 
   /* For insns with operands there are more diddles to do to the opcode.  */
   if (i.operands)
@@ -2518,6 +2952,9 @@ md_assemble (line)
       as_warn (_("translating to `%sp'"), i.tm.name);
     }
 
+  if (i.tm.opcode_modifier.vex)
+    build_vex_prefix (t);
+
   /* Handle conversion of 'int $3' --> special int3 insn.  */
   if (i.tm.base_opcode == INT_OPCODE && i.op[0].imms->X_add_number == 3)
     {
@@ -2576,14 +3013,7 @@ md_assemble (line)
        }
     }
 
-  /* If the instruction has the DREX attribute (aka SSE5), don't emit a
-     REX prefix.  */
-  if (i.tm.opcode_modifier.drex || i.tm.opcode_modifier.drexc)
-    {
-      i.drex.rex = i.rex;
-      i.rex = 0;
-    }
-  else if (i.rex != 0)
+  if (i.rex != 0)
     add_prefix (REX_OPCODE | i.rex);
 
   /* We are ready to output the insn.  */
@@ -2598,6 +3028,7 @@ parse_insn (char *line, char *mnemonic)
   char *mnem_p;
   int supported;
   const template *t;
+  char *dot_p = NULL;
 
   /* Non-zero if we found a prefix only acceptable with string insns.  */
   const char *expecting_string_instruction = NULL;
@@ -2607,6 +3038,8 @@ parse_insn (char *line, char *mnemonic)
       mnem_p = mnemonic;
       while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
        {
+         if (*mnem_p == '.')
+           dot_p = mnem_p;
          mnem_p++;
          if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
            {
@@ -2680,6 +3113,19 @@ parse_insn (char *line, char *mnemonic)
 
   if (!current_templates)
     {
+      /* Check if we should swap operand in encoding.  */
+      if (mnem_p - 2 == dot_p && dot_p[1] == 's')
+       i.swap_operand = 1;
+      else
+       goto check_suffix;
+      mnem_p = dot_p;
+      *dot_p = '\0';
+      current_templates = hash_find (op_hash, mnemonic);
+    }
+
+  if (!current_templates)
+    {
+check_suffix:
       /* See if we can get a match by trimming off a suffix.  */
       switch (mnem_p[-1])
        {
@@ -2760,12 +3206,12 @@ parse_insn (char *line, char *mnemonic)
   supported = 0;
   for (t = current_templates->start; t < current_templates->end; ++t)
     {
-      supported |= cpu_flags_match (t->cpu_flags);
-      if (supported == 3)
+      supported |= cpu_flags_match (t);
+      if (supported == CPU_FLAGS_PERFECT_MATCH)
        goto skip;
     }
 
-  if (!(supported & 2))
+  if (!(supported & CPU_FLAGS_64BIT_MATCH))
     {
       as_bad (flag_code == CODE_64BIT
              ? _("`%s' is not supported in 64-bit mode")
@@ -2773,10 +3219,11 @@ parse_insn (char *line, char *mnemonic)
              current_templates->start->name);
       return NULL;
     }
-  if (!(supported & 1))
+  if (supported != CPU_FLAGS_PERFECT_MATCH)
     {
       as_bad (_("`%s' is not supported on `%s%s'"),
-             current_templates->start->name, cpu_arch_name,
+             current_templates->start->name,
+             cpu_arch_name ? cpu_arch_name : default_arch,
              cpu_sub_arch_name ? cpu_sub_arch_name : "");
       return NULL;
     }
@@ -2954,6 +3401,7 @@ swap_operands (void)
 {
   switch (i.operands)
     {
+    case 5:
     case 4:
       swap_2_operands (1, i.operands - 2);
     case 3:
@@ -2991,7 +3439,7 @@ optimize_imm (void)
         In any case, we can't set i.suffix yet.  */
       for (op = i.operands; --op >= 0;)
        if (i.types[op].bitfield.reg8)
-         { 
+         {
            guess_suffix = BYTE_MNEM_SUFFIX;
            break;
          }
@@ -3085,8 +3533,8 @@ optimize_imm (void)
              i386_operand_type mask, allowed;
              const template *t;
 
-             UINTS_CLEAR (mask);
-             UINTS_CLEAR (allowed);
+             operand_type_set (&mask, 0);
+             operand_type_set (&allowed, 0);
 
              for (t = current_templates->start;
                   t < current_templates->end;
@@ -3112,7 +3560,7 @@ optimize_imm (void)
                  break;
                }
              allowed = operand_type_and (mask, allowed);
-             if (!UINTS_ALL_ZERO (allowed))
+             if (!operand_type_all_zero (&allowed))
                i.types[op] = operand_type_and (i.types[op], mask);
            }
            break;
@@ -3195,12 +3643,13 @@ optimize_disp (void)
       }
 }
 
-static int
+static const template *
 match_template (void)
 {
   /* Points to template once we've found it.  */
   const template *t;
   i386_operand_type overlap0, overlap1, overlap2, overlap3;
+  i386_operand_type overlap4;
   unsigned int found_reverse_match;
   i386_opcode_modifier suffix_check;
   i386_operand_type operand_types [MAX_OPERANDS];
@@ -3209,8 +3658,8 @@ match_template (void)
   unsigned int found_cpu_match;
   unsigned int check_register;
 
-#if MAX_OPERANDS != 4
-# error "MAX_OPERANDS must be 4."
+#if MAX_OPERANDS != 5
+# error "MAX_OPERANDS must be 5."
 #endif
 
   found_reverse_match = 0;
@@ -3239,7 +3688,8 @@ match_template (void)
        continue;
 
       /* Check processor support.  */
-      found_cpu_match = cpu_flags_match (t->cpu_flags) == 3;
+      found_cpu_match = (cpu_flags_match (t)
+                        == CPU_FLAGS_PERFECT_MATCH);
       if (!found_cpu_match)
        continue;
 
@@ -3280,14 +3730,29 @@ match_template (void)
                 && !intel_float_operand (t->name))
              : intel_float_operand (t->name) != 2)
          && ((!operand_types[0].bitfield.regmmx
-              && !operand_types[0].bitfield.regxmm)
+              && !operand_types[0].bitfield.regxmm
+              && !operand_types[0].bitfield.regymm)
              || (!operand_types[t->operands > 1].bitfield.regmmx
-                 && !!operand_types[t->operands > 1].bitfield.regxmm))
+                 && !!operand_types[t->operands > 1].bitfield.regxmm
+                 && !!operand_types[t->operands > 1].bitfield.regymm))
          && (t->base_opcode != 0x0fc7
              || t->extension_opcode != 1 /* cmpxchg8b */))
        continue;
 
-      /* Do not verify operands when there are none.  */
+      /* In general, don't allow 32-bit operands on pre-386.  */
+      else if (i.suffix == LONG_MNEM_SUFFIX
+              && !cpu_arch_flags.bitfield.cpui386
+              && (intel_syntax
+                  ? (!t->opcode_modifier.ignoresize
+                     && !intel_float_operand (t->name))
+                  : intel_float_operand (t->name) != 2)
+              && ((!operand_types[0].bitfield.regmmx
+                   && !operand_types[0].bitfield.regxmm)
+                  || (!operand_types[t->operands > 1].bitfield.regmmx
+                      && !!operand_types[t->operands > 1].bitfield.regxmm)))
+       continue;
+
+      /* Do not verify operands when there are none.  */
       else
        {
          if (!t->operands)
@@ -3358,11 +3823,25 @@ match_template (void)
             zero-extend %eax to %rax.  */
          if (flag_code == CODE_64BIT
              && t->base_opcode == 0x90
-             && UINTS_EQUAL (i.types [0], acc32)
-             && UINTS_EQUAL (i.types [1], acc32))
+             && operand_type_equal (&i.types [0], &acc32)
+             && operand_type_equal (&i.types [1], &acc32))
            continue;
+         if (i.swap_operand)
+           {
+             /* If we swap operand in encoding, we either match
+                the next one or reverse direction of operands.  */
+             if (t->opcode_modifier.s)
+               continue;
+             else if (t->opcode_modifier.d)
+               goto check_reverse;
+           }
+
        case 3:
+         /* If we swap operand in encoding, we match the next one.  */
+         if (i.swap_operand && t->opcode_modifier.s)
+           continue;
        case 4:
+       case 5:
          overlap1 = operand_type_and (i.types[1], operand_types[1]);
          if (!operand_type_match (overlap0, i.types[0])
              || !operand_type_match (overlap1, i.types[1])
@@ -3376,6 +3855,7 @@ match_template (void)
              if (!t->opcode_modifier.d && !t->opcode_modifier.floatd)
                continue;
 
+check_reverse:
              /* Try reversing direction of operands.  */
              overlap0 = operand_type_and (i.types[0], operand_types[1]);
              overlap1 = operand_type_and (i.types[1], operand_types[0]);
@@ -3408,6 +3888,9 @@ match_template (void)
              /* Found a forward 2 operand match here.  */
              switch (t->operands)
                {
+               case 5:
+                 overlap4 = operand_type_and (i.types[4],
+                                              operand_types[4]);
                case 4:
                  overlap3 = operand_type_and (i.types[3],
                                               operand_types[3]);
@@ -3419,6 +3902,15 @@ match_template (void)
 
              switch (t->operands)
                {
+               case 5:
+                 if (!operand_type_match (overlap4, i.types[4])
+                     || !operand_type_register_match (overlap3,
+                                                      i.types[3],
+                                                      operand_types[3],
+                                                      overlap4,
+                                                      i.types[4],
+                                                      operand_types[4]))
+                   continue;
                case 4:
                  if (!operand_type_match (overlap3, i.types[3])
                      || (check_register
@@ -3454,6 +3946,7 @@ match_template (void)
          found_reverse_match = 0;
          continue;
        }
+
       /* We've found a match; break out of loop.  */
       break;
     }
@@ -3461,9 +3954,13 @@ match_template (void)
   if (t == current_templates->end)
     {
       /* We found no match.  */
-      as_bad (_("suffix or operands invalid for `%s'"),
-             current_templates->start->name);
-      return 0;
+      if (intel_syntax)
+       as_bad (_("ambiguous operand size or operands invalid for `%s'"),
+               current_templates->start->name);
+      else
+       as_bad (_("suffix or operands invalid for `%s'"),
+               current_templates->start->name);
+      return NULL;
     }
 
   if (!quiet_warnings)
@@ -3503,7 +4000,7 @@ match_template (void)
       i.tm.operand_types[1] = operand_types[0];
     }
 
-  return 1;
+  return t;
 }
 
 static int
@@ -3514,9 +4011,10 @@ check_string (void)
     {
       if (i.seg[0] != NULL && i.seg[0] != &es)
        {
-         as_bad (_("`%s' operand %d must use `%%es' segment"),
+         as_bad (_("`%s' operand %d must use `%ses' segment"),
                  i.tm.name,
-                 mem_op + 1);
+                 mem_op + 1,
+                 register_prefix);
          return 0;
        }
       /* There's only ever one segment override allowed per instruction.
@@ -3529,9 +4027,10 @@ check_string (void)
     {
       if (i.seg[1] != NULL && i.seg[1] != &es)
        {
-         as_bad (_("`%s' operand %d must use `%%es' segment"),
+         as_bad (_("`%s' operand %d must use `%ses' segment"),
                  i.tm.name,
-                 mem_op + 2);
+                 mem_op + 2,
+                 register_prefix);
          return 0;
        }
     }
@@ -3637,9 +4136,10 @@ process_suffix (void)
          if (!check_word_reg ())
            return 0;
        }
-      else if (i.suffix == XMMWORD_MNEM_SUFFIX)
+      else if (i.suffix == XMMWORD_MNEM_SUFFIX
+              || i.suffix == YMMWORD_MNEM_SUFFIX)
        {
-         /* Skip if the instruction has x suffix.  match_template
+         /* Skip if the instruction has x/y suffix.  match_template
             should check if it is a valid suffix.  */
        }
       else if (intel_syntax && i.tm.opcode_modifier.ignoresize)
@@ -3696,7 +4196,7 @@ process_suffix (void)
       else
        {
          unsigned int suffixes;
-         
+
          suffixes = !i.tm.opcode_modifier.no_bsuf;
          if (!i.tm.opcode_modifier.no_wsuf)
            suffixes |= 1 << 1;
@@ -3726,7 +4226,8 @@ process_suffix (void)
 
   if (i.suffix
       && i.suffix != BYTE_MNEM_SUFFIX
-      && i.suffix != XMMWORD_MNEM_SUFFIX)
+      && i.suffix != XMMWORD_MNEM_SUFFIX
+      && i.suffix != YMMWORD_MNEM_SUFFIX)
     {
       /* It's not a byte, select word/dword operation.  */
       if (i.tm.opcode_modifier.w)
@@ -3778,8 +4279,8 @@ process_suffix (void)
          if (! (i.operands == 2
                 && i.tm.base_opcode == 0x90
                 && i.tm.extension_opcode == None
-                && UINTS_EQUAL (i.types [0], acc64)
-                && UINTS_EQUAL (i.types [1], acc64))
+                && operand_type_equal (&i.types [0], &acc64)
+                && operand_type_equal (&i.types [1], &acc64))
              && ! (i.operands == 1
                    && i.tm.base_opcode == 0xfc7
                    && i.tm.extension_opcode == 1
@@ -3853,6 +4354,7 @@ check_byte_reg (void)
          || i.types[op].bitfield.reg64
          || i.types[op].bitfield.regmmx
          || i.types[op].bitfield.regxmm
+         || i.types[op].bitfield.regymm
          || i.types[op].bitfield.sreg2
          || i.types[op].bitfield.sreg3
          || i.types[op].bitfield.control
@@ -4036,28 +4538,26 @@ check_word_reg (void)
 static int
 update_imm (unsigned int j)
 {
-  i386_operand_type overlap;
-
-  overlap = operand_type_and (i.types[j], i.tm.operand_types[j]);
+  i386_operand_type overlap = i.types[j];
   if ((overlap.bitfield.imm8
        || overlap.bitfield.imm8s
        || overlap.bitfield.imm16
        || overlap.bitfield.imm32
        || overlap.bitfield.imm32s
        || overlap.bitfield.imm64)
-      && !UINTS_EQUAL (overlap, imm8)
-      && !UINTS_EQUAL (overlap, imm8s)
-      && !UINTS_EQUAL (overlap, imm16)
-      && !UINTS_EQUAL (overlap, imm32)
-      && !UINTS_EQUAL (overlap, imm32s)
-      && !UINTS_EQUAL (overlap, imm64))
+      && !operand_type_equal (&overlap, &imm8)
+      && !operand_type_equal (&overlap, &imm8s)
+      && !operand_type_equal (&overlap, &imm16)
+      && !operand_type_equal (&overlap, &imm32)
+      && !operand_type_equal (&overlap, &imm32s)
+      && !operand_type_equal (&overlap, &imm64))
     {
       if (i.suffix)
        {
          i386_operand_type temp;
 
-         UINTS_CLEAR (temp);
-         if (i.suffix == BYTE_MNEM_SUFFIX) 
+         operand_type_set (&temp, 0);
+         if (i.suffix == BYTE_MNEM_SUFFIX)
            {
              temp.bitfield.imm8 = overlap.bitfield.imm8;
              temp.bitfield.imm8s = overlap.bitfield.imm8s;
@@ -4073,22 +4573,21 @@ update_imm (unsigned int j)
            temp.bitfield.imm32 = overlap.bitfield.imm32;
          overlap = temp;
        }
-      else if (UINTS_EQUAL (overlap, imm16_32_32s)
-              || UINTS_EQUAL (overlap, imm16_32)
-              || UINTS_EQUAL (overlap, imm16_32s))
+      else if (operand_type_equal (&overlap, &imm16_32_32s)
+              || operand_type_equal (&overlap, &imm16_32)
+              || operand_type_equal (&overlap, &imm16_32s))
        {
-         UINTS_CLEAR (overlap);
          if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
-           overlap.bitfield.imm16 = 1;
+           overlap = imm16;
          else
-           overlap.bitfield.imm32s = 1;
+           overlap = imm32s;
        }
-      if (!UINTS_EQUAL (overlap, imm8)
-         && !UINTS_EQUAL (overlap, imm8s)
-         && !UINTS_EQUAL (overlap, imm16)
-         && !UINTS_EQUAL (overlap, imm32)
-         && !UINTS_EQUAL (overlap, imm32s)
-         && !UINTS_EQUAL (overlap, imm64))
+      if (!operand_type_equal (&overlap, &imm8)
+         && !operand_type_equal (&overlap, &imm8s)
+         && !operand_type_equal (&overlap, &imm16)
+         && !operand_type_equal (&overlap, &imm32)
+         && !operand_type_equal (&overlap, &imm32s)
+         && !operand_type_equal (&overlap, &imm64))
        {
          as_bad (_("no instruction mnemonic suffix given; "
                    "can't determine immediate size"));
@@ -4103,378 +4602,136 @@ update_imm (unsigned int j)
 static int
 finalize_imm (void)
 {
-  unsigned int j;
+  unsigned int j, n;
 
-  for (j = 0; j < 2; j++)
-    if (update_imm (j) == 0)
-      return 0;
+  /* Update the first 2 immediate operands.  */
+  n = i.operands > 2 ? 2 : i.operands;
+  if (n)
+    {
+      for (j = 0; j < n; j++)
+       if (update_imm (j) == 0)
+         return 0;
 
-  i.types[2] = operand_type_and (i.types[2], i.tm.operand_types[2]);
-  assert (operand_type_check (i.types[2], imm) == 0);
+      /* The 3rd operand can't be immediate operand.  */
+      gas_assert (operand_type_check (i.types[2], imm) == 0);
+    }
 
   return 1;
 }
 
-static void
-process_drex (void)
-{
-  i.drex.modrm_reg = 0;
-  i.drex.modrm_regmem = 0;
-
-  /* SSE5 4 operand instructions must have the destination the same as 
-     one of the inputs.  Figure out the destination register and cache
-     it away in the drex field, and remember which fields to use for 
-     the modrm byte.  */
-  if (i.tm.opcode_modifier.drex 
-      && i.tm.opcode_modifier.drexv 
-      && i.operands == 4)
-    {
-      i.tm.extension_opcode = None;
-
-      /* Case 1: 4 operand insn, dest = src1, src3 = register.  */
-      if (i.types[0].bitfield.regxmm != 0
-         && i.types[1].bitfield.regxmm != 0
-         && i.types[2].bitfield.regxmm != 0
-         && i.types[3].bitfield.regxmm != 0
-         && i.op[0].regs->reg_num == i.op[3].regs->reg_num
-         && i.op[0].regs->reg_flags == i.op[3].regs->reg_flags)
-       {
-         /* Clear the arguments that are stored in drex.  */
-         UINTS_CLEAR (i.types[0]); 
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* There are two different ways to encode a 4 operand 
-            instruction with all registers that uses OC1 set to 
-            0 or 1.  Favor setting OC1 to 0 since this mimics the 
-            actions of other SSE5 assemblers.  Use modrm encoding 2 
-            for register/register.  Include the high order bit that 
-            is normally stored in the REX byte in the register
-            field.  */
-         i.tm.extension_opcode = DREX_X1_XMEM_X2_X1;
-         i.drex.modrm_reg = 2;
-         i.drex.modrm_regmem = 1;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+static int
+bad_implicit_operand (int xmm)
+{
+  const char *reg = xmm ? "xmm0" : "ymm0";
+  if (intel_syntax)
+    as_bad (_("the last operand of `%s' must be `%s%s'"),
+           i.tm.name, register_prefix, reg);
+  else
+    as_bad (_("the first operand of `%s' must be `%s%s'"),
+           i.tm.name, register_prefix, reg);
+  return 0;
+}
 
-      /* Case 2: 4 operand insn, dest = src1, src3 = memory.  */
-      else if (i.types[0].bitfield.regxmm != 0
-              && i.types[1].bitfield.regxmm != 0
-              && (i.types[2].bitfield.regxmm 
-                  || operand_type_check (i.types[2], anymem))
-              && i.types[3].bitfield.regxmm != 0
-              && i.op[0].regs->reg_num == i.op[3].regs->reg_num
-              && i.op[0].regs->reg_flags == i.op[3].regs->reg_flags)
-       {
-         /* clear the arguments that are stored in drex */
-         UINTS_CLEAR (i.types[0]);
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* Specify the modrm encoding for memory addressing.  Include 
-            the high order bit that is normally stored in the REX byte
-            in the register field.  */
-         i.tm.extension_opcode = DREX_X1_X2_XMEM_X1;
-         i.drex.modrm_reg = 1;
-         i.drex.modrm_regmem = 2;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+static int
+process_operands (void)
+{
+  /* Default segment register this instruction will use for memory
+     accesses.  0 means unknown.  This is only for optimizing out
+     unnecessary segment overrides.  */
+  const seg_entry *default_seg = 0;
 
-      /* Case 3: 4 operand insn, dest = src1, src2 = memory.  */
-      else if (i.types[0].bitfield.regxmm != 0
-              && operand_type_check (i.types[1], anymem) != 0
-              && i.types[2].bitfield.regxmm != 0
-              && i.types[3].bitfield.regxmm != 0
-              && i.op[0].regs->reg_num == i.op[3].regs->reg_num
-              && i.op[0].regs->reg_flags == i.op[3].regs->reg_flags)
-       {
-         /* Clear the arguments that are stored in drex.  */
-         UINTS_CLEAR (i.types[0]);
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* Specify the modrm encoding for memory addressing.  Include
-            the high order bit that is normally stored in the REX byte 
-            in the register field.  */
-         i.tm.extension_opcode = DREX_X1_XMEM_X2_X1;
-         i.drex.modrm_reg = 2;
-         i.drex.modrm_regmem = 1;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+  if (i.tm.opcode_modifier.sse2avx
+      && (i.tm.opcode_modifier.vexnds
+         || i.tm.opcode_modifier.vexndd))
+    {
+      unsigned int dup = i.operands;
+      unsigned int dest = dup - 1;
+      unsigned int j;
 
-      /* Case 4: 4 operand insn, dest = src3, src2 = register. */
-      else if (i.types[0].bitfield.regxmm != 0
-              && i.types[1].bitfield.regxmm != 0
-              && i.types[2].bitfield.regxmm != 0
-              && i.types[3].bitfield.regxmm != 0
-              && i.op[2].regs->reg_num == i.op[3].regs->reg_num
-              && i.op[2].regs->reg_flags == i.op[3].regs->reg_flags)
-       {
-         /* clear the arguments that are stored in drex */
-         UINTS_CLEAR (i.types[2]);
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* There are two different ways to encode a 4 operand 
-            instruction with all registers that uses OC1 set to 
-            0 or 1.  Favor setting OC1 to 0 since this mimics the 
-            actions of other SSE5 assemblers.  Use modrm encoding 
-            2 for register/register.  Include the high order bit that 
-            is normally stored in the REX byte in the register 
-            field.  */
-         i.tm.extension_opcode = DREX_XMEM_X1_X2_X2;
-         i.drex.modrm_reg = 1;
-         i.drex.modrm_regmem = 0;
-
-         /* Remember the register, including the upper bits */
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+      /* The destination must be an xmm register.  */
+      gas_assert (i.reg_operands
+                 && MAX_OPERANDS > dup
+                 && operand_type_equal (&i.types[dest], &regxmm));
 
-      /* Case 5: 4 operand insn, dest = src3, src2 = memory.  */
-      else if (i.types[0].bitfield.regxmm != 0
-              && (i.types[1].bitfield.regxmm 
-                  || operand_type_check (i.types[1], anymem)) 
-              && i.types[2].bitfield.regxmm != 0
-              && i.types[3].bitfield.regxmm != 0
-              && i.op[2].regs->reg_num == i.op[3].regs->reg_num
-              && i.op[2].regs->reg_flags == i.op[3].regs->reg_flags)
+      if (i.tm.opcode_modifier.firstxmm0)
        {
-         /* Clear the arguments that are stored in drex.  */
-         UINTS_CLEAR (i.types[2]);
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* Specify the modrm encoding and remember the register 
-            including the bits normally stored in the REX byte. */
-         i.tm.extension_opcode = DREX_X1_XMEM_X2_X2;
-         i.drex.modrm_reg = 0;
-         i.drex.modrm_regmem = 1;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+         /* 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)
+           return bad_implicit_operand (1);
 
-      /* Case 6: 4 operand insn, dest = src3, src1 = memory.  */
-      else if (operand_type_check (i.types[0], anymem) != 0
-              && i.types[1].bitfield.regxmm != 0
-              && i.types[2].bitfield.regxmm != 0
-              && i.types[3].bitfield.regxmm != 0
-              && i.op[2].regs->reg_num == i.op[3].regs->reg_num
-              && i.op[2].regs->reg_flags == i.op[3].regs->reg_flags)
-       {
-         /* clear the arguments that are stored in drex */
-         UINTS_CLEAR (i.types[2]);
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* Specify the modrm encoding and remember the register 
-            including the bits normally stored in the REX byte. */
-         i.tm.extension_opcode = DREX_XMEM_X1_X2_X2;
-         i.drex.modrm_reg = 1;
-         i.drex.modrm_regmem = 0;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
+         if (i.tm.opcode_modifier.vex3sources)
+           {
+             /* Keep xmm0 for instructions with VEX prefix and 3
+                sources.  */
+             goto duplicate;
+           }
+         else
+           {
+             /* We remove the first xmm0 and keep the number of
+                operands unchanged, which in fact duplicates the
+                destination.  */
+             for (j = 1; j < i.operands; j++)
+               {
+                 i.op[j - 1] = i.op[j];
+                 i.types[j - 1] = i.types[j];
+                 i.tm.operand_types[j - 1] = i.tm.operand_types[j];
+               }
+           }
        }
-
-      else
-       as_bad (_("Incorrect operands for the '%s' instruction"), 
-               i.tm.name);
-    }
-
-  /* SSE5 instructions with the DREX byte where the only memory operand 
-     is in the 2nd argument, and the first and last xmm register must 
-     match, and is encoded in the DREX byte. */
-  else if (i.tm.opcode_modifier.drex 
-          && !i.tm.opcode_modifier.drexv 
-          && i.operands == 4)
-    {
-      /* Case 1: 4 operand insn, dest = src1, src3 = reg/mem.  */
-      if (i.types[0].bitfield.regxmm != 0
-         && (i.types[1].bitfield.regxmm 
-             || operand_type_check(i.types[1], anymem)) 
-         && i.types[2].bitfield.regxmm != 0
-         && i.types[3].bitfield.regxmm != 0
-         && i.op[0].regs->reg_num == i.op[3].regs->reg_num
-         && i.op[0].regs->reg_flags == i.op[3].regs->reg_flags)
+      else if (i.tm.opcode_modifier.implicit1stxmm0)
        {
-         /* clear the arguments that are stored in drex */
-         UINTS_CLEAR (i.types[0]);
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands -= 2;
-
-         /* Specify the modrm encoding and remember the register 
-            including the high bit normally stored in the REX 
-            byte.  */
-         i.drex.modrm_reg = 2;
-         i.drex.modrm_regmem = 1;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
-
-      else
-       as_bad (_("Incorrect operands for the '%s' instruction"), 
-               i.tm.name);
-    }
-
-  /* SSE5 3 operand instructions that the result is a register, being 
-     either operand can be a memory operand, using OC0 to note which 
-     one is the memory.  */
-  else if (i.tm.opcode_modifier.drex 
-          && i.tm.opcode_modifier.drexv
-          && i.operands == 3)
-    {
-      i.tm.extension_opcode = None;
+         gas_assert ((MAX_OPERANDS - 1) > dup
+                     && i.tm.opcode_modifier.vex3sources);
 
-      /* Case 1: 3 operand insn, src1 = register.  */
-      if (i.types[0].bitfield.regxmm != 0
-         && i.types[1].bitfield.regxmm != 0
-         && i.types[2].bitfield.regxmm != 0)
-       {
-         /* Clear the arguments that are stored in drex.  */
-         UINTS_CLEAR (i.types[2]);
-         i.reg_operands--;
-
-         /* Specify the modrm encoding and remember the register 
-            including the high bit normally stored in the REX byte.  */
-         i.tm.extension_opcode = DREX_XMEM_X1_X2;
-         i.drex.modrm_reg = 1;
-         i.drex.modrm_regmem = 0;
-         i.drex.reg = (i.op[2].regs->reg_num
-                       + ((i.op[2].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+         /* Add the implicit xmm0 for instructions with VEX prefix
+            and 3 sources.  */
+         for (j = i.operands; j > 0; j--)
+           {
+             i.op[j] = i.op[j - 1];
+             i.types[j] = i.types[j - 1];
+             i.tm.operand_types[j] = i.tm.operand_types[j - 1];
+           }
+         i.op[0].regs
+           = (const reg_entry *) hash_find (reg_hash, "xmm0");
+         i.types[0] = regxmm;
+         i.tm.operand_types[0] = regxmm;
 
-      /* Case 2: 3 operand insn, src1 = memory.  */
-      else if (operand_type_check (i.types[0], anymem) != 0
-              && i.types[1].bitfield.regxmm != 0
-              && i.types[2].bitfield.regxmm != 0)
-       {
-         /* Clear the arguments that are stored in drex.  */
-         UINTS_CLEAR (i.types[2]);
-         i.reg_operands--;
-
-         /* Specify the modrm encoding and remember the register 
-            including the high bit normally stored in the REX 
-            byte.  */
-         i.tm.extension_opcode = DREX_XMEM_X1_X2;
-         i.drex.modrm_reg = 1;
-         i.drex.modrm_regmem = 0;
-         i.drex.reg = (i.op[2].regs->reg_num
-                       + ((i.op[2].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+         i.operands += 2;
+         i.reg_operands += 2;
+         i.tm.operands += 2;
 
-      /* Case 3: 3 operand insn, src2 = memory.  */
-      else if (i.types[0].bitfield.regxmm != 0
-              && operand_type_check (i.types[1], anymem) != 0
-              && i.types[2].bitfield.regxmm != 0)
-       {
-         /* Clear the arguments that are stored in drex.  */
-         UINTS_CLEAR (i.types[2]);
-         i.reg_operands--;
-
-         /* Specify the modrm encoding and remember the register 
-            including the high bit normally stored in the REX byte.  */
-         i.tm.extension_opcode = DREX_X1_XMEM_X2;
-         i.drex.modrm_reg = 0;
-         i.drex.modrm_regmem = 1;
-         i.drex.reg = (i.op[2].regs->reg_num
-                       + ((i.op[2].regs->reg_flags & RegRex) ? 8 : 0));
+         dup++;
+         dest++;
+         i.op[dup] = i.op[dest];
+         i.types[dup] = i.types[dest];
+         i.tm.operand_types[dup] = i.tm.operand_types[dest];
        }
-
       else
-       as_bad (_("Incorrect operands for the '%s' instruction"), 
-               i.tm.name);
-    }
-
-  /* SSE5 4 operand instructions that are the comparison instructions 
-     where the first operand is the immediate value of the comparison 
-     to be done.  */
-  else if (i.tm.opcode_modifier.drexc != 0 && i.operands == 4)
-    {
-      /* Case 1: 4 operand insn, src1 = reg/memory. */
-      if (operand_type_check (i.types[0], imm) != 0
-         && (i.types[1].bitfield.regxmm 
-             || operand_type_check (i.types[1], anymem)) 
-         && i.types[2].bitfield.regxmm != 0
-         && i.types[3].bitfield.regxmm != 0)
        {
-         /* clear the arguments that are stored in drex */
-         UINTS_CLEAR (i.types[3]);
-         i.reg_operands--;
-
-         /* Specify the modrm encoding and remember the register 
-            including the high bit normally stored in the REX byte.  */
-         i.drex.modrm_reg = 2;
-         i.drex.modrm_regmem = 1;
-         i.drex.reg = (i.op[3].regs->reg_num
-                       + ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
-       }
+duplicate:
+         i.operands++;
+         i.reg_operands++;
+         i.tm.operands++;
 
-      /* Case 2: 3 operand insn with ImmExt that places the 
-        opcode_extension as an immediate argument.  This is used for 
-        all of the varients of comparison that supplies the appropriate
-        value as part of the instruction.  */
-      else if ((i.types[0].bitfield.regxmm
-               || operand_type_check (i.types[0], anymem)) 
-              && i.types[1].bitfield.regxmm != 0
-              && i.types[2].bitfield.regxmm != 0
-              && operand_type_check (i.types[3], imm) != 0)
-       {
-         /* clear the arguments that are stored in drex */
-         UINTS_CLEAR (i.types[2]);
-         i.reg_operands--;
-
-         /* Specify the modrm encoding and remember the register 
-            including the high bit normally stored in the REX byte.  */
-         i.drex.modrm_reg = 1;
-         i.drex.modrm_regmem = 0;
-         i.drex.reg = (i.op[2].regs->reg_num
-                       + ((i.op[2].regs->reg_flags & RegRex) ? 8 : 0));
+         i.op[dup] = i.op[dest];
+         i.types[dup] = i.types[dest];
+         i.tm.operand_types[dup] = i.tm.operand_types[dest];
        }
 
-      else
-       as_bad (_("Incorrect operands for the '%s' instruction"), 
-               i.tm.name);
+       if (i.tm.opcode_modifier.immext)
+        process_immext ();
     }
-
-  else if (i.tm.opcode_modifier.drex 
-          || i.tm.opcode_modifier.drexv 
-          || i.tm.opcode_modifier.drexc)
-    as_bad (_("Internal error for the '%s' instruction"), i.tm.name);
-}
-
-static int
-process_operands (void)
-{
-  /* Default segment register this instruction will use for memory
-     accesses.  0 means unknown.  This is only for optimizing out
-     unnecessary segment overrides.  */
-  const seg_entry *default_seg = 0;
-
-  /* Handle all of the DREX munging that SSE5 needs.  */
-  if (i.tm.opcode_modifier.drex 
-      || i.tm.opcode_modifier.drexv 
-      || i.tm.opcode_modifier.drexc)
-    process_drex ();
-
-  if (i.tm.opcode_modifier.firstxmm0)
+  else if (i.tm.opcode_modifier.firstxmm0)
     {
       unsigned int j;
 
-      /* The first operand is implicit and must be xmm0.  */
-      assert (i.reg_operands && UINTS_EQUAL (i.types[0], regxmm));
+      /* The first operand is implicit and must be xmm0/ymm0.  */
+      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 (intel_syntax)
-           as_bad (_("the last operand of `%s' must be `%sxmm0'"),
-                   i.tm.name, register_prefix);
-         else
-           as_bad (_("the first operand of `%s' must be `%sxmm0'"),
-                   i.tm.name, register_prefix);
-         return 0;
-       }
+       return bad_implicit_operand (i.types[0].bitfield.regxmm);
 
       for (j = 1; j < i.operands; j++)
        {
@@ -4503,8 +4760,8 @@ process_operands (void)
       else
        first_reg_op = 1;
       /* Pretend we saw the extra register operand.  */
-      assert (i.reg_operands == 1
-             && i.op[first_reg_op + 1].regs == 0);
+      gas_assert (i.reg_operands == 1
+                 && i.op[first_reg_op + 1].regs == 0);
       i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
       i.types[first_reg_op + 1] = i.types[first_reg_op];
       i.operands++;
@@ -4519,7 +4776,7 @@ process_operands (void)
          if (i.tm.base_opcode == POP_SEG_SHORT
              && i.op[0].regs->reg_num == 1)
            {
-             as_bad (_("you can't `pop %%cs'"));
+             as_bad (_("you can't `pop %scs'"), register_prefix);
              return 0;
            }
          i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
@@ -4528,15 +4785,15 @@ process_operands (void)
        }
       else
        {
-         /* The register or float register operand is in operand 
+         /* The register or float register operand is in operand
             0 or 1.  */
          unsigned int op;
-         
-          if (i.types[0].bitfield.floatreg
-              || operand_type_check (i.types[0], reg))
-            op = 0;
-          else
-            op = 1;
+
+         if (i.types[0].bitfield.floatreg
+             || operand_type_check (i.types[0], reg))
+           op = 0;
+         else
+           op = 1;
          /* Register goes in low 3 bits of opcode.  */
          i.tm.base_opcode |= i.op[op].regs->reg_num;
          if ((i.op[op].regs->reg_flags & RegRex) != 0)
@@ -4549,8 +4806,8 @@ process_operands (void)
                {
                  /* Reversed arguments on faddp, fsubp, etc.  */
                  as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name,
-                          register_prefix, i.op[1].regs->reg_name,
-                          register_prefix, i.op[0].regs->reg_name);
+                          register_prefix, i.op[!intel_syntax].regs->reg_name,
+                          register_prefix, i.op[intel_syntax].regs->reg_name);
                }
              else
                {
@@ -4602,34 +4859,90 @@ static const seg_entry *
 build_modrm_byte (void)
 {
   const seg_entry *default_seg = 0;
+  unsigned int source, dest;
+  int vex_3_sources;
 
-  /* SSE5 4 operand instructions are encoded in such a way that one of 
-     the inputs must match the destination register.  Process_drex hides
-     the 3rd argument in the drex field, so that by the time we get 
-     here, it looks to GAS as if this is a 2 operand instruction.  */
-  if ((i.tm.opcode_modifier.drex 
-       || i.tm.opcode_modifier.drexv 
-       || i.tm.opcode_modifier.drexc)
-      && i.reg_operands == 2)
+  /* The first operand of instructions with VEX prefix and 3 sources
+     must be VEX_Imm4.  */
+  vex_3_sources = i.tm.opcode_modifier.vex3sources;
+  if (vex_3_sources)
     {
-      const reg_entry *reg = i.op[i.drex.modrm_reg].regs;
-      const reg_entry *regmem = i.op[i.drex.modrm_regmem].regs;
+      unsigned int nds, reg;
 
-      i.rm.reg = reg->reg_num;
-      i.rm.regmem = regmem->reg_num;
-      i.rm.mode = 3;
-      if ((reg->reg_flags & RegRex) != 0)
-       i.rex |= REX_R;
-      if ((regmem->reg_flags & RegRex) != 0)
-       i.rex |= REX_B;
+      if (i.tm.opcode_modifier.veximmext
+         && i.tm.opcode_modifier.immext)
+       {
+         dest = i.operands - 2;
+         gas_assert (dest == 3);
+       }
+      else
+      dest = i.operands - 1;
+      nds = dest - 1;
+
+      /* This instruction must have 4 register operands 
+        or 3 register operands plus 1 memory operand.  
+        It must have VexNDS and VexImmExt.  */
+      gas_assert ((i.reg_operands == 4
+                     || (i.reg_operands == 3 && i.mem_operands == 1))
+                 && i.tm.opcode_modifier.vexnds
+                 && i.tm.opcode_modifier.veximmext
+           && (operand_type_equal (&i.tm.operand_types[dest], &regxmm)
+               || operand_type_equal (&i.tm.operand_types[dest], &regymm)));
+
+      /* Generate an 8bit immediate operand to encode the register
+        operand.  */
+      expressionS *exp = &im_expressions[i.imm_operands++];
+      i.op[i.operands].imms = exp;
+      i.types[i.operands] = imm8;
+      i.operands++;
+      /* If VexW1 is set, the first operand is the source and
+        the second operand is encoded in the immediate operand.  */
+      if (i.tm.opcode_modifier.vexw1)
+       {
+         source = 0;
+         reg = 1;
+       }
+      else
+       {
+         source = 1;
+         reg = 0;
+       }      
+      /* FMA4 swaps REG and NDS.  */
+      if (i.tm.cpu_flags.bitfield.cpufma4)
+       {
+         unsigned int tmp;
+         tmp = reg;
+         reg = nds;
+         nds = tmp;
+       }      
+      gas_assert ((operand_type_equal (&i.tm.operand_types[reg], &regxmm)
+                  || operand_type_equal (&i.tm.operand_types[reg],
+                                         &regymm)) 
+                 && (operand_type_equal (&i.tm.operand_types[nds], &regxmm)
+                     || operand_type_equal (&i.tm.operand_types[nds], 
+                                            &regymm)));
+      exp->X_op = O_constant;
+      exp->X_add_number
+       = ((i.op[reg].regs->reg_num
+           + ((i.op[reg].regs->reg_flags & RegRex) ? 8 : 0)) << 4);      
+      i.vex.register_specifier = i.op[nds].regs;
     }
+  else
+    source = dest = 0;
 
   /* i.reg_operands MUST be the number of real register operands;
-     implicit registers do not count.  */
-  else if (i.reg_operands == 2)
+     implicit registers do not count.  If there are 3 register
+     operands, it must be a instruction with VexNDS.  For a
+     instruction with VexNDD, the destination register is encoded
+     in VEX prefix.  If there are 4 register operands, it must be
+     a instruction with VEX prefix and 3 sources.  */
+  if (i.mem_operands == 0
+      && ((i.reg_operands == 2
+          && !i.tm.opcode_modifier.vexndd)
+         || (i.reg_operands == 3
+             && i.tm.opcode_modifier.vexnds)
+         || (i.reg_operands == 4 && vex_3_sources)))
     {
-      unsigned int source, dest;
-
       switch (i.operands)
        {
        case 2:
@@ -4638,10 +4951,12 @@ build_modrm_byte (void)
        case 3:
          /* When there are 3 operands, one of them may be immediate,
             which may be the first or the last operand.  Otherwise,
-            the first operand must be shift count register (cl). */
-         assert (i.imm_operands == 1
-                 || (i.imm_operands == 0
-                     && i.types[0].bitfield.shiftcount));
+            the first operand must be shift count register (cl) or it
+            is an instruction with VexNDS. */
+         gas_assert (i.imm_operands == 1
+                     || (i.imm_operands == 0
+                         && (i.tm.opcode_modifier.vexnds
+                             || i.types[0].bitfield.shiftcount)));
          if (operand_type_check (i.types[0], imm)
              || i.types[0].bitfield.shiftcount)
            source = 1;
@@ -4651,17 +4966,54 @@ build_modrm_byte (void)
        case 4:
          /* When there are 4 operands, the first two must be 8bit
             immediate operands. The source operand will be the 3rd
-            one.  */
-         assert (i.imm_operands == 2
-                 && i.types[0].bitfield.imm8
-                 && i.types[1].bitfield.imm8);
-         source = 2;
+            one.
+
+            For instructions with VexNDS, if the first operand
+            an imm8, the source operand is the 2nd one.  If the last
+            operand is imm8, the source operand is the first one.  */
+         gas_assert ((i.imm_operands == 2
+                      && i.types[0].bitfield.imm8
+                      && i.types[1].bitfield.imm8)
+                     || (i.tm.opcode_modifier.vexnds
+                         && i.imm_operands == 1
+                         && (i.types[0].bitfield.imm8
+                             || i.types[i.operands - 1].bitfield.imm8)));
+         if (i.tm.opcode_modifier.vexnds)
+           {
+             if (i.types[0].bitfield.imm8)
+               source = 1;
+             else
+               source = 0;
+           }
+         else
+           source = 2;
+         break;
+       case 5:
          break;
        default:
          abort ();
        }
 
-      dest = source + 1;
+      if (!vex_3_sources)
+       {
+         dest = source + 1;
+
+         if (i.tm.opcode_modifier.vexnds)
+           {
+             /* For instructions with VexNDS, the register-only
+                source operand must be XMM or YMM register. It is
+                encoded in VEX prefix.  We need to clear RegMem bit
+                before calling operand_type_equal.  */
+             i386_operand_type op = i.tm.operand_types[dest];
+             op.bitfield.regmem = 0;
+             if ((dest + 1) >= i.operands
+                 || (!operand_type_equal (&op, &regxmm)
+                     && !operand_type_equal (&op, &regymm)))
+               abort ();
+             i.vex.register_specifier = i.op[dest].regs;
+             dest++;
+           }
+       }
 
       i.rm.mode = 3;
       /* One of the register operands will be encoded in the i.tm.reg
@@ -4700,24 +5052,17 @@ build_modrm_byte (void)
     }
   else
     {                  /* If it's not 2 reg operands...  */
+      unsigned int mem;
+
       if (i.mem_operands)
        {
          unsigned int fake_zero_displacement = 0;
          unsigned int op;
 
-         /* This has been precalculated for SSE5 instructions 
-            that have a DREX field earlier in process_drex.  */
-         if (i.tm.opcode_modifier.drex 
-             || i.tm.opcode_modifier.drexv 
-             || i.tm.opcode_modifier.drexc)
-           op = i.drex.modrm_regmem;
-         else
-           {
-             for (op = 0; op < i.operands; op++)
-               if (operand_type_check (i.types[op], anymem))
-                 break;
-             assert (op < i.operands);
-           }
+         for (op = 0; op < i.operands; op++)
+           if (operand_type_check (i.types[op], anymem))
+             break;
+         gas_assert (op < i.operands);
 
          default_seg = &ds;
 
@@ -4831,7 +5176,7 @@ build_modrm_byte (void)
                  && operand_type_check (i.types[op], disp))
                {
                  i386_operand_type temp;
-                 UINTS_CLEAR (temp);
+                 operand_type_set (&temp, 0);
                  temp.bitfield.disp8 = i.types[op].bitfield.disp8;
                  i.types[op] = temp;
                  if (i.prefix[ADDR_PREFIX] == 0)
@@ -4895,7 +5240,7 @@ build_modrm_byte (void)
                 holds the correct displacement size.  */
              expressionS *exp;
 
-             assert (i.op[op].disps == 0);
+             gas_assert (i.op[op].disps == 0);
              exp = &disp_expressions[i.disp_operands++];
              i.op[op].disps = exp;
              exp->X_op = O_constant;
@@ -4903,7 +5248,11 @@ build_modrm_byte (void)
              exp->X_add_symbol = (symbolS *) 0;
              exp->X_op_symbol = (symbolS *) 0;
            }
+
+         mem = op;
        }
+      else
+       mem = ~0;
 
       /* Fill in i.rm.reg or i.rm.regmem field with register operand
         (if any) based on i.tm.extension_opcode.  Again, we must be
@@ -4912,51 +5261,80 @@ build_modrm_byte (void)
       if (i.reg_operands)
        {
          unsigned int op;
+         unsigned int vex_reg = ~0;
+
+         for (op = 0; op < i.operands; op++)
+           if (i.types[op].bitfield.reg8
+               || i.types[op].bitfield.reg16
+               || i.types[op].bitfield.reg32
+               || i.types[op].bitfield.reg64
+               || i.types[op].bitfield.regmmx
+               || i.types[op].bitfield.regxmm
+               || i.types[op].bitfield.regymm
+               || i.types[op].bitfield.sreg2
+               || i.types[op].bitfield.sreg3
+               || i.types[op].bitfield.control
+               || i.types[op].bitfield.debug
+               || i.types[op].bitfield.test)
+             break;
 
-         /* This has been precalculated for SSE5 instructions 
-            that have a DREX field earlier in process_drex.  */
-         if (i.tm.opcode_modifier.drex 
-             || i.tm.opcode_modifier.drexv 
-             || i.tm.opcode_modifier.drexc)
-           {
-             op = i.drex.modrm_reg;
-             i.rm.reg = i.op[op].regs->reg_num;
-             if ((i.op[op].regs->reg_flags & RegRex) != 0)
-               i.rex |= REX_R;
-           }
-         else
+         if (vex_3_sources)
+           op = dest;
+         else if (i.tm.opcode_modifier.vexnds)
            {
-             for (op = 0; op < i.operands; op++)
-               if (i.types[op].bitfield.reg8
-                   || i.types[op].bitfield.reg16
-                   || i.types[op].bitfield.reg32
-                   || i.types[op].bitfield.reg64
-                   || i.types[op].bitfield.regmmx
-                   || i.types[op].bitfield.regxmm
-                   || i.types[op].bitfield.sreg2
-                   || i.types[op].bitfield.sreg3
-                   || i.types[op].bitfield.control
-                   || i.types[op].bitfield.debug
-                   || i.types[op].bitfield.test)
-                 break;
+             /* For instructions with VexNDS, the register-only
+                source operand is encoded in VEX prefix. */
+             gas_assert (mem != (unsigned int) ~0);
 
-             assert (op < i.operands);
-
-             /* If there is an extension opcode to put here, the 
-                register number must be put into the regmem field.  */
-             if (i.tm.extension_opcode != None)
+             if (op > mem)
                {
-                 i.rm.regmem = i.op[op].regs->reg_num;
-                 if ((i.op[op].regs->reg_flags & RegRex) != 0)
-                   i.rex |= REX_B;
+                 vex_reg = op++;
+                 gas_assert (op < i.operands);
                }
              else
                {
-                 i.rm.reg = i.op[op].regs->reg_num;
-                 if ((i.op[op].regs->reg_flags & RegRex) != 0)
-                   i.rex |= REX_R;
+                 vex_reg = op + 1;
+                 gas_assert (vex_reg < i.operands);
                }
            }
+         else if (i.tm.opcode_modifier.vexndd)
+           {
+             /* For instructions with VexNDD, there should be
+                no memory operand and the register destination
+                is encoded in VEX prefix.  */
+             gas_assert (i.mem_operands == 0
+                         && (op + 2) == i.operands);
+             vex_reg = op + 1;
+           }
+         else
+           gas_assert (op < i.operands);
+
+         if (vex_reg != (unsigned int) ~0)
+           {
+             gas_assert (i.reg_operands == 2);
+
+             if (!operand_type_equal (&i.tm.operand_types[vex_reg],
+                                      & regxmm)
+                 && !operand_type_equal (&i.tm.operand_types[vex_reg],
+                                         &regymm))
+               abort ();
+             i.vex.register_specifier = i.op[vex_reg].regs;
+           }
+
+         /* If there is an extension opcode to put here, the
+            register number must be put into the regmem field.  */
+         if (i.tm.extension_opcode != None)
+           {
+             i.rm.regmem = i.op[op].regs->reg_num;
+             if ((i.op[op].regs->reg_flags & RegRex) != 0)
+               i.rex |= REX_B;
+           }
+         else
+           {
+             i.rm.reg = i.op[op].regs->reg_num;
+             if ((i.op[op].regs->reg_flags & RegRex) != 0)
+               i.rex |= REX_R;
+           }
 
          /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we
             must set it to 3 to indicate this is a register operand
@@ -4966,10 +5344,7 @@ build_modrm_byte (void)
        }
 
       /* Fill in i.rm.reg field with extension opcode (if any).  */
-      if (i.tm.extension_opcode != None
-         && !(i.tm.opcode_modifier.drex 
-             || i.tm.opcode_modifier.drexv 
-             || i.tm.opcode_modifier.drexc))
+      if (i.tm.extension_opcode != None)
        i.rm.reg = i.tm.extension_opcode;
     }
   return default_seg;
@@ -5213,40 +5588,71 @@ output_insn (void)
       unsigned int j;
       unsigned int prefix;
 
-      switch (i.tm.opcode_length)
+      /* Since the VEX prefix contains the implicit prefix, we don't
+         need the explicit prefix.  */
+      if (!i.tm.opcode_modifier.vex)
        {
-       case 3:
-         if (i.tm.base_opcode & 0xff000000)
-           {
-             prefix = (i.tm.base_opcode >> 24) & 0xff;
-             goto check_prefix;
-           }
-         break;
-       case 2:
-         if ((i.tm.base_opcode & 0xff0000) != 0)
+         switch (i.tm.opcode_length)
            {
-             prefix = (i.tm.base_opcode >> 16) & 0xff;
-             if (i.tm.cpu_flags.bitfield.cpupadlock)
+           case 3:
+             if (i.tm.base_opcode & 0xff000000)
+               {
+                 prefix = (i.tm.base_opcode >> 24) & 0xff;
+                 goto check_prefix;
+               }
+             break;
+           case 2:
+             if ((i.tm.base_opcode & 0xff0000) != 0)
                {
+                 prefix = (i.tm.base_opcode >> 16) & 0xff;
+                 if (i.tm.cpu_flags.bitfield.cpupadlock)
+                   {
 check_prefix:
-                 if (prefix != REPE_PREFIX_OPCODE
-                     || i.prefix[LOCKREP_PREFIX] != REPE_PREFIX_OPCODE)
+                     if (prefix != REPE_PREFIX_OPCODE
+                         || (i.prefix[LOCKREP_PREFIX]
+                             != REPE_PREFIX_OPCODE))
+                       add_prefix (prefix);
+                   }
+                 else
                    add_prefix (prefix);
                }
-             else
-               add_prefix (prefix);
+             break;
+           case 1:
+             break;
+           default:
+             abort ();
            }
-         break;
-       case 1:
-         break;
-       default:
-         abort ();
+
+         /* The prefix bytes.  */
+         for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
+           if (*q)
+             FRAG_APPEND_1_CHAR (*q);
        }
 
-      /* The prefix bytes.  */
-      for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
-       if (*q)
-         FRAG_APPEND_1_CHAR (*q);
+      if (i.tm.opcode_modifier.vex)
+       {
+         for (j = 0, q = i.prefix; j < ARRAY_SIZE (i.prefix); j++, q++)
+           if (*q)
+             switch (j)
+               {
+               case REX_PREFIX:
+                 /* REX byte is encoded in VEX prefix.  */
+                 break;
+               case SEG_PREFIX:
+               case ADDR_PREFIX:
+                 FRAG_APPEND_1_CHAR (*q);
+                 break;
+               default:
+                 /* There should be no other prefixes for instructions
+                    with VEX prefix.  */
+                 abort ();
+               }
+
+         /* Now the VEX prefix.  */
+         p = frag_more (i.vex.length);
+         for (j = 0; j < i.vex.length; j++)
+           p[j] = i.vex.bytes[j];
+       }
 
       /* Now the opcode; be careful about word order here!  */
       if (i.tm.opcode_length == 1)
@@ -5272,13 +5678,6 @@ check_prefix:
          /* Put out high byte first: can't use md_number_to_chars!  */
          *p++ = (i.tm.base_opcode >> 8) & 0xff;
          *p = i.tm.base_opcode & 0xff;
-
-         /* On SSE5, encode the OC1 bit in the DREX field if this 
-            encoding has multiple formats.  */
-         if (i.tm.opcode_modifier.drex 
-             && i.tm.opcode_modifier.drexv 
-             && DREX_OC1 (i.tm.extension_opcode))
-           *p |= DREX_OC1_MASK;
        }
 
       /* Now the modrm byte and sib byte (if present).  */
@@ -5299,20 +5698,6 @@ check_prefix:
                                 | i.sib.scale << 6));
        }
 
-      /* Write the DREX byte if needed.  */
-      if (i.tm.opcode_modifier.drex || i.tm.opcode_modifier.drexc)
-       {
-         p = frag_more (1);
-         *p = (((i.drex.reg & 0xf) << 4) | (i.drex.rex & 0x7));
-
-         /* Encode the OC0 bit if this encoding has multiple 
-            formats.  */
-         if ((i.tm.opcode_modifier.drex 
-              || i.tm.opcode_modifier.drexv) 
-             && DREX_OC0 (i.tm.extension_opcode))
-           *p |= DREX_OC0_MASK;
-       }
-
       if (i.disp_operands)
        output_disp (insn_start_frag, insn_start_off);
 
@@ -5386,7 +5771,7 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off)
              int pcrel = (i.flags[n] & Operand_PCrel) != 0;
 
              /* We can't have 8 bit displacement here.  */
-             assert (!i.types[n].bitfield.disp8);
+             gas_assert (!i.types[n].bitfield.disp8);
 
              /* The PC relative address is computed relative
                 to the instruction boundary, so in case immediate
@@ -5401,12 +5786,12 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off)
                      {
                        /* Only one immediate is allowed for PC
                           relative address.  */
-                       assert (sz == 0);
+                       gas_assert (sz == 0);
                        sz = imm_size (n1);
                        i.op[n].disps->X_add_number -= sz;
                      }
                  /* We should find the immediate.  */
-                 assert (sz != 0);
+                 gas_assert (sz != 0);
                }
 
              p = frag_more (size);
@@ -5668,7 +6053,7 @@ lex_got (enum bfd_reloc_code_real *reloc,
       OPERAND_TYPE_NONE },
     { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32,
                    BFD_RELOC_X86_64_DTPOFF32 },
-      
+
       OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
     { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,
                    0                         },
@@ -5763,6 +6148,8 @@ lex_got (enum bfd_reloc_code_real *reloc,
 void
 x86_cons (expressionS *exp, int size)
 {
+  intel_syntax = -intel_syntax;
+
   if (size == 4 || (object_64bit && size == 8))
     {
       /* Handle @GOTOFF and the like in an expression.  */
@@ -5801,6 +6188,11 @@ x86_cons (expressionS *exp, int size)
     }
   else
     expression (exp);
+
+  intel_syntax = -intel_syntax;
+
+  if (intel_syntax)
+    i386_intel_simplify (exp);
 }
 #endif
 
@@ -5843,7 +6235,7 @@ i386_immediate (char *imm_start)
   expressionS *exp;
   i386_operand_type types;
 
-  UINTS_SET (types, ~0);
+  operand_type_set (&types, ~0);
 
   if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
     {
@@ -5873,14 +6265,21 @@ i386_immediate (char *imm_start)
 
   input_line_pointer = save_input_line_pointer;
   if (gotfree_input_line)
-    free (gotfree_input_line);
+    {
+      free (gotfree_input_line);
+
+      if (exp->X_op == O_constant || exp->X_op == O_register)
+       exp->X_op = O_illegal;
+    }
+
+  return i386_finalize_immediate (exp_seg, exp, types, imm_start);
+}
 
-  if (exp->X_op == O_absent
-      || exp->X_op == O_illegal
-      || exp->X_op == O_big
-      || (gotfree_input_line
-         && (exp->X_op == O_constant
-             || exp->X_op == O_register)))
+static int
+i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
+                        i386_operand_type types, const char *imm_start)
+{
+  if (exp->X_op == O_absent || exp->X_op == O_illegal || exp->X_op == O_big)
     {
       as_bad (_("missing or invalid immediate expression `%s'"),
              imm_start);
@@ -5995,7 +6394,7 @@ i386_displacement (char *disp_start, char *disp_end)
       return 0;
     }
 
-  UINTS_CLEAR (bigdisp);
+  operand_type_set (&bigdisp, 0);
   if ((i.types[this_operand].bitfield.jumpabsolute)
       || (!current_templates->start->opcode_modifier.jump
          && !current_templates->start->opcode_modifier.jumpdword))
@@ -6113,8 +6512,26 @@ i386_displacement (char *disp_start, char *disp_end)
 #endif
   input_line_pointer = save_input_line_pointer;
   if (gotfree_input_line)
-    free (gotfree_input_line);
-  ret = 1;
+    {
+      free (gotfree_input_line);
+
+      if (exp->X_op == O_constant || exp->X_op == O_register)
+       exp->X_op = O_illegal;
+    }
+
+  ret = i386_finalize_displacement (exp_seg, exp, types, disp_start);
+
+  RESTORE_END_STRING (disp_end);
+
+  return ret;
+}
+
+static int
+i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
+                           i386_operand_type types, const char *disp_start)
+{
+  i386_operand_type bigdisp;
+  int ret = 1;
 
   /* We do this to make sure that the section symbol is in
      the symbol table.  We will ultimately change the relocation
@@ -6141,10 +6558,7 @@ i386_displacement (char *disp_start, char *disp_end)
 
   else if (exp->X_op == O_absent
           || exp->X_op == O_illegal
-          || exp->X_op == O_big
-          || (gotfree_input_line
-              && (exp->X_op == O_constant
-                  || exp->X_op == O_register)))
+          || exp->X_op == O_big)
     {
     inv_disp:
       as_bad (_("missing or invalid displacement expression `%s'"),
@@ -6167,8 +6581,6 @@ i386_displacement (char *disp_start, char *disp_end)
     }
 #endif
 
-  RESTORE_END_STRING (disp_end);
-
   /* Check if this is a displacement only operand.  */
   bigdisp = i.types[this_operand];
   bigdisp.bitfield.disp8 = 0;
@@ -6176,7 +6588,7 @@ i386_displacement (char *disp_start, char *disp_end)
   bigdisp.bitfield.disp32 = 0;
   bigdisp.bitfield.disp32s = 0;
   bigdisp.bitfield.disp64 = 0;
-  if (UINTS_ALL_ZERO (bigdisp))
+  if (operand_type_all_zero (&bigdisp))
     i.types[this_operand] = operand_type_and (i.types[this_operand],
                                              types);
 
@@ -6190,13 +6602,77 @@ static int
 i386_index_check (const char *operand_string)
 {
   int ok;
+  const char *kind = "base/index";
 #if INFER_ADDR_PREFIX
   int fudged = 0;
 
  tryprefix:
 #endif
   ok = 1;
-  if (flag_code == CODE_64BIT)
+  if (current_templates->start->opcode_modifier.isstring
+      && !current_templates->start->opcode_modifier.immext
+      && (current_templates->end[-1].opcode_modifier.isstring
+         || i.mem_operands))
+    {
+      /* 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;
+
+      kind = "string address";
+
+      if (current_templates->start->opcode_modifier.w)
+       {
+         i386_operand_type type = current_templates->end[-1].operand_types[0];
+
+         if (!type.bitfield.baseindex
+             || ((!i.mem_operands != !intel_syntax)
+                 && 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 */;
+       }
+      else
+       expected = 3 /* rBX */;
+
+      if (!i.base_reg || i.index_reg
+         || 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);
+         as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"),
+                  operand_string,
+                  intel_syntax ? '[' : '(',
+                  register_prefix,
+                  i386_regtab[j].reg_name,
+                  intel_syntax ? ']' : ')');
+         ok = 1;
+       }
+    }
+  else if (flag_code == CODE_64BIT)
     {
       if ((i.base_reg
           && ((i.prefix[ADDR_PREFIX] == 0
@@ -6249,7 +6725,7 @@ i386_index_check (const char *operand_string)
   if (!ok)
     {
 #if INFER_ADDR_PREFIX
-      if (i.prefix[ADDR_PREFIX] == 0)
+      if (!i.mem_operands && !i.prefix[ADDR_PREFIX])
        {
          i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
          i.prefixes += 1;
@@ -6267,18 +6743,24 @@ i386_index_check (const char *operand_string)
          goto tryprefix;
        }
       if (fudged)
-       as_bad (_("`%s' is not a valid base/index expression"),
-               operand_string);
+       as_bad (_("`%s' is not a valid %s expression"),
+               operand_string,
+               kind);
       else
 #endif
-       as_bad (_("`%s' is not a valid %s bit base/index expression"),
+       as_bad (_("`%s' is not a valid %s-bit %s expression"),
                operand_string,
-               flag_code_names[flag_code]);
+               flag_code_names[i.prefix[ADDR_PREFIX]
+                                        ? flag_code == CODE_32BIT
+                                          ? CODE_16BIT
+                                          : CODE_32BIT
+                                        : flag_code],
+               kind);
     }
   return ok;
 }
 
-/* Parse OPERAND_STRING into the i386_insn structure I.  Returns non-zero
+/* Parse OPERAND_STRING into the i386_insn structure I.  Returns zero
    on error.  */
 
 static int
@@ -6549,14 +7031,14 @@ i386_att_operand (char *operand_string)
 
       /* Special case for (%dx) while doing input/output op.  */
       if (i.base_reg
-         && UINTS_EQUAL (i.base_reg->reg_type, reg16_inoutportreg)
+         && operand_type_equal (&i.base_reg->reg_type,
+                                &reg16_inoutportreg)
          && i.index_reg == 0
          && i.log2_scale_factor == 0
          && i.seg[i.mem_operands] == 0
          && !operand_type_check (i.types[this_operand], disp))
        {
-         UINTS_CLEAR (i.types[this_operand]);
-         i.types[this_operand].bitfield.inoutportreg = 1;
+         i.types[this_operand] = inoutportreg;
          return 1;
        }
 
@@ -6603,7 +7085,13 @@ md_estimate_size_before_relax (fragP, segment)
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       || (IS_ELF
          && (S_IS_EXTERNAL (fragP->fr_symbol)
-             || S_IS_WEAK (fragP->fr_symbol)))
+             || S_IS_WEAK (fragP->fr_symbol)
+             || ((symbol_get_bfdsym (fragP->fr_symbol)->flags
+                  & BSF_GNU_INDIRECT_FUNCTION))))
+#endif
+#if defined (OBJ_COFF) && defined (TE_PE)
+      || (OUTPUT_FLAVOR == bfd_target_coff_flavour
+         && S_IS_WEAK (fragP->fr_symbol))
 #endif
       )
     {
@@ -6880,7 +7368,7 @@ md_apply_fix (fixP, valP, seg)
          if ((sym_seg == seg
               || (symbol_section_p (fixP->fx_addsy)
                   && sym_seg != absolute_section))
-             && !generic_force_reloc (fixP))
+             && !TC_FORCE_RELOCATION (fixP))
            {
              /* Yes, we add the values in twice.  This is because
                 bfd_install_relocation subtracts them out again.  I think
@@ -6898,6 +7386,12 @@ md_apply_fix (fixP, valP, seg)
        value += md_pcrel_from (fixP);
 #endif
     }
+#if defined (OBJ_COFF) && defined (TE_PE)
+  if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
+    {
+      value -= S_GET_VALUE (fixP->fx_addsy);
+    }
+#endif
 
   /* Fix a few things - the dynamic linker expects certain values here,
      and we must not disappoint it.  */
@@ -6961,6 +7455,16 @@ md_apply_fix (fixP, valP, seg)
   /* Are we finished with this relocation now?  */
   if (fixP->fx_addsy == NULL)
     fixP->fx_done = 1;
+#if defined (OBJ_COFF) && defined (TE_PE)
+  else if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
+    {
+      fixP->fx_done = 0;
+      /* Remember value for tc_gen_reloc.  */
+      fixP->fx_addnumber = value;
+      /* Clear out the frag for now.  */
+      value = 0;
+    }
+#endif
   else if (use_rela_relocations)
     {
       fixP->fx_no_overflow = 1;
@@ -7061,19 +7565,42 @@ parse_real_register (char *reg_string, char **end_op)
   if (r == NULL || allow_pseudo_reg)
     return r;
 
-  if (UINTS_ALL_ZERO (r->reg_type))
+  if (operand_type_all_zero (&r->reg_type))
     return (const reg_entry *) NULL;
 
-  /* Don't allow fake index register unless allow_index_reg isn't 0. */
-  if (!allow_index_reg
-      && (r->reg_num == RegEiz || r->reg_num == RegRiz))
+  if ((r->reg_type.bitfield.reg32
+       || r->reg_type.bitfield.sreg3
+       || r->reg_type.bitfield.control
+       || r->reg_type.bitfield.debug
+       || r->reg_type.bitfield.test)
+      && !cpu_arch_flags.bitfield.cpui386)
     return (const reg_entry *) NULL;
 
-  if (((r->reg_flags & (RegRex64 | RegRex))
-       || r->reg_type.bitfield.reg64)
-      && (!cpu_arch_flags.bitfield.cpulm
-         || !UINTS_EQUAL (r->reg_type, control))
-      && flag_code != CODE_64BIT)
+  if (r->reg_type.bitfield.floatreg
+      && !cpu_arch_flags.bitfield.cpu8087
+      && !cpu_arch_flags.bitfield.cpu287
+      && !cpu_arch_flags.bitfield.cpu387)
+    return (const reg_entry *) NULL;
+
+  if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpummx)
+    return (const reg_entry *) NULL;
+
+  if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpusse)
+    return (const reg_entry *) NULL;
+
+  if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuavx)
+    return (const reg_entry *) NULL;
+
+  /* Don't allow fake index register unless allow_index_reg isn't 0. */
+  if (!allow_index_reg
+      && (r->reg_num == RegEiz || r->reg_num == RegRiz))
+    return (const reg_entry *) NULL;
+
+  if (((r->reg_flags & (RegRex64 | RegRex))
+       || r->reg_type.bitfield.reg64)
+      && (!cpu_arch_flags.bitfield.cpulm
+         || !operand_type_equal (&r->reg_type, &control))
+      && flag_code != CODE_64BIT)
     return (const reg_entry *) NULL;
 
   if (r->reg_type.bitfield.sreg3 && r->reg_num == RegFlat && !intel_syntax)
@@ -7136,23 +7663,45 @@ i386_parse_name (char *name, expressionS *e, char *nextcharP)
     }
   input_line_pointer = end;
   *end = 0;
-  return 0;
+  return intel_syntax ? i386_intel_parse_name (name, e) : 0;
 }
 
 void
 md_operand (expressionS *e)
 {
-  if (*input_line_pointer == REGISTER_PREFIX)
-    {
-      char *end;
-      const reg_entry *r = parse_real_register (input_line_pointer, &end);
+  char *end;
+  const reg_entry *r;
 
+  switch (*input_line_pointer)
+    {
+    case REGISTER_PREFIX:
+      r = parse_real_register (input_line_pointer, &end);
       if (r)
        {
          e->X_op = O_register;
          e->X_add_number = r - i386_regtab;
          input_line_pointer = end;
        }
+      break;
+
+    case '[':
+      gas_assert (intel_syntax);
+      end = input_line_pointer++;
+      expression (e);
+      if (*input_line_pointer == ']')
+       {
+         ++input_line_pointer;
+         e->X_op_symbol = make_expr_symbol (e);
+         e->X_add_symbol = NULL;
+         e->X_add_number = 0;
+         e->X_op = O_index;
+       }
+      else
+       {
+         e->X_op = O_absent;
+         input_line_pointer = end;
+       }
+      break;
     }
 }
 
@@ -7173,11 +7722,14 @@ const char *md_shortopts = "qn";
 #define OPTION_MINDEX_REG (OPTION_MD_BASE + 7)
 #define OPTION_MNAKED_REG (OPTION_MD_BASE + 8)
 #define OPTION_MOLD_GCC (OPTION_MD_BASE + 9)
+#define OPTION_MSSE2AVX (OPTION_MD_BASE + 10)
+#define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11)
 
 struct option md_longopts[] =
 {
   {"32", no_argument, NULL, OPTION_32},
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined(TE_PEP)
+#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
+     || defined (TE_PE) || defined (TE_PEP))
   {"64", no_argument, NULL, OPTION_64},
 #endif
   {"divide", no_argument, NULL, OPTION_DIVIDE},
@@ -7188,6 +7740,8 @@ struct option md_longopts[] =
   {"mindex-reg", no_argument, NULL, OPTION_MINDEX_REG},
   {"mnaked-reg", no_argument, NULL, OPTION_MNAKED_REG},
   {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
+  {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
+  {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
@@ -7228,7 +7782,8 @@ md_parse_option (int c, char *arg)
         .stab instead of .stab.excl.  We always use .stab anyhow.  */
       break;
 #endif
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined(TE_PEP)
+#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
+     || defined (TE_PE) || defined (TE_PEP))
     case OPTION_64:
       {
        const char **list, **l;
@@ -7302,9 +7857,14 @@ md_parse_option (int c, char *arg)
                {
                  /* ISA entension.  */
                  i386_cpu_flags flags;
-                 flags = cpu_flags_or (cpu_arch_flags,
-                                       cpu_arch[i].flags);
-                 if (!UINTS_EQUAL (flags, cpu_arch_flags))
+
+                 if (strncmp (arch, "no", 2))
+                   flags = cpu_flags_or (cpu_arch_flags,
+                                         cpu_arch[i].flags);
+                 else
+                   flags = cpu_flags_and_not (cpu_arch_flags,
+                                              cpu_arch[i].flags);
+                 if (!cpu_flags_equal (&flags, &cpu_arch_flags))
                    {
                      if (cpu_sub_arch_name)
                        {
@@ -7377,6 +7937,21 @@ md_parse_option (int c, char *arg)
       old_gcc = 1;
       break;
 
+    case OPTION_MSSE2AVX:
+      sse2avx = 1;
+      break;
+
+    case OPTION_MSSE_CHECK:
+      if (strcasecmp (arg, "error") == 0)
+       sse_check = sse_check_error;
+      else if (strcasecmp (arg, "warning") == 0)
+       sse_check = sse_check_warning;
+      else if (strcasecmp (arg, "none") == 0)
+       sse_check = sse_check_none;
+      else
+       as_fatal (_("Invalid -msse-check= option: `%s'"), arg);
+      break;
+
     default:
       return 0;
     }
@@ -7400,7 +7975,8 @@ md_show_usage (stream)
   fprintf (stream, _("\
   -s                      ignored\n"));
 #endif
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined(TE_PEP)
+#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
+     || defined (TE_PE) || defined (TE_PEP))
   fprintf (stream, _("\
   --32/--64               generate 32bit/64bit code\n"));
 #endif
@@ -7416,18 +7992,25 @@ md_show_usage (stream)
                           generate code for CPU and EXTENSION, CPU is one of:\n\
                            i8086, i186, i286, i386, i486, pentium, pentiumpro,\n\
                            pentiumii, pentiumiii, pentium4, prescott, nocona,\n\
-                           core, core2, k6, k6_2, athlon, k8, amdfam10,\n\
-                           generic32, generic64\n\
+                           core, core2, corei7, l1om, k6, k6_2, athlon, k8,\n\
+                           amdfam10, generic32, generic64\n\
                           EXTENSION is combination of:\n\
-                           mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, sse4,\n\
-                           vmx, smx, xsave, 3dnow, 3dnowa, sse4a, sse5, svme,\n\
-                          abm, padlock\n"));
+                           8087, 287, 387, no87, mmx, nommx, sse, sse2, sse3,\n\
+                           ssse3, sse4.1, sse4.2, sse4, nosse, avx, noavx,\n\
+                           vmx, smx, xsave, movbe, ept, aes, pclmul, fma,\n\
+                           clflush, syscall, rdtscp, 3dnow, 3dnowa, sse4a,\n\
+                           svme, abm, padlock, fma4\n"));
   fprintf (stream, _("\
   -mtune=CPU              optimize for CPU, CPU is one of:\n\
                            i8086, i186, i286, i386, i486, pentium, pentiumpro,\n\
                            pentiumii, pentiumiii, pentium4, prescott, nocona,\n\
-                           core, core2, k6, k6_2, athlon, k8, amdfam10,\n\
-                           generic32, generic64\n"));
+                           core, core2, corei7, l1om, k6, k6_2, athlon, k8,\n\
+                           amdfam10, generic32, generic64\n"));
+  fprintf (stream, _("\
+  -msse2avx               encode SSE instructions with VEX prefix\n"));
+  fprintf (stream, _("\
+  -msse-check=[none|error|warning]\n\
+                          check SSE instructions\n"));
   fprintf (stream, _("\
   -mmnemonic=[att|intel]  use AT&T/Intel mnemonic\n"));
   fprintf (stream, _("\
@@ -7441,7 +8024,8 @@ md_show_usage (stream)
 }
 
 #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
-     || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (TE_PEP))
+     || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
+     || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
 
 /* Pick the target format to use.  */
 
@@ -7451,7 +8035,7 @@ i386_target_format (void)
   if (!strcmp (default_arch, "x86_64"))
     {
       set_code_flag (CODE_64BIT);
-      if (UINTS_ALL_ZERO (cpu_arch_isa_flags))
+      if (cpu_flags_all_zero (&cpu_arch_isa_flags))
        {
          cpu_arch_isa_flags.bitfield.cpui186 = 1;
          cpu_arch_isa_flags.bitfield.cpui286 = 1;
@@ -7459,12 +8043,13 @@ i386_target_format (void)
          cpu_arch_isa_flags.bitfield.cpui486 = 1;
          cpu_arch_isa_flags.bitfield.cpui586 = 1;
          cpu_arch_isa_flags.bitfield.cpui686 = 1;
-         cpu_arch_isa_flags.bitfield.cpup4 = 1;
+         cpu_arch_isa_flags.bitfield.cpuclflush = 1;
          cpu_arch_isa_flags.bitfield.cpummx= 1;
          cpu_arch_isa_flags.bitfield.cpusse = 1;
          cpu_arch_isa_flags.bitfield.cpusse2 = 1;
+         cpu_arch_isa_flags.bitfield.cpulm = 1;
        }
-      if (UINTS_ALL_ZERO (cpu_arch_tune_flags))
+      if (cpu_flags_all_zero (&cpu_arch_tune_flags))
        {
          cpu_arch_tune_flags.bitfield.cpui186 = 1;
          cpu_arch_tune_flags.bitfield.cpui286 = 1;
@@ -7472,7 +8057,7 @@ i386_target_format (void)
          cpu_arch_tune_flags.bitfield.cpui486 = 1;
          cpu_arch_tune_flags.bitfield.cpui586 = 1;
          cpu_arch_tune_flags.bitfield.cpui686 = 1;
-         cpu_arch_tune_flags.bitfield.cpup4 = 1;
+         cpu_arch_tune_flags.bitfield.cpuclflush = 1;
          cpu_arch_tune_flags.bitfield.cpummx= 1;
          cpu_arch_tune_flags.bitfield.cpusse = 1;
          cpu_arch_tune_flags.bitfield.cpusse2 = 1;
@@ -7481,13 +8066,13 @@ i386_target_format (void)
   else if (!strcmp (default_arch, "i386"))
     {
       set_code_flag (CODE_32BIT);
-      if (UINTS_ALL_ZERO (cpu_arch_isa_flags))
+      if (cpu_flags_all_zero (&cpu_arch_isa_flags))
        {
          cpu_arch_isa_flags.bitfield.cpui186 = 1;
          cpu_arch_isa_flags.bitfield.cpui286 = 1;
          cpu_arch_isa_flags.bitfield.cpui386 = 1;
        }
-      if (UINTS_ALL_ZERO (cpu_arch_tune_flags))
+      if (cpu_flags_all_zero (&cpu_arch_tune_flags))
        {
          cpu_arch_tune_flags.bitfield.cpui186 = 1;
          cpu_arch_tune_flags.bitfield.cpui286 = 1;
@@ -7498,10 +8083,9 @@ i386_target_format (void)
     as_fatal (_("Unknown architecture"));
   switch (OUTPUT_FLAVOR)
     {
-#ifdef TE_PEP
+#if defined (TE_PE) || defined (TE_PEP)
     case bfd_target_coff_flavour:
-      return flag_code == CODE_64BIT ? COFF_TARGET_FORMAT : "coff-i386";
-      break;
+      return flag_code == CODE_64BIT ? "pe-x86-64" : "pe-i386";
 #endif
 #ifdef OBJ_MAYBE_AOUT
     case bfd_target_aout_flavour:
@@ -7519,8 +8103,20 @@ i386_target_format (void)
            object_64bit = 1;
            use_rela_relocations = 1;
          }
-       return flag_code == CODE_64BIT ? ELF_TARGET_FORMAT64 : ELF_TARGET_FORMAT;
+       if (cpu_arch_isa_flags.bitfield.cpul1om)
+         {
+           if (flag_code != CODE_64BIT)
+             as_fatal (_("Intel L1OM is 64bit only"));
+           return ELF_TARGET_L1OM_FORMAT;
+         }
+       else
+         return (flag_code == CODE_64BIT
+                 ? ELF_TARGET_FORMAT64 : ELF_TARGET_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";
 #endif
     default:
       abort ();
@@ -7796,7 +8392,11 @@ tc_gen_reloc (section, fixp)
         vtable entry to be used in the relocation's section offset.  */
       if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
        rel->address = fixp->fx_offset;
-
+#if defined (OBJ_COFF) && defined (TE_PE)
+      else if (fixp->fx_addsy && S_IS_WEAK (fixp->fx_addsy))
+       rel->addend = fixp->fx_addnumber - (S_GET_VALUE (fixp->fx_addsy) * 2);
+      else
+#endif
       rel->addend = 0;
     }
   /* Use the rela in 64bit mode.  */
@@ -7834,1324 +8434,13 @@ tc_gen_reloc (section, fixp)
                    bfd_get_reloc_code_name (code));
       /* Set howto to a garbage value so that we can keep going.  */
       rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
-      assert (rel->howto != NULL);
+      gas_assert (rel->howto != NULL);
     }
 
   return rel;
 }
 
-\f
-/* Parse operands using Intel syntax. This implements a recursive descent
-   parser based on the BNF grammar published in Appendix B of the MASM 6.1
-   Programmer's Guide.
-
-   FIXME: We do not recognize the full operand grammar defined in the MASM
-         documentation.  In particular, all the structure/union and
-         high-level macro operands are missing.
-
-   Uppercase words are terminals, lower case words are non-terminals.
-   Objects surrounded by double brackets '[[' ']]' are optional. Vertical
-   bars '|' denote choices. Most grammar productions are implemented in
-   functions called 'intel_<production>'.
-
-   Initial production is 'expr'.
-
-    addOp              + | -
-
-    alpha              [a-zA-Z]
-
-    binOp              & | AND | \| | OR | ^ | XOR
-
-    byteRegister       AL | AH | BL | BH | CL | CH | DL | DH
-
-    constant           digits [[ radixOverride ]]
-
-    dataType           BYTE | WORD | DWORD | FWORD | QWORD | TBYTE | OWORD | XMMWORD
-
-    digits             decdigit
-                       | digits decdigit
-                       | digits hexdigit
-
-    decdigit           [0-9]
-
-    e04                        e04 addOp e05
-                       | e05
-
-    e05                        e05 binOp e06
-                       | e06
-
-    e06                        e06 mulOp e09
-                       | e09
-
-    e09                        OFFSET e10
-                       | SHORT e10
-                       | + e10
-                       | - e10
-                       | ~ e10
-                       | NOT e10
-                       | e09 PTR e10
-                       | e09 : e10
-                       | e10
-
-    e10                        e10 [ expr ]
-                       | e11
-
-    e11                        ( expr )
-                       | [ expr ]
-                       | constant
-                       | dataType
-                       | id
-                       | $
-                       | register
-
- => expr               expr cmpOp e04
-                       | e04
-
-    gpRegister         AX | EAX | BX | EBX | CX | ECX | DX | EDX
-                       | BP | EBP | SP | ESP | DI | EDI | SI | ESI
-
-    hexdigit           a | b | c | d | e | f
-                       | A | B | C | D | E | F
-
-    id                 alpha
-                       | id alpha
-                       | id decdigit
-
-    mulOp              * | / | % | MOD | << | SHL | >> | SHR
-
-    quote              " | '
-
-    register           specialRegister
-                       | gpRegister
-                       | byteRegister
-
-    segmentRegister    CS | DS | ES | FS | GS | SS
-
-    specialRegister    CR0 | CR2 | CR3 | CR4
-                       | DR0 | DR1 | DR2 | DR3 | DR6 | DR7
-                       | TR3 | TR4 | TR5 | TR6 | TR7
-
-    We simplify the grammar in obvious places (e.g., register parsing is
-    done by calling parse_register) and eliminate immediate left recursion
-    to implement a recursive-descent parser.
-
-    expr       e04 expr'
-
-    expr'      cmpOp e04 expr'
-               | Empty
-
-    e04                e05 e04'
-
-    e04'       addOp e05 e04'
-               | Empty
-
-    e05                e06 e05'
-
-    e05'       binOp e06 e05'
-               | Empty
-
-    e06                e09 e06'
-
-    e06'       mulOp e09 e06'
-               | Empty
-
-    e09                OFFSET e10 e09'
-               | SHORT e10'
-               | + e10'
-               | - e10'
-               | ~ e10'
-               | NOT e10'
-               | e10 e09'
-
-    e09'       PTR e10 e09'
-               | : e10 e09'
-               | Empty
-
-    e10                e11 e10'
-
-    e10'       [ expr ] e10'
-               | Empty
-
-    e11                ( expr )
-               | [ expr ]
-               | BYTE
-               | WORD
-               | DWORD
-               | FWORD
-               | QWORD
-               | TBYTE
-               | OWORD
-               | XMMWORD
-               | .
-               | $
-               | register
-               | id
-               | constant  */
-
-/* Parsing structure for the intel syntax parser. Used to implement the
-   semantic actions for the operand grammar.  */
-struct intel_parser_s
-  {
-    char *op_string;           /* The string being parsed.  */
-    int got_a_float;           /* Whether the operand is a float.  */
-    int op_modifier;           /* Operand modifier.  */
-    int is_mem;                        /* 1 if operand is memory reference.  */
-    int in_offset;             /* >=1 if parsing operand of offset.  */
-    int in_bracket;            /* >=1 if parsing operand in brackets.  */
-    const reg_entry *reg;      /* Last register reference found.  */
-    char *disp;                        /* Displacement string being built.  */
-    char *next_operand;                /* Resume point when splitting operands.  */
-  };
-
-static struct intel_parser_s intel_parser;
-
-/* Token structure for parsing intel syntax.  */
-struct intel_token
-  {
-    int code;                  /* Token code.  */
-    const reg_entry *reg;      /* Register entry for register tokens.  */
-    char *str;                 /* String representation.  */
-  };
-
-static struct intel_token cur_token, prev_token;
-
-/* Token codes for the intel parser. Since T_SHORT is already used
-   by COFF, undefine it first to prevent a warning.  */
-#define T_NIL          -1
-#define T_CONST                1
-#define T_REG          2
-#define T_BYTE         3
-#define T_WORD         4
-#define T_DWORD                5
-#define T_FWORD                6
-#define T_QWORD                7
-#define T_TBYTE                8
-#define T_XMMWORD      9
-#undef  T_SHORT
-#define T_SHORT                10
-#define T_OFFSET       11
-#define T_PTR          12
-#define T_ID           13
-#define T_SHL          14
-#define T_SHR          15
-
-/* Prototypes for intel parser functions.  */
-static int intel_match_token (int);
-static void intel_putback_token        (void);
-static void intel_get_token (void);
-static int intel_expr (void);
-static int intel_e04 (void);
-static int intel_e05 (void);
-static int intel_e06 (void);
-static int intel_e09 (void);
-static int intel_e10 (void);
-static int intel_e11 (void);
-
-static int
-i386_intel_operand (char *operand_string, int got_a_float)
-{
-  int ret;
-  char *p;
-
-  p = intel_parser.op_string = xstrdup (operand_string);
-  intel_parser.disp = (char *) xmalloc (strlen (operand_string) + 1);
-
-  for (;;)
-    {
-      /* Initialize token holders.  */
-      cur_token.code = prev_token.code = T_NIL;
-      cur_token.reg = prev_token.reg = NULL;
-      cur_token.str = prev_token.str = NULL;
-
-      /* Initialize parser structure.  */
-      intel_parser.got_a_float = got_a_float;
-      intel_parser.op_modifier = 0;
-      intel_parser.is_mem = 0;
-      intel_parser.in_offset = 0;
-      intel_parser.in_bracket = 0;
-      intel_parser.reg = NULL;
-      intel_parser.disp[0] = '\0';
-      intel_parser.next_operand = NULL;
-
-      /* Read the first token and start the parser.  */
-      intel_get_token ();
-      ret = intel_expr ();
-
-      if (!ret)
-       break;
-
-      if (cur_token.code != T_NIL)
-       {
-         as_bad (_("invalid operand for '%s' ('%s' unexpected)"),
-                 current_templates->start->name, cur_token.str);
-         ret = 0;
-       }
-      /* If we found a memory reference, hand it over to i386_displacement
-        to fill in the rest of the operand fields.  */
-      else if (intel_parser.is_mem)
-       {
-         if ((i.mem_operands == 1
-              && !current_templates->start->opcode_modifier.isstring)
-             || i.mem_operands == 2)
-           {
-             as_bad (_("too many memory references for '%s'"),
-                     current_templates->start->name);
-             ret = 0;
-           }
-         else
-           {
-             char *s = intel_parser.disp;
-             i.types[this_operand].bitfield.mem = 1;
-             i.mem_operands++;
-
-             if (!quiet_warnings && intel_parser.is_mem < 0)
-               /* See the comments in intel_bracket_expr.  */
-               as_warn (_("Treating `%s' as memory reference"), operand_string);
-
-             /* Add the displacement expression.  */
-             if (*s != '\0')
-               ret = i386_displacement (s, s + strlen (s));
-             if (ret)
-               {
-                 /* Swap base and index in 16-bit memory operands like
-                    [si+bx]. Since i386_index_check is also used in AT&T
-                    mode we have to do that here.  */
-                 if (i.base_reg
-                     && i.index_reg
-                     && i.base_reg->reg_type.bitfield.reg16
-                     && i.index_reg->reg_type.bitfield.reg16
-                     && i.base_reg->reg_num >= 6
-                     && i.index_reg->reg_num < 6)
-                   {
-                     const reg_entry *base = i.index_reg;
-
-                     i.index_reg = i.base_reg;
-                     i.base_reg = base;
-                   }
-                 ret = i386_index_check (operand_string);
-               }
-           }
-       }
-
-      /* Constant and OFFSET expressions are handled by i386_immediate.  */
-      else if ((intel_parser.op_modifier & (1 << T_OFFSET))
-              || intel_parser.reg == NULL)
-       {
-         if (i.mem_operands < 2 && i.seg[i.mem_operands])
-           {
-             if (!(intel_parser.op_modifier & (1 << T_OFFSET)))
-               as_warn (_("Segment override ignored"));
-             i.seg[i.mem_operands] = NULL;
-           }
-         ret = i386_immediate (intel_parser.disp);
-       }
-
-      if (intel_parser.next_operand && this_operand >= MAX_OPERANDS - 1)
-       ret = 0;
-      if (!ret || !intel_parser.next_operand)
-       break;
-      intel_parser.op_string = intel_parser.next_operand;
-      this_operand = i.operands++;
-      i.types[this_operand].bitfield.unspecified = 1;
-    }
-
-  free (p);
-  free (intel_parser.disp);
-
-  return ret;
-}
-
-#define NUM_ADDRESS_REGS (!!i.base_reg + !!i.index_reg)
-
-/* expr        e04 expr'
-
-   expr'  cmpOp e04 expr'
-       | Empty  */
-static int
-intel_expr (void)
-{
-  /* XXX Implement the comparison operators.  */
-  return intel_e04 ();
-}
-
-/* e04 e05 e04'
-
-   e04'        addOp e05 e04'
-       | Empty  */
-static int
-intel_e04 (void)
-{
-  int nregs = -1;
-
-  for (;;)
-    {
-      if (!intel_e05())
-       return 0;
-
-      if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
-       i.base_reg = i386_regtab + REGNAM_AL; /* al is invalid as base */
-
-      if (cur_token.code == '+')
-       nregs = -1;
-      else if (cur_token.code == '-')
-       nregs = NUM_ADDRESS_REGS;
-      else
-       return 1;
-
-      strcat (intel_parser.disp, cur_token.str);
-      intel_match_token (cur_token.code);
-    }
-}
-
-/* e05 e06 e05'
-
-   e05'        binOp e06 e05'
-       | Empty  */
-static int
-intel_e05 (void)
-{
-  int nregs = ~NUM_ADDRESS_REGS;
-
-  for (;;)
-    {
-      if (!intel_e06())
-       return 0;
-
-      if (cur_token.code == '&'
-         || cur_token.code == '|'
-         || cur_token.code == '^')
-       {
-         char str[2];
-
-         str[0] = cur_token.code;
-         str[1] = 0;
-         strcat (intel_parser.disp, str);
-       }
-      else
-       break;
-
-      intel_match_token (cur_token.code);
-
-      if (nregs < 0)
-       nregs = ~nregs;
-    }
-  if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
-    i.base_reg = i386_regtab + REGNAM_AL + 1; /* cl is invalid as base */
-  return 1;
-}
-
-/* e06 e09 e06'
-
-   e06'        mulOp e09 e06'
-       | Empty  */
-static int
-intel_e06 (void)
-{
-  int nregs = ~NUM_ADDRESS_REGS;
-
-  for (;;)
-    {
-      if (!intel_e09())
-       return 0;
-
-      if (cur_token.code == '*'
-         || cur_token.code == '/'
-         || cur_token.code == '%')
-       {
-         char str[2];
-
-         str[0] = cur_token.code;
-         str[1] = 0;
-         strcat (intel_parser.disp, str);
-       }
-      else if (cur_token.code == T_SHL)
-       strcat (intel_parser.disp, "<<");
-      else if (cur_token.code == T_SHR)
-       strcat (intel_parser.disp, ">>");
-      else
-       break;
-
-      intel_match_token (cur_token.code);
-
-      if (nregs < 0)
-       nregs = ~nregs;
-    }
-  if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
-    i.base_reg = i386_regtab + REGNAM_AL + 2; /* dl is invalid as base */
-  return 1;
-}
-
-/* e09 OFFSET e09
-       | SHORT e09
-       | + e09
-       | - e09
-       | ~ e09
-       | NOT e09
-       | e10 e09'
-
-   e09'        PTR e10 e09'
-       | : e10 e09'
-       | Empty */
-static int
-intel_e09 (void)
-{
-  int nregs = ~NUM_ADDRESS_REGS;
-  int in_offset = 0;
-
-  for (;;)
-    {
-      /* Don't consume constants here.  */
-      if (cur_token.code == '+' || cur_token.code == '-')
-       {
-         /* Need to look one token ahead - if the next token
-            is a constant, the current token is its sign.  */
-         int next_code;
-
-         intel_match_token (cur_token.code);
-         next_code = cur_token.code;
-         intel_putback_token ();
-         if (next_code == T_CONST)
-           break;
-       }
-
-      /* e09  OFFSET e09  */
-      if (cur_token.code == T_OFFSET)
-       {
-         if (!in_offset++)
-           ++intel_parser.in_offset;
-       }
-
-      /* e09  SHORT e09  */
-      else if (cur_token.code == T_SHORT)
-       intel_parser.op_modifier |= 1 << T_SHORT;
-
-      /* e09  + e09  */
-      else if (cur_token.code == '+')
-       strcat (intel_parser.disp, "+");
-
-      /* e09  - e09
-             | ~ e09
-             | NOT e09  */
-      else if (cur_token.code == '-' || cur_token.code == '~')
-       {
-         char str[2];
-
-         if (nregs < 0)
-           nregs = ~nregs;
-         str[0] = cur_token.code;
-         str[1] = 0;
-         strcat (intel_parser.disp, str);
-       }
-
-      /* e09  e10 e09'  */
-      else
-       break;
-
-      intel_match_token (cur_token.code);
-    }
-
-  for (;;)
-    {
-      if (!intel_e10 ())
-       return 0;
-
-      /* e09'  PTR e10 e09' */
-      if (cur_token.code == T_PTR)
-       {
-         char suffix;
-
-         if (prev_token.code == T_BYTE)
-           {
-             suffix = BYTE_MNEM_SUFFIX;
-             i.types[this_operand].bitfield.byte = 1;
-           }
-
-         else if (prev_token.code == T_WORD)
-           {
-             if ((current_templates->start->name[0] == 'l'
-                  && current_templates->start->name[2] == 's'
-                  && current_templates->start->name[3] == 0)
-                 || current_templates->start->base_opcode == 0x62 /* bound */)
-               suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
-             else if (intel_parser.got_a_float == 2)   /* "fi..." */
-               suffix = SHORT_MNEM_SUFFIX;
-             else
-               suffix = WORD_MNEM_SUFFIX;
-             i.types[this_operand].bitfield.word = 1;
-           }
-
-         else if (prev_token.code == T_DWORD)
-           {
-             if ((current_templates->start->name[0] == 'l'
-                  && current_templates->start->name[2] == 's'
-                  && current_templates->start->name[3] == 0)
-                 || current_templates->start->base_opcode == 0x62 /* bound */)
-               suffix = WORD_MNEM_SUFFIX;
-             else if (flag_code == CODE_16BIT
-                      && (current_templates->start->opcode_modifier.jump
-                          || current_templates->start->opcode_modifier.jumpdword))
-               suffix = LONG_DOUBLE_MNEM_SUFFIX;
-             else if (intel_parser.got_a_float == 1)   /* "f..." */
-               suffix = SHORT_MNEM_SUFFIX;
-             else
-               suffix = LONG_MNEM_SUFFIX;
-             i.types[this_operand].bitfield.dword = 1;
-           }
-
-         else if (prev_token.code == T_FWORD)
-           {
-             if (current_templates->start->name[0] == 'l'
-                 && current_templates->start->name[2] == 's'
-                 && current_templates->start->name[3] == 0)
-               suffix = LONG_MNEM_SUFFIX;
-             else if (!intel_parser.got_a_float)
-               {
-                 if (flag_code == CODE_16BIT)
-                   add_prefix (DATA_PREFIX_OPCODE);
-                 suffix = LONG_DOUBLE_MNEM_SUFFIX;
-               }
-             else
-               suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
-             i.types[this_operand].bitfield.fword = 1;
-           }
-
-         else if (prev_token.code == T_QWORD)
-           {
-             if (current_templates->start->base_opcode == 0x62 /* bound */
-                 || intel_parser.got_a_float == 1)     /* "f..." */
-               suffix = LONG_MNEM_SUFFIX;
-             else
-               suffix = QWORD_MNEM_SUFFIX;
-             i.types[this_operand].bitfield.qword = 1;
-           }
-
-         else if (prev_token.code == T_TBYTE)
-           {
-             if (intel_parser.got_a_float == 1)
-               suffix = LONG_DOUBLE_MNEM_SUFFIX;
-             else
-               suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
-           }
-
-         else if (prev_token.code == T_XMMWORD)
-           {
-             suffix = XMMWORD_MNEM_SUFFIX;
-             i.types[this_operand].bitfield.xmmword = 1;
-           }
-
-         else
-           {
-             as_bad (_("Unknown operand modifier `%s'"), prev_token.str);
-             return 0;
-           }
-
-         i.types[this_operand].bitfield.unspecified = 0;
-
-         /* Operands for jump/call using 'ptr' notation denote absolute
-            addresses.  */
-         if (current_templates->start->opcode_modifier.jump
-             || current_templates->start->opcode_modifier.jumpdword)
-           i.types[this_operand].bitfield.jumpabsolute = 1;
-
-         if (current_templates->start->base_opcode == 0x8d /* lea */)
-           ;
-         else if (!i.suffix)
-           i.suffix = suffix;
-         else if (i.suffix != suffix)
-           {
-             as_bad (_("Conflicting operand modifiers"));
-             return 0;
-           }
-
-       }
-
-      /* e09'  : e10 e09'  */
-      else if (cur_token.code == ':')
-       {
-         if (prev_token.code != T_REG)
-           {
-             /* While {call,jmp} SSSS:OOOO is MASM syntax only when SSSS is a
-                segment/group identifier (which we don't have), using comma
-                as the operand separator there is even less consistent, since
-                there all branches only have a single operand.  */
-             if (this_operand != 0
-                 || intel_parser.in_offset
-                 || intel_parser.in_bracket
-                 || (!current_templates->start->opcode_modifier.jump
-                     && !current_templates->start->opcode_modifier.jumpdword
-                     && !current_templates->start->opcode_modifier.jumpintersegment
-                     && !current_templates->start->operand_types[0].bitfield.jumpabsolute))
-               return intel_match_token (T_NIL);
-             /* Remember the start of the 2nd operand and terminate 1st
-                operand here.
-                XXX This isn't right, yet (when SSSS:OOOO is right operand of
-                another expression), but it gets at least the simplest case
-                (a plain number or symbol on the left side) right.  */
-             intel_parser.next_operand = intel_parser.op_string;
-             *--intel_parser.op_string = '\0';
-             return intel_match_token (':');
-           }
-       }
-
-      /* e09'  Empty  */
-      else
-       break;
-
-      intel_match_token (cur_token.code);
-
-    }
-
-  if (in_offset)
-    {
-      --intel_parser.in_offset;
-      if (nregs < 0)
-       nregs = ~nregs;
-      if (NUM_ADDRESS_REGS > nregs)
-       {
-         as_bad (_("Invalid operand to `OFFSET'"));
-         return 0;
-       }
-      intel_parser.op_modifier |= 1 << T_OFFSET;
-    }
-
-  if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
-    i.base_reg = i386_regtab + REGNAM_AL + 3; /* bl is invalid as base */
-  return 1;
-}
-
-static int
-intel_bracket_expr (void)
-{
-  int was_offset = intel_parser.op_modifier & (1 << T_OFFSET);
-  const char *start = intel_parser.op_string;
-  int len;
-
-  if (i.op[this_operand].regs)
-    return intel_match_token (T_NIL);
-
-  intel_match_token ('[');
-
-  /* Mark as a memory operand only if it's not already known to be an
-     offset expression.  If it's an offset expression, we need to keep
-     the brace in.  */
-  if (!intel_parser.in_offset)
-    {
-      ++intel_parser.in_bracket;
-
-      /* Operands for jump/call inside brackets denote absolute addresses.  */
-      if (current_templates->start->opcode_modifier.jump
-         || current_templates->start->opcode_modifier.jumpdword)
-       i.types[this_operand].bitfield.jumpabsolute = 1;
-
-      /* Unfortunately gas always diverged from MASM in a respect that can't
-        be easily fixed without risking to break code sequences likely to be
-        encountered (the testsuite even check for this): MASM doesn't consider
-        an expression inside brackets unconditionally as a memory reference.
-        When that is e.g. a constant, an offset expression, or the sum of the
-        two, this is still taken as a constant load. gas, however, always
-        treated these as memory references. As a compromise, we'll try to make
-        offset expressions inside brackets work the MASM way (since that's
-        less likely to be found in real world code), but make constants alone
-        continue to work the traditional gas way. In either case, issue a
-        warning.  */
-      intel_parser.op_modifier &= ~was_offset;
-    }
-  else
-    strcat (intel_parser.disp, "[");
-
-  /* Add a '+' to the displacement string if necessary.  */
-  if (*intel_parser.disp != '\0'
-      && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
-    strcat (intel_parser.disp, "+");
-
-  if (intel_expr ()
-      && (len = intel_parser.op_string - start - 1,
-         intel_match_token (']')))
-    {
-      /* Preserve brackets when the operand is an offset expression.  */
-      if (intel_parser.in_offset)
-       strcat (intel_parser.disp, "]");
-      else
-       {
-         --intel_parser.in_bracket;
-         if (i.base_reg || i.index_reg)
-           intel_parser.is_mem = 1;
-         if (!intel_parser.is_mem)
-           {
-             if (!(intel_parser.op_modifier & (1 << T_OFFSET)))
-               /* Defer the warning until all of the operand was parsed.  */
-               intel_parser.is_mem = -1;
-             else if (!quiet_warnings)
-               as_warn (_("`[%.*s]' taken to mean just `%.*s'"),
-                        len, start, len, start);
-           }
-       }
-      intel_parser.op_modifier |= was_offset;
-
-      return 1;
-    }
-  return 0;
-}
-
-/* e10 e11 e10'
-
-   e10'        [ expr ] e10'
-       | Empty  */
-static int
-intel_e10 (void)
-{
-  if (!intel_e11 ())
-    return 0;
-
-  while (cur_token.code == '[')
-    {
-      if (!intel_bracket_expr ())
-       return 0;
-    }
-
-  return 1;
-}
-
-/* e11 ( expr )
-       | [ expr ]
-       | BYTE
-       | WORD
-       | DWORD
-       | FWORD
-       | QWORD
-       | TBYTE
-       | OWORD
-       | XMMWORD
-       | $
-       | .
-       | register
-       | id
-       | constant  */
-static int
-intel_e11 (void)
-{
-  switch (cur_token.code)
-    {
-    /* e11  ( expr ) */
-    case '(':
-      intel_match_token ('(');
-      strcat (intel_parser.disp, "(");
-
-      if (intel_expr () && intel_match_token (')'))
-       {
-         strcat (intel_parser.disp, ")");
-         return 1;
-       }
-      return 0;
-
-    /* e11  [ expr ] */
-    case '[':
-      return intel_bracket_expr ();
-
-    /* e11  $
-           | .  */
-    case '.':
-      strcat (intel_parser.disp, cur_token.str);
-      intel_match_token (cur_token.code);
-
-      /* Mark as a memory operand only if it's not already known to be an
-        offset expression.  */
-      if (!intel_parser.in_offset)
-       intel_parser.is_mem = 1;
-
-      return 1;
-
-    /* e11  register  */
-    case T_REG:
-      {
-       const reg_entry *reg = intel_parser.reg = cur_token.reg;
-
-       intel_match_token (T_REG);
-
-       /* Check for segment change.  */
-       if (cur_token.code == ':')
-         {
-           if (!reg->reg_type.bitfield.sreg2
-               && !reg->reg_type.bitfield.sreg3)
-             {
-               as_bad (_("`%s' is not a valid segment register"),
-                       reg->reg_name);
-               return 0;
-             }
-           else if (i.mem_operands >= 2)
-             as_warn (_("Segment override ignored"));
-           else if (i.seg[i.mem_operands])
-             as_warn (_("Extra segment override ignored"));
-           else
-             {
-               if (!intel_parser.in_offset)
-                 intel_parser.is_mem = 1;
-               switch (reg->reg_num)
-                 {
-                 case 0:
-                   i.seg[i.mem_operands] = &es;
-                   break;
-                 case 1:
-                   i.seg[i.mem_operands] = &cs;
-                   break;
-                 case 2:
-                   i.seg[i.mem_operands] = &ss;
-                   break;
-                 case 3:
-                   i.seg[i.mem_operands] = &ds;
-                   break;
-                 case 4:
-                   i.seg[i.mem_operands] = &fs;
-                   break;
-                 case 5:
-                   i.seg[i.mem_operands] = &gs;
-                   break;
-                 }
-             }
-         }
-
-       else if (reg->reg_type.bitfield.sreg3 && reg->reg_num == RegFlat)
-         {
-           as_bad (_("cannot use `FLAT' here"));
-           return 0;
-         }
-
-       /* Not a segment register. Check for register scaling.  */
-       else if (cur_token.code == '*')
-         {
-           if (!intel_parser.in_bracket)
-             {
-               as_bad (_("Register scaling only allowed in memory operands"));
-               return 0;
-             }
-
-           if (reg->reg_type.bitfield.reg16) /* Disallow things like [si*1]. */
-             reg = i386_regtab + REGNAM_AX + 4; /* sp is invalid as index */
-           else if (i.index_reg)
-             reg = i386_regtab + REGNAM_EAX + 4; /* esp is invalid as index */
-
-           /* What follows must be a valid scale.  */
-           intel_match_token ('*');
-           i.index_reg = reg;
-           i.types[this_operand].bitfield.baseindex = 1;
-
-           /* Set the scale after setting the register (otherwise,
-              i386_scale will complain)  */
-           if (cur_token.code == '+' || cur_token.code == '-')
-             {
-               char *str, sign = cur_token.code;
-               intel_match_token (cur_token.code);
-               if (cur_token.code != T_CONST)
-                 {
-                   as_bad (_("Syntax error: Expecting a constant, got `%s'"),
-                           cur_token.str);
-                   return 0;
-                 }
-               str = (char *) xmalloc (strlen (cur_token.str) + 2);
-               strcpy (str + 1, cur_token.str);
-               *str = sign;
-               if (!i386_scale (str))
-                 return 0;
-               free (str);
-             }
-           else if (!i386_scale (cur_token.str))
-             return 0;
-           intel_match_token (cur_token.code);
-         }
-
-       /* No scaling. If this is a memory operand, the register is either a
-          base register (first occurrence) or an index register (second
-          occurrence).  */
-       else if (intel_parser.in_bracket)
-         {
-
-           if (!i.base_reg)
-             i.base_reg = reg;
-           else if (!i.index_reg)
-             i.index_reg = reg;
-           else
-             {
-               as_bad (_("Too many register references in memory operand"));
-               return 0;
-             }
-
-           i.types[this_operand].bitfield.baseindex = 1;
-         }
-
-       /* It's neither base nor index.  */
-       else if (!intel_parser.in_offset && !intel_parser.is_mem)
-         {
-           i386_operand_type temp = reg->reg_type;
-           temp.bitfield.baseindex = 0;
-           i.types[this_operand] = operand_type_or (i.types[this_operand],
-                                                    temp);
-           i.types[this_operand].bitfield.unspecified = 0;
-           i.op[this_operand].regs = reg;
-           i.reg_operands++;
-         }
-       else
-         {
-           as_bad (_("Invalid use of register"));
-           return 0;
-         }
-
-       /* Since registers are not part of the displacement string (except
-          when we're parsing offset operands), we may need to remove any
-          preceding '+' from the displacement string.  */
-       if (*intel_parser.disp != '\0'
-           && !intel_parser.in_offset)
-         {
-           char *s = intel_parser.disp;
-           s += strlen (s) - 1;
-           if (*s == '+')
-             *s = '\0';
-         }
-
-       return 1;
-      }
-
-    /* e11  BYTE
-           | WORD
-           | DWORD
-           | FWORD
-           | QWORD
-           | TBYTE
-           | OWORD
-           | XMMWORD  */
-    case T_BYTE:
-    case T_WORD:
-    case T_DWORD:
-    case T_FWORD:
-    case T_QWORD:
-    case T_TBYTE:
-    case T_XMMWORD:
-      intel_match_token (cur_token.code);
-
-      if (cur_token.code == T_PTR)
-       return 1;
-
-      /* It must have been an identifier.  */
-      intel_putback_token ();
-      cur_token.code = T_ID;
-      /* FALLTHRU */
-
-    /* e11  id
-           | constant  */
-    case T_ID:
-      if (!intel_parser.in_offset && intel_parser.is_mem <= 0)
-       {
-         symbolS *symbolP;
-
-         /* The identifier represents a memory reference only if it's not
-            preceded by an offset modifier and if it's not an equate.  */
-         symbolP = symbol_find(cur_token.str);
-         if (!symbolP || S_GET_SEGMENT(symbolP) != absolute_section)
-           intel_parser.is_mem = 1;
-       }
-       /* FALLTHRU */
-
-    case T_CONST:
-    case '-':
-    case '+':
-      {
-       char *save_str, sign = 0;
-
-       /* Allow constants that start with `+' or `-'.  */
-       if (cur_token.code == '-' || cur_token.code == '+')
-         {
-           sign = cur_token.code;
-           intel_match_token (cur_token.code);
-           if (cur_token.code != T_CONST)
-             {
-               as_bad (_("Syntax error: Expecting a constant, got `%s'"),
-                       cur_token.str);
-               return 0;
-             }
-         }
-
-       save_str = (char *) xmalloc (strlen (cur_token.str) + 2);
-       strcpy (save_str + !!sign, cur_token.str);
-       if (sign)
-         *save_str = sign;
-
-       /* Get the next token to check for register scaling.  */
-       intel_match_token (cur_token.code);
-
-       /* Check if this constant is a scaling factor for an
-          index register.  */
-       if (cur_token.code == '*')
-         {
-           if (intel_match_token ('*') && cur_token.code == T_REG)
-             {
-               const reg_entry *reg = cur_token.reg;
-
-               if (!intel_parser.in_bracket)
-                 {
-                   as_bad (_("Register scaling only allowed "
-                             "in memory operands"));
-                   return 0;
-                 }
-
-                /* Disallow things like [1*si].
-                   sp and esp are invalid as index.  */
-               if (reg->reg_type.bitfield.reg16)
-                 reg = i386_regtab + REGNAM_AX + 4;
-               else if (i.index_reg)
-                 reg = i386_regtab + REGNAM_EAX + 4;
-
-               /* The constant is followed by `* reg', so it must be
-                  a valid scale.  */
-               i.index_reg = reg;
-               i.types[this_operand].bitfield.baseindex = 1;
-
-               /* Set the scale after setting the register (otherwise,
-                  i386_scale will complain)  */
-               if (!i386_scale (save_str))
-                 return 0;
-               intel_match_token (T_REG);
-
-               /* Since registers are not part of the displacement
-                  string, we may need to remove any preceding '+' from
-                  the displacement string.  */
-               if (*intel_parser.disp != '\0')
-                 {
-                   char *s = intel_parser.disp;
-                   s += strlen (s) - 1;
-                   if (*s == '+')
-                     *s = '\0';
-                 }
-
-               free (save_str);
-
-               return 1;
-             }
-
-           /* The constant was not used for register scaling. Since we have
-              already consumed the token following `*' we now need to put it
-              back in the stream.  */
-           intel_putback_token ();
-         }
-
-       /* Add the constant to the displacement string.  */
-       strcat (intel_parser.disp, save_str);
-       free (save_str);
-
-       return 1;
-      }
-    }
-
-  as_bad (_("Unrecognized token '%s'"), cur_token.str);
-  return 0;
-}
-
-/* Match the given token against cur_token. If they match, read the next
-   token from the operand string.  */
-static int
-intel_match_token (int code)
-{
-  if (cur_token.code == code)
-    {
-      intel_get_token ();
-      return 1;
-    }
-  else
-    {
-      as_bad (_("Unexpected token `%s'"), cur_token.str);
-      return 0;
-    }
-}
-
-/* Read a new token from intel_parser.op_string and store it in cur_token.  */
-static void
-intel_get_token (void)
-{
-  char *end_op;
-  const reg_entry *reg;
-  struct intel_token new_token;
-
-  new_token.code = T_NIL;
-  new_token.reg = NULL;
-  new_token.str = NULL;
-
-  /* Free the memory allocated to the previous token and move
-     cur_token to prev_token.  */
-  if (prev_token.str)
-    free (prev_token.str);
-
-  prev_token = cur_token;
-
-  /* Skip whitespace.  */
-  while (is_space_char (*intel_parser.op_string))
-    intel_parser.op_string++;
-
-  /* Return an empty token if we find nothing else on the line.  */
-  if (*intel_parser.op_string == '\0')
-    {
-      cur_token = new_token;
-      return;
-    }
-
-  /* The new token cannot be larger than the remainder of the operand
-     string.  */
-  new_token.str = (char *) xmalloc (strlen (intel_parser.op_string) + 1);
-  new_token.str[0] = '\0';
-
-  if (strchr ("0123456789", *intel_parser.op_string))
-    {
-      char *p = new_token.str;
-      char *q = intel_parser.op_string;
-      new_token.code = T_CONST;
-
-      /* Allow any kind of identifier char to encompass floating point and
-        hexadecimal numbers.  */
-      while (is_identifier_char (*q))
-       *p++ = *q++;
-      *p = '\0';
-
-      /* Recognize special symbol names [0-9][bf].  */
-      if (strlen (intel_parser.op_string) == 2
-         && (intel_parser.op_string[1] == 'b'
-             || intel_parser.op_string[1] == 'f'))
-       new_token.code = T_ID;
-    }
-
-  else if ((reg = parse_register (intel_parser.op_string, &end_op)) != NULL)
-    {
-      size_t len = end_op - intel_parser.op_string;
-
-      new_token.code = T_REG;
-      new_token.reg = reg;
-
-      memcpy (new_token.str, intel_parser.op_string, len);
-      new_token.str[len] = '\0';
-    }
-
-  else if (is_identifier_char (*intel_parser.op_string))
-    {
-      char *p = new_token.str;
-      char *q = intel_parser.op_string;
-
-      /* A '.' or '$' followed by an identifier char is an identifier.
-        Otherwise, it's operator '.' followed by an expression.  */
-      if ((*q == '.' || *q == '$') && !is_identifier_char (*(q + 1)))
-       {
-         new_token.code = '.';
-         new_token.str[0] = '.';
-         new_token.str[1] = '\0';
-       }
-      else
-       {
-         while (is_identifier_char (*q) || *q == '@')
-           *p++ = *q++;
-         *p = '\0';
-
-         if (strcasecmp (new_token.str, "NOT") == 0)
-           new_token.code = '~';
-
-         else if (strcasecmp (new_token.str, "MOD") == 0)
-           new_token.code = '%';
-
-         else if (strcasecmp (new_token.str, "AND") == 0)
-           new_token.code = '&';
-
-         else if (strcasecmp (new_token.str, "OR") == 0)
-           new_token.code = '|';
-
-         else if (strcasecmp (new_token.str, "XOR") == 0)
-           new_token.code = '^';
-
-         else if (strcasecmp (new_token.str, "SHL") == 0)
-           new_token.code = T_SHL;
-
-         else if (strcasecmp (new_token.str, "SHR") == 0)
-           new_token.code = T_SHR;
-
-         else if (strcasecmp (new_token.str, "BYTE") == 0)
-           new_token.code = T_BYTE;
-
-         else if (strcasecmp (new_token.str, "WORD") == 0)
-           new_token.code = T_WORD;
-
-         else if (strcasecmp (new_token.str, "DWORD") == 0)
-           new_token.code = T_DWORD;
-
-         else if (strcasecmp (new_token.str, "FWORD") == 0)
-           new_token.code = T_FWORD;
-
-         else if (strcasecmp (new_token.str, "QWORD") == 0)
-           new_token.code = T_QWORD;
-
-         else if (strcasecmp (new_token.str, "TBYTE") == 0
-                  /* XXX remove (gcc still uses it) */
-                  || strcasecmp (new_token.str, "XWORD") == 0)
-           new_token.code = T_TBYTE;
-
-         else if (strcasecmp (new_token.str, "XMMWORD") == 0
-                  || strcasecmp (new_token.str, "OWORD") == 0)
-           new_token.code = T_XMMWORD;
-
-         else if (strcasecmp (new_token.str, "PTR") == 0)
-           new_token.code = T_PTR;
-
-         else if (strcasecmp (new_token.str, "SHORT") == 0)
-           new_token.code = T_SHORT;
-
-         else if (strcasecmp (new_token.str, "OFFSET") == 0)
-           {
-             new_token.code = T_OFFSET;
-
-             /* ??? This is not mentioned in the MASM grammar but gcc
-                    makes use of it with -mintel-syntax.  OFFSET may be
-                    followed by FLAT:  */
-             if (strncasecmp (q, " FLAT:", 6) == 0)
-               strcat (new_token.str, " FLAT:");
-           }
-
-         else
-           new_token.code = T_ID;
-       }
-    }
-
-  else if (strchr ("+-/*%|&^:[]()~", *intel_parser.op_string))
-    {
-      new_token.code = *intel_parser.op_string;
-      new_token.str[0] = *intel_parser.op_string;
-      new_token.str[1] = '\0';
-    }
-
-  else if (strchr ("<>", *intel_parser.op_string)
-          && *intel_parser.op_string == *(intel_parser.op_string + 1))
-    {
-      new_token.code = *intel_parser.op_string == '<' ? T_SHL : T_SHR;
-      new_token.str[0] = *intel_parser.op_string;
-      new_token.str[1] = *intel_parser.op_string;
-      new_token.str[2] = '\0';
-    }
-
-  else
-    as_bad (_("Unrecognized token `%s'"), intel_parser.op_string);
-
-  intel_parser.op_string += strlen (new_token.str);
-  cur_token = new_token;
-}
-
-/* Put cur_token back into the token stream and make cur_token point to
-   prev_token.  */
-static void
-intel_putback_token (void)
-{
-  if (cur_token.code != T_NIL)
-    {
-      intel_parser.op_string -= strlen (cur_token.str);
-      free (cur_token.str);
-    }
-  cur_token = prev_token;
-
-  /* Forget prev_token.  */
-  prev_token.code = T_NIL;
-  prev_token.reg = NULL;
-  prev_token.str = NULL;
-}
+#include "tc-i386-intel.c"
 
 void
 tc_x86_parse_to_dw2regnum (expressionS *exp)
@@ -9195,7 +8484,7 @@ tc_x86_frame_initial_instructions (void)
 
       input_line_pointer = sp[flag_code >> 1];
       tc_x86_parse_to_dw2regnum (&exp);
-      assert (exp.X_op == O_constant);
+      gas_assert (exp.X_op == O_constant);
       sp_regno[flag_code >> 1] = exp.X_add_number;
       input_line_pointer = saved_input;
     }
@@ -9215,6 +8504,15 @@ i386_elf_section_type (const char *str, size_t len)
   return -1;
 }
 
+#ifdef TE_SOLARIS
+void
+i386_solaris_fix_up_eh_frame (segT sec)
+{
+  if (flag_code == CODE_64BIT)
+    elf_section_type (sec) = SHT_X86_64_UNWIND;
+}
+#endif
+
 #ifdef TE_PE
 void
 tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
@@ -9231,7 +8529,7 @@ tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 /* For ELF on x86-64, add support for SHF_X86_64_LARGE.  */
 
-int
+bfd_vma
 x86_64_section_letter (int letter, char **ptr_msg)
 {
   if (flag_code == CODE_64BIT)
@@ -9246,7 +8544,7 @@ x86_64_section_letter (int letter, char **ptr_msg)
   return -1;
 }
 
-int
+bfd_vma
 x86_64_section_word (char *str, size_t len)
 {
   if (len == 5 && flag_code == CODE_64BIT && CONST_STRNEQ (str, "large"))
This page took 0.076706 seconds and 4 git commands to generate.