]> gcc.gnu.org Git - gcc.git/commitdiff
invoke.texi: Document -mabi=meabi, and expand on the EABI description.
authorRichard Sandiford <rsandifo@redhat.com>
Thu, 25 Jul 2002 10:16:00 +0000 (10:16 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 25 Jul 2002 10:16:00 +0000 (10:16 +0000)
* doc/invoke.texi: Document -mabi=meabi, and expand on the EABI
description.  Document -mips32, -mips64, and the associated -march
values.  Describe the "mipsN" arguments to -march.  Say that the
-mipsN options are equivalent to -march.  Reword the description
of default type sizes.
* toplev.h (target_flags_explicit): Declare.
* toplev.c (target_flags_explicit): New var.
(set_target_switch): Update target_flags_explicit.
* config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine.
* config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine.
* config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3.
* config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine.
* config/mips/mips.h (mips_cpu_info): New struct.
(mips_cpu_string, mips_explicit_type_size_string): Remove.
(mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare.
(MIPS_CPP_SET_PROCESSOR): New macro.
(TARGET_CPP_BUILTINS): Declare a macro for each supported processor.
Define _MIPS_ARCH and _MIPS_TUNE.
(MIPS_ISA_DEFAULT): Don't provide a default value.  Instead...
(MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor
MIPS_ISA_DEFAULT were already defined.
(MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT.
(TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size.
(ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New.
(GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules.
(ABI_GAS_ASM_SPEC): Remove.
(MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros.
(ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64.
Invoke %(asm_abi_default_spec) if no ABI was specified.
(CC1_SPEC): Remove ISA -> register-size rules.
(EXTRA_SPECS): Remove abi_gas_asm_spec.  Add asm_abi_default_spec.
* config/mips/mips.c (mips_arch_info, mips_tune_info): New vars.
(mips_cpu_string, mips_explicit_type_size_string): Remove.
(mips_cpu_info_table): New array.
(mips_set_architecture, mips_set_tune): New fns.
(override_options): Rework to make -mipsN equivalent to -march.
Detect more erroneous cases, including those removed from CC1_SPEC.
Don't change the ABI based on architecture, or vice versa.
Unify logic with GAS.
(mips_asm_file_start): Get architecture name from mips_arch_info.
(mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
(mips_parse_cpu): Take the name of the option as argument.  Handle
'from-abi'.  Raise an error if the option is wrong.
(mips_cpu_info_from_isa): New fn.

[gcc/testsuite]
* gcc.dg/mips-args-[123].c: New tests.

From-SVN: r55747

14 files changed:
gcc/ChangeLog
gcc/config/mips/abi64.h
gcc/config/mips/elf64.h
gcc/config/mips/iris6.h
gcc/config/mips/isa3264.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/mips-args-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/mips-args-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/mips-args-3.c [new file with mode: 0644]
gcc/toplev.c
gcc/toplev.h

index e75a97d56f1da2a9388cd090722db85044fecd69..ad40abd9b0bd5d27f73127088b4368a69d4ed0cb 100644 (file)
@@ -1,3 +1,50 @@
+2002-07-25  Richard Sandiford  <rsandifo@redhat.com>
+
+       * doc/invoke.texi: Document -mabi=meabi, and expand on the EABI
+       description.  Document -mips32, -mips64, and the associated -march
+       values.  Describe the "mipsN" arguments to -march.  Say that the
+       -mipsN options are equivalent to -march.  Reword the description
+       of default type sizes.
+       * toplev.h (target_flags_explicit): Declare.
+       * toplev.c (target_flags_explicit): New var.
+       (set_target_switch): Update target_flags_explicit.
+       * config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine.
+       * config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine.
+       * config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3.
+       * config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine.
+       * config/mips/mips.h (mips_cpu_info): New struct.
+       (mips_cpu_string, mips_explicit_type_size_string): Remove.
+       (mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare.
+       (MIPS_CPP_SET_PROCESSOR): New macro.
+       (TARGET_CPP_BUILTINS): Declare a macro for each supported processor.
+       Define _MIPS_ARCH and _MIPS_TUNE.
+       (MIPS_ISA_DEFAULT): Don't provide a default value.  Instead...
+       (MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor
+       MIPS_ISA_DEFAULT were already defined.
+       (MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT.
+       (TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size.
+       (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New.
+       (GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules.
+       (ABI_GAS_ASM_SPEC): Remove.
+       (MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros.
+       (ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64.
+       Invoke %(asm_abi_default_spec) if no ABI was specified.
+       (CC1_SPEC): Remove ISA -> register-size rules.
+       (EXTRA_SPECS): Remove abi_gas_asm_spec.  Add asm_abi_default_spec.
+       * config/mips/mips.c (mips_arch_info, mips_tune_info): New vars.
+       (mips_cpu_string, mips_explicit_type_size_string): Remove.
+       (mips_cpu_info_table): New array.
+       (mips_set_architecture, mips_set_tune): New fns.
+       (override_options): Rework to make -mipsN equivalent to -march.
+       Detect more erroneous cases, including those removed from CC1_SPEC.
+       Don't change the ABI based on architecture, or vice versa.
+       Unify logic with GAS.
+       (mips_asm_file_start): Get architecture name from mips_arch_info.
+       (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
+       (mips_parse_cpu): Take the name of the option as argument.  Handle
+       'from-abi'.  Raise an error if the option is wrong.
+       (mips_cpu_info_from_isa): New fn.
+
 2002-07-25  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips.md (tablejump_mips161): Use gen_rtx_LABEL_REF.
index c5125d794413ace57300fd11fb5f0157863a3820..86b8aa819d18cdebdb9c3e9a4a6e2a0748bd2168 100644 (file)
@@ -21,11 +21,6 @@ Boston, MA 02111-1307, USA.  */
 /* Macros to implement the 64 bit ABI.  This file is meant to be included
    after mips.h.  */
 
-#undef SUBTARGET_TARGET_OPTIONS
-#define SUBTARGET_TARGET_OPTIONS \
-  { "abi=", &mips_abi_string,                                          \
-      "Specify ABI to use"},
-
 #undef STACK_BOUNDARY
 #define STACK_BOUNDARY \
   ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
index ee226b916dd7f1e40a81b2d55473a4bb085369dd..4fd74313ed0cd9fdc19a94311ee4f4b9266c0765 100644 (file)
@@ -22,15 +22,12 @@ Boston, MA 02111-1307, USA.  */
 
 #define OBJECT_FORMAT_ELF
 
-/* Default to -mips3.  */
+/* If an embedded ABI is selected, prefer to generate 64-bit code.
+   Implies -mips3 in such cases.  */
 #ifndef TARGET_DEFAULT
 #define TARGET_DEFAULT MASK_FLOAT64|MASK_64BIT
 #endif
 
-#ifndef MIPS_ISA_DEFAULT
-#define MIPS_ISA_DEFAULT 3
-#endif
-
 /* This should change to n32 when it is supported in gas.  */
 #ifndef MIPS_ABI_DEFAULT
 #define MIPS_ABI_DEFAULT ABI_O64
index 4dac304cbf9d6808b862909d45ca99f9a792b236..e42fa541ec1f57fb4838951aa623019270d0653e 100644 (file)
@@ -238,7 +238,7 @@ Boston, MA 02111-1307, USA.  */
    on the mipsX option.  */
 /* If no mips[3,4] option given, give the appropriate default for mabi=X */
 #undef SUBTARGET_ASM_SPEC
-#define SUBTARGET_ASM_SPEC "%{!mabi*:-n32} %{!mips*: %{!mabi*:-mips3} %{mabi=n32:-mips3} %{mabi=64:-mips4}}"
+#define SUBTARGET_ASM_SPEC "%{!mabi*:-n32} %{!mips*: %{!mabi*:-mips3} %{mabi=n32|mabi=64:-mips3}}"
 
 /* Must pass -g0 to the assembler, otherwise it may overwrite our
    debug info with its own debug info.  */
index fc2b2894225b6c48f73f4c05eb7f379dd1329fbf..b7ab601cfec32dd6ed4e1c9bd584e7fa176eeedd 100644 (file)
@@ -27,10 +27,6 @@ Boston, MA 02111-1307, USA.  */
 #define MIPS_ABI_DEFAULT ABI_MEABI
 #endif
 
-#ifndef MIPS_ENABLE_EMBEDDED_O32
-#define MIPS_ENABLE_EMBEDDED_O32 1
-#endif
-
 #ifndef PREFERRED_DEBUGGING_TYPE
 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
 #endif
index 56225f4e9e239f9836390d9710fffe8e6030a7b4..8c5a34ffbc786bd84c91c96b4c44811cb8d11c9c 100644 (file)
@@ -119,7 +119,15 @@ static int symbolic_expression_p                PARAMS ((rtx));
 static bool mips_assemble_integer        PARAMS ((rtx, unsigned int, int));
 static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
 static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static enum processor_type mips_parse_cpu       PARAMS ((const char *));
+static void mips_set_architecture    PARAMS ((const struct mips_cpu_info *));
+static void mips_set_tune           PARAMS ((const struct mips_cpu_info *));
+static bool mips_strict_matching_cpu_name_p    PARAMS ((const char *,
+                                                        const char *));
+static bool mips_matching_cpu_name_p           PARAMS ((const char *,
+                                                        const char *));
+static const struct mips_cpu_info *mips_parse_cpu   PARAMS ((const char *,
+                                                             const char *));
+static const struct mips_cpu_info *mips_cpu_info_from_isa PARAMS ((int));
 static void copy_file_data                     PARAMS ((FILE *, FILE *));
 #ifdef TARGET_IRIX6
 static void iris6_asm_named_section_1          PARAMS ((const char *,
@@ -294,9 +302,11 @@ enum cmp_type branch_type;
 
 /* The target cpu for code generation.  */
 enum processor_type mips_arch;
+const struct mips_cpu_info *mips_arch_info;
 
 /* The target cpu for optimization and scheduling.  */
 enum processor_type mips_tune;
+const struct mips_cpu_info *mips_tune_info;
 
 /* which instruction set architecture to use.  */
 int mips_isa;
@@ -305,7 +315,6 @@ int mips_isa;
 int mips_abi;
 
 /* Strings to hold which cpu and instruction set architecture to use.  */
-const char *mips_cpu_string;   /* for -mcpu=<xxx> */
 const char *mips_arch_string;   /* for -march=<xxx> */
 const char *mips_tune_string;   /* for -mtune=<xxx> */
 const char *mips_isa_string;   /* for -mips{1,2,3,4} */
@@ -320,11 +329,6 @@ int mips16;
    just a way to avoid using up another bit in target_flags.  */
 const char *mips_no_mips16_string;
 
-/* This is only used to determine if an type size setting option was
-   explicitly specified (-mlong64, -mint64, -mlong32).  The specs
-   set this option if such an option is used.  */
-const char *mips_explicit_type_size_string;
-
 /* Whether we are generating mips16 hard float code.  In mips16 mode
    we always set TARGET_SOFT_FLOAT; this variable is nonzero if
    -msoft-float was not specified by the user, which means that we
@@ -562,6 +566,54 @@ enum reg_class mips_char_to_class[256] =
   NO_REGS,     NO_REGS,        NO_REGS,        NO_REGS,
 };
 \f
+/* A table describing all the processors gcc knows about.  Names are
+   matched in the order listed.  The first mention of an ISA level is
+   taken as the canonical name for that ISA.
+
+   To ease comparison, please keep this table in the same order as
+   gas's mips_cpu_info_table[].  */
+const struct mips_cpu_info mips_cpu_info_table[] = {
+  /* Entries for generic ISAs */
+  { "mips1", PROCESSOR_R3000, 1 },
+  { "mips2", PROCESSOR_R6000, 2 },
+  { "mips3", PROCESSOR_R4000, 3 },
+  { "mips4", PROCESSOR_R8000, 4 },
+  { "mips32", PROCESSOR_R4KC, 32 },
+  { "mips64", PROCESSOR_R5KC, 64 },
+
+  /* MIPS I */
+  { "r3000", PROCESSOR_R3000, 1 },
+  { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */
+  { "r3900", PROCESSOR_R3900, 1 },
+
+  /* MIPS II */
+  { "r6000", PROCESSOR_R6000, 2 },
+
+  /* MIPS III */
+  { "r4000", PROCESSOR_R4000, 3 },
+  { "vr4100", PROCESSOR_R4100, 3 },
+  { "vr4300", PROCESSOR_R4300, 3 },
+  { "r4400", PROCESSOR_R4000, 3 }, /* = r4000 */
+  { "r4600", PROCESSOR_R4600, 3 },
+  { "orion", PROCESSOR_R4600, 3 }, /* = r4600 */
+  { "r4650", PROCESSOR_R4650, 3 },
+
+  /* MIPS IV */
+  { "r8000", PROCESSOR_R8000, 4 },
+  { "vr5000", PROCESSOR_R5000, 4 },
+
+  /* MIPS 32 */
+  { "4kc", PROCESSOR_R4KC, 32 },
+  { "4kp", PROCESSOR_R4KC, 32 }, /* = 4kc */
+
+  /* MIPS 64 */
+  { "5kc", PROCESSOR_R5KC, 64 },
+  { "20kc", PROCESSOR_R20KC, 64 },
+
+  /* End marker */
+  { 0, 0, 0 }
+};
+\f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -4931,16 +4983,44 @@ abort_with_insn (insn, reason)
   abort ();
 }
 \f
+/* Set up globals to generate code for the ISA or processor
+   described by INFO.  */
+
+static void
+mips_set_architecture (info)
+     const struct mips_cpu_info *info;
+{
+  if (info != 0)
+    {
+      mips_arch_info = info;
+      mips_arch = info->cpu;
+      mips_isa = info->isa;
+    }
+}
+
+
+/* Likewise for tuning.  */
+
+static void
+mips_set_tune (info)
+     const struct mips_cpu_info *info;
+{
+  if (info != 0)
+    {
+      mips_tune_info = info;
+      mips_tune = info->cpu;
+    }
+}
+
+
 /* Set up the threshold for data to go into the small data area, instead
    of the normal data area, and detect any conflicts in the switches.  */
 
 void
 override_options ()
 {
-  register int i, start;
-  register int regno;
-  register enum machine_mode mode;
-  register enum processor_type mips_cpu;
+  int i, start, regno;
+  enum machine_mode mode;
 
   mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
 
@@ -4958,250 +5038,137 @@ override_options ()
     target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT));
 #endif
 
-  /* Get the architectural level.  */
-  if (mips_isa_string == 0)
-    mips_isa = MIPS_ISA_DEFAULT;
+  /* Interpret -mabi.  */
+  mips_abi = MIPS_ABI_DEFAULT;
+  if (mips_abi_string != 0)
+    {
+      if (strcmp (mips_abi_string, "32") == 0)
+       mips_abi = ABI_32;
+      else if (strcmp (mips_abi_string, "o64") == 0)
+       mips_abi = ABI_O64;
+      else if (strcmp (mips_abi_string, "n32") == 0)
+       mips_abi = ABI_N32;
+      else if (strcmp (mips_abi_string, "64") == 0)
+       mips_abi = ABI_64;
+      else if (strcmp (mips_abi_string, "eabi") == 0)
+       mips_abi = ABI_EABI;
+      else if (strcmp (mips_abi_string, "meabi") == 0)
+       mips_abi = ABI_MEABI;
+      else
+       fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string);
+    }
+
+  /* The following code determines the architecture and register size.
+     Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
+     The GAS and GCC code should be kept in sync as much as possible.  */
 
-  else if (mips_isa_string != 0
-          && mips_arch_string != 0)
-      warning ("The -march option is incompatible to -mipsN and therefore ignored.");
+  if (mips_arch_string != 0)
+    mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string));
 
-  else if (ISDIGIT (*mips_isa_string))
+  if (mips_tune_string != 0)
+    mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string));
+
+  if (mips_isa_string != 0)
     {
-      mips_isa = atoi (mips_isa_string);
-      if (mips_isa == 16)
+      /* Handle -mipsN.  */
+      int level = atoi (mips_isa_string);
+      if (level == 16)
        {
-         /* -mno-mips16 overrides -mips16.  */
+         /* -mips16 specifies an ASE rather than a processor, so don't
+            change mips_arch here.  -mno-mips16 overrides -mips16.  */
          if (mips_no_mips16_string == NULL)
-           {
-             target_flags |= MASK_MIPS16;
-             if (TARGET_64BIT)
-               mips_isa = 3;
-             else
-               mips_isa = MIPS_ISA_DEFAULT;
-           }
-         else
-           {
-             mips_isa = MIPS_ISA_DEFAULT;
-           }
+           target_flags |= MASK_MIPS16;
        }
-      else if (mips_isa < 1
-              || (mips_isa > 4
-                  && mips_isa != 32
-                  && mips_isa != 64))
+      else if (mips_arch_info != 0)
        {
-         error ("-mips%d not supported", mips_isa);
-         mips_isa = 1;
+         /* -march takes precedence over -mipsN, since it is more descriptive.
+            There's no harm in specifying both as long as the ISA levels
+            are the same.  */
+         if (mips_isa != level)
+           error ("-mips%d conflicts with the other architecture options, which specify a MIPS%d processor",
+                  level, mips_isa);
        }
-    }
-
-  else
-    {
-      error ("bad value (%s) for -mips switch", mips_isa_string);
-      mips_isa = 1;
-    }
-
-#ifdef MIPS_ABI_DEFAULT
-  /* Get the ABI to use.  */
-  if (mips_abi_string == (char *) 0)
-    mips_abi = MIPS_ABI_DEFAULT;
-  else if (! strcmp (mips_abi_string, "32"))
-    mips_abi = ABI_32;
-  else if (! strcmp (mips_abi_string, "o64"))
-    mips_abi = ABI_O64;
-  else if (! strcmp (mips_abi_string, "n32"))
-    mips_abi = ABI_N32;
-  else if (! strcmp (mips_abi_string, "64"))
-    mips_abi = ABI_64;
-  else if (! strcmp (mips_abi_string, "eabi"))
-    mips_abi = ABI_EABI;
-  else if (! strcmp (mips_abi_string, "meabi"))
-    mips_abi = ABI_MEABI;
-  else
-    error ("bad value (%s) for -mabi= switch", mips_abi_string);
-
-  /* A specified ISA defaults the ABI if it was not specified.  */
-  if (mips_abi_string == 0 && mips_isa_string
-      && mips_abi != ABI_EABI
-      && mips_abi != ABI_O64
-      && mips_abi != ABI_MEABI)
-    {
-      if (mips_isa == 64)
-       mips_abi = ABI_O64;
       else
        {
-         if (! ISA_HAS_64BIT_REGS)
-           mips_abi = ABI_32;
-         else if (mips_abi != ABI_N32)
-           mips_abi = ABI_64;
+         mips_set_architecture (mips_cpu_info_from_isa (level));
+         if (mips_arch_info == 0)
+           error ("bad value (%s) for -mips switch", mips_isa_string);
        }
     }
 
-#ifdef MIPS_CPU_STRING_DEFAULT
-  /* A specified ABI defaults the ISA if it was not specified.  */
-  else if (mips_isa_string == 0 && mips_abi_string
-          && mips_abi != ABI_EABI && mips_abi != ABI_O64)
-    {
-      if (mips_abi == ABI_32)
-       mips_isa = 1;
-      else if (mips_abi == ABI_N32)
-       mips_isa = 3;
-      else
-       mips_isa = 4;
-    }
-#endif
-
-  /* If both ABI and ISA were specified, check for conflicts.  */
-  else if (mips_isa_string && mips_abi_string)
+  if (mips_arch_info == 0)
     {
-      if (! ISA_HAS_64BIT_REGS && (mips_abi == ABI_N32 || mips_abi == ABI_64
-                            || mips_abi == ABI_O64))
-       error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa);
-    }
-
-  /* Override TARGET_DEFAULT if necessary.  */
-  if (mips_abi == ABI_32)
-    target_flags &= ~ (MASK_FLOAT64|MASK_64BIT);
-
-  /* If no type size setting options (-mlong64,-mint64,-mlong32) were used
-     then set the type sizes.  In the EABI in 64 bit mode, longs and
-     pointers are 64 bits.  Likewise for the SGI Irix6 N64 ABI.  */
-  if (mips_explicit_type_size_string == NULL
-      && ((mips_abi == ABI_EABI && TARGET_64BIT)
-         || mips_abi == ABI_64))
-    target_flags |= MASK_LONG64;
-
+#ifdef MIPS_CPU_STRING_DEFAULT
+      mips_set_architecture (mips_parse_cpu ("default CPU",
+                                            MIPS_CPU_STRING_DEFAULT));
 #else
-  if (mips_abi_string)
-    error ("this target does not support the -mabi switch");
+      mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT));
 #endif
+    }
 
-#ifdef MIPS_CPU_STRING_DEFAULT
-  /* ??? There is a minor inconsistency here.  If the user specifies an ISA
-     greater than that supported by the default processor, then the user gets
-     an error.  Normally, the compiler will just default to the base level cpu
-     for the indicated isa.  */
-  if (mips_arch_string == 0)
-    mips_arch_string = MIPS_CPU_STRING_DEFAULT;
-  if (mips_tune_string == 0)
-    mips_tune_string = MIPS_CPU_STRING_DEFAULT;
-#endif
+  if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS)
+    error ("-march=%s is not compatible with the selected ABI",
+          mips_arch_info->name);
 
-  /* Identify the processor type.  */
+  /* Optimize for mips_arch, unless -mtune selects a different processor.  */
+  if (mips_tune_info == 0)
+    mips_set_tune (mips_arch_info);
 
-  if (mips_cpu_string != 0)
+  if ((target_flags_explicit & MASK_64BIT) != 0)
     {
-      mips_cpu = mips_parse_cpu (mips_cpu_string);
-      if (mips_cpu == PROCESSOR_DEFAULT)
-       {
-         error ("bad value (%s) for -mcpu= switch", mips_cpu_string);
-         mips_cpu_string = "default";
-       }
-      mips_arch = mips_cpu;
-      mips_tune = mips_cpu;
-    }
-
-  if (mips_arch_string == 0
-      || ! strcmp (mips_arch_string, "default")
-      || ! strcmp (mips_arch_string, "DEFAULT"))
-    {
-      switch (mips_isa)
-       {
-       default:
-         mips_arch_string = "3000";
-         mips_arch = PROCESSOR_R3000;
-         break;
-       case 2:
-         mips_arch_string = "6000";
-         mips_arch = PROCESSOR_R6000;
-         break;
-       case 3:
-         mips_arch_string = "4000";
-         mips_arch = PROCESSOR_R4000;
-         break;
-       case 4:
-         mips_arch_string = "8000";
-         mips_arch = PROCESSOR_R8000;
-         break;
-       case 32:
-          mips_arch_string = "4kc";
-          mips_arch = PROCESSOR_R4KC;
-          break;
-        case 64:
-          mips_arch_string = "5kc";
-          mips_arch = PROCESSOR_R5KC;
-          break;
-       }
+      /* The user specified the size of the integer registers.  Make sure
+        it agrees with the ABI and ISA.  */
+      if (TARGET_64BIT && !ISA_HAS_64BIT_REGS)
+       error ("-mgp64 used with a 32-bit processor");
+      else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS)
+       error ("-mgp32 used with a 64-bit ABI");
+      else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS)
+       error ("-mgp64 used with a 32-bit ABI");
     }
   else
     {
-      mips_arch = mips_parse_cpu (mips_arch_string);
-      if (mips_arch == PROCESSOR_DEFAULT)
-       {
-         error ("bad value (%s) for -march= switch", mips_arch_string);
-         mips_arch_string = "default";
-       }
-    }
-  if (mips_tune_string == 0
-      || ! strcmp (mips_tune_string, "default")
-      || ! strcmp (mips_tune_string, "DEFAULT"))
-    {
-      if (mips_arch != PROCESSOR_DEFAULT)
-       mips_tune = mips_arch;
+      /* Infer the integer register size from the ABI and processor.
+        Restrict ourselves to 32-bit registers if that's all the
+        processor has, or if the ABI cannot handle 64-bit registers.  */
+      if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS)
+       target_flags &= ~MASK_64BIT;
       else
-      switch (mips_isa)
-       {
-       default:
-         mips_tune_string = "3000";
-         mips_tune = PROCESSOR_R3000;
-         break;
-       case 2:
-         mips_tune_string = "6000";
-         mips_tune = PROCESSOR_R6000;
-         break;
-       case 3:
-         mips_tune_string = "4000";
-         mips_tune = PROCESSOR_R4000;
-         break;
-       case 4:
-         mips_tune_string = "8000";
-         mips_tune = PROCESSOR_R8000;
-         break;
-       case 32:
-         mips_tune_string = "4kc";
-         mips_tune = PROCESSOR_R4KC;
-         break;
-       case 64:
-         mips_tune_string = "5kc";
-         mips_tune = PROCESSOR_R5KC;
-         break;
-       }
+       target_flags |= MASK_64BIT;
+    }
 
+  if ((target_flags_explicit & MASK_FLOAT64) != 0)
+    {
+      /* Really, -mfp32 and -mfp64 are ornamental options.  There's
+        only one right answer here.  */
+      if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64)
+       error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
+      else if (!TARGET_64BIT && TARGET_FLOAT64)
+       error ("unsupported combination: %s", "-mgp32 -mfp64");
+      else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64)
+       error ("unsupported combination: %s", "-mfp64 -msingle-float");
     }
   else
     {
-       mips_tune = mips_parse_cpu (mips_tune_string);
-      if (mips_tune == PROCESSOR_DEFAULT)
-       {
-         error ("bad value (%s) for -mtune= switch", mips_tune_string);
-         mips_tune_string = "default";
-       }
+      /* -msingle-float selects 32-bit float registers.  Otherwise the
+        float registers should be the same size as the integer ones.  */
+      if (TARGET_64BIT && TARGET_DOUBLE_FLOAT)
+       target_flags |= MASK_FLOAT64;
+      else
+       target_flags &= ~MASK_FLOAT64;
     }
 
-  /* make sure sizes of ints/longs/etc. are ok */
-  if (! ISA_HAS_64BIT_REGS)
-    {
-      if (TARGET_FLOAT64)
-       {
-         error ("-mips%d does not support 64 bit fp registers", mips_isa);
-         target_flags &= ~ MASK_FLOAT64;
-       }
+  /* End of code shared with GAS.  */
 
-      else if (TARGET_64BIT)
-       {
-         error ("-mips%d does not support 64 bit gp registers", mips_isa);
-         target_flags &= ~MASK_64BIT;
-       }
+  if ((target_flags_explicit & MASK_LONG64) == 0)
+    {
+      /* If no type size setting options (-mlong64,-mint64,-mlong32)
+        were used, then set the type sizes.  In the EABI in 64 bit mode,
+        longs and pointers are 64 bits.  Likewise for the SGI Irix6 N64
+        ABI.  */
+      if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64)
+       target_flags |= MASK_LONG64;
+      else
+       target_flags &= ~MASK_LONG64;
     }
 
   if (mips_abi != ABI_32 && mips_abi != ABI_O64)
@@ -6361,7 +6328,7 @@ mips_asm_file_start (stream)
   if (flag_verbose_asm)
     fprintf (stream, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
             ASM_COMMENT_START,
-            mips_section_threshold, mips_arch_string, mips_isa);
+            mips_section_threshold, mips_arch_info->name, mips_isa);
 }
 \f
 /* If we are optimizing the global pointer, emit the text section now and any
@@ -10166,115 +10133,120 @@ mips_output_conditional_branch (insn,
   /* NOTREACHED */
   return 0;
 }
+\f
+/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
+   with a final "000" replaced by "k".  Ignore case.
+
+   Note: this function is shared between GCC and GAS.  */
 
-static enum processor_type
-mips_parse_cpu (cpu_string)
-     const char *cpu_string;
+static bool
+mips_strict_matching_cpu_name_p (canonical, given)
+     const char *canonical, *given;
 {
-  const char *p = cpu_string;
-  int seen_v = 0;
-  enum processor_type cpu;
-  int warn_upper_case = 0;
+  while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
+    given++, canonical++;
 
-  /* We need to cope with the various "vr" prefixes for the NEC 4300
-     and 4100 processors.  */
-  if (*p == 'v' || *p == 'V')
-    {
-      if (*p == 'V')
-       warn_upper_case = 1;
-      seen_v = 1, p++;
-    }
+  return ((*given == 0 && *canonical == 0)
+         || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
+}
 
-  if (*p == 'r' || *p == 'R')
-    {
-      if (*p == 'R')
-       warn_upper_case = 1;
-      p++;
-    }
 
-  if (warn_upper_case)
-    warning ("the cpu name must be lower case");
+/* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
+   CPU name.  We've traditionally allowed a lot of variation here.
 
-  /* Since there is no difference between a R2000 and R3000 in
-     terms of the scheduler, we collapse them into just an R3000.  */
+   Note: this function is shared between GCC and GAS.  */
 
-  cpu = PROCESSOR_DEFAULT;
-  switch (*p)
-    {
-    case '2':
-      if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K"))
-       cpu = PROCESSOR_R3000;
-      else if (!strcmp (p, "20kc") || !strcmp (p, "20Kc") )
-        cpu = PROCESSOR_R20KC;
-      break;
+static bool
+mips_matching_cpu_name_p (canonical, given)
+     const char *canonical, *given;
+{
+  /* First see if the name matches exactly, or with a final "000"
+     turned into "k".  */
+  if (mips_strict_matching_cpu_name_p (canonical, given))
+    return true;
 
-    case '3':
-      if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K"))
-       cpu = PROCESSOR_R3000;
-      else if (!strcmp (p, "3900"))
-       cpu = PROCESSOR_R3900;
-      break;
+  /* If not, try comparing based on numerical designation alone.
+     See if GIVEN is an unadorned number, or 'r' followed by a number.  */
+  if (TOLOWER (*given) == 'r')
+    given++;
+  if (!ISDIGIT (*given))
+    return false;
 
-    case '4':
-      if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K"))
-       cpu = PROCESSOR_R4000;
-      /* The vr4100 is a non-FP ISA III processor with some extra
-        instructions.  */
-      else if (!strcmp (p, "4100"))
-         cpu = PROCESSOR_R4100;
-      /* The vr4300 is a standard ISA III processor, but with a different
-        pipeline.  */
-      else if (!strcmp (p, "4300"))
-       cpu = PROCESSOR_R4300;
-      /* The r4400 is exactly the same as the r4000 from the compiler's
-        viewpoint.  */
-      else if (!strcmp (p, "4400"))
-       cpu = PROCESSOR_R4000;
-      else if (!strcmp (p, "4600"))
-       cpu = PROCESSOR_R4600;
-      else if (!strcmp (p, "4650"))
-       cpu = PROCESSOR_R4650;
-      /* The 4kc and 4kp processor cores are the same for
-        scheduling purposes; they both implement the MIPS32
-        ISA and only differ in their memory management
-        methods.  */
-      else if (!strcmp (p, "4kc") || !strcmp (p, "4Kc")
-               || !strcmp (p, "4kp") || !strcmp (p, "4Kp") )
-       cpu = PROCESSOR_R4KC;
-      break;
+  /* Skip over some well-known prefixes in the canonical name,
+     hoping to find a number there too.  */
+  if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
+    canonical += 2;
+  else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
+    canonical += 2;
+  else if (TOLOWER (canonical[0]) == 'r')
+    canonical += 1;
 
-    case '5':
-      if (!strcmp (p, "5000") || !strcmp (p, "5k") || !strcmp (p, "5K"))
-       cpu = PROCESSOR_R5000;
-      else if (!strcmp (p, "5kc") || !strcmp (p, "5Kc") )
-          cpu = PROCESSOR_R5KC;
-      break;
+  return mips_strict_matching_cpu_name_p (canonical, given);
+}
 
-    case '6':
-      if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K"))
-       cpu = PROCESSOR_R6000;
-      break;
 
-    case '8':
-      if (!strcmp (p, "8000"))
-       cpu = PROCESSOR_R8000;
-      break;
+/* Parse an option that takes the name of a processor as its argument.
+   OPTION is the name of the option and CPU_STRING is the argument.
+   Return the corresponding processor enumeration if the CPU_STRING is
+   recognized, otherwise report an error and return null.
 
-    case 'o':
-      if (!strcmp (p, "orion"))
-       cpu = PROCESSOR_R4600;
-      break;
-    }
+   A similar function exists in GAS.  */
+
+static const struct mips_cpu_info *
+mips_parse_cpu (option, cpu_string)
+     const char *option, *cpu_string;
+{
+  const struct mips_cpu_info *p;
+  const char *s;
 
-  if (seen_v
-      && cpu != PROCESSOR_R4300
-      && cpu != PROCESSOR_R4100
-      && cpu != PROCESSOR_R5000)
-    cpu = PROCESSOR_DEFAULT;
+  /* In the past, we allowed upper-case CPU names, but it doesn't
+     work well with the multilib machinery.  */
+  for (s = cpu_string; *s != 0; s++)
+    if (ISUPPER (*s))
+      {
+       warning ("the cpu name must be lower case");
+       break;
+      }
 
-  return cpu;
+  /* 'from-abi' selects the most compatible architecture for the given
+     ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs.  For the
+     EABIs, we have to decide whether we're using the 32-bit or 64-bit
+     version.  Look first at the -mgp options, if given, otherwise base
+     the choice on MASK_64BIT in TARGET_DEFAULT.  */
+  if (strcasecmp (cpu_string, "from-abi") == 0)
+    return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS ? 1
+                                  : ABI_NEEDS_64BIT_REGS ? 3
+                                  : (TARGET_64BIT ? 3 : 1));
+
+  /* 'default' has traditionally been a no-op.  Probably not very useful.  */
+  if (strcasecmp (cpu_string, "default") == 0)
+    return 0;
+
+  for (p = mips_cpu_info_table; p->name != 0; p++)
+    if (mips_matching_cpu_name_p (p->name, cpu_string))
+      return p;
+
+  error ("bad value (%s) for %s", cpu_string, option);
+  return 0;
 }
 
+
+/* Return the processor associated with the given ISA level, or null
+   if the ISA isn't valid.  */
+
+static const struct mips_cpu_info *
+mips_cpu_info_from_isa (isa)
+     int isa;
+{
+  const struct mips_cpu_info *p;
+
+  for (p = mips_cpu_info_table; p->name != 0; p++)
+    if (p->isa == isa)
+      return p;
+
+  return 0;
+}
+\f
 /* Adjust the cost of INSN based on the relationship between INSN that
    is dependent on DEP_INSN through the dependence LINK.  The default
    is to make no adjustment to COST.
index 5f2b74ee9bd00304a8b81d3238ee8c2ce8fb3aae..84b6880ddf1dd1cb9437c6ae08548b64d5421035 100644 (file)
@@ -118,6 +118,23 @@ enum block_move_type {
   BLOCK_MOVE_LAST                      /* generate just the last store */
 };
 
+/* Information about one recognised processor.  Defined here for the
+   benefit of TARGET_CPU_CPP_BUILTINS.  */
+struct mips_cpu_info {
+  /* The 'canonical' name of the processor as far as GCC is concerned.
+     It's typically a manufacturer's prefix followed by a numerical
+     designation.  It should be lower case.  */
+  const char *name;
+
+  /* The internal processor number that most closely matches this
+     entry.  Several processors can have the same value, if there's no
+     difference between them from GCC's point of view.  */
+  enum processor_type cpu;
+
+  /* The ISA level that the processor implements.  */
+  int isa;
+};
+
 extern char mips_reg_names[][8];       /* register names (a0 vs. $4).  */
 extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
 extern const char *current_function_file; /* filename current function is in */
@@ -146,14 +163,12 @@ extern int mips_isa;                      /* architectural level */
 extern int mips16;                     /* whether generating mips16 code */
 extern int mips16_hard_float;          /* mips16 without -msoft-float */
 extern int mips_entry;                 /* generate entry/exit for mips16 */
-extern const char *mips_cpu_string;    /* for -mcpu=<xxx> */
 extern const char *mips_arch_string;    /* for -march=<xxx> */
 extern const char *mips_tune_string;    /* for -mtune=<xxx> */
 extern const char *mips_isa_string;    /* for -mips{1,2,3,4} */
 extern const char *mips_abi_string;    /* for -mabi={32,n32,64} */
 extern const char *mips_entry_string;  /* for -mentry */
 extern const char *mips_no_mips16_string;/* for -mno-mips16 */
-extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
 extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
 extern int mips_split_addresses;       /* perform high/lo_sum support */
 extern int dslots_load_total;          /* total # load related delay slots */
@@ -167,6 +182,9 @@ extern GTY(()) rtx mips_load_reg2;  /* 2nd reg to check for load delay */
 extern GTY(()) rtx mips_load_reg3;     /* 3rd reg to check for load delay */
 extern GTY(()) rtx mips_load_reg4;     /* 4th reg to check for load delay */
 extern int mips_string_length;         /* length of strings for mips16 */
+extern const struct mips_cpu_info mips_cpu_info_table[];
+extern const struct mips_cpu_info *mips_arch_info;
+extern const struct mips_cpu_info *mips_tune_info;
 
 /* Functions to change what output section we are using.  */
 extern void            sdata_section PARAMS ((void));
@@ -342,6 +360,25 @@ extern void                sbss_section PARAMS ((void));
 #define TUNE_MIPS5000               (mips_tune == PROCESSOR_R5000)
 #define TUNE_MIPS6000               (mips_tune == PROCESSOR_R6000)
 
+/* Define preprocessor macros for the -march and -mtune options.
+   PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected
+   processor.  If INFO's canonical name is "foo", define PREFIX to
+   be "foo", and define an additional macro PREFIX_FOO.  */
+#define MIPS_CPP_SET_PROCESSOR(PREFIX, INFO)                   \
+  do                                                           \
+    {                                                          \
+      char *macro, *p;                                         \
+                                                               \
+      macro = concat ((PREFIX), "_", (INFO)->name, NULL);      \
+      for (p = macro; *p != 0; p++)                            \
+       *p = TOUPPER (*p);                                      \
+                                                               \
+      builtin_define (macro);                                  \
+      builtin_define_with_value ((PREFIX), (INFO)->name, 1);   \
+      free (macro);                                            \
+    }                                                          \
+  while (0)
+
 /* Target CPU builtins.  */
 #define TARGET_CPU_CPP_BUILTINS()                              \
   do                                                           \
@@ -355,16 +392,16 @@ extern void               sbss_section PARAMS ((void));
       if (!flag_iso)                                           \
          builtin_define ("mips");                              \
                                                                \
+      /* Treat _R3000 and _R4000 like register-size defines,   \
+        which is how they've historically been used.  */       \
       if (TARGET_64BIT)                                                \
        {                                                       \
          builtin_define ("__mips64");                          \
-         /* Silly, but will do until processor defines.  */    \
          builtin_define_std ("R4000");                         \
          builtin_define ("_R4000");                            \
        }                                                       \
       else                                                     \
        {                                                       \
-         /* Ditto.  */                                         \
          builtin_define_std ("R3000");                         \
          builtin_define ("_R3000");                            \
        }                                                       \
@@ -376,6 +413,9 @@ extern void         sbss_section PARAMS ((void));
       if (TARGET_MIPS16)                                       \
          builtin_define ("__mips16");                          \
                                                                \
+      MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info);   \
+      MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info);   \
+                                                               \
       if (ISA_MIPS1)                                           \
        {                                                       \
          builtin_define ("__mips=1");                          \
@@ -605,8 +645,11 @@ extern void                sbss_section PARAMS ((void));
 #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
 #endif
 
+/* 'from-abi' makes a good default: you get whatever the ABI requires.  */
 #ifndef MIPS_ISA_DEFAULT
-#define MIPS_ISA_DEFAULT 1
+#ifndef MIPS_CPU_STRING_DEFAULT
+#define MIPS_CPU_STRING_DEFAULT "from-abi"
+#endif
 #endif
 
 #ifdef IN_LIBGCC2
@@ -656,7 +699,8 @@ extern void         sbss_section PARAMS ((void));
 #endif
 
 #ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT }
+#define MULTILIB_DEFAULTS \
+    { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT, MULTILIB_ABI_DEFAULT }
 #endif
 
 /* We must pass -EL to the linker by default for little endian embedded
@@ -675,20 +719,18 @@ extern void               sbss_section PARAMS ((void));
 #define TARGET_OPTIONS                                                 \
 {                                                                      \
   SUBTARGET_TARGET_OPTIONS                                             \
-  { "cpu=",    &mips_cpu_string,                                       \
-      N_("Specify CPU for scheduling purposes")},                      \
   { "tune=",    &mips_tune_string,                                     \
       N_("Specify CPU for scheduling purposes")},                       \
   { "arch=",    &mips_arch_string,                                      \
       N_("Specify CPU for code generation purposes")},                  \
+  { "abi=", &mips_abi_string,                                          \
+      N_("Specify an ABI")},                                           \
   { "ips",     &mips_isa_string,                                       \
       N_("Specify a Standard MIPS ISA")},                              \
   { "entry",   &mips_entry_string,                                     \
       N_("Use mips16 entry/exit psuedo ops")},                         \
   { "no-mips16", &mips_no_mips16_string,                               \
       N_("Don't use MIPS16 instructions")},                            \
-  { "explicit-type-size", &mips_explicit_type_size_string,             \
-      NULL},                                                           \
   { "no-flush-func", &mips_cache_flush_func,                           \
       N_("Don't call any cache flush functions")},                     \
   { "flush-func=", &mips_cache_flush_func,                             \
@@ -716,6 +758,16 @@ extern void                sbss_section PARAMS ((void));
 #define BRANCH_LIKELY_P()      GENERATE_BRANCHLIKELY
 #define HAVE_SQRT_P()          (!ISA_MIPS1)
 
+/* True if the ABI can only work with 64-bit integer registers.  We
+   generally allow ad-hoc variations for TARGET_SINGLE_FLOAT, but
+   otherwise floating-point registers must also be 64-bit.  */
+#define ABI_NEEDS_64BIT_REGS   (mips_abi == ABI_64                     \
+                                || mips_abi == ABI_O64                 \
+                                || mips_abi == ABI_N32)
+
+/* Likewise for 32-bit regs.  */
+#define ABI_NEEDS_32BIT_REGS   (mips_abi == ABI_32)
+
 /* ISA has instructions for managing 64 bit fp and gp regs (eg. mips3).  */
 #define ISA_HAS_64BIT_REGS     (ISA_MIPS3                              \
                                 || ISA_MIPS4                           \
