gas/
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index 451e466a7974e16af15ff6dcf6a544a91091ce05..ecf122e4350bf407d6b0e414bd1cb6904680ad63 100644 (file)
 #define INFER_ADDR_PREFIX 1
 #endif
 
-#ifndef SCALE1_WHEN_NO_INDEX
-/* Specifying a scale factor besides 1 when there is no index is
-   futile.  eg. `mov (%ebx,2),%al' does exactly the same as
-   `mov (%ebx),%al'.  To slavishly follow what the programmer
-   specified, set SCALE1_WHEN_NO_INDEX to 0.  */
-#define SCALE1_WHEN_NO_INDEX 1
-#endif
-
 #ifndef DEFAULT_ARCH
 #define DEFAULT_ARCH "i386"
 #endif
@@ -66,6 +58,7 @@
 static void set_code_flag (int);
 static void set_16bit_gcc_code_flag (int);
 static void set_intel_syntax (int);
+static void set_allow_index_reg (int);
 static void set_cpu_arch (int);
 #ifdef TE_PE
 static void pe_directive_secrel (int);
@@ -89,6 +82,7 @@ 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);
@@ -161,11 +155,13 @@ 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.  */
+       addressing modes of this insn are encoded.  DREX is the byte
+       added by the SSE5 instructions.  */
 
     modrm_byte rm;
     rex_byte rex;
     sib_byte sib;
+    drex_byte drex;
   };
 
 typedef struct _i386_insn i386_insn;
@@ -270,7 +266,6 @@ enum flag_code {
        CODE_32BIT,
        CODE_16BIT,
        CODE_64BIT };
-#define NUM_FLAG_CODE ((int) CODE_64BIT + 1)
 
 static enum flag_code flag_code;
 static unsigned int object_64bit;
@@ -291,6 +286,9 @@ static int intel_syntax = 0;
 /* 1 if register prefix % not required.  */
 static int allow_naked_reg = 0;
 
+/* 1 if fake index register, eiz/riz, is allowed .  */
+static int allow_index_reg = 0;
+
 /* Register prefix used for error message.  */
 static const char *register_prefix = "%";
 
@@ -508,6 +506,8 @@ static const arch_entry cpu_arch[] =
    CPU_SSE4A_FLAGS },
   {".abm", PROCESSOR_UNKNOWN,
    CPU_ABM_FLAGS },
+  {".sse5", PROCESSOR_UNKNOWN,
+   CPU_SSE5_FLAGS },
 };
 
 const pseudo_typeS md_pseudo_table[] =
@@ -534,6 +534,8 @@ const pseudo_typeS md_pseudo_table[] =
   {"code64", set_code_flag, CODE_64BIT},
   {"intel_syntax", set_intel_syntax, 1},
   {"att_syntax", set_intel_syntax, 0},
+  {"allow_index_reg", set_allow_index_reg, 1},
+  {"disallow_index_reg", set_allow_index_reg, 0},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
 #else
@@ -883,32 +885,92 @@ i386_align_code (fragS *fragP, int count)
   fragP->fr_var = count;
 }
 
-static int
-cpu_flags_check_x64 (i386_cpu_flags f)
+static INLINE int
+uints_all_zero (const unsigned int *x, unsigned int size)
 {
-  return !((flag_code == CODE_64BIT && f.bitfield.cpuno64)
-          || (flag_code != CODE_64BIT && f.bitfield.cpu64));
+  switch (size)
+    {
+    case 3:
+      if (x[2])
+       return 0;
+    case 2:
+      if (x[1])
+       return 0;
+    case 1:
+      return !x[0];
+    default:
+      abort ();
+    }
 }
 
-static int
-cpu_flags_all_zero (i386_cpu_flags f)
+static INLINE void
+uints_set (unsigned int *x, unsigned int v, unsigned int size)
 {
-  unsigned int j;
+  switch (size)
+    {
+    case 3:
+      x[2] = v;
+    case 2:
+      x[1] = v;
+    case 1:
+      x[0] = v;
+      break;
+    default:
+      abort ();
+    }
+}
 
-  for (j = 0; j < ARRAY_SIZE (f.array); j++)
-    if (f.array [j])
-      return 0;
+static INLINE int
+uints_equal (const unsigned int *x, const unsigned int *y,
+            unsigned int size)
+{
+  switch (size)
+    {
+    case 3:
+      if (x[2] != y [2])
+       return 0;
+    case 2:
+      if (x[1] != y [1])
+       return 0;
+    case 1:
+      return x[0] == y [0];
+      break;
+    default:
+      abort ();
+    }
+}
 
-  return 1;
+#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_check_cpu64 (i386_cpu_flags f)
+{
+  return !((flag_code == CODE_64BIT && f.bitfield.cpuno64)
+          || (flag_code != CODE_64BIT && f.bitfield.cpu64));
 }
 
-static i386_cpu_flags
+static INLINE i386_cpu_flags
 cpu_flags_not (i386_cpu_flags x)
 {
-  unsigned int j;
-
-  for (j = 0; j < ARRAY_SIZE (x.array); j++)
-    x.array [j] = ~x.array [j];
+  switch (ARRAY_SIZE (x.array))
+    {
+    case 3:
+      x.array [2] = ~x.array [2];
+    case 2:
+      x.array [1] = ~x.array [1];
+    case 1:
+      x.array [0] = ~x.array [0];
+      break;
+    default:
+      abort ();
+    }
 
 #ifdef CpuUnused
   x.bitfield.unused = 0;
@@ -917,37 +979,39 @@ cpu_flags_not (i386_cpu_flags x)
   return x;
 }
 
-enum i386_array_biop
+static INLINE i386_cpu_flags
+cpu_flags_and (i386_cpu_flags x, i386_cpu_flags y)
 {
-  and,
-  or,
-  xor
-};
+  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;
+}
 
