OSDN Git Service

* doc/invoke.texi: Document -mabi=meabi, and expand on the EABI
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.h
index 7778361..84b6880 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));
@@ -225,7 +243,6 @@ extern void         sbss_section PARAMS ((void));
 #define MASK_DEBUG_E   0               /* function_arg debug */
 #define MASK_DEBUG_F   0               /* ??? */
 #define MASK_DEBUG_G   0               /* don't support 64 bit arithmetic */
-#define MASK_DEBUG_H   0               /* allow ints in FP registers */
 #define MASK_DEBUG_I   0               /* unused */
 
                                        /* Dummy switches used only in specs */
@@ -253,7 +270,6 @@ extern void         sbss_section PARAMS ((void));
 #define TARGET_DEBUG_E_MODE    (target_flags & MASK_DEBUG_E)
 #define TARGET_DEBUG_F_MODE    (target_flags & MASK_DEBUG_F)
 #define TARGET_DEBUG_G_MODE    (target_flags & MASK_DEBUG_G)
-#define TARGET_DEBUG_H_MODE    (target_flags & MASK_DEBUG_H)
 #define TARGET_DEBUG_I_MODE    (target_flags & MASK_DEBUG_I)
 
                                        /* Reg. Naming in .s ($21 vs. $a0) */
@@ -344,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                                                           \
@@ -357,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");                            \
        }                                                       \
@@ -378,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");                          \
@@ -561,10 +599,6 @@ extern void                sbss_section PARAMS ((void));
      N_("Work around early 4300 hardware bug")},                       \
   {"no-fix4300",         -MASK_4300_MUL_FIX,                           \
      N_("Don't work around early 4300 hardware bug")},                 \
-  {"3900",               0,                                            \
-     N_("Optimize for 3900")},                                         \
-  {"4650",               0,                                            \
-     N_("Optimize for 4650")},                                         \
   {"check-zero-division",-MASK_NO_CHECK_ZERO_DIV,                      \
      N_("Trap on integer divide by zero")},                            \
   {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV,                   \
@@ -589,8 +623,6 @@ extern void         sbss_section PARAMS ((void));
      NULL},                                                            \
   {"debugg",             MASK_DEBUG_G,                                 \
      NULL},                                                            \
-  {"debugh",             MASK_DEBUG_H,                                 \
-     NULL},                                                            \
   {"debugi",             MASK_DEBUG_I,                                 \
      NULL},                                                            \
   {"",                   (TARGET_DEFAULT                               \
@@ -613,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
@@ -664,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
@@ -683,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,                                   \
+  { "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,                             \
@@ -724,15 +758,25 @@ 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           \
+#define ISA_HAS_64BIT_REGS     (ISA_MIPS3                              \
+                                || ISA_MIPS4                           \
                                  || ISA_MIPS64)
 
 /* ISA has branch likely instructions (eg. mips2).  */
 /* Disable branchlikely for tx39 until compare rewrite.  They haven't
    been generated up to this point.  */
-#define ISA_HAS_BRANCHLIKELY   (!ISA_MIPS1                          \
+#define ISA_HAS_BRANCHLIKELY   (!ISA_MIPS1                             \
                                 && !TARGET_MIPS16)
 
 /* ISA has the conditional move instructions introduced in mips4.  */
@@ -751,8 +795,8 @@ extern void         sbss_section PARAMS ((void));
                                 || ISA_MIPS64)
 
 /* This is a catch all for the other new mips4 instructions: indexed load and
-   indexed prefetch instructions, the FP madd,msub,nmadd, and nmsub
-   instructions, and the FP recip and recip sqrt instructions */
+   indexed prefetch instructions, the FP madd and msub instructions,
+   and the FP recip and recip sqrt instructions */
 #define ISA_HAS_FP4             ((ISA_MIPS4                            \
                                  || ISA_MIPS64)                        \
                                 && !TARGET_MIPS16)
@@ -781,6 +825,17 @@ extern void                sbss_section PARAMS ((void));
 #define ISA_HAS_DCLZ_DCLO       (ISA_MIPS64                            \
                                 && !TARGET_MIPS16)
 
