OSDN Git Service

* doc/invoke.texi: Document -mabi=meabi, and expand on the EABI
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.h
index a6467c0..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 */
@@ -137,7 +154,7 @@ extern int set_noat;                        /* # of nested .set noat's  */
 extern int set_volatile;               /* # of nested .set volatile's  */
 extern int mips_branch_likely;         /* emit 'l' after br (branch likely) */
 extern int mips_dbx_regno[];           /* Map register # to debug register # */
-extern struct rtx_def *branch_cmp[2];  /* operands for compare */
+extern GTY(()) rtx branch_cmp[2];      /* operands for compare */
 extern enum cmp_type branch_type;      /* what type of branch to use */
 extern enum processor_type mips_arch;   /* which cpu to codegen for */
 extern enum processor_type mips_tune;   /* which cpu to schedule for */
@@ -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 */
@@ -162,31 +177,19 @@ extern int dslots_jump_total;             /* total # jump related delay slots */
 extern int dslots_jump_filled;         /* # filled jump delay slots */
 extern int dslots_number_nops;         /* # of nops needed by previous insn */
 extern int num_refs[3];                        /* # 1/2/3 word references */
-extern struct rtx_def *mips_load_reg;  /* register to check for load delay */
-extern struct rtx_def *mips_load_reg2; /* 2nd reg to check for load delay */
-extern struct rtx_def *mips_load_reg3; /* 3rd reg to check for load delay */
-extern struct rtx_def *mips_load_reg4; /* 4th reg to check for load delay */
+extern GTY(()) rtx mips_load_reg;      /* register to check for load delay */
+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            rdata_section PARAMS ((void));
 extern void            sdata_section PARAMS ((void));
 extern void            sbss_section PARAMS ((void));
 
-/* Stubs for half-pic support if not OSF/1 reference platform.  */
-
-#ifndef HALF_PIC_P
-#define HALF_PIC_P() 0
-#define HALF_PIC_NUMBER_PTRS 0
-#define HALF_PIC_NUMBER_REFS 0
-#define HALF_PIC_ENCODE(DECL)
-#define HALF_PIC_DECLARE(NAME)
-#define HALF_PIC_INIT()        error ("half-pic init called on systems that don't support it")
-#define HALF_PIC_ADDRESS_P(X) 0
-#define HALF_PIC_PTR(X) X
-#define HALF_PIC_FINISH(STREAM)
-#endif
-
 /* Macros to silence warnings about numbers being signed in traditional
    C and unsigned in ISO C when compiled on 32-bit hosts.  */
 
@@ -211,7 +214,7 @@ extern void         sbss_section PARAMS ((void));
 #define MASK_SOFT_FLOAT           0x00000100   /* software floating point */
 #define MASK_FLOAT64      0x00000200   /* fp registers are 64 bits */
 #define MASK_ABICALLS     0x00000400   /* emit .abicalls/.cprestore/.cpload */
-#define MASK_HALF_PIC     0x00000800   /* Emit OSF-style pic refs to externs*/
+#define MASK_UNUSED1      0x00000800   /* Unused Mask.  */
 #define MASK_LONG_CALLS           0x00001000   /* Always call through a register */
 #define MASK_64BIT        0x00002000   /* Use 64 bit GP registers and insns */
 #define MASK_EMBEDDED_PIC  0x00004000  /* Generate embedded PIC code */
@@ -240,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 */
@@ -268,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) */
@@ -286,9 +287,6 @@ extern void         sbss_section PARAMS ((void));
                                        /* .abicalls, etc from Pyramid V.4 */
 #define TARGET_ABICALLS                (target_flags & MASK_ABICALLS)
 
-                                       /* OSF pic references to externs */
-#define TARGET_HALF_PIC                (target_flags & MASK_HALF_PIC)
-
                                        /* software floating point */
 #define TARGET_SOFT_FLOAT      (target_flags & MASK_SOFT_FLOAT)
 #define TARGET_HARD_FLOAT      (! TARGET_SOFT_FLOAT)
@@ -339,6 +337,14 @@ extern void                sbss_section PARAMS ((void));
                                        /* Generate mips16 code */
 #define TARGET_MIPS16          (target_flags & MASK_MIPS16)
 
+/* Generic ISA defines.  */
+#define ISA_MIPS1                  (mips_isa == 1)
+#define ISA_MIPS2                  (mips_isa == 2)
+#define ISA_MIPS3                   (mips_isa == 3)
+#define ISA_MIPS4                  (mips_isa == 4)
+#define ISA_MIPS32                 (mips_isa == 32)
+#define ISA_MIPS64                  (mips_isa == 64)
+
 /* Architecture target defines.  */
 #define TARGET_MIPS3900             (mips_arch == PROCESSOR_R3900)
 #define TARGET_MIPS4000             (mips_arch == PROCESSOR_R4000)
