gas/
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index fd79330487de15bc58c0977aa6201e788488055a..ecf122e4350bf407d6b0e414bd1cb6904680ad63 100644 (file)
@@ -2201,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);
 
@@ -3000,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++)
     {
@@ -3016,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;
 
@@ -3384,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)
@@ -3488,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
@@ -3565,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.  */
@@ -3686,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
@@ -3733,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
@@ -4224,57 +4211,56 @@ process_operands (void)
       || i.tm.opcode_modifier.drexc)
     process_drex ();
 
-  /* 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
-                  && 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;
-            }
-          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++;
-        }
+  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)
@@ -4415,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:
@@ -6784,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];
This page took 0.031557 seconds and 4 git commands to generate.