2005-02-17 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index 606d16b521348eb686915316bf1a95e67654fb9e..391192f3e52d9271f9d128dc6b47dfbe18d2211f 100644 (file)
@@ -314,6 +314,7 @@ static int quiet_warnings = 0;
 
 /* CPU name.  */
 static const char *cpu_arch_name = NULL;
+static const char *cpu_sub_arch_name = NULL;
 
 /* CPU feature flags.  */
 static unsigned int cpu_arch_flags = CpuUnknownFlags | CpuNo64;
@@ -416,14 +417,24 @@ static const arch_entry cpu_arch[] = {
   {"i286",     Cpu086|Cpu186|Cpu286 },
   {"i386",     Cpu086|Cpu186|Cpu286|Cpu386 },
   {"i486",     Cpu086|Cpu186|Cpu286|Cpu386|Cpu486 },
-  {"i586",     Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuMMX },
-  {"i686",     Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE },
-  {"pentium",  Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuMMX },
-  {"pentiumpro",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE },
-  {"pentium4", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2 },
-  {"k6",       Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow },
-  {"athlon",   Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuMMX|Cpu3dnow },
-  {"sledgehammer",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuSledgehammer|CpuMMX|Cpu3dnow|CpuSSE|CpuSSE2 },
+  {"i586",     Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586 },
+  {"i686",     Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 },
+  {"pentium",  Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586 },
+  {"pentiumpro",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 },
+  {"pentiumii",        Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX },
+  {"pentiumiii",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuMMX2|CpuSSE },
+  {"pentium4", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2 },
+  {"prescott", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuPNI },
+  {"k6",       Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX },
+  {"k6_2",     Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow },
+  {"athlon",   Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA },
+  {"sledgehammer",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuSledgehammer|CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2 },
+  {".mmx",     CpuMMX },
+  {".sse",     CpuMMX|CpuMMX2|CpuSSE },
+  {".sse2",    CpuMMX|CpuMMX2|CpuSSE|CpuSSE2 },
+  {".3dnow",   CpuMMX|Cpu3dnow },
+  {".3dnowa",  CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA },
+  {".padlock", CpuPadLock },
   {NULL, 0 }
 };
 
@@ -836,10 +847,22 @@ set_cpu_arch (dummy)
        {
          if (strcmp (string, cpu_arch[i].name) == 0)
            {
-             cpu_arch_name = cpu_arch[i].name;
-             cpu_arch_flags = (cpu_arch[i].flags
-                               | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64));
-             break;
+             if (*string != '.')
+               {
+                 cpu_arch_name = cpu_arch[i].name;
+                 cpu_sub_arch_name = NULL;
+                 cpu_arch_flags = (cpu_arch[i].flags
+                                   | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64));
+                 break;
+               }
+             if ((cpu_arch_flags | cpu_arch[i].flags) != cpu_arch_flags)
+               {
+                 cpu_sub_arch_name = cpu_arch[i].name;
+                 cpu_arch_flags |= cpu_arch[i].flags;
+               }
+             *input_line_pointer = e;
+             demand_empty_rest_of_line ();
+             return;
            }
        }
       if (!cpu_arch[i].name)
@@ -1561,6 +1584,8 @@ parse_insn (line, mnemonic)
   char *l = line;
   char *token_start = l;
   char *mnem_p;
+  int supported;
+  const template *t;
 
   /* Non-zero if we found a prefix only acceptable with string insns.  */
   const char *expecting_string_instruction = NULL;
@@ -1709,11 +1734,29 @@ parse_insn (line, mnemonic)
     }
 
   /* Check if instruction is supported on specified architecture.  */