@@ -354,6 +360,145 @@ 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                                                           \
+    {                                                          \
+      builtin_assert ("cpu=mips");                             \
+      builtin_define ("__mips__");                                     \
+      builtin_define ("_mips");                                        \
+                                                               \
+      /* We do this here because __mips is defined below       \
+        and so we can't use builtin_define_std.  */            \
+      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");                          \
+         builtin_define_std ("R4000");                         \
+         builtin_define ("_R4000");                            \
+       }                                                       \
+      else                                                     \
+       {                                                       \
+         builtin_define_std ("R3000");                         \
+         builtin_define ("_R3000");                            \
+       }                                                       \
+      if (TARGET_FLOAT64)                                      \
+         builtin_define ("__mips_fpr=64");                     \
+      else                                                     \
+         builtin_define ("__mips_fpr=32");                     \
+                                                               \
+      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");                          \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS1");         \
+       }                                                       \
+      else if (ISA_MIPS2)                                      \
+       {                                                       \
+         builtin_define ("__mips=2");                          \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS2");         \
+       }                                                       \
+      else if (ISA_MIPS3)                                      \
+       {                                                       \
+         builtin_define ("__mips=3");                          \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS3");         \
+       }                                                       \
+      else if (ISA_MIPS4)                                      \
+       {                                                       \
+         builtin_define ("__mips=4");                          \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS4");         \
+       }                                                       \
+      else if (ISA_MIPS32)                                     \
+       {                                                       \
+         builtin_define ("__mips=32");                         \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32");        \
+       }                                                       \
+      else if (ISA_MIPS64)                                     \
+       {                                                       \
+         builtin_define ("__mips=64");                         \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64");        \
+       }                                                       \
+                                                               \
+      if (TARGET_HARD_FLOAT)                                   \
+         builtin_define ("__mips_hard_float");                 \
+      else if (TARGET_SOFT_FLOAT)                              \
+         builtin_define ("__mips_soft_float");                 \
+                                                               \
+      if (TARGET_SINGLE_FLOAT)                                 \
+         builtin_define ("__mips_single_float");               \
+                                                               \
+      if (TARGET_BIG_ENDIAN)                                   \
+       {                                                       \
+         builtin_define_std ("MIPSEB");                        \
+         builtin_define ("_MIPSEB");                           \
+       }                                                       \
+      else                                                     \
+       {                                                       \
+         builtin_define_std ("MIPSEL");                        \
+         builtin_define ("_MIPSEL");                           \
+       }                                                       \
+                                                               \
+        /* Macros dependent on the C dialect.  */              \
+      if (preprocessing_asm_p ())                              \
+       {                                                       \
+          builtin_define_std ("LANGUAGE_ASSEMBLY");            \
+         builtin_define ("_LANGUAGE_ASSEMBLY");                \
+       }                                                       \
+      else if (c_language == clk_c)                            \
+       {                                                       \
+          builtin_define_std ("LANGUAGE_C");                   \
+         builtin_define ("_LANGUAGE_C");                       \
+       }                                                       \
+      else if (c_language == clk_cplusplus)                    \
+        {                                                      \
+         builtin_define ("_LANGUAGE_C_PLUS_PLUS");             \
+          builtin_define ("__LANGUAGE_C_PLUS_PLUS");           \
+          builtin_define ("__LANGUAGE_C_PLUS_PLUS__");         \
+        }                                                      \
+      else if (c_language == clk_objective_c)                  \
+        {                                                      \
+         builtin_define ("_LANGUAGE_OBJECTIVE_C");             \
+          builtin_define ("__LANGUAGE_OBJECTIVE_C");           \
+         /* Bizzare, but needed at least for Irix.  */         \
+         builtin_define_std ("LANGUAGE_C");                    \
+         builtin_define ("_LANGUAGE_C");                       \
+        }                                                      \
+                                                               \
+      if (mips_abi == ABI_EABI)                                        \
+       builtin_define ("__mips_eabi");                         \
+                                                               \
+} while (0)
+
+
+
 /* Macro to define tables used to set the flags.
    This is a list in braces of pairs in braces,
    each pair being { "NAME", VALUE }
@@ -418,10 +563,6 @@ extern void                sbss_section PARAMS ((void));
      N_("Use Irix PIC")},                                              \
   {"no-abicalls",       -MASK_ABICALLS,                                \
      N_("Don't use Irix PIC")},                                                \
-  {"half-pic",           MASK_HALF_PIC,                                \
-     N_("Use OSF PIC")},                                               \
-  {"no-half-pic",       -MASK_HALF_PIC,                                \
-     N_("Don't use OSF PIC")},                                         \
   {"long-calls",         MASK_LONG_CALLS,                              \
      N_("Use indirect calls")},                                                \
   {"no-long-calls",     -MASK_LONG_CALLS,                              \
@@ -458,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,                   \
@@ -486,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                               \
@@ -507,15 +642,14 @@ extern void               sbss_section PARAMS ((void));
 #endif
 
 #ifndef TARGET_ENDIAN_DEFAULT
-#ifndef DECSTATION
 #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
-#else
-#define TARGET_ENDIAN_DEFAULT 0
-#endif
 #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
@@ -565,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
@@ -584,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,                             \
@@ -607,12 +740,12 @@ extern void               sbss_section PARAMS ((void));
 /* This is meant to be redefined in the host dependent files.  */
 #define SUBTARGET_TARGET_OPTIONS
 