-static i386_cpu_flags
-cpu_flags_biop (i386_cpu_flags x, i386_cpu_flags y,
-               enum i386_array_biop op)
+static INLINE i386_cpu_flags
+cpu_flags_or (i386_cpu_flags x, i386_cpu_flags y)
 {
-  unsigned int j;
-
-  switch (op)
+  switch (ARRAY_SIZE (x.array))
     {
-    case and:
-      for (j = 0; j < ARRAY_SIZE (x.array); j++)
-       x.array [j] &= y.array [j];
-      break;
-    case or:
-      for (j = 0; j < ARRAY_SIZE (x.array); j++)
-       x.array [j] |= y.array [j];
-      break;
-    case xor:
-      for (j = 0; j < ARRAY_SIZE (x.array); j++)
-       x.array [j] ^= y.array [j];
+    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;
 }
 
@@ -962,45 +1026,61 @@ cpu_flags_match (i386_cpu_flags x)
   x.bitfield.cpu64 = 0;
   x.bitfield.cpuno64 = 0;
 
-  return cpu_flags_all_zero (cpu_flags_biop (x, not, and));
+  not = cpu_flags_and (x, not);
+  return UINTS_ALL_ZERO (not);
 }
 
-static int
-operand_type_all_zero (i386_operand_type t)
+static INLINE i386_operand_type
+operand_type_and (i386_operand_type x, i386_operand_type y)
 {
-  unsigned int j;
-
-  for (j = 0; j < ARRAY_SIZE (t.array); j++)
-    if (t.array [j])
-      return 0;
-
-  return 1;
+  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;
 }
 
-static i386_operand_type
-operand_type_biop (i386_operand_type x, i386_operand_type y,
-                  enum i386_array_biop op)
+static INLINE i386_operand_type
+operand_type_or (i386_operand_type x, i386_operand_type y)
 {
-  unsigned int j;
-
-  switch (op)
+  switch (ARRAY_SIZE (x.array))
     {
-    case and:
-      for (j = 0; j < ARRAY_SIZE (x.array); j++)
-       x.array [j] &= y.array [j];
-      break;
-    case or:
-      for (j = 0; j < ARRAY_SIZE (x.array); j++)
-       x.array [j] |= y.array [j];
-      break;
-    case xor:
-      for (j = 0; j < ARRAY_SIZE (x.array); j++)
-       x.array [j] ^= y.array [j];
+    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;
+}
 
+static INLINE i386_operand_type
+operand_type_xor (i386_operand_type x, i386_operand_type 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;
 }
 
@@ -1015,7 +1095,6 @@ static const i386_operand_type disp32s = OPERAND_TYPE_DISP32S;
 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 baseindex = OPERAND_TYPE_BASEINDEX;
 static const i386_operand_type regxmm = OPERAND_TYPE_REGXMM;
 static const i386_operand_type imm8 = OPERAND_TYPE_IMM8;
 static const i386_operand_type imm8s = OPERAND_TYPE_IMM8S;
@@ -1030,13 +1109,12 @@ static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S;
 enum operand_type
 {
   reg,
-  implicitregister,
   imm,
   disp,
   anymem
 };
 
-static int
+static INLINE int
 operand_type_check (i386_operand_type t, enum operand_type c)
 {
   switch (c)
@@ -1047,12 +1125,6 @@ operand_type_check (i386_operand_type t, enum operand_type c)
              || t.bitfield.reg32
              || t.bitfield.reg64);
 
-    case implicitregister:
-      return (t.bitfield.inoutportreg
-             || t.bitfield.shiftcount
-             || t.bitfield.acc
-             || t.bitfield.floatacc);
-
     case imm:
       return (t.bitfield.imm8
              || t.bitfield.imm8s
@@ -1081,14 +1153,14 @@ operand_type_check (i386_operand_type t, enum operand_type c)
     }
 }
 
-static int
+static INLINE int
 operand_type_match (i386_operand_type overlap,
                    i386_operand_type given)
 {
   i386_operand_type temp = overlap;
 
   temp.bitfield.jumpabsolute = 0;
-  if (operand_type_all_zero (temp))
+  if (UINTS_ALL_ZERO (temp))
     return 0;
 
   return (given.bitfield.baseindex == overlap.bitfield.baseindex
@@ -1099,7 +1171,7 @@ operand_type_match (i386_operand_type overlap,
    unless the expected operand type register overlap is null.
    Note that Acc in a template matches every size of reg.  */
 
-static int
+static INLINE int
 operand_type_register_match (i386_operand_type m0,
                             i386_operand_type g0,
                             i386_operand_type t0,
@@ -1204,7 +1276,7 @@ smallest_imm_type (offsetT num)
 {
   i386_operand_type t;
  
-  memset (&t, 0, sizeof (t));
+  UINTS_CLEAR (t);
   t.bitfield.imm64 = 1;
 
   if (cpu_arch_tune != PROCESSOR_I486 && num == 1)
@@ -1432,6 +1504,12 @@ set_intel_syntax (int syntax_flag)
   register_prefix = allow_naked_reg ? "" : "%";
 }
 
+static void
+set_allow_index_reg (int flag)
+{
+  allow_index_reg = flag;
+}
+
 static void
 set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
 {
@@ -1474,9 +1552,9 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
                  break;
                }
 
-             flags = cpu_flags_biop (cpu_arch_flags,
-                                     cpu_arch[i].flags, or);
-             if (memcmp (&flags, &cpu_arch_flags, sizeof (flags)))
+             flags = cpu_flags_or (cpu_arch_flags,
+                                   cpu_arch[i].flags);
+             if (!UINTS_EQUAL (flags, cpu_arch_flags))
                {
                  cpu_sub_arch_name = cpu_arch[i].name;
                  cpu_arch_flags = flags;
@@ -1696,6 +1774,8 @@ 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);
@@ -1814,12 +1894,14 @@ static void
 pt (i386_operand_type t)
 {
   unsigned int j;
+  i386_operand_type a;
 
   for (j = 0; j < ARRAY_SIZE (type_names); j++)
-    if (!operand_type_all_zero (operand_type_biop (t,
-                                                  type_names[j].mask,
-                                                  and)))
-      fprintf (stdout, "%s, ",  type_names[j].name);
+    {
+      a = operand_type_and (t, type_names[j].mask);
+      if (!UINTS_ALL_ZERO (a))
+       fprintf (stdout, "%s, ",  type_names[j].name);
+    }
   fflush (stdout);
 }
 
@@ -2062,20 +2144,6 @@ md_assemble (line)
   if (line == NULL)
     return;
 
-  /* The order of the immediates should be reversed
-     for 2 immediates extrq and insertq instructions */
-  if ((i.imm_operands == 2)
-      && ((strcmp (mnemonic, "extrq") == 0)
-         || (strcmp (mnemonic, "insertq") == 0)))
-    {
-      swap_2_operands (0, 1);
-      /* "extrq" and insertq" are the only two instructions whose operands
-        have to be reversed even though they have two immediate operands.
-      */
-      if (intel_syntax)
-       swap_operands ();
-    }
-
   /* Now we've parsed the mnemonic into a set of templates, and have the
      operands at hand.  */
 
@@ -2091,6 +2159,13 @@ md_assemble (line)
           && operand_type_check (i.types[1], imm)))
     swap_operands ();
 
+  /* The order of the immediates should be reversed
+     for 2 immediates extrq and insertq instructions */
+  if (i.imm_operands == 2
+      && (strcmp (mnemonic, "extrq") == 0
+         || strcmp (mnemonic, "insertq") == 0))
+      swap_2_operands (0, 1);
+
   if (i.imm_operands)
     optimize_imm ();
 
@@ -2126,7 +2201,7 @@ md_assemble (line)
                  || !i.tm.opcode_modifier.no_wsuf
                  || !i.tm.opcode_modifier.no_lsuf
                  || !i.tm.opcode_modifier.no_ssuf
-                 || !i.tm.opcode_modifier.no_xsuf
+                 || !i.tm.opcode_modifier.no_ldsuf
                  || !i.tm.opcode_modifier.no_qsuf))
            as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
 