-  if ((current_templates->start->cpu_flags & ~(Cpu64 | CpuNo64))
-      & ~(cpu_arch_flags & ~(Cpu64 | CpuNo64)))
+  supported = 0;
+  for (t = current_templates->start; t < current_templates->end; ++t)
+    {
+      if (!((t->cpu_flags & ~(Cpu64 | CpuNo64))
+           & ~(cpu_arch_flags & ~(Cpu64 | CpuNo64))))
+         supported |= 1;
+      if (!(t->cpu_flags & (flag_code == CODE_64BIT ? CpuNo64 : Cpu64)))
+         supported |= 2;
+    }
+  if (!(supported & 2))
+    {
+      as_bad (flag_code == CODE_64BIT
+             ? _("`%s' is not supported in 64-bit mode")
+             : _("`%s' is only supported in 64-bit mode"),
+             current_templates->start->name);
+      return NULL;
+    }
+  if (!(supported & 1))
     {
-      as_warn (_("`%s' is not supported on `%s'"),
-              current_templates->start->name, cpu_arch_name);
+      as_warn (_("`%s' is not supported on `%s%s'"),
+              current_templates->start->name,
+              cpu_arch_name,
+              cpu_sub_arch_name ? cpu_sub_arch_name : "");
     }
   else if ((Cpu386 & ~cpu_arch_flags) && (flag_code != CODE_16BIT))
     {
@@ -2319,9 +2362,6 @@ process_suffix (void)
           && (i.tm.opcode_modifier & No_sSuf))
     {
       i.suffix = stackop_size;
-      if (i.suffix == QWORD_MNEM_SUFFIX
-         && (i.tm.opcode_modifier & No_qSuf))
-       i.suffix = LONG_MNEM_SUFFIX;
     }
   else if (intel_syntax
           && !i.suffix
@@ -2449,14 +2489,7 @@ check_byte_reg (void)
              || i.tm.base_opcode == 0xfbf))
        continue;
 
-      if ((i.types[op] & WordReg) && i.op[op].regs->reg_num < 4
-#if 0
-         /* Check that the template allows eight bit regs.  This
-            kills insns such as `orb $1,%edx', which maybe should be
-            allowed.  */
-         && (i.tm.operand_types[op] & (Reg8 | InOutPortReg))
-#endif
-         )
+      if ((i.types[op] & WordReg) && i.op[op].regs->reg_num < 4)
        {
          /* Prohibit these changes in the 64bit mode, since the
             lowering is more complicated.  */
@@ -2659,7 +2692,7 @@ finalize_imm ()
   i.types[0] = overlap0;
 
   overlap1 = i.types[1] & i.tm.operand_types[1];
-  if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32))
+  if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32 | Imm64))
       && overlap1 != Imm8 && overlap1 != Imm8S
       && overlap1 != Imm16 && overlap1 != Imm32S
       && overlap1 != Imm32 && overlap1 != Imm64)
@@ -3912,7 +3945,6 @@ i386_scale (scale)
 
   switch (val)
     {
-    case 0:
     case 1:
       i.log2_scale_factor = 0;
       break;
@@ -4801,9 +4833,13 @@ md_apply_fix3 (fixP, valP, seg)
        }
 #endif
 #if defined (OBJ_COFF) && defined (TE_PE)
-      /* For some reason, the PE format does not store a section
-        address offset for a PC relative symbol.  */
-      if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+      /* For some reason, the PE format does not store a
+        section address offset for a PC relative symbol.  */
+      if (S_GET_SEGMENT (fixP->fx_addsy) != seg
+#if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK)
+         || S_IS_WEAK (fixP->fx_addsy)
+#endif
+         )
        value += md_pcrel_from (fixP);
 #endif
     }
@@ -5378,11 +5414,6 @@ tc_gen_reloc (section, fixp)
 
   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
 
-#ifdef TE_PE
-  if (S_IS_WEAK (fixp->fx_addsy))
-    rel->addend = rel->address - (*rel->sym_ptr_ptr)->value + 4;
-  else
-#endif
   if (!use_rela_relocations)
     {
       /* HACK: Since i386 ELF uses Rel instead of Rela, encode the
This page took 0.026719 seconds and 4 git commands to generate.