@@ -911,7 +963,7 @@ while (0)
 /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS
    assembler.  */
 
-#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
+#define GAS_ASM_SPEC "%{mtune=*} %{v}"
 
 
 extern int mips_abi;
@@ -920,8 +972,43 @@ extern int mips_abi;
 #define MIPS_ABI_DEFAULT ABI_32
 #endif
 
-#ifndef ABI_GAS_ASM_SPEC
-#define ABI_GAS_ASM_SPEC ""
+/* Use the most portable ABI flag for the ASM specs.  */
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define MULTILIB_ABI_DEFAULT "mabi=32"
+#define ASM_ABI_DEFAULT_SPEC "-32"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define MULTILIB_ABI_DEFAULT "mabi=o64"
+#define ASM_ABI_DEFAULT_SPEC "-mabi=o64"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_N32
+#define MULTILIB_ABI_DEFAULT "mabi=n32"
+#define ASM_ABI_DEFAULT_SPEC "-n32"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_64
+#define MULTILIB_ABI_DEFAULT "mabi=64"
+#define ASM_ABI_DEFAULT_SPEC "-64"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_EABI
+#define MULTILIB_ABI_DEFAULT "mabi=eabi"
+#define ASM_ABI_DEFAULT_SPEC "-mabi=eabi"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_MEABI
+/* Most GAS don't know about MEABI.  */
+#define MULTILIB_ABI_DEFAULT "mabi=meabi"
+#define ASM_ABI_DEFAULT_SPEC ""
+#endif
+
+/* Only ELF targets can switch the ABI.  */
+#ifndef OBJECT_FORMAT_ELF
+#undef ASM_ABI_DEFAULT_SPEC
+#define ASM_ABI_DEFAULT_SPEC ""
 #endif
 
 /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