+/* ISA has data prefetch instruction.  */
+#define ISA_HAS_PREFETCH       ((ISA_MIPS4                             \
+                                 || ISA_MIPS32                         \
+                                 || ISA_MIPS64)                        \
+                                && !TARGET_MIPS16)
+
+/* True if trunc.w.s and trunc.w.d are real (not synthetic)
+   instructions.  Both require TARGET_HARD_FLOAT, and trunc.w.d
+   also requires TARGET_DOUBLE_FLOAT.  */
+#define ISA_HAS_TRUNC_W                (!ISA_MIPS1)
+
 /* CC1_SPEC causes -mips3 and -mips4 to set -mfp64 and -mgp64; -mips1 or
    -mips2 sets -mfp32 and -mgp32.  This can be overridden by an explicit
    -mfp32, -mfp64, -mgp32 or -mgp64.  -mfp64 sets MASK_FLOAT64 in
@@ -908,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;
@@ -917,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
@@ -966,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 "\
@@ -975,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)"
 
@@ -1038,16 +1134,6 @@ extern int mips_abi;
 #define SUBTARGET_CC1_SPEC ""
 #endif
 
-/* Deal with historic options.  */
-#ifndef CC1_CPU_SPEC
-#define CC1_CPU_SPEC "\
-%{!mcpu*: \
-%{m3900:-march=r3900 -mips1 -mfp32 -mgp32 \
-%n`-m3900' is deprecated. Use `-march=r3900' instead.\n} \
-%{m4650:-march=r4650 -mmad -msingle-float \
-%n`-m4650' is deprecated. Use `-march=r4650' instead.\n}}"
-#endif
-
 /* CC1_SPEC is the set of arguments to pass to the compiler proper.  */
 /* Note, we will need to adjust the following if we ever find a MIPS variant
    that has 32-bit GPRs and 64-bit FPRs as well as fix all of the reload bugs
@@ -1056,19 +1142,9 @@ 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:%{!m4650:-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) \
-%(cc1_cpu_spec)"
+%(subtarget_cc1_spec)"
 #endif
 
 /* Preprocessor specs.  */
@@ -1093,16 +1169,15 @@ extern int mips_abi;
 
 #define EXTRA_SPECS                                                    \
   { "subtarget_cc1_spec", SUBTARGET_CC1_SPEC },                                \
-  { "cc1_cpu_spec", CC1_CPU_SPEC},                                      \
   { "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
 
@@ -1343,21 +1418,21 @@ do {                                                    \
 
 #define PUT_SDB_FUNCTION_START(LINE)
 
-#define PUT_SDB_FUNCTION_END(LINE)            \
-do {                                                  \
-  extern FILE *asm_out_text_file;             \
+#define PUT_SDB_FUNCTION_END(LINE)                     \
+do {                                                   \
+  extern FILE *asm_out_text_file;                      \
   ASM_OUTPUT_SOURCE_LINE (asm_out_text_file, LINE + sdb_begin_function_line); \
 } while (0)
 
 #define PUT_SDB_EPILOGUE_END(NAME)
 
-#define PUT_SDB_SRC_FILE(FILENAME) \
+#define PUT_SDB_SRC_FILE(FILENAME)                     \
 do {                                                   \
   extern FILE *asm_out_text_file;                      \
-  output_file_directive (asm_out_text_file, (FILENAME)); \
+  output_file_directive (asm_out_text_file, (FILENAME));\
 } while (0)
 
-#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
+#define SDB_GENERATE_FAKE(BUFFER, NUMBER)              \
   sprintf ((BUFFER), ".%dfake", (NUMBER));
 
 /* Correct the offset of automatic variables and arguments.  Note that
@@ -1367,9 +1442,9 @@ do {                                                      \
    the frame pointer to be the stack pointer after the initial
    adjustment.  */
 
-#define DEBUGGER_AUTO_OFFSET(X)  \
+#define DEBUGGER_AUTO_OFFSET(X)                                \
   mips_debugger_offset (X, (HOST_WIDE_INT) 0)
-#define DEBUGGER_ARG_OFFSET(OFFSET, X)  \
+#define DEBUGGER_ARG_OFFSET(OFFSET, X)                 \
   mips_debugger_offset (X, (HOST_WIDE_INT) OFFSET)
 
 /* Tell collect that the object format is ECOFF */
@@ -2253,17 +2328,24 @@ extern enum reg_class mips_char_to_class[256];
 
 /* If defined, gives a class of registers that cannot be used as the
    operand of a SUBREG that changes the mode of the object illegally.
-   When FP regs are larger than integer regs... Er, anyone remember what
-   goes wrong?
 
    In little-endian mode, the hi-lo registers are numbered backwards,
    so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
-   word as intended.  */
+   word as intended.
+
+   Similarly, when using paired floating-point registers, the first
+   register holds the low word, regardless of endianness.  So in big
+   endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word
+   as intended.
+
+   Also, loading a 32-bit value into a 64-bit floating-point register
+   will not sign-extend the value, despite what LOAD_EXTEND_OP says.
+   We can't allow 64-bit float registers to change from a 32-bit
+   mode to a 64-bit mode.  */
 
 #define CLASS_CANNOT_CHANGE_MODE                                       \
-  (TARGET_BIG_ENDIAN                                                   \
-   ? (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS)            \
-   : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI_REG))
+  (TARGET_BIG_ENDIAN ? FP_REGS                                         \
+   : (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
 
 /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
 
@@ -2346,31 +2428,6 @@ extern enum reg_class mips_char_to_class[256];
 
 #define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta
 
-/* Structure to be filled in by compute_frame_size with register
-   save masks, and offsets for the current function.  */
-
-struct mips_frame_info
-{
-  long total_size;             /* # bytes that the entire frame takes up */
-  long var_size;               /* # bytes that variables take up */
-  long args_size;              /* # bytes that outgoing arguments take up */
-  long extra_size;             /* # bytes of extra gunk */
-  int  gp_reg_size;            /* # bytes needed to store gp regs */
-  int  fp_reg_size;            /* # bytes needed to store fp regs */
-  long mask;                   /* mask of saved gp registers */
-  long fmask;                  /* mask of saved fp registers */
-  long gp_save_offset;         /* offset from vfp to store gp registers */
-  long fp_save_offset;         /* offset from vfp to store fp registers */
-  long gp_sp_offset;           /* offset from new sp to store gp registers */
-  long fp_sp_offset;           /* offset from new sp to store fp registers */
-  int  initialized;            /* != 0 if frame size already calculated */
-  int  num_gp;                 /* number of gp registers saved */
-  int  num_fp;                 /* number of fp registers saved */
-  long insns_len;              /* length of insns; mips16 only */
-};
-
-extern struct mips_frame_info current_frame_info;
-
 /* If defined, this macro specifies a table of register pairs used to
    eliminate unneeded registers that point into the stack frame.  If
    it is not defined, the only elimination attempted by the compiler
@@ -2442,47 +2499,8 @@ extern struct mips_frame_info current_frame_info;
              && (! TARGET_MIPS16                                       \
                  || compute_frame_size (get_frame_size ()) < 32768)))))
 
-/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'.  It
-   specifies the initial difference between the specified pair of
-   registers.  This macro must be defined if `ELIMINABLE_REGS' is
-   defined.  */
-
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                    \
-{  compute_frame_size (get_frame_size ());                              \
-  if (TARGET_MIPS16 && (FROM) == FRAME_POINTER_REGNUM                   \
-      && (TO) == HARD_FRAME_POINTER_REGNUM)                             \
-    (OFFSET) = - current_function_outgoing_args_size;                   \
-  else if ((FROM) == FRAME_POINTER_REGNUM)                              \
-    (OFFSET) = 0;                                                       \
-  else if (TARGET_MIPS16 && (FROM) == ARG_POINTER_REGNUM                \
-          && (TO) == HARD_FRAME_POINTER_REGNUM)                         \
-    (OFFSET) = (current_frame_info.total_size                           \
-               - current_function_outgoing_args_size                    \
-               - ((mips_abi != ABI_32                                   \
-                   && mips_abi != ABI_O64                               \
-                   && mips_abi != ABI_EABI)                             \
-                  ? current_function_pretend_args_size                  \
-                  : 0));                                                \
-  else if ((FROM) == ARG_POINTER_REGNUM)                                \
-    (OFFSET) = (current_frame_info.total_size                           \
-               - ((mips_abi != ABI_32                                   \
-                   && mips_abi != ABI_O64                               \
-                   && mips_abi != ABI_EABI)                             \
-                  ? current_function_pretend_args_size                  \
-                  : 0));                                                \
-  /* Some ABIs store 64 bits to the stack, but Pmode is 32 bits,        \
-     so we must add 4 bytes to the offset to get the right value.  */   \
-  else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM)                     \
-  {                                                                     \
-    (OFFSET) = current_frame_info.gp_sp_offset                          \
-      + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))              \
-        * (BYTES_BIG_ENDIAN != 0));                                     \
-    if (TARGET_MIPS16 && (TO) != STACK_POINTER_REGNUM)                  \
-      (OFFSET) -= current_function_outgoing_args_size;                  \
-  }                                                                     \
-  else                                                                  \
-    abort();                                                            \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+       (OFFSET) = mips_initial_elimination_offset ((FROM), (TO))
 
 /* If we generate an insn to push BYTES bytes,
    this says how many the stack pointer really advances by.
@@ -2631,11 +2649,10 @@ extern struct mips_frame_info current_frame_info;
 /* For o64 we should be checking the mode for SFmode as well.  */
 
 #define FUNCTION_ARG_REGNO_P(N)                                        \