@@ -2157,7 +2232,10 @@ md_assemble (line)
     i.imm_operands = 0;        /* kludge for shift insns.  */
 
   for (j = 0; j < 3; j++)
-    if (operand_type_check (i.types[j], implicitregister))
+    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)
@@ -2185,13 +2263,18 @@ md_assemble (line)
       /* 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.  */
+        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 && 2 < MAX_OPERANDS);
+      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;
-      memset (&i.types[i.operands], 0, sizeof (i.types[i.operands]));
+      UINTS_CLEAR (i.types[i.operands]);
       i.types[i.operands].bitfield.imm8 = 1;
       i.operands++;
       exp->X_op = O_constant;
@@ -2269,7 +2352,14 @@ md_assemble (line)
        }
     }
 
-  if (i.rex != 0)
+  /* 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)
     add_prefix (REX_OPCODE | i.rex);
 
   /* We are ready to output the insn.  */
@@ -2328,7 +2418,7 @@ parse_insn (char *line, char *mnemonic)
          && current_templates
          && current_templates->start->opcode_modifier.isprefix)
        {
-         if (!cpu_flags_check_x64 (current_templates->start->cpu_flags))
+         if (!cpu_flags_check_cpu64 (current_templates->start->cpu_flags))
            {
              as_bad ((flag_code != CODE_64BIT
                       ? _("`%s' is only supported in 64-bit mode")
@@ -2448,7 +2538,7 @@ parse_insn (char *line, char *mnemonic)
     {
       if (cpu_flags_match (t->cpu_flags))
        supported |= 1;
-      if (cpu_flags_check_x64 (t->cpu_flags))
+      if (cpu_flags_check_cpu64 (t->cpu_flags))
        supported |= 2;
     }
   if (!(supported & 2))
@@ -2746,9 +2836,8 @@ optimize_imm (void)
                                               - ((offsetT) 1 << 31));
              }
            i.types[op]
-             = operand_type_biop (i.types[op],
-                                  smallest_imm_type (i.op[op].imms->X_add_number),
-                                  or);
+             = operand_type_or (i.types[op],
+                                smallest_imm_type (i.op[op].imms->X_add_number));
 
            /* We must avoid matching of Imm32 templates when 64bit
               only immediate is available.  */
@@ -2769,14 +2858,14 @@ optimize_imm (void)
              i386_operand_type mask, allowed;
              const template *t;
 
-             memset (&mask, 0, sizeof (mask));
-             memset (&allowed, 0, sizeof (allowed));
+             UINTS_CLEAR (mask);
+             UINTS_CLEAR (allowed);
 
              for (t = current_templates->start;
                   t < current_templates->end;
                   ++t)
-               allowed = operand_type_biop (allowed,
-                                            t->operand_types[op], or);
+               allowed = operand_type_or (allowed,
+                                          t->operand_types[op]);
              switch (guess_suffix)
                {
                case QWORD_MNEM_SUFFIX:
@@ -2795,11 +2884,9 @@ optimize_imm (void)
                default:
                  break;
                }
-             if (!operand_type_all_zero (operand_type_biop (mask,
-                                                            allowed,
-                                                            and)))
-               i.types[op] = operand_type_biop (i.types[op],
-                                                mask, and);
+             allowed = operand_type_and (mask, allowed);
+             if (!UINTS_ALL_ZERO (allowed))
+               i.types[op] = operand_type_and (i.types[op], mask);
            }
            break;
          }
@@ -2892,6 +2979,7 @@ match_template (void)
   i386_operand_type operand_types [MAX_OPERANDS];
   int addr_prefix_disp;
   unsigned int j;
+  i386_cpu_flags overlap;
 
 #if MAX_OPERANDS != 4
 # error "MAX_OPERANDS must be 4."
@@ -2912,7 +3000,7 @@ match_template (void)
   else if (i.suffix == QWORD_MNEM_SUFFIX)
     suffix_check.no_qsuf = 1;
   else if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX)
-    suffix_check.no_xsuf = 1;
+    suffix_check.no_ldsuf = 1;
 
   for (t = current_templates->start; t < current_templates->end; t++)
     {
@@ -2928,7 +3016,7 @@ match_template (void)
           || (t->opcode_modifier.no_lsuf & suffix_check.no_lsuf)
           || (t->opcode_modifier.no_ssuf & suffix_check.no_ssuf)
           || (t->opcode_modifier.no_qsuf & suffix_check.no_qsuf)
-          || (t->opcode_modifier.no_xsuf & suffix_check.no_xsuf))
+          || (t->opcode_modifier.no_ldsuf & suffix_check.no_ldsuf))
          && !(intel_syntax && t->opcode_modifier.ignoresize))
        continue;
 
@@ -2951,14 +3039,16 @@ match_template (void)
        continue;
 
       /* Do not verify operands when there are none.  */