-#define GENERATE_BRANCHLIKELY  (!TARGET_MIPS16 && ISA_HAS_BRANCHLIKELY)
+#define GENERATE_BRANCHLIKELY   (!TARGET_MIPS16 && ISA_HAS_BRANCHLIKELY)
 
 /* Generate three-operand multiply instructions for SImode.  */
 #define GENERATE_MULT3_SI       ((TARGET_MIPS3900                       \
-                                  || mips_isa == 32                     \
-                                  || mips_isa == 64)                    \
+                                  || ISA_MIPS32                                \
+                                  || ISA_MIPS64)                        \
                                  && !TARGET_MIPS16)
 
 /* Generate three-operand multiply instructions for DImode.  */
@@ -623,62 +756,85 @@ extern void               sbss_section PARAMS ((void));
    depending on the instruction set architecture level.  */
 
 #define BRANCH_LIKELY_P()      GENERATE_BRANCHLIKELY
-#define HAVE_SQRT_P()          (mips_isa != 1)
+#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     (mips_isa == 3          \
-                                || mips_isa == 4       \
-                                 || mips_isa == 64)
+#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   (mips_isa != 1                          \
-                                && ! TARGET_MIPS16)
+#define ISA_HAS_BRANCHLIKELY   (!ISA_MIPS1                             \
+                                && !TARGET_MIPS16)
 
 /* ISA has the conditional move instructions introduced in mips4.  */
-#define ISA_HAS_CONDMOVE        ((mips_isa == 4                                \
-                                 || mips_isa == 32                     \
-                                 || mips_isa == 64)                    \
-                                && ! TARGET_MIPS16)
+#define ISA_HAS_CONDMOVE        ((ISA_MIPS4                            \
+                                 || ISA_MIPS32                         \
+                                 || ISA_MIPS64)                        \
+                                && !TARGET_MIPS16)
 
 /* ISA has just the integer condition move instructions (movn,movz) */
 #define ISA_HAS_INT_CONDMOVE     0
 
 /* ISA has the mips4 FP condition code instructions: FP-compare to CC,
    branch on CC, and move (both FP and non-FP) on CC.  */
-#define ISA_HAS_8CC            (mips_isa == 4                          \
-                                || mips_isa == 32                      \
-                                || mips_isa == 64)
+#define ISA_HAS_8CC            (ISA_MIPS4                              \
+                                || ISA_MIPS32                          \
+                                || 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,
+   indexed prefetch instructions, the FP madd and msub instructions,
    and the FP recip and recip sqrt instructions */
-#define ISA_HAS_FP4             (mips_isa == 4                         \
-                                && ! TARGET_MIPS16)
+#define ISA_HAS_FP4             ((ISA_MIPS4                            \
+                                 || ISA_MIPS64)                        \
+                                && !TARGET_MIPS16)
 
 /* ISA has conditional trap instructions.  */
-#define ISA_HAS_COND_TRAP      (mips_isa >= 2                          \
-                                && ! TARGET_MIPS16)
+#define ISA_HAS_COND_TRAP      (!ISA_MIPS1                             \
+                                && !TARGET_MIPS16)
 
-/* ISA has multiply-accumulate instructions, madd and msub.  */
-#define ISA_HAS_MADD_MSUB       ((mips_isa == 32                       \
-                                 || mips_isa == 64                     \
-                                 ) && ! TARGET_MIPS16)
+/* ISA has integer multiply-accumulate instructions, madd and msub.  */
+#define ISA_HAS_MADD_MSUB       ((ISA_MIPS32                           \
+                                 || ISA_MIPS64                         \
+                                 ) && !TARGET_MIPS16)
 
-/* ISA has nmadd and nmsub instructions.  */
-#define ISA_HAS_NMADD_NMSUB    (mips_isa == 4                          \
+/* ISA has floating-point nmadd and nmsub instructions.  */
+#define ISA_HAS_NMADD_NMSUB    ((ISA_MIPS4                             \
+                                 || ISA_MIPS64)                        \
                                 && ! TARGET_MIPS16)
 
 /* ISA has count leading zeroes/ones instruction (not implemented).  */
-#define ISA_HAS_CLZ_CLO         ((mips_isa == 32                       \
-                                  || mips_isa == 64                    \
-                                 ) && ! TARGET_MIPS16)
+#define ISA_HAS_CLZ_CLO         ((ISA_MIPS32                           \
+                                  || ISA_MIPS64                                \
+                                 ) && !TARGET_MIPS16)
 
 /* ISA has double-word count leading zeroes/ones instruction (not
    implemented).  */