-  ((((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST)                        \
-    || ((N) >= FP_ARG_FIRST && (N) <= FP_ARG_LAST              \
-       && (((N) % FP_INC) == 0                                 \
-           && (! mips_abi == ABI_O64)))                        \
-   && !fixed_regs[N]))
+  ((IN_RANGE((N), GP_ARG_FIRST, GP_ARG_LAST)                   \
+    || (IN_RANGE((N), FP_ARG_FIRST, FP_ARG_LAST)               \
+       && ((N) % FP_INC == 0) && mips_abi != ABI_O64))         \
+   && !fixed_regs[N])
 
 /* A C expression which can inhibit the returning of certain function
    values in registers, based on the type of value.  A nonzero value says
@@ -2820,8 +2837,8 @@ typedef struct mips_args {
   (VALIST) = mips_build_va_list ()
 
 /* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
-  mips_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+  mips_va_start (valist, nextarg)
 
 /* Implement `va_arg'.  */
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
@@ -3040,15 +3057,18 @@ typedef struct mips_args {
    assembler would use $at as a temp to load in the large offset.  In this
    case $at is already in use.  We convert such problem addresses to
    `la $5,s;sw $4,70000($5)' via LEGITIMIZE_ADDRESS.  */
-/* ??? SGI Irix 6 assembler fails for CONST address, so reject them.  */
+/* ??? SGI Irix 6 assembler fails for CONST address, so reject them
+   when !TARGET_GAS.  */
+/* We should be rejecting everything but const addresses.  */
 #define CONSTANT_ADDRESS_P(X)                                          \
   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
     || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH               \
     || (GET_CODE (X) == CONST                                          \
        && ! (flag_pic && pic_address_needs_scratch (X))                \
-       && (mips_abi == ABI_32                                          \
-           || mips_abi == ABI_O64                                      \
-           || mips_abi == ABI_EABI)))
+       && (TARGET_GAS)                                                 \
+       && (mips_abi != ABI_N32                                         \
+           && mips_abi != ABI_64)))
+
 
 /* Define this, so that when PIC, reload won't try to reload invalid
    addresses which require two reload registers.  */
@@ -3139,9 +3159,9 @@ typedef struct mips_args {
   if (GET_CODE (xinsn) == CONST                                                \
       && ((flag_pic && pic_address_needs_scratch (xinsn))              \
          /* ??? SGI's Irix 6 assembler can't handle CONST.  */         \
-         || (mips_abi != ABI_32                                        \
-             && mips_abi != ABI_O64                                    \
-             && mips_abi != ABI_EABI)))                                \
+         || (!TARGET_GAS                                               \
+             && (mips_abi == ABI_N32                                   \
+                 || mips_abi == ABI_64))))                             \
     {                                                                  \
       rtx ptr_reg = gen_reg_rtx (Pmode);                               \
       rtx constant = XEXP (XEXP (xinsn, 0), 1);                                \
@@ -3511,11 +3531,11 @@ typedef struct mips_args {
       enum machine_mode xmode = GET_MODE (X);                          \
       if (xmode == SFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-             || TUNE_MIPS3900                          \
-             || TUNE_MIPS5000)                         \
+         if (TUNE_MIPS3000                                             \
+             || TUNE_MIPS3900                                          \
+             || TUNE_MIPS5000)                                         \
            return COSTS_N_INSNS (4);                                   \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (5);                                   \
          else                                                          \
            return COSTS_N_INSNS (7);                                   \
@@ -3523,23 +3543,23 @@ typedef struct mips_args {
                                                                        \
       if (xmode == DFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-             || TUNE_MIPS3900                          \
-             || TUNE_MIPS5000)                         \
+         if (TUNE_MIPS3000                                             \
+             || TUNE_MIPS3900                                          \
+             || TUNE_MIPS5000)                                         \
            return COSTS_N_INSNS (5);                                   \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (6);                                   \
          else                                                          \
            return COSTS_N_INSNS (8);                                   \
        }                                                               \
                                                                        \
-      if (TUNE_MIPS3000)                                       \
+      if (TUNE_MIPS3000)                                               \
        return COSTS_N_INSNS (12);                                      \
-      else if (TUNE_MIPS3900)                          \
+      else if (TUNE_MIPS3900)                                          \
        return COSTS_N_INSNS (2);                                       \
-      else if (TUNE_MIPS6000)                          \
+      else if (TUNE_MIPS6000)                                          \
        return COSTS_N_INSNS (17);                                      \
-      else if (TUNE_MIPS5000)                          \
+      else if (TUNE_MIPS5000)                                          \
        return COSTS_N_INSNS (5);                                       \
       else                                                             \
        return COSTS_N_INSNS (10);                                      \
@@ -3551,10 +3571,10 @@ typedef struct mips_args {
       enum machine_mode xmode = GET_MODE (X);                          \
       if (xmode == SFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-              || TUNE_MIPS3900)                                \
+         if (TUNE_MIPS3000                                             \
+              || TUNE_MIPS3900)                                                \
            return COSTS_N_INSNS (12);                                  \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (15);                                  \
          else                                                          \
            return COSTS_N_INSNS (23);                                  \
@@ -3562,10 +3582,10 @@ typedef struct mips_args {
                                                                        \
       if (xmode == DFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-              || TUNE_MIPS3900)                                \
+         if (TUNE_MIPS3000                                             \
+              || TUNE_MIPS3900)                                                \
            return COSTS_N_INSNS (19);                                  \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (16);                                  \
          else                                                          \
            return COSTS_N_INSNS (36);                                  \
@@ -3575,12 +3595,12 @@ typedef struct mips_args {
                                                                        \
   case UDIV:                                                           \
   case UMOD:                                                           \
-    if (TUNE_MIPS3000                                  \
-        || TUNE_MIPS3900)                                      \
+    if (TUNE_MIPS3000                                                  \
+        || TUNE_MIPS3900)                                              \
       return COSTS_N_INSNS (35);                                       \
-    else if (TUNE_MIPS6000)                            \
+    else if (TUNE_MIPS6000)                                            \
       return COSTS_N_INSNS (38);                                       \
-    else if (TUNE_MIPS5000)                            \
+    else if (TUNE_MIPS5000)                                            \
       return COSTS_N_INSNS (36);                                       \
     else                                                               \
       return COSTS_N_INSNS (69);                                       \
@@ -3749,7 +3769,6 @@ typedef struct mips_args {
   {"se_nonmemory_operand",     { CONST_INT, CONST_DOUBLE, CONST,       \
                                  SYMBOL_REF, LABEL_REF, SUBREG,        \
                                  REG, SIGN_EXTEND }},                  \
-  {"se_nonimmediate_operand",   { SUBREG, REG, MEM, SIGN_EXTEND }},    \
   {"consttable_operand",       { LABEL_REF, SYMBOL_REF, CONST_INT,     \
                                  CONST_DOUBLE, CONST }},               \
   {"extend_operator",           { SIGN_EXTEND, ZERO_EXTEND }},          \
@@ -4332,11 +4351,12 @@ do {                                                    \
 /* This is how to declare a function name.  The actual work of
    emitting the label is moved to function_prologue, so that we can
    get the line number correctly emitted before the .ent directive,
-   and after any .file directives.  */
-/*
+   and after any .file directives.  Define as empty so that the function
+   is not declared before the .ent directive elsewhere.  */
+
 #undef ASM_DECLARE_FUNCTION_NAME
 #define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL)
-*/
+
 
 /* This is how to output an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.  */
@@ -4418,9 +4438,6 @@ do {                                                                      \
 #define ASM_OUTPUT_ASCII(STREAM, STRING, LEN)                          \
   mips_output_ascii (STREAM, STRING, LEN)
 
-/* Handle certain cpp directives used in header files on sysV.  */
-#define SCCS_DIRECTIVE
-
 /* Output #ident as a in the read-only data section.  */
 #undef  ASM_OUTPUT_IDENT
 #define ASM_OUTPUT_IDENT(FILE, STRING)                                 \