-      else if (!t->operands)
+      else 
        {
-         if (!cpu_flags_all_zero (cpu_flags_biop (t->cpu_flags,
-                                                  cpu_arch_flags_not,
-                                                  and)))
-           continue;
-         /* We've found a match; break out of loop.  */
-         break;
+         overlap = cpu_flags_and (t->cpu_flags, cpu_arch_flags_not);
+         if (!t->operands)
+           {
+             if (!UINTS_ALL_ZERO (overlap))
+               continue;
+             /* We've found a match; break out of loop.  */
+             break;
+           }
        }
 
       /* Address size prefix will turn Disp64/Disp32/Disp16 operand
@@ -3007,8 +3097,7 @@ match_template (void)
            }
          }
 
-      overlap0 = operand_type_biop (i.types[0], operand_types[0],
-                                   and);
+      overlap0 = operand_type_and (i.types[0], operand_types[0]);
       switch (t->operands)
        {
        case 1:
@@ -3022,13 +3111,12 @@ match_template (void)
             zero-extend %eax to %rax.  */
          if (flag_code == CODE_64BIT
              && t->base_opcode == 0x90
-             && memcmp (&i.types [0], &acc32, sizeof (acc32)) == 0
-             && memcmp (&i.types [1], &acc32, sizeof (acc32)) == 0)
+             && UINTS_EQUAL (i.types [0], acc32)
+             && UINTS_EQUAL (i.types [1], acc32))
            continue;
        case 3:
        case 4:
-         overlap1 = operand_type_biop (i.types[1], operand_types[1],
-                                       and);
+         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])
              /* monitor in SSE3 is a very special case.  The first
@@ -3053,10 +3141,8 @@ match_template (void)
                continue;
 
              /* Try reversing direction of operands.  */