-#define ISA_HAS_DCLZ_DCLO       (mips_isa == 64                                \
-                                && ! TARGET_MIPS16)
+#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
@@ -781,49 +937,12 @@ while (0)
 /* Show we can debug even without a frame pointer.  */
 #define CAN_DEBUG_WITHOUT_FP
 \f
-/* Complain about missing specs and predefines that should be defined in each
-   of the target tm files to override the defaults.  This is mostly a place-
-   holder until I can get each of the files updated [mm].  */
-
-#if defined(OSF_OS) \
-    || defined(DECSTATION) \
-    || defined(SGI_TARGET) \
-    || defined(MIPS_NEWS) \
-    || defined(MIPS_SYSV) \
-    || defined(MIPS_SVR4) \
-    || defined(MIPS_BSD43)
-
-#ifndef CPP_PREDEFINES
-       #error "Define CPP_PREDEFINES in the appropriate tm.h file"
-#endif
-
-#ifndef LIB_SPEC
-       #error "Define LIB_SPEC in the appropriate tm.h file"
-#endif
-
-#ifndef STARTFILE_SPEC
-       #error "Define STARTFILE_SPEC in the appropriate tm.h file"
-#endif
-
-#ifndef MACHINE_TYPE
-       #error "Define MACHINE_TYPE in the appropriate tm.h file"
-#endif
-#endif
-
 /* Tell collect what flags to pass to nm.  */
 #ifndef NM_FLAGS
 #define NM_FLAGS "-Bn"
 #endif
 
 \f
-/* Names to predefine in the preprocessor for this target machine.  */
-
-#ifndef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \
--D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43 \
--Asystem=unix -Asystem=bsd -Acpu=mips -Amachine=mips"
-#endif
-
 /* Assembler specs.  */
 
 /* MIPS_AS_ASM_SPEC is passed when using the MIPS assembler rather
@@ -844,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;
@@ -853,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
@@ -902,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 "\
@@ -911,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)"
 
@@ -974,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
@@ -992,140 +1142,20 @@ 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}} \
-%{pic-none:   -mno-half-pic} \
-%{pic-lib:    -mhalf-pic} \
-%{pic-extern: -mhalf-pic} \
-%{pic-calls:  -mhalf-pic} \
 %{save-temps: } \
-%(subtarget_cc1_spec) \
-%(cc1_cpu_spec)"
+%(subtarget_cc1_spec)"
 #endif
 
 /* Preprocessor specs.  */
 
-/* Rules for SIZE_TYPE and PTRDIFF_TYPE are:
-
-   both gp64 and long64 (not the options, but the corresponding flags,
-   so defaults came into play) are required in order to have `long' in
-   SIZE_TYPE and PTRDIFF_TYPE.
-
-   on eabi, -mips1, -mips2 and -mips32 disable gp64, whereas mips3,
-   -mips4, -mips5 and -mips64 enable it.
-
-   on other ABIs, -mips* options do not affect gp32/64, but the
-   default ISA affects the default gp size.
-
-   -mgp32 disables gp64, whereas -mgp64 enables it.
-
-   on eabi, gp64 implies long64.
-
-   -mlong64, and -mabi=64 are the only other ways to enable long64.
-
-*/
-
-#if MIPS_ISA_DEFAULT != 3 && MIPS_ISA_DEFAULT != 4 && MIPS_ISA_DEFAULT != 5 && MIPS_ISA_DEFAULT != 64
-
-/* 32-bit cases first.  */
-
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi|!mabi=*:\
-  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
-    %{mips3|mips4|mips5|mips64|mgp64: \
-      -D__LONG_MAX__=9223372036854775807L}}}}}}}} \
-"
-#else /* ABI_DEFAULT != ABI_EABI */
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi:\
-  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
-    %{mips3|mips4|mips5|mips64|mgp64: \
-      -D__LONG_MAX__=9223372036854775807L}}}}}}}} \
-"
-#endif
-
-#else
-
-/* 64-bit default ISA.  */
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi|!mabi=*:\
-  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
-    -D__LONG_MAX__=9223372036854775807L}}}}}}}\
-"
-#else /* ABI_DEFAULT != ABI_EABI */
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi:\
-  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
-    -D__LONG_MAX__=9223372036854775807L}}}}}}}\
-"
-#endif
-
-#endif
-
 /* SUBTARGET_CPP_SPEC is passed to the preprocessor.  It may be
    overridden by subtargets.  */
 #ifndef SUBTARGET_CPP_SPEC
 #define SUBTARGET_CPP_SPEC ""
 #endif
 