@@ -969,7 +1056,11 @@ extern int mips_abi;
 #define SUBTARGET_ASM_SPEC ""
 #endif
 
-/* ASM_SPEC is the set of arguments to pass to the assembler.  */
+/* ASM_SPEC is the set of arguments to pass to the assembler.  Note: we
+   pass -mgp32, -mgp64, -march, -mabi=eabi and -meabi=o64 regardless of
+   whether we're using GAS.  These options can only be used properly
+   with GAS, and it is better to get an error from a non-GAS assembler
+   than to silently generate bad code.  */
 
 #undef ASM_SPEC
 #define ASM_SPEC "\
@@ -978,7 +1069,9 @@ extern int mips_abi;
 %(subtarget_asm_optimizing_spec) \
 %(subtarget_asm_debugging_spec) \
 %{membedded-pic} \
-%{mabi=32:-32}%{mabi=o32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
+%{mabi=32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
+%{mabi=eabi} %{mabi=o64} %{!mabi*: %(asm_abi_default_spec)} \
+%{mgp32} %{mgp64} %{march=*} \
 %(target_asm_spec) \
 %(subtarget_asm_spec)"
 
@@ -1049,15 +1142,6 @@ extern int mips_abi;
 #ifndef CC1_SPEC
 #define CC1_SPEC "\
 %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
-%{mips1:-mfp32 -mgp32} %{mips2:-mfp32 -mgp32}\
-%{mips3:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
-%{mips4:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
-%{mips32:-mfp32 -mgp32} \
-%{mips64:%{!msingle-float:-mfp64} -mgp64} \
-%{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
-%{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
-%{mint64|mlong64|mlong32:-mexplicit-type-size }\
-%{mgp32: %{mfp64:%emay not use both -mgp32 and -mfp64} %{!mfp32: -mfp32}} \
 %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
 %{save-temps: } \
 %(subtarget_cc1_spec)"
@@ -1088,12 +1172,12 @@ extern int mips_abi;
   { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC },                                \
   { "mips_as_asm_spec", MIPS_AS_ASM_SPEC },                            \
   { "gas_asm_spec", GAS_ASM_SPEC },                                    \
-  { "abi_gas_asm_spec", ABI_GAS_ASM_SPEC },                             \
   { "target_asm_spec", TARGET_ASM_SPEC },                              \
   { "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC },        \
   { "subtarget_asm_optimizing_spec", SUBTARGET_ASM_OPTIMIZING_SPEC },  \
   { "subtarget_asm_debugging_spec", SUBTARGET_ASM_DEBUGGING_SPEC },    \
   { "subtarget_asm_spec", SUBTARGET_ASM_SPEC },                                \
+  { "asm_abi_default_spec", ASM_ABI_DEFAULT_SPEC },                    \
   { "endian_spec", ENDIAN_SPEC },                                      \
   SUBTARGET_EXTRA_SPECS
 
index f5e0febc5b0557770afa63b32b13274beebe66b8..427f5c47384af1d0391a9cb819b254af96fd3642 100644 (file)
@@ -6976,65 +6976,77 @@ These @samp{-m} options are defined for the MIPS family of computers:
 
 @table @gcctabopt
 
-@item -march=@var{cpu-type}
+@item -march=@var{arch}
 @opindex march
-Assume the defaults for the machine type @var{cpu-type} when generating
-instructions.  The choices for @var{cpu-type} are  @samp{r2000}, @samp{r3000},
-@samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400},
-@samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000},
-and @samp{orion}.  Additionally, the @samp{r2000}, @samp{r3000},
-@samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as
-@samp{r2k} (or @samp{r2K}), @samp{r3k}, etc.
-
-@item -mtune=@var{cpu-type}
+Generate code that will run on @var{arch}, which can be the name of a
+generic MIPS ISA, or the name of a particular processor.  The ISA names
+are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, @samp{mips32}
+and @samp{mips64}.  The processor names are: @samp{r2000},
+@samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{vr4100}, @samp{vr4300},
+@samp{r4400}, @samp{r4600}, @samp{r4650}, @samp{vr5000}, @samp{r6000},
+@samp{r8000}, @samp{4kc}, @samp{4kp}, @samp{5kc}, @samp{20kc}
+and @samp{orion}.  The special value @samp{from-abi} selects the
+most compatible architecture for the selected ABI (that is,
+@samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@.
+
+In processor names, a final @samp{000} can be abbreviated as @samp{k}
+(for example, @samp{-march=r2k}).  Prefixes are optional, and
+@samp{vr} may be written @samp{r}.
+
+GCC defines two macros based on the value of this option.  The first
+is @samp{_MIPS_ARCH}, which gives the name of target architecture, as
+a string.  The second has the form @samp{_MIPS_ARCH_@var{foo}},
+where @var{foo} is the capitialized value of @samp{_MIPS_ARCH}@.
+For example, @samp{-march=r2000} will set @samp{_MIPS_ARCH}
+to @samp{"r2000"} and define the macro @samp{_MIPS_ARCH_R2000}.
+
+Note that the @samp{_MIPS_ARCH} macro uses the processor names given
+above.  In other words, it will have the full prefix and will not
+abbreviate @samp{000} as @samp{k}.  In the case of @samp{from-abi},
+the macro names the resolved architecture (either @samp{"mips1"} or
+@samp{"mips3"}).  It names the default architecture when no
+@option{-march} option is given.
+
+@item -mtune=@var{arch}
 @opindex mtune
-Assume the defaults for the machine type @var{cpu-type} when scheduling
-instructions.  The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000},
-@samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400},
-@samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000},
-and @samp{orion}.  Additionally, the @samp{r2000}, @samp{r3000},
-@samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as
-@samp{r2k} (or @samp{r2K}), @samp{r3k}, etc.  While picking a specific
-@var{cpu-type} will schedule things appropriately for that particular
-chip, the compiler will not generate any code that does not meet level 1
-of the MIPS ISA (instruction set architecture) without a @option{-mipsX}
-or @option{-mabi} switch being used.
+Optimize for @var{arch}.  Among other things, this option controls
+the way instructions are scheduled, and the perceived cost of arithmetic
+operations.  The list of @var{arch} values is the same as for
+@option{-march}.
 
-@item -mcpu=@var{cpu-type}
-@opindex mcpu
-This is identical to specifying both @option{-march} and @option{-mtune}.
+When this option is not used, GCC will optimize for the processor
+specified by @option{-march}.  By using @option{-march} and
+@option{-mtune} together, it is possible to generate code that will
+run on a family of processors, but optimize the code for one
+particular member of that family.
+
+@samp{-mtune} defines the macros @samp{_MIPS_TUNE} and
+@samp{_MIPS_TUNE_@var{foo}}, which work in the same way as the
+@samp{-march} ones described above.
 
 @item -mips1
 @opindex mips1
-Issue instructions from level 1 of the MIPS ISA@.  This is the default.
-@samp{r3000} is the default @var{cpu-type} at this ISA level.
+Equivalent to @samp{-march=mips1}.
 
 @item -mips2
 @opindex mips2
-Issue instructions from level 2 of the MIPS ISA (branch likely, square
-root instructions).  @samp{r6000} is the default @var{cpu-type} at this
-ISA level.
+Equivalent to @samp{-march=mips2}.
 
 @item -mips3
 @opindex mips3
-Issue instructions from level 3 of the MIPS ISA (64-bit instructions).
-@samp{r4000} is the default @var{cpu-type} at this ISA level.
+Equivalent to @samp{-march=mips3}.
 
 @item -mips4
 @opindex mips4
-Issue instructions from level 4 of the MIPS ISA (conditional move,
-prefetch, enhanced FPU instructions).  @samp{r8000} is the default
-@var{cpu-type} at this ISA level.
+Equivalent to @samp{-march=mips4}.
 
-@item -mfp32
-@opindex mfp32
-Assume that 32 32-bit floating point registers are available.  This is
-the default.
+@item -mips32
+@opindex mips32
+Equivalent to @samp{-march=mips32}.
 
-@item -mfp64
-@opindex mfp64
-Assume that 32 64-bit floating point registers are available.  This is
-the default when the @option{-mips3} option is used.
+@item -mips64
+@opindex mips64
+Equivalent to @samp{-march=mips64}.
 
 @item -mfused-madd
 @itemx -mno-fused-madd
@@ -7048,15 +7060,21 @@ in the mode where denormals are rounded to zero where denormals
 generated by multiply and accumulate instructions cause exceptions
 anyway.
 
+@item -mfp32
+@opindex mfp32
+Assume that floating point registers are 32 bits wide.
+
+@item -mfp64
+@opindex mfp64
+Assume that floating point registers are 64 bits wide.
+
 @item -mgp32
 @opindex mgp32
-Assume that 32 32-bit general purpose registers are available.  This is
-the default.
+Assume that general purpose registers are 32 bits wide.
 
 @item -mgp64
 @opindex mgp64
-Assume that 32 64-bit general purpose registers are available.  This is
-the default when the @option{-mips3} option is used.
+Assume that general purpose registers are 64 bits wide.
 
 @item -mint64
 @opindex mint64
@@ -7072,31 +7090,32 @@ explanation of the default, and the width of pointers.
 @opindex mlong32
 Force long, int, and pointer types to be 32 bits wide.
 
-If none of @option{-mlong32}, @option{-mlong64}, or @option{-mint64} are set,
-the size of ints, longs, and pointers depends on the ABI and ISA chosen.
-For @option{-mabi=32}, and @option{-mabi=n32}, ints and longs are 32 bits
-wide.  For @option{-mabi=64}, ints are 32 bits, and longs are 64 bits wide.
-For @option{-mabi=eabi} and either @option{-mips1} or @option{-mips2}, ints
-and longs are 32 bits wide.  For @option{-mabi=eabi} and higher ISAs, ints
-are 32 bits, and longs are 64 bits wide.  The width of pointer types is
-the smaller of the width of longs or the width of general purpose
-registers (which in turn depends on the ISA)@.
+The default size of ints, longs and pointers depends on the ABI@.  All
+the supported ABIs use 32-bit ints.  The n64 ABI uses 64-bit longs, as
+does the 64-bit Cygnus EABI; the others use 32-bit longs.  Pointers
+are the same size as longs, or the same size as integer registers,
+whichever is smaller.
 
 @item -mabi=32
 @itemx -mabi=o64
 @itemx -mabi=n32
 @itemx -mabi=64
 @itemx -mabi=eabi
+@itemx -mabi=meabi
 @opindex mabi=32
 @opindex mabi=o64
 @opindex mabi=n32
 @opindex mabi=64
 @opindex mabi=eabi
-Generate code for the indicated ABI@.  The default instruction level is
-@option{-mips1} for @samp{32}, @option{-mips3} for @samp{n32}, and
-@option{-mips4} otherwise.  Conversely, with @option{-mips1} or
-@option{-mips2}, the default ABI is @samp{32}; otherwise, the default ABI
-is @samp{64}.
+@opindex mabi=meabi
+Generate code for the given ABI@.
+
+Note that there are two embedded ABIs: @option{-mabi=eabi}
+selects the one defined by Cygnus while @option{-meabi=meabi}
+selects the one defined by MIPS@.  Both these ABIs have
+32-bit and 64-bit variants.  Normally, GCC will generate
+64-bit code when you select a 64-bit architecture, but you
+can use @option{-mgp32} to get 32-bit code instead.
 
 @item -mmips-as
 @opindex mmips-as
index 531e688028307a4640ec19cd8e715a59354bccd8..991d5e1349b7428b2caf0405082bdabdf429730b 100644 (file)
@@ -1,3 +1,7 @@
+2002-07-25  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gcc.dg/mips-args-[123].c: New tests.
+
 2002-07-24  Aldy Hernandez  <aldyh@redhat.com>
 
        * gcc.dg/ppc-spe.c: New.
diff --git a/gcc/testsuite/gcc.dg/mips-args-1.c b/gcc/testsuite/gcc.dg/mips-args-1.c
new file mode 100644 (file)
index 0000000..d5799fa
--- /dev/null
@@ -0,0 +1,35 @@
+/* Check that certain preprocessor macros are defined, and do some
+   consistency checks.  */
+/* { dg-do compile { target mips*-*-* } } */
+
+const char *compiled_for = _MIPS_ARCH;
+const char *optimized_for = _MIPS_TUNE;
+
+#if __mips_fpr != 32 && __mips_fpr != 64
+#error Bad __mips_fpr
+#endif
+
+/* Test complementary macro pairs: exactly one of each pair
+   must be defined.  */
+
+#if defined (_R3000) == defined (_R4000)
+#error _R3000 / _R4000 mismatch
+#endif
+
+#if defined (__mips_hard_float) == defined (__mips_soft_float)
+#error __mips_hard_float / __mips_soft_float mismatch
+#endif
+
+#if defined (_MIPSEL) == defined (_MIPSEB)
+#error _MIPSEL / _MIPSEB mismatch
+#endif
+
+/* Check for __mips64 consistency.  */
+
+#if defined (__mips64) != defined (_R4000)
+#error __mips64 / _R4000 mismatch
+#endif
+
+#if defined (__mips64) && __mips != 3 && __mips != 4 && __mips != 64
+#error __mips64 / __mips mismatch
+#endif
diff --git a/gcc/testsuite/gcc.dg/mips-args-2.c b/gcc/testsuite/gcc.dg/mips-args-2.c
new file mode 100644 (file)
index 0000000..f53bfb2
--- /dev/null
@@ -0,0 +1,15 @@
+/* Check the _MIPSEB and _MIPSEL macros are accurate.  */
+/* { dg-do run { target mips*-*-* } } */
+short foo = 1;
+int main ()
+{
+  char *p = (char *) &foo;
+
+#ifdef _MIPSEB
+  if (p[0] != 0 || p[1] != 1)
+#else
+  if (p[0] != 1 || p[1] != 0)
+#endif
+    abort ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/mips-args-3.c b/gcc/testsuite/gcc.dg/mips-args-3.c
new file mode 100644 (file)
index 0000000..9ce3553
--- /dev/null
@@ -0,0 +1,35 @@
+/* __mips, and related defines, guarantee that certain assembly
+   instructions can be used.  Check a few examples.  */
+/* { dg-do run { target mips*-*-* } } */
+typedef int int32 __attribute__ ((mode (SI)));
+typedef int int64 __attribute__ ((mode (DI)));
+int foo (float inf, int64 in64, int32 in32)
+{
+  int64 res64;
+  int32 res32;
+
+#if __mips != 1 && defined (__mips_hard_float)
+  __asm__ ("trunc.w.s %0, %1" : "=f" (res32) : "f" (inf));
+  if (res32 != 11)
+    abort ();
+#endif
+
+#if defined (__mips64)
+  __asm__ ("daddu %0, %1, %1" : "=r" (res64) : "r" (in64));
+  if (res64 != 50)
+    abort ();
+#endif
+
+#if (__mips == 4 || __mips == 32 || __mips == 64) && !defined (__mips16)
+  __asm__ ("move %0,%.\n\tmovn %0,%1,%2"
+          : "=&r" (res32) : "r" (in32), "r" (in64 != 0));
+  if (res32 != 60)
+    abort ();
+#endif
+}
+
+int main ()
+{
+  foo (11.4f, 25, 60);
+  exit (0);
+}
index c72d37c8f27faee3ffb1acd5a2cc652b5a5742db..0022fcb289cb67f9a5a50883ff939b98dd9bf481 100644 (file)
@@ -179,6 +179,11 @@ const char *dump_base_name;
 
 extern int target_flags;
 
+/* A mask of target_flags that includes bit X if X was set or cleared
+   on the command line.  */
+
+int target_flags_explicit;
+
 /* Debug hooks - dependent upon command line options.  */
 
 const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
@@ -4411,6 +4416,13 @@ set_target_switch (name)
          target_flags &= ~-target_switches[j].value;
        else
          target_flags |= target_switches[j].value;
+       if (name[0] != 0)
+         {
+           if (target_switches[j].value < 0)
+             target_flags_explicit |= -target_switches[j].value;
+           else
+             target_flags_explicit |= target_switches[j].value;
+         }
        valid_target_option = 1;
       }
 
index 24deaaee8ec3859128fef3b748caaa2d41feda6d..aa7345b477e6adb77acebba535183348c2e8675d 100644 (file)
@@ -108,6 +108,7 @@ extern void check_global_declarations   PARAMS ((union tree_node **, int));
 
 extern const char *progname;
 extern const char *dump_base_name;
+extern int target_flags_explicit;
 
 /* The hashtable, so that the C front ends can pass it to cpplib.  */
 extern struct ht *ident_hash;
This page took 0.264903 seconds and 5 git commands to generate.