-             overlap0 = operand_type_biop (i.types[0], operand_types[1],
-                                           and);
-             overlap1 = operand_type_biop (i.types[1], operand_types[0],
-                                           and);
+             overlap0 = operand_type_and (i.types[0], operand_types[1]);
+             overlap1 = operand_type_and (i.types[1], operand_types[0]);
              if (!operand_type_match (overlap0, i.types[0])
                  || !operand_type_match (overlap1, i.types[1])
                  || !operand_type_register_match (overlap0, i.types[0],
@@ -3084,11 +3170,11 @@ match_template (void)
              switch (t->operands)
                {
                case 4:
-                 overlap3 = operand_type_biop (i.types[3],
-                                               operand_types[3], and);
+                 overlap3 = operand_type_and (i.types[3],
+                                              operand_types[3]);
                case 3:
-                 overlap2 = operand_type_biop (i.types[2],
-                                               operand_types[2], and);
+                 overlap2 = operand_type_and (i.types[2],
+                                              operand_types[2]);
                  break;
                }
 
@@ -3122,9 +3208,7 @@ match_template (void)
          /* Found either forward/reverse 2, 3 or 4 operand match here:
             slip through to break.  */
        }
-      if (!cpu_flags_all_zero (cpu_flags_biop (t->cpu_flags,
-                                              cpu_arch_flags_not,
-                                              and)))
+      if (!UINTS_ALL_ZERO (overlap))
        {
          found_reverse_match = 0;
          continue;
@@ -3300,7 +3384,11 @@ process_suffix (void)
        }
       else if (i.suffix == QWORD_MNEM_SUFFIX)
        {
-         if (!check_qword_reg ())
+         if (intel_syntax
+             && i.tm.opcode_modifier.ignoresize
+             && i.tm.opcode_modifier.no_qsuf)
+           i.suffix = 0;
+         else if (!check_qword_reg ())
            return 0;
        }
       else if (i.suffix == WORD_MNEM_SUFFIX)
@@ -3404,17 +3492,10 @@ process_suffix (void)
       /* Now select between word & dword operations via the operand
         size prefix, except for instructions that will ignore this
         prefix anyway.  */
-      if (i.tm.base_opcode == 0x0f01
-          && (i.tm.extension_opcode == 0xc8
-              || i.tm.extension_opcode == 0xd8
-              || i.tm.extension_opcode == 0xda
-              || i.tm.extension_opcode == 0xdb
-              || i.tm.extension_opcode == 0xdf))
-       {
-         /* monitor in SSE3 is a very special case. The default size
-            of AX is the size of mode. The address size override
-            prefix will change the size of AX.  It is also true for
-            invlpga, vmload, vmrun and vmsave in SVME.  */
+      if (i.tm.opcode_modifier.addrprefixop0)
+       {
+         /* The address size override prefix changes the size of the
+            first operand.  */
          if ((flag_code == CODE_32BIT
               && i.op->regs[0].reg_type.bitfield.reg16)
              || (flag_code != CODE_32BIT
@@ -3449,8 +3530,8 @@ process_suffix (void)
          if (! (i.operands == 2
                 && i.tm.base_opcode == 0x90
                 && i.tm.extension_opcode == None
-                && memcmp (&i.types [0], &acc64, sizeof (acc64)) == 0
-                && memcmp (&i.types [1], &acc64, sizeof (acc64)) == 0)
+                && UINTS_EQUAL (i.types [0], acc64)
+                && UINTS_EQUAL (i.types [1], acc64))
              && ! (i.operands == 1
                    && i.tm.base_opcode == 0xfc7
                    && i.tm.extension_opcode == 1
@@ -3481,16 +3562,8 @@ check_byte_reg (void)
       if (i.types[op].bitfield.reg8)
        continue;
 
-      /* movzx, movsx, pextrb and pinsrb should not generate this
-        warning.  */
-      if (intel_syntax
-         && (i.tm.base_opcode == 0xfb7
-             || i.tm.base_opcode == 0xfb6
-             || i.tm.base_opcode == 0x63
-             || i.tm.base_opcode == 0xfbe
-             || i.tm.base_opcode == 0xfbf
-             || i.tm.base_opcode == 0x660f3a14
-             || i.tm.base_opcode == 0x660f3a20))
+      /* Don't generate this warning if not needed.  */
+      if (intel_syntax && i.tm.opcode_modifier.byteokintel)
        continue;
 
       /* crc32 doesn't generate this warning.  */
@@ -3602,11 +3675,10 @@ check_long_reg (void)
                 || i.tm.operand_types[op].bitfield.acc))
       {
        if (intel_syntax
-           && i.tm.base_opcode == 0xf30f2d
+           && i.tm.opcode_modifier.toqword
            && !i.types[0].bitfield.regxmm)
          {
-           /* cvtss2si converts DWORD memory to Reg64.  We want
-              REX byte. */
+           /* Convert to QWORD.  We want REX byte. */
            i.suffix = QWORD_MNEM_SUFFIX;
          }
        else
@@ -3649,11 +3721,10 @@ check_qword_reg (void)
        /* Prohibit these changes in the 64bit mode, since the
           lowering is more complicated.  */
        if (intel_syntax
-           && i.tm.base_opcode == 0xf20f2d
+           && i.tm.opcode_modifier.todword
            && !i.types[0].bitfield.regxmm)
          {
-           /* cvtsd2si converts QWORD memory to Reg32.  We don't want
-              REX byte. */
+           /* Convert to DWORD.  We don't want REX byte. */
            i.suffix = LONG_MNEM_SUFFIX;
          }
        else
@@ -3719,26 +3790,25 @@ update_imm (unsigned int j)
 {
   i386_operand_type overlap;
 
-  overlap = operand_type_biop (i.types[j], i.tm.operand_types[j],
-                              and);
+  overlap = operand_type_and (i.types[j], i.tm.operand_types[j]);
   if ((overlap.bitfield.imm8
        || overlap.bitfield.imm8s
        || overlap.bitfield.imm16
        || overlap.bitfield.imm32
        || overlap.bitfield.imm32s
        || overlap.bitfield.imm64)
-      && memcmp (&overlap, &imm8, sizeof (overlap))
-      && memcmp (&overlap, &imm8s, sizeof (overlap))
-      && memcmp (&overlap, &imm16, sizeof (overlap))
-      && memcmp (&overlap, &imm32, sizeof (overlap))
-      && memcmp (&overlap, &imm32s, sizeof (overlap))
-      && memcmp (&overlap, &imm64, sizeof (overlap)))
+      && !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 (i.suffix)
        {
          i386_operand_type temp;
 
-         memset (&temp, 0, sizeof (temp));
+         UINTS_CLEAR (temp);
          if (i.suffix == BYTE_MNEM_SUFFIX) 
            {
              temp.bitfield.imm8 = overlap.bitfield.imm8;
@@ -3755,22 +3825,22 @@ update_imm (unsigned int j)
            temp.bitfield.imm32 = overlap.bitfield.imm32;
          overlap = temp;
        }
-      else if (memcmp (&overlap, &imm16_32_32s, sizeof (overlap)) == 0
-              || memcmp (&overlap, &imm16_32, sizeof (overlap)) == 0
-              || memcmp (&overlap, &imm16_32s, sizeof (overlap)) == 0)
+      else if (UINTS_EQUAL (overlap, imm16_32_32s)
+              || UINTS_EQUAL (overlap, imm16_32)
+              || UINTS_EQUAL (overlap, imm16_32s))
        {
-         memset (&overlap, 0, sizeof (overlap));
+         UINTS_CLEAR (overlap);
          if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
            overlap.bitfield.imm16 = 1;
          else
            overlap.bitfield.imm32s = 1;
        }
-      if (memcmp (&overlap, &imm8, sizeof (overlap))
-         && memcmp (&overlap, &imm8s, sizeof (overlap))
-         && memcmp (&overlap, &imm16, sizeof (overlap))
-         && memcmp (&overlap, &imm32, sizeof (overlap))
-         && memcmp (&overlap, &imm32s, sizeof (overlap))
-         && memcmp (&overlap, &imm64, sizeof (overlap)))
+      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))
        {
          as_bad (_("no instruction mnemonic suffix given; "
                    "can't determine immediate size"));
@@ -3791,13 +3861,342 @@ finalize_imm (void)
     if (update_imm (j) == 0)
       return 0;
 
-  i.types[2] = operand_type_biop (i.types[2], i.tm.operand_types[2],
-                                 and);
+  i.types[2] = operand_type_and (i.types[2], i.tm.operand_types[2]);
   assert (operand_type_check (i.types[2], imm) == 0);
 
   return 1;
 }
 
+static void
+process_drex (void)
+{
+  i.drex.modrm_reg = None;
+  i.drex.modrm_regmem = None;
+
+  /* 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));
+       }
+
+      /* 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));
+       }
+
+      /* 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));
+       }
+
+      /* 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));
+       }
+
+      /* 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)
+       {
+         /* 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));
+       }
+
+      /* 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));
+       }
+
+      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)
+       {
+         /* 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;
+
+      /* 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));
+       }
+
+      /* 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));
+       }
+
+      /* 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));
+       }
+
+      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));
+       }
+
+      /* 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));
+       }
+
+      else
+       as_bad (_("Incorrect operands for the '%s' instruction"), 
+               i.tm.name);
+    }
+
+  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)
 {
@@ -3806,57 +4205,62 @@ process_operands (void)
      unnecessary segment overrides.  */
   const seg_entry *default_seg = 0;
 
-  /* The imul $imm, %reg instruction is converted into
-     imul $imm, %reg, %reg, and the clr %reg instruction
-     is converted into xor %reg, %reg.  */
-  if (i.tm.opcode_modifier.regkludge)
-    {
-       if (i.tm.cpu_flags.bitfield.cpusse4_1)
-        {
-          /* The first operand in instruction blendvpd, blendvps and
-             pblendvb in SSE4.1 is implicit and must be xmm0.  */
-          assert (i.operands == 3
-                  && i.reg_operands >= 2
-                  && memcmp (&i.types[0], &regxmm, sizeof (regxmm)) == 0);
-          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;
-            }
-          i.op[0] = i.op[1];
-          i.op[1] = i.op[2];
-          i.types[0] = i.types[1];
-          i.types[1] = i.types[2];
-          i.operands--;
-          i.reg_operands--;
-
-          /* We need to adjust fields in i.tm since they are used by
-             build_modrm_byte.  */
-          i.tm.operand_types [0] = i.tm.operand_types [1];
-          i.tm.operand_types [1] = i.tm.operand_types [2];
-          i.tm.operands--;
-        }
-       else
-        {
-          unsigned int first_reg_op;
-          
-          if (operand_type_check (i.types[0], reg))
-            first_reg_op = 0;
-          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);
-          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++;
-          i.reg_operands++;
-        }
+  /* 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)
+    {
+      unsigned int j;
+
+      /* The first operand is implicit and must be xmm0.  */
+      assert (i.reg_operands && UINTS_EQUAL (i.types[0], regxmm));
+      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;
+       }
+
+      for (j = 1; j < i.operands; j++)
+       {
+         i.op[j - 1] = i.op[j];
+         i.types[j - 1] = i.types[j];
+
+         /* We need to adjust fields in i.tm since they are used by
+            build_modrm_byte.  */
+         i.tm.operand_types [j - 1] = i.tm.operand_types [j];
+       }
+
+      i.operands--;
+      i.reg_operands--;
+      i.tm.operands--;
+    }
+  else if (i.tm.opcode_modifier.regkludge)
+    {
+      /* The imul $imm, %reg instruction is converted into
+        imul $imm, %reg, %reg, and the clr %reg instruction
+        is converted into xor %reg, %reg.  */
+
+      unsigned int first_reg_op;
+
+      if (operand_type_check (i.types[0], reg))
+       first_reg_op = 0;
+      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);
+      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++;
+      i.reg_operands++;
     }
 
   if (i.tm.opcode_modifier.shortform)
@@ -3876,7 +4280,8 @@ process_operands (void)
        }
       else
        {
-         /* The register or float register operand is in operand 0 or 1.  */
+         /* The register or float register operand is in operand 
+            0 or 1.  */
          unsigned int op;
          
           if (i.types[0].bitfield.floatreg
@@ -3950,9 +4355,30 @@ build_modrm_byte (void)
 {
   const seg_entry *default_seg = 0;
 
+  /* 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)
+    {
+      const reg_entry *reg = i.op[i.drex.modrm_reg].regs;
+      const reg_entry *regmem = i.op[i.drex.modrm_regmem].regs;
+
+      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;
+    }
+
   /* i.reg_operands MUST be the number of real register operands;
      implicit registers do not count.  */
-  if (i.reg_operands == 2)
+  else if (i.reg_operands == 2)
     {
       unsigned int source, dest;
 
@@ -3975,11 +4401,12 @@ build_modrm_byte (void)
            source = 0;
          break;
        case 4:
-         /* When there are 4 operands, the first two must be immediate
-            operands. The source operand will be the 3rd one.  */
+         /* 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
-                 && operand_type_check (i.types[0], imm)
-                 && operand_type_check (i.types[1], imm));
+                 && i.types[0].bitfield.imm8
+                 && i.types[1].bitfield.imm8);
          source = 2;
          break;
        default:
@@ -4030,10 +4457,19 @@ build_modrm_byte (void)
          unsigned int fake_zero_displacement = 0;
          unsigned int op;
 
-         for (op = 0; op < i.operands; op++)
-           if (operand_type_check (i.types[op], anymem))
-             break;
-         assert (op < i.operands);
+         /* 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);
+           }
 
          default_seg = &ds;
 
@@ -4071,7 +4507,11 @@ build_modrm_byte (void)
                }
              else /* !i.base_reg && i.index_reg  */
                {
-                 i.sib.index = i.index_reg->reg_num;
+                 if (i.index_reg->reg_num == RegEiz
+                     || i.index_reg->reg_num == RegRiz)
+                   i.sib.index = NO_INDEX_REGISTER;
+                 else
+                   i.sib.index = i.index_reg->reg_num;
                  i.sib.base = NO_BASE_REGISTER;
                  i.sib.scale = i.log2_scale_factor;
                  i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
@@ -4094,8 +4534,8 @@ build_modrm_byte (void)
                }
            }
          /* RIP addressing for 64bit mode.  */
-         else if (memcmp (&i.base_reg->reg_type, &baseindex,
-                          sizeof (baseindex)) == 0)
+         else if (i.base_reg->reg_num == RegRip ||
+                  i.base_reg->reg_num == RegEip)
            {
              i.rm.regmem = NO_BASE_REGISTER;
              i.types[op].bitfield.disp8 = 0;
@@ -4143,8 +4583,7 @@ build_modrm_byte (void)
                  && operand_type_check (i.types[op], disp))
                {
                  i386_operand_type temp;
-
-                 memset (&temp, 0, sizeof (temp));
+                 UINTS_CLEAR (temp);
                  temp.bitfield.disp8 = i.types[op].bitfield.disp8;
                  i.types[op] = temp;
                  if (i.prefix[ADDR_PREFIX] == 0)
@@ -4181,15 +4620,14 @@ build_modrm_byte (void)
                     Any base register besides %esp will not use the
                     extra modrm byte.  */
                  i.sib.index = NO_INDEX_REGISTER;
-#if !SCALE1_WHEN_NO_INDEX
-                 /* Another case where we force the second modrm byte.  */
-                 if (i.log2_scale_factor)
-                   i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
-#endif
                }
              else
                {
-                 i.sib.index = i.index_reg->reg_num;
+                 if (i.index_reg->reg_num == RegEiz
+                     || i.index_reg->reg_num == RegRiz)
+                   i.sib.index = NO_INDEX_REGISTER;
+                 else
+                   i.sib.index = i.index_reg->reg_num;
                  i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
                  if ((i.index_reg->reg_flags & RegRex) != 0)
                    i.rex |= REX_X;
@@ -4227,34 +4665,49 @@ build_modrm_byte (void)
        {
          unsigned int op;
 
-         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;
-         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)
+         /* 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)
            {
-             i.rm.regmem = i.op[op].regs->reg_num;
+             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_B;
+               i.rex |= REX_R;
            }
          else
            {
-             i.rm.reg = i.op[op].regs->reg_num;
-             if ((i.op[op].regs->reg_flags & RegRex) != 0)
-               i.rex |= REX_R;
+             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;
+
+             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)
+               {
+                 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
@@ -4265,7 +4718,10 @@ build_modrm_byte (void)
        }
 
       /* Fill in i.rm.reg field with extension opcode (if any).  */
-      if (i.tm.extension_opcode != None)
+      if (i.tm.extension_opcode != None
+         && !(i.tm.opcode_modifier.drex 
+             || i.tm.opcode_modifier.drexv 
+             || i.tm.opcode_modifier.drexc))
        i.rm.reg = i.tm.extension_opcode;
     }
   return default_seg;
@@ -4507,36 +4963,35 @@ output_insn (void)
       char *p;
       unsigned char *q;
       unsigned int prefix;
-      int opc_3b;
-
-      /* All opcodes on i386 have either 1 or 2 bytes.  SSSE3 and
-        SSE4 instructions have 3 bytes.  We may use one more higher
-        byte to specify a prefix the instruction requires.  Exclude
-        instructions which are in both SSE4 and ABM.  */
-      opc_3b = ((i.tm.cpu_flags.bitfield.cpussse3
-                || i.tm.cpu_flags.bitfield.cpusse4_1
-                || i.tm.cpu_flags.bitfield.cpusse4_2)
-               && !i.tm.cpu_flags.bitfield.cpuabm);
-      if (opc_3b)
+
+      switch (i.tm.opcode_length)
        {
+       case 3:
          if (i.tm.base_opcode & 0xff000000)
            {
              prefix = (i.tm.base_opcode >> 24) & 0xff;
              goto check_prefix;
            }
-       }
-      else if ((i.tm.base_opcode & 0xff0000) != 0)
-       {
-         prefix = (i.tm.base_opcode >> 16) & 0xff;
-         if (i.tm.cpu_flags.bitfield.cpupadlock)
+         break;
+       case 2:
+         if ((i.tm.base_opcode & 0xff0000) != 0)
            {
-           check_prefix:
-             if (prefix != REPE_PREFIX_OPCODE
-                 || i.prefix[LOCKREP_PREFIX] != REPE_PREFIX_OPCODE)
+             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)
+                   add_prefix (prefix);
+               }
+             else
                add_prefix (prefix);
            }
-         else
-           add_prefix (prefix);
+         break;
+       case 1:
+         break;
+       default:
+         abort ();
        }
 
       /* The prefix bytes.  */
@@ -4552,23 +5007,36 @@ output_insn (void)
        }
 
       /* Now the opcode; be careful about word order here!  */
-      if (fits_in_unsigned_byte (i.tm.base_opcode))
+      if (i.tm.opcode_length == 1)
        {
          FRAG_APPEND_1_CHAR (i.tm.base_opcode);
        }
       else
        {
-         if (opc_3b)
+         switch (i.tm.opcode_length)
            {
+           case 3:
              p = frag_more (3);
              *p++ = (i.tm.base_opcode >> 16) & 0xff;
+             break;
+           case 2:
+             p = frag_more (2);
+             break;
+           default:
+             abort ();
+             break;
            }
-         else
-           p = frag_more (2);
 
          /* 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).  */
@@ -4597,6 +5065,20 @@ output_insn (void)
            }
        }
 