-/* Define appropriate macros for fpr register size.  */
-#ifndef CPP_FPR_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_FLOAT64)
-#define CPP_FPR_SPEC "-D__mips_fpr=64"
-#else
-#define CPP_FPR_SPEC "-D__mips_fpr=32"
-#endif
-#endif
-
-/* For C++ we need to ensure that _LANGUAGE_C_PLUS_PLUS is defined independent
-   of the source file extension.  */
-#undef CPLUSPLUS_CPP_SPEC
-#define CPLUSPLUS_CPP_SPEC "\
--D__LANGUAGE_C_PLUS_PLUS -D_LANGUAGE_C_PLUS_PLUS \
-%(cpp) \
-"
-/* CPP_SPEC is the set of arguments to pass to the preprocessor.  */
-
-#ifndef CPP_SPEC
-#define CPP_SPEC "\
-%{.m:  -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C -D__LANGUAGE_C -D_LANGUAGE_C} \
-%{.S|.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \
-%{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.cpp: %{!.cp: %{!.c++: %{!.C: %{!.m: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}}}}}}}} \
-%(subtarget_cpp_size_spec) \
-%{mips3:-U__mips -D__mips=3 -D__mips64} \
-%{mips4:-U__mips -D__mips=4 -D__mips64} \
-%{mips32:-U__mips -D__mips=32} \
-%{mips64:-U__mips -D__mips=64 -D__mips64} \
-%{mgp32:-U__mips64} %{mgp64:-D__mips64} \
-%{mfp32:-D__mips_fpr=32} %{mfp64:-D__mips_fpr=64} %{!mfp32: %{!mfp64: %{mgp32:-D__mips_fpr=32} %{!mgp32: %(cpp_fpr_spec)}}} \
-%{msingle-float:%{!msoft-float:-D__mips_single_float}} \
-%{m4650:%{!msoft-float:-D__mips_single_float}} \
-%{msoft-float:-D__mips_soft_float} \
-%{mabi=eabi:-D__mips_eabi} \
-%{mips16:%{!mno-mips16:-D__mips16}} \
-%{EB:-UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__ -D_MIPSEB -D__MIPSEB -D__MIPSEB__ %{!ansi:-DMIPSEB}} \
-%{EL:-UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__ -D_MIPSEL -D__MIPSEL -D__MIPSEL__ %{!ansi:-DMIPSEL}} \
-%(long_max_spec) \
-%(subtarget_cpp_spec) "
-#endif
+#define CPP_SPEC "%(subtarget_cpp_spec)"
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
@@ -1139,18 +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 },                                \
-  { "long_max_spec", LONG_MAX_SPEC },                                  \
-  { "cpp_fpr_spec", CPP_FPR_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
 
@@ -1391,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
@@ -1415,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 */
@@ -2235,7 +2262,6 @@ extern enum reg_class mips_char_to_class[256];
 
    `Q' is for mips16 GP relative constants
    `R' is for memory references which take 1 word for the instruction.
-   `S' is for references to extern items which are PIC for OSF/rose.
    `T' is for memory addresses that can be used to load two words.  */
 
 #define EXTRA_CONSTRAINT(OP,CODE)                                      \
@@ -2244,8 +2270,6 @@ extern enum reg_class mips_char_to_class[256];
                             && mips16_gp_offset_p (OP))                \
    : (GET_CODE (OP) != MEM) ? FALSE                                    \
    : ((CODE) == 'R')     ? simple_memory_operand (OP, GET_MODE (OP))   \
-   : ((CODE) == 'S')     ? (HALF_PIC_P () && CONSTANT_P (OP)           \
-                            && HALF_PIC_ADDRESS_P (OP))                \
    : FALSE)
 
 /* Given an rtx X being reloaded into a reg required to be
@@ -2304,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.  */
 
@@ -2364,7 +2395,7 @@ extern enum reg_class mips_char_to_class[256];
        : current_function_outgoing_args_size)
 #endif
 
-/* The return address for the current frame is in r31 is this is a leaf
+/* The return address for the current frame is in r31 if this is a leaf
    function.  Otherwise, it is on the stack.  It is at a variable offset
    from sp/fp/ap, so we define a fake hard register rap which is a
    poiner to the return address on the stack.  This always gets eliminated
@@ -2397,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
@@ -2493,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.
@@ -2682,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
@@ -2791,7 +2757,7 @@ typedef struct mips_args {
      the shift patterns, and function_arg, which returns them when given
      a VOIDmode argument.  */
   unsigned int num_adjusts;
-  struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS];
+  rtx adjust[MAX_ARGS_IN_REGISTERS];
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
@@ -2871,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) \
@@ -3055,53 +3021,7 @@ typedef struct mips_args {
 
 /* A C compound statement with a conditional `goto LABEL;' executed
    if X (an RTX) is a legitimate memory address on the target
-   machine for a memory operand of mode MODE.
-
-   It usually pays to define several simpler macros to serve as
-   subroutines for this one.  Otherwise it may be too complicated
-   to understand.
-
-   This macro must exist in two variants: a strict variant and a
-   non-strict one.  The strict variant is used in the reload pass.
-   It must be defined so that any pseudo-register that has not been
-   allocated a hard register is considered a memory reference.  In
-   contexts where some kind of register is required, a
-   pseudo-register with no hard register must be rejected.
-
-   The non-strict variant is used in other passes.  It must be
-   defined to accept all pseudo-registers in every context where
-   some kind of register is required.
-
-   Compiler source files that want to use the strict variant of
-   this macro define the macro `REG_OK_STRICT'.  You should use an
-   `#ifdef REG_OK_STRICT' conditional to define the strict variant
-   in that case and the non-strict variant otherwise.
-
-   Typically among the subroutines used to define
-   `GO_IF_LEGITIMATE_ADDRESS' are subroutines to check for
-   acceptable registers for various purposes (one for base
-   registers, one for index registers, and so on).  Then only these
-   subroutine macros need have two variants; the higher levels of
-   macros may be the same whether strict or not.
-
-   Normally, constant addresses which are the sum of a `symbol_ref'
-   and an integer are stored inside a `const' RTX to mark them as
-   constant.  Therefore, there is no need to recognize such sums
-   specifically as legitimate addresses.  Normally you would simply
-   recognize any `const' as legitimate.
-
-   Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle
-   constant sums that are not marked with  `const'.  It assumes
-   that a naked `plus' indicates indexing.  If so, then you *must*
-   reject such naked constant sums as illegitimate addresses, so
-   that none of them will be given to `PRINT_OPERAND_ADDRESS'.
-
-   On some machines, whether a symbolic address is legitimate
-   depends on the section that the address refers to.  On these
-   machines, define the macro `ENCODE_SECTION_INFO' to store the
-   information into the `symbol_ref', and then check for it here.
-   When you see a `const', you will have to look inside it to find
-   the `symbol_ref' in order to determine the section.  */
+   machine for a memory operand of mode MODE.  */
 
 #if 1
 #define GO_PRINTF(x)   fprintf(stderr, (x))
@@ -3137,16 +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) == 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)))                                  \
-   && (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X)))
+       && (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.  */
@@ -3237,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);                                \
@@ -3307,143 +3229,6 @@ typedef struct mips_args {
 
 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
 
-
-/* Define this macro if references to a symbol must be treated
-   differently depending on something about the variable or
-   function named by the symbol (such as what section it is in).
-
-   The macro definition, if any, is executed immediately after the
-   rtl for DECL has been created and stored in `DECL_RTL (DECL)'.
-   The value of the rtl will be a `mem' whose address is a
-   `symbol_ref'.
-
-   The usual thing for this macro to do is to a flag in the
-   `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
-   name string in the `symbol_ref' (if one bit is not enough
-   information).
-
-   The best way to modify the name string is by adding text to the
-   beginning, with suitable punctuation to prevent any ambiguity.
-   Allocate the new name in `saveable_obstack'.  You will have to
-   modify `ASM_OUTPUT_LABELREF' to remove and decode the added text
-   and output the name accordingly.
-
-   You can also check the information stored in the `symbol_ref' in
-   the definition of `GO_IF_LEGITIMATE_ADDRESS' or
-   `PRINT_OPERAND_ADDRESS'.
-
-   When optimizing for the $gp pointer, SYMBOL_REF_FLAG is set for all
-   small objects.
-
-   When generating embedded PIC code, SYMBOL_REF_FLAG is set for
-   symbols which are not in the .text section.
-
-   When generating mips16 code, SYMBOL_REF_FLAG is set for string
-   constants which are put in the .text section.  We also record the
-   total length of all such strings; this total is used to decide
-   whether we need to split the constant table, and need not be
-   precisely correct.
-
-   When not mips16 code nor embedded PIC, if a symbol is in a
-   gp addresable section, SYMBOL_REF_FLAG is set prevent gcc from
-   splitting the reference so that gas can generate a gp relative
-   reference.
-
-   When TARGET_EMBEDDED_DATA is set, we assume that all const
-   variables will be stored in ROM, which is too far from %gp to use
-   %gprel addressing.  Note that (1) we include "extern const"
-   variables in this, which mips_select_section doesn't, and (2) we
-   can't always tell if they're really const (they might be const C++
-   objects with non-const constructors), so we err on the side of
-   caution and won't use %gprel anyway (otherwise we'd have to defer
-   this decision to the linker/loader).  The handling of extern consts
-   is why the DECL_INITIAL macros differ from mips_select_section.
-
-   If you are changing this macro, you should look at
-   mips_select_section and see if it needs a similar change.  */
-
-#define ENCODE_SECTION_INFO(DECL, FIRST)                               \
-do                                                                     \
-  {                                                                    \
-    if (TARGET_MIPS16)                                                 \
-      {                                                                        \
-       if ((FIRST) && TREE_CODE (DECL) == STRING_CST                   \
-           && ! flag_writable_strings                                  \
-           /* If this string is from a function, and the function will \
-              go in a gnu linkonce section, then we can't directly     \
-              access the string.  This gets an assembler error         \
-              "unsupported PC relative reference to different section".\
-              If we modify SELECT_SECTION to put it in function_section\
-              instead of text_section, it still fails because          \
-              DECL_SECTION_NAME isn't set until assemble_start_function.\
-              If we fix that, it still fails because strings are shared\
-              among multiple functions, and we have cross section      \
-              references again.  We force it to work by putting string \
-              addresses in the constant pool and indirecting.  */      \
-           && (! current_function_decl                                 \
-               || ! DECL_ONE_ONLY (current_function_decl)))            \
-         {                                                             \
-           SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (DECL), 0)) = 1;        \
-           mips_string_length += TREE_STRING_LENGTH (DECL);            \
-         }                                                             \
-      }                                                                        \
-                                                                       \
-    if (TARGET_EMBEDDED_DATA                                           \
-       && (TREE_CODE (DECL) == VAR_DECL                                \
-           && TREE_READONLY (DECL) && !TREE_SIDE_EFFECTS (DECL))       \
-           && (!DECL_INITIAL (DECL)                                    \
-               || TREE_CONSTANT (DECL_INITIAL (DECL))))                \
-      {                                                                        \
-       SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 0;                \
-      }                                                                        \
-                                                                       \
-    else if (TARGET_EMBEDDED_PIC)                                      \
-      {                                                                        \
-        if (TREE_CODE (DECL) == VAR_DECL)                              \
-         SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;              \
-        else if (TREE_CODE (DECL) == FUNCTION_DECL)                    \
-         SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 0;              \
-       else if (TREE_CODE (DECL) == STRING_CST                         \
-                && ! flag_writable_strings)                            \
-         SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (DECL), 0)) = 0;          \
-        else                                                           \
-         SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (DECL), 0)) = 1;          \
-      }                                                                        \
-                                                                       \
-    else if (TREE_CODE (DECL) == VAR_DECL                              \
-             && DECL_SECTION_NAME (DECL) != NULL_TREE                   \
-             && (0 == strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (DECL)), \
-                              ".sdata")                                 \
-                || 0 == strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (DECL)),\
-                              ".sbss")))                                \
-      {                                                                        \
-        SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;               \
-      }                                                                        \
-                                                                       \
-    /* We can not perform GP optimizations on variables which are in   \
-       specific sections, except for .sdata and .sbss which are                \
-       handled above.  */                                              \
-    else if (TARGET_GP_OPT && TREE_CODE (DECL) == VAR_DECL             \
-            && DECL_SECTION_NAME (DECL) == NULL_TREE                   \
-            && ! (TARGET_MIPS16 && TREE_PUBLIC (DECL)                  \
-                  && (DECL_COMMON (DECL)                               \
-                      || DECL_ONE_ONLY (DECL)                          \
-                      || DECL_WEAK (DECL))))                           \
-      {                                                                        \
-       int size = int_size_in_bytes (TREE_TYPE (DECL));                \
-                                                                       \
-       if (size > 0 && size <= mips_section_threshold)                 \
-         SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;              \
-      }                                                                        \
-                                                                       \
-    else if (HALF_PIC_P ())                                            \
-      {                                                                        \
-       if (FIRST)                                                      \
-          HALF_PIC_ENCODE (DECL);                                      \
-      }                                                                        \
-  }                                                                    \
-while (0)
-
 /* This handles the magic '..CURRENT_FUNCTION' symbol, which means
    'the start of the function that this code is output in'.  */
 
@@ -3538,13 +3323,6 @@ while (0)
 
 #define FUNCTION_MODE (Pmode == DImode ? DImode : SImode)
 
-/* Define TARGET_MEM_FUNCTIONS if we want to use calls to memcpy and
-   memset, instead of the BSD functions bcopy and bzero.  */
-
-#if defined(MIPS_SYSV) || defined(OSF_OS)
-#define TARGET_MEM_FUNCTIONS
-#endif
-
 \f
 /* A part of a C `switch' statement that describes the relative
    costs of constant RTL expressions.  It must contain `case'
@@ -3753,11 +3531,11 @@ while (0)
       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);                                   \
@@ -3765,23 +3543,23 @@ while (0)
                                                                        \
       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);                                      \
@@ -3793,10 +3571,10 @@ while (0)
       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);                                  \
@@ -3804,10 +3582,10 @@ while (0)
                                                                        \
       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);                                  \
@@ -3817,12 +3595,12 @@ while (0)
                                                                        \
   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);                                       \
@@ -3991,7 +3769,6 @@ while (0)
   {"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 }},          \
@@ -4345,7 +4122,7 @@ while (0)
   ALL_COP_ADDITIONAL_REGISTER_NAMES                                    \
 }
 
-/* This is meant to be redefined in the host dependent files.  It is a 
+/* This is meant to be redefined in the host dependent files.  It is a
    set of alternative names and regnums for mips coprocessors.  */
 
 #define ALL_COP_ADDITIONAL_REGISTER_NAMES
@@ -4384,12 +4161,7 @@ while (0)
 
 /* A C compound statement to output to stdio stream STREAM the
    assembler syntax for an instruction operand that is a memory
-   reference whose address is ADDR.  ADDR is an RTL expression.
-
-   On some machines, the syntax for a symbolic address depends on
-   the section that the address refers to.  On these machines,
-   define the macro `ENCODE_SECTION_INFO' to store the information
-   into the `symbol_ref', and then check for it here.  */
+   reference whose address is ADDR.  ADDR is an RTL expression.  */
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
 
@@ -4471,8 +4243,7 @@ while (0)
        LM[0-9]+        Silicon Graphics/ECOFF stabs label before each stmt.
        $Lb[0-9]+       Begin blocks for MIPS debug support
        $Lc[0-9]+       Label for use in s<xx> operation.
-       $Le[0-9]+       End blocks for MIPS debug support
-       $Lp\..+         Half-pic labels.  */
+       $Le[0-9]+       End blocks for MIPS debug support  */
 
 /* This is how to output the definition of a user-level label named NAME,
    such as the label on a static function or variable NAME.
@@ -4505,7 +4276,6 @@ do {                                                                      \
 do                                                                     \
  {                                                                     \
    mips_declare_object (STREAM, NAME, "", ":\n", 0);                   \
-   HALF_PIC_DECLARE (NAME);                                            \
  }                                                                     \
 while (0)
 
@@ -4534,7 +4304,7 @@ while (0)
        if (TREE_PUBLIC (DECL) && DECL_NAME (DECL))                     \
          ASM_GLOBALIZE_LABEL (STREAM, NAME);                           \
                                                                        \
-       READONLY_DATA_SECTION ();                                       \
+       readonly_data_section ();                                       \
        ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));  \
        mips_declare_object (STREAM, NAME, "", ":\n\t.space\t%u\n",     \
            (SIZE));                                                    \
@@ -4581,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)    \
-  HALF_PIC_DECLARE (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.  */
@@ -4667,16 +4438,13 @@ 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)                                 \
 {                                                                      \
   const char *p = STRING;                                              \
   int size = strlen (p) + 1;                                           \
-  rdata_section ();                                                    \
+  readonly_data_section ();                                            \
   assemble_string (p, size);                                           \
 }
 \f
@@ -4689,15 +4457,15 @@ do {                                                                    \
 #define TEXT_SECTION_ASM_OP    "\t.text"       /* instructions */
 #define DATA_SECTION_ASM_OP    "\t.data"       /* large data */
 #define SDATA_SECTION_ASM_OP   "\t.sdata"      /* small data */
-#define RDATA_SECTION_ASM_OP   "\t.rdata"      /* read-only data */
-#undef READONLY_DATA_SECTION
-#define READONLY_DATA_SECTION  rdata_section
+#ifndef READONLY_DATA_SECTION_ASM_OP
+#define READONLY_DATA_SECTION_ASM_OP   "\t.rdata"      /* read-only data */
+#endif
 #define SMALL_DATA_SECTION     sdata_section
 
 /* What other sections we support other than the normal .data/.text.  */
 
 #undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_sdata, in_rdata
+#define EXTRA_SECTIONS in_sdata
 
 /* Define the additional functions to select our additional sections.  */
 
@@ -4719,29 +4487,13 @@ sdata_section ()                                                        \
       fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP);            \
       in_section = in_sdata;                                           \
     }                                                                  \
-}                                                                      \
-                                                                       \
-void                                                                   \
-rdata_section ()                                                       \
-{                                                                      \
-  if (in_section != in_rdata)                                          \
-    {                                                                  \
-      fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP);            \
-      in_section = in_rdata;                                           \
-    }                                                                  \
 }
 
 /* Given a decl node or constant node, choose the section to output it in
    and select that section.  */
 
-#undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
-  mips_select_rtx_section (MODE, RTX)
-
-#undef SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC, ALIGN) \
-  mips_select_section (DECL, RELOC)
-
+#undef  TARGET_ASM_SELECT_SECTION
+#define TARGET_ASM_SELECT_SECTION  mips_select_section
 \f
 /* Store in OUTPUT a string (made with alloca) containing
    an assembler-name for a local static variable named NAME.
@@ -4897,3 +4649,10 @@ do                                                                       \
       }                                                                        \
   }                                                                    \
 while (0)
+
+#define DFMODE_NAN \
+       unsigned short DFbignan[4] = {0x7ff7, 0xffff, 0xffff, 0xffff}; \
+       unsigned short DFlittlenan[4] = {0xffff, 0xffff, 0xffff, 0xfff7}
+#define SFMODE_NAN \
+       unsigned short SFbignan[2] = {0x7fbf, 0xffff}; \
+       unsigned short SFlittlenan[2] = {0xffff, 0xffbf}