+      /* 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);
 
@@ -5127,7 +5609,7 @@ i386_immediate (char *imm_start)
   expressionS *exp;
   i386_operand_type types;
 
-  memset (&types, ~0, sizeof (types));
+  UINTS_SET (types, ~0);
 
   if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
     {
@@ -5208,8 +5690,8 @@ i386_immediate (char *imm_start)
       i.types[this_operand].bitfield.imm32 = 1;
       i.types[this_operand].bitfield.imm32s = 1;
       i.types[this_operand].bitfield.imm64 = 1;
-      i.types[this_operand] = operand_type_biop (i.types[this_operand],
-                                                types, and);
+      i.types[this_operand] = operand_type_and (i.types[this_operand],
+                                               types);
     }
 
   return 1;
@@ -5254,9 +5736,7 @@ i386_scale (char *scale)
     {
       as_warn (_("scale factor of %d without an index register"),
               1 << i.log2_scale_factor);
-#if SCALE1_WHEN_NO_INDEX
       i.log2_scale_factor = 0;
-#endif
     }
   scale = input_line_pointer;
   input_line_pointer = save;
@@ -5281,7 +5761,7 @@ i386_displacement (char *disp_start, char *disp_end)
       return 0;
     }
 
-  memset (&bigdisp, 0, sizeof (bigdisp));
+  UINTS_CLEAR (bigdisp);
   if ((i.types[this_operand].bitfield.jumpabsolute)
       || (!current_templates->start->opcode_modifier.jump
          && !current_templates->start->opcode_modifier.jumpdword))
@@ -5331,8 +5811,8 @@ i386_displacement (char *disp_start, char *disp_end)
            }
        }
     }
-  i.types[this_operand] = operand_type_biop (i.types[this_operand],
-                                            bigdisp, or);
+  i.types[this_operand] = operand_type_or (i.types[this_operand],
+                                          bigdisp);
 
   exp = &disp_expressions[i.disp_operands];
   i.op[this_operand].disps = exp;
@@ -5462,9 +5942,9 @@ i386_displacement (char *disp_start, char *disp_end)
   bigdisp.bitfield.disp32 = 0;
   bigdisp.bitfield.disp32s = 0;
   bigdisp.bitfield.disp64 = 0;
-  if (operand_type_all_zero (bigdisp))
-    i.types[this_operand] = operand_type_biop (i.types[this_operand],
-                                              types, and);
+  if (UINTS_ALL_ZERO (bigdisp))
+    i.types[this_operand] = operand_type_and (i.types[this_operand],
+                                             types);
 
   return ret;
 }
@@ -5490,13 +5970,16 @@ i386_index_check (const char *operand_string)
               || (i.prefix[ADDR_PREFIX]
                   && !i.base_reg->reg_type.bitfield.reg32))
           && (i.index_reg
-              || memcmp (&i.base_reg->reg_type, &baseindex,
-                         sizeof (baseindex))))
+              || i.base_reg->reg_num !=
+                 (i.prefix[ADDR_PREFIX] == 0 ? RegRip : RegEip)))
          || (i.index_reg
              && (!i.index_reg->reg_type.bitfield.baseindex
                  || (i.prefix[ADDR_PREFIX] == 0
-                     && !i.index_reg->reg_type.bitfield.reg64)
+                     && i.index_reg->reg_num != RegRiz
+                     && !i.index_reg->reg_type.bitfield.reg64
+                     )
                  || (i.prefix[ADDR_PREFIX]
+                     && i.index_reg->reg_num != RegEiz
                      && !i.index_reg->reg_type.bitfield.reg32))))
        ok = 0;
     }
@@ -5523,7 +6006,8 @@ i386_index_check (const char *operand_string)
          if ((i.base_reg
               && !i.base_reg->reg_type.bitfield.reg32)
              || (i.index_reg
-                 && (!i.index_reg->reg_type.bitfield.reg32
+                 && ((!i.index_reg->reg_type.bitfield.reg32
+                      && i.index_reg->reg_num != RegEiz)
                      || !i.index_reg->reg_type.bitfield.baseindex)))
            ok = 0;
        }
@@ -5544,8 +6028,7 @@ i386_index_check (const char *operand_string)
              && (i.types[this_operand].bitfield.disp16
                  || i.types[this_operand].bitfield.disp32))
            i.types[this_operand]
-             = operand_type_biop (i.types[this_operand], disp16_32,
-                                  xor);
+             = operand_type_xor (i.types[this_operand], disp16_32);
          fudged = 1;
          goto tryprefix;
        }
@@ -5650,8 +6133,8 @@ i386_operand (char *operand_string)
        }
       temp = r->reg_type;
       temp.bitfield.baseindex = 0;
-      i.types[this_operand] = operand_type_biop (i.types[this_operand],
-                                                temp, or);
+      i.types[this_operand] = operand_type_or (i.types[this_operand],
+                                              temp);
       i.op[this_operand].regs = r;
       i.reg_operands++;
     }
@@ -5831,15 +6314,13 @@ i386_operand (char *operand_string)
 
       /* Special case for (%dx) while doing input/output op.  */
       if (i.base_reg
-         && memcmp (&i.base_reg->reg_type, &reg16_inoutportreg,
-                    sizeof (reg16_inoutportreg)) == 0
+         && UINTS_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))
        {
-         memset (&i.types[this_operand], 0,
-                 sizeof (i.types[this_operand]));
+         UINTS_CLEAR (i.types[this_operand]);
          i.types[this_operand].bitfield.inoutportreg = 1;
          return 1;
        }
@@ -6290,58 +6771,12 @@ md_apply_fix (fixP, valP, seg)
   md_number_to_chars (p, value, fixP->fx_size);
 }
 \f
-#define MAX_LITTLENUMS 6
-
-/* Turn the string pointed to by litP into a floating point constant
-   of type TYPE, and emit the appropriate bytes.  The number of
-   LITTLENUMS emitted is stored in *SIZEP.  An error message is
-   returned, or NULL on OK.  */
-
 char *
-md_atof (type, litP, sizeP)
-     int type;
-     char *litP;
-     int *sizeP;
+md_atof (int type, char *litP, int *sizeP)
 {
-  int prec;
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *wordP;
-  char *t;
-
-  switch (type)
-    {
-    case 'f':
-    case 'F':
-      prec = 2;
-      break;
-
-    case 'd':
-    case 'D':
-      prec = 4;
-      break;
-
-    case 'x':
-    case 'X':
-      prec = 5;
-      break;
-
-    default:
-      *sizeP = 0;
-      return _("Bad call to md_atof ()");
-    }
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-
-  *sizeP = prec * sizeof (LITTLENUM_TYPE);
-  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
-     the bigendian 386.  */
-  for (wordP = words + prec - 1; prec--;)
-    {
-      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
-      litP += sizeof (LITTLENUM_TYPE);
-    }
-  return 0;
+  /* This outputs the LITTLENUMs in REVERSE order;
+     in accord with the bigendian 386.  */
+  return ieee_md_atof (type, litP, sizeP, FALSE);
 }
 \f
 static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
@@ -6422,11 +6857,17 @@ parse_real_register (char *reg_string, char **end_op)
        }
     }
 
+  /* Don't allow fake index register unless allow_index_reg isn't 0. */
+  if (r != NULL
+      && !allow_index_reg
+      && (r->reg_num == RegEiz || r->reg_num == RegRiz))
+    return (const reg_entry *) NULL;
+
   if (r != NULL
       && ((r->reg_flags & (RegRex64 | RegRex))
          || r->reg_type.bitfield.reg64)
       && (!cpu_arch_flags.bitfield.cpulm
-         || memcmp (&r->reg_type, &control, sizeof (control)))
+         || !UINTS_EQUAL (r->reg_type, control))
       && flag_code != CODE_64BIT)
     return (const reg_entry *) NULL;
 
@@ -6701,7 +7142,7 @@ i386_target_format (void)
   if (!strcmp (default_arch, "x86_64"))
     {
       set_code_flag (CODE_64BIT);
-      if (cpu_flags_all_zero (cpu_arch_isa_flags))
+      if (UINTS_ALL_ZERO (cpu_arch_isa_flags))
        {
          cpu_arch_isa_flags.bitfield.cpui186 = 1;
          cpu_arch_isa_flags.bitfield.cpui286 = 1;
@@ -6715,7 +7156,7 @@ i386_target_format (void)
          cpu_arch_isa_flags.bitfield.cpusse = 1;
          cpu_arch_isa_flags.bitfield.cpusse2 = 1;
        }
-      if (cpu_flags_all_zero (cpu_arch_tune_flags))
+      if (UINTS_ALL_ZERO (cpu_arch_tune_flags))
        {
          cpu_arch_tune_flags.bitfield.cpui186 = 1;
          cpu_arch_tune_flags.bitfield.cpui286 = 1;
@@ -6733,13 +7174,13 @@ i386_target_format (void)
   else if (!strcmp (default_arch, "i386"))
     {
       set_code_flag (CODE_32BIT);
-      if (cpu_flags_all_zero (cpu_arch_isa_flags))
+      if (UINTS_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 (cpu_flags_all_zero (cpu_arch_tune_flags))
+      if (UINTS_ALL_ZERO (cpu_arch_tune_flags))
        {
          cpu_arch_tune_flags.bitfield.cpui186 = 1;
          cpu_arch_tune_flags.bitfield.cpui286 = 1;
@@ -8005,8 +8446,8 @@ intel_e11 (void)
          {
            i386_operand_type temp = reg->reg_type;
            temp.bitfield.baseindex = 0;
-           i.types[this_operand] = operand_type_biop (i.types[this_operand],
-                                                      temp, or);
+           i.types[this_operand] = operand_type_or (i.types[this_operand],
+                                                    temp);
            i.op[this_operand].regs = reg;
            i.reg_operands++;
          }
This page took 0.048798 seconds and 4 git commands to generate.