OSDN Git Service

* config/mips/mips.h (ISA_HAS_COND_TRAP): Not available on MIPS16.
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.h
index b917a78..644592d 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler.  MIPS version.
    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by A. Lichnewsky (lich@inria.inria.fr).
    Changed by Michael Meissner (meissner@osf.org).
    64 bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
@@ -67,7 +67,10 @@ enum processor_type {
   PROCESSOR_R4600,
   PROCESSOR_R4650,
   PROCESSOR_R5000,
-  PROCESSOR_R8000
+  PROCESSOR_R8000,
+  PROCESSOR_R4KC,
+  PROCESSOR_R5KC,
+  PROCESSOR_R20KC
 };
 
 /* Recast the cpu class to be the cpu attribute.  */
@@ -77,21 +80,24 @@ enum processor_type {
    value at preprocessing time.
 
    ABI_32 (original 32, or o32), ABI_N32 (n32), ABI_64 (n64) are all
-   defined by SGI.  ABI_O64 is o32 extended to work on a 64 bit machine. */
+   defined by SGI.  ABI_O64 is o32 extended to work on a 64 bit machine.  */
 
 #define ABI_32  0
 #define ABI_N32 1
 #define ABI_64  2
 #define ABI_EABI 3
 #define ABI_O64  4
-
-#ifndef MIPS_ABI_DEFAULT
-/* We define this away so that there is no extra runtime cost if the target
-   doesn't support multiple ABIs.  */
-#define mips_abi ABI_32
-#else
-extern int mips_abi;
-#endif
+/* MEABI is gcc's internal name for MIPS' new EABI (defined by MIPS)
+   which is not the same as the above EABI (defined by Cygnus,
+   Greenhills, and Toshiba?).  MEABI is not yet complete or published,
+   but at this point it looks like N32 as far as calling conventions go,
+   but allows for either 32 or 64 bit registers.
+
+   Currently MIPS is calling their EABI "the" MIPS EABI, and Cygnus'
+   EABI the legacy EABI.  In the end we may end up calling both ABI's
+   EABI but give them different version numbers, but for now I'm going
+   with different names.  */
+#define ABI_MEABI 5
 
 /* Whether to emit abicalls code sequences or not.  */
 
@@ -112,8 +118,8 @@ enum block_move_type {
   BLOCK_MOVE_LAST                      /* generate just the last store */
 };
 
-extern char mips_reg_names[][8];       /* register names (a0 vs. $4). */
-extern char mips_print_operand_punct[];        /* print_operand punctuation chars */
+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 */
 extern int num_source_filenames;       /* current .file # */
 extern int inside_function;            /* != 0 if inside of a function */
@@ -148,6 +154,7 @@ 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 */
 extern int dslots_load_filled;         /* # filled load delay slots */
@@ -159,9 +166,7 @@ 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 struct rtx_def *embedded_pic_fnaddr_rtx;        /* function address */
 extern int mips_string_length;         /* length of strings for mips16 */
-extern struct rtx_def *mips16_gp_pseudo_rtx; /* psuedo reg holding $gp */
 
 /* Functions to change what output section we are using.  */
 extern void            rdata_section PARAMS ((void));
@@ -176,7 +181,7 @@ extern void         sbss_section PARAMS ((void));
 #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_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)
@@ -223,12 +228,14 @@ extern void               sbss_section PARAMS ((void));
 #define MASK_UNINIT_CONST_IN_RODATA \
                           0x00800000   /* Store uninitialized
                                           consts in rodata */
+#define MASK_NO_FUSED_MADD 0x01000000   /* Don't generate floating point
+                                          multiply-add operations.  */
 
                                        /* Debug switches, not documented */
 #define MASK_DEBUG     0               /* unused */
 #define MASK_DEBUG_A   0               /* don't allow <label>($reg) addrs */
 #define MASK_DEBUG_B   0               /* GO_IF_LEGITIMATE_ADDRESS debug */
-#define MASK_DEBUG_C   0               /* don't expand seq, etc. */
+#define MASK_DEBUG_C   0               /* don't expand seq, etc.  */
 #define MASK_DEBUG_D   0               /* don't do define_split's */
 #define MASK_DEBUG_E   0               /* function_arg debug */
 #define MASK_DEBUG_F   0               /* ??? */
@@ -300,7 +307,7 @@ extern void         sbss_section PARAMS ((void));
 
                                        /* always store uninitialized const
                                           variables in rodata, requires
-                                          TARGET_EMBEDDED_DATA. */
+                                          TARGET_EMBEDDED_DATA.  */
 #define TARGET_UNINIT_CONST_IN_RODATA  (target_flags & MASK_UNINIT_CONST_IN_RODATA)
 
                                        /* generate big endian code.  */
@@ -311,6 +318,8 @@ extern void         sbss_section PARAMS ((void));
 
 #define TARGET_MAD             (target_flags & MASK_MAD)
 
+#define TARGET_FUSED_MADD      (! (target_flags & MASK_NO_FUSED_MADD))
+
 #define TARGET_4300_MUL_FIX     (target_flags & MASK_4300_MUL_FIX)
 
 #define TARGET_NO_CHECK_ZERO_DIV (target_flags & MASK_NO_CHECK_ZERO_DIV)
@@ -319,7 +328,8 @@ extern void         sbss_section PARAMS ((void));
 /* This is true if we must enable the assembly language file switching
    code.  */
 
-#define TARGET_FILE_SWITCHING  (TARGET_GP_OPT && ! TARGET_GAS)
+#define TARGET_FILE_SWITCHING \
+  (TARGET_GP_OPT && ! TARGET_GAS && ! TARGET_MIPS16)
 
 /* We must disable the function end stabs when doing the file switching trick,
    because the Lscope stabs end up in the wrong place, making it impossible
@@ -334,6 +344,8 @@ extern void         sbss_section PARAMS ((void));
 #define TARGET_MIPS4000             (mips_arch == PROCESSOR_R4000)
 #define TARGET_MIPS4100             (mips_arch == PROCESSOR_R4100)
 #define TARGET_MIPS4300             (mips_arch == PROCESSOR_R4300)
+#define TARGET_MIPS4KC              (mips_arch == PROCESSOR_R4KC)
+#define TARGET_MIPS5KC              (mips_arch == PROCESSOR_R5KC)
 
 /* Scheduling target defines.  */
 #define TUNE_MIPS3000               (mips_tune == PROCESSOR_R3000)
@@ -438,6 +450,10 @@ extern void                sbss_section PARAMS ((void));
      N_("Use multiply accumulate")},                                   \
   {"no-mad",            -MASK_MAD,                                     \
      N_("Don't use multiply accumulate")},                             \
+  {"no-fused-madd",       MASK_NO_FUSED_MADD,                           \
+     N_("Don't generate fused multiply/add instructions")},            \
+  {"fused-madd",         -MASK_NO_FUSED_MADD,                           \
+     N_("Generate fused multiply/add instructions")},                  \
   {"fix4300",             MASK_4300_MUL_FIX,                           \
      N_("Work around early 4300 hardware bug")},                       \
   {"no-fix4300",         -MASK_4300_MUL_FIX,                           \
@@ -533,8 +549,16 @@ extern void                sbss_section PARAMS ((void));
 #        if MIPS_ISA_DEFAULT == 4
 #          define MULTILIB_ISA_DEFAULT "mips4"
 #        else
+#          if MIPS_ISA_DEFAULT == 32
+#            define MULTILIB_ISA_DEFAULT "mips32"
+#          else
+#            if MIPS_ISA_DEFAULT == 64
+#              define MULTILIB_ISA_DEFAULT "mips64"
+#            else
 #          define MULTILIB_ISA_DEFAULT "mips1"
+#         endif
 #        endif
+#       endif
 #      endif
 #    endif
 #  endif
@@ -551,29 +575,12 @@ extern void               sbss_section PARAMS ((void));
 
 #ifndef ENDIAN_SPEC
 #if TARGET_ENDIAN_DEFAULT == 0
-#define ENDIAN_SPEC "%{!EB:%{!meb:-EL}} %{EL} %{EB}"
+#define ENDIAN_SPEC "%{!EB:%{!meb:-EL}} %{EB|meb:-EB}"
 #else
-#define ENDIAN_SPEC "%{!EL:%{!mel:-EB}} %{EB} %{EL}"
+#define ENDIAN_SPEC "%{!EL:%{!mel:-EB}} %{EL|mel:-EL}"
 #endif
 #endif
 
-/* This macro is similar to `TARGET_SWITCHES' but defines names of
-   command options that have values.  Its definition is an
-   initializer with a subgrouping for each command option.
-
-   Each subgrouping contains a string constant, that defines the
-   fixed part of the option name, and the address of a variable.
-   The variable, type `char *', is set to the variable part of the
-   given option if the fixed part matches.  The actual option name
-   is made by appending `-m' to the specified name.
-
-   Here is an example which defines `-mshort-data-NUMBER'.  If the
-   given option is `-mshort-data-512', the variable `m88k_short_data'
-   will be set to the string `"512"'.
-
-       extern char *m88k_short_data;
-       #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
-
 #define TARGET_OPTIONS                                                 \
 {                                                                      \
   SUBTARGET_TARGET_OPTIONS                                             \
@@ -591,6 +598,10 @@ extern void                sbss_section PARAMS ((void));
       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,                             \
+      N_("Specify cache flush function")},                             \
 }
 
 /* This is meant to be redefined in the host dependent files.  */
@@ -598,9 +609,15 @@ extern void                sbss_section PARAMS ((void));
 
 #define GENERATE_BRANCHLIKELY  (!TARGET_MIPS16 && ISA_HAS_BRANCHLIKELY)
 
-/* Generate three-operand multiply instructions for both SImode and DImode.  */
-#define GENERATE_MULT3         (TARGET_MIPS3900                                \
-                               && !TARGET_MIPS16)
+/* Generate three-operand multiply instructions for SImode.  */
+#define GENERATE_MULT3_SI       ((TARGET_MIPS3900                       \
+                                  || mips_isa == 32                     \
+                                  || mips_isa == 64)                    \
+                                 && !TARGET_MIPS16)
+
+/* Generate three-operand multiply instructions for DImode.  */
+#define GENERATE_MULT3_DI       ((TARGET_MIPS3900)                      \
+                                && !TARGET_MIPS16)
 
 /* Macros to decide whether certain features are available or not,
    depending on the instruction set architecture level.  */
@@ -608,19 +625,21 @@ extern void               sbss_section PARAMS ((void));
 #define BRANCH_LIKELY_P()      GENERATE_BRANCHLIKELY
 #define HAVE_SQRT_P()          (mips_isa != 1)
 
-/* ISA has instructions for managing 64 bit fp and gp regs (eg. mips3). */
-#define ISA_HAS_64BIT_REGS     (mips_isa == 3 || mips_isa == 4         \
-                                )
+/* 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)
 
-/* ISA has branch likely instructions (eg. mips2). */
+/* 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_MIPS3900 */)
 
-/* ISA has the conditional move instructions introduced in mips4. */
+/* ISA has the conditional move instructions introduced in mips4.  */
 #define ISA_HAS_CONDMOVE        (mips_isa == 4                         \
-                                )
+                                || mips_isa == 32                      \
+                                || mips_isa == 64)
 
 /* ISA has just the integer condition move instructions (movn,movz) */
 #define ISA_HAS_INT_CONDMOVE     0
@@ -628,9 +647,10 @@ extern void                sbss_section PARAMS ((void));
 
 
 /* ISA has the mips4 FP condition code instructions: FP-compare to CC,
-   branch on CC, and move (both FP and non-FP) on 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)
 
 
 /* This is a catch all for the other new mips4 instructions: indexed load and
@@ -640,12 +660,27 @@ extern void               sbss_section PARAMS ((void));
                                )
 
 /* ISA has conditional trap instructions.  */
-#define ISA_HAS_COND_TRAP      (mips_isa >= 2)
+#define ISA_HAS_COND_TRAP      (mips_isa >= 2 && ! TARGET_MIPS16)
+
+/* ISA has multiply-accumulate instructions, madd and msub.  */
+#define ISA_HAS_MADD_MSUB       (mips_isa == 32                         \
+                                || mips_isa == 64                       \
+                                )
 
 /* ISA has nmadd and nmsub instructions.  */
 #define ISA_HAS_NMADD_NMSUB    (mips_isa == 4                          \
                                )
 
+/* ISA has count leading zeroes/ones instruction (not implemented).  */
+#define ISA_HAS_CLZ_CLO         (mips_isa == 32                         \
+                                || mips_isa == 64                       \
+                                )
+
+/* ISA has double-word count leading zeroes/ones instruction (not
+   implemented).  */
+#define ISA_HAS_DCLZ_DCLO       (mips_isa == 64)
+
+
 /* 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
@@ -661,10 +696,7 @@ extern void                sbss_section PARAMS ((void));
 \f
 /* Switch  Recognition by gcc.c.  Add -G xx support */
 
-#ifdef SWITCH_TAKES_ARG
-#undef SWITCH_TAKES_ARG
-#endif
-
+#undef  SWITCH_TAKES_ARG
 #define SWITCH_TAKES_ARG(CHAR)                                         \
   (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
 
@@ -800,7 +832,7 @@ while (0)
 
 #define MIPS_AS_ASM_SPEC "\
 %{!.s:-nocpp} %{.s: %{cpp} %{nocpp}} \
-%{pipe: %e-pipe is not supported.} \
+%{pipe: %e-pipe is not supported} \
 %{K} %(subtarget_mips_as_asm_spec)"
 
 /* SUBTARGET_MIPS_AS_ASM_SPEC is passed when using the MIPS assembler
@@ -813,7 +845,18 @@ 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}"
+#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
+
+
+extern int mips_abi;
+
+#ifndef MIPS_ABI_DEFAULT
+#define MIPS_ABI_DEFAULT ABI_32
+#endif
+
+#ifndef ABI_GAS_ASM_SPEC
+#define ABI_GAS_ASM_SPEC ""
+#endif
 
 /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
    GAS_ASM_SPEC as the default, depending upon the value of
@@ -864,12 +907,11 @@ while (0)
 
 #undef ASM_SPEC
 #define ASM_SPEC "\
-%{!membedded-pic:%{G*}} %(endian_spec) %{mips1} %{mips2} %{mips3} %{mips4} \
+%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips64}\
 %{mips16:%{!mno-mips16:-mips16}} %{mno-mips16:-no-mips16} \
 %(subtarget_asm_optimizing_spec) \
 %(subtarget_asm_debugging_spec) \
 %{membedded-pic} \
-%{mfix7000} \
 %{mabi=32:-32}%{mabi=o32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
 %(target_asm_spec) \
 %(subtarget_asm_spec)"
@@ -907,7 +949,7 @@ while (0)
 
 /* Redefinition of libraries used.  Mips doesn't support normal
    UNIX style profiling via calling _mcount.  It does offer
-   profiling that samples the PC, so do what we can... */
+   profiling that samples the PC, so do what we can...  */
 
 #ifndef LIB_SPEC
 #define LIB_SPEC "%{pg:-lprof1} %{p:-lprof1} -lc"
@@ -920,9 +962,10 @@ while (0)
 #ifndef LINK_SPEC
 #define LINK_SPEC "\
 %(endian_spec) \
-%{G*} %{mips1} %{mips2} %{mips3} %{mips4} \
+%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips64} \
 %{bestGnum} %{shared} %{non_shared}"
-#endif /* LINK_SPEC defined */
+#endif  /* LINK_SPEC defined */
+
 
 /* Specs for the compiler proper */
 
@@ -943,6 +986,9 @@ while (0)
 #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
+   that show up in this case.  */
 
 #ifndef CC1_SPEC
 #define CC1_SPEC "\
@@ -950,9 +996,12 @@ while (0)
 %{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} \
@@ -969,9 +1018,199 @@ while (0)
    be overridden by subtargets.  */
 
 #ifndef SUBTARGET_CPP_SIZE_SPEC
+
+/* 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 SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi|!mabi=*:\
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    %{mips3|mips4|mips5|mips64|mgp64: \
+      -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+    %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+      -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#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
+
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    %{mips3|mips4|mips5|mips64|mgp64: \
+      -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+    %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+      -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64|!mabi=*:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    %{mips3|mips4|mips5|mips64|mgp64: \
+      -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+    %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+      -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_MEABI
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    %{mips3|mips4|mips5|mips64|mgp64: \
+      -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+    %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+      -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#else
+
+/* 64-bit default ISA.  */
+#if MIPS_ABI_DEFAULT == ABI_EABI
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi|!mabi=*: \
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#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
+
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi: \
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64|!mabi=*:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_MEABI
 #define SUBTARGET_CPP_SIZE_SPEC "\
-%{mlong64:%{!mips1:%{!mips2:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
-%{!mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}"
+%{mabi=eabi:\
+  %{mips1|mips2|mips32|mgp32|mlong32: \
+    -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+  %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+    -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#endif
+
 #endif
 
 /* SUBTARGET_CPP_SPEC is passed to the preprocessor.  It may be
@@ -980,13 +1219,12 @@ while (0)
 #define SUBTARGET_CPP_SPEC ""
 #endif
 
-/* If we're using 64bit longs, then we have to define __LONG_MAX__
-   correctly.  Similarly for 64bit ints and __INT_MAX__.  */
-#ifndef LONG_MAX_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_LONG64)
-#define LONG_MAX_SPEC "%{!mlong32:-D__LONG_MAX__=9223372036854775807L}"
+/* 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 LONG_MAX_SPEC "%{mlong64:-D__LONG_MAX__=9223372036854775807L}"
+#define CPP_FPR_SPEC "-D__mips_fpr=32"
 #endif
 #endif
 
@@ -1007,7 +1245,10 @@ while (0)
 %(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} \
@@ -1035,8 +1276,10 @@ while (0)
   { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC },                                \
   { "subtarget_cpp_size_spec", SUBTARGET_CPP_SIZE_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 },  \
@@ -1101,14 +1344,14 @@ while (0)
 
 /* Local compiler-generated symbols must have a prefix that the assembler
    understands.   By default, this is $, although some targets (e.g.,
-   NetBSD-ELF) need to override this. */
+   NetBSD-ELF) need to override this.  */
 
 #ifndef LOCAL_LABEL_PREFIX
 #define LOCAL_LABEL_PREFIX     "$"
 #endif
 
 /* By default on the mips, external symbols do not have an underscore
-   prepended, but some targets (e.g., NetBSD) require this. */
+   prepended, but some targets (e.g., NetBSD) require this.  */
 
 #ifndef USER_LABEL_PREFIX
 #define USER_LABEL_PREFIX      ""
@@ -1125,7 +1368,7 @@ while (0)
 #undef DBX_CONTIN_LENGTH
 #define DBX_CONTIN_LENGTH 1500
 
-/* How to renumber registers for dbx and gdb. */
+/* How to renumber registers for dbx and gdb.  */
 #define DBX_REGISTER_NUMBER(REGNO) mips_dbx_regno[ (REGNO) ]
 
 /* The mapping from gcc register number to DWARF 2 CFA column number.
@@ -1142,7 +1385,7 @@ while (0)
 #define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)
 
 /* Describe how we implement __builtin_eh_return.  */
-#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
+#define EH_RETURN_DATA_REGNO(N) ((N) < (TARGET_MIPS16 ? 2 : 4) ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
 #define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
 
 /* Offsets recorded in opcodes are a multiple of this alignment factor.
@@ -1160,7 +1403,9 @@ do {                                                      \
 #define PUT_SDB_INT_VAL(a)                             \
 do {                                                   \
   extern FILE *asm_out_text_file;                      \
-  fprintf (asm_out_text_file, "\t.val\t%d;", (a));     \
+  fprintf (asm_out_text_file, "\t.val\t");             \
+  fprintf (asm_out_text_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a)); \
+  fprintf (asm_out_text_file, ";");                    \
 } while (0)
 
 #define PUT_SDB_VAL(a)                                 \
@@ -1202,7 +1447,9 @@ do {                                                      \
 #define PUT_SDB_SIZE(a)                                        \
 do {                                                   \
   extern FILE *asm_out_text_file;                      \
-  fprintf (asm_out_text_file, "\t.size\t%d;", (a));    \
+  fprintf (asm_out_text_file, "\t.size\t");            \
+  fprintf (asm_out_text_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a)); \
+  fprintf (asm_out_text_file, ";");                    \
 } while (0)
 
 #define PUT_SDB_DIM(a)                                 \
@@ -1312,35 +1559,18 @@ do {                                                    \
 #define OBJECT_FORMAT_COFF     /* Object file looks like COFF */
 #define EXTENDED_COFF          /* ECOFF, not normal coff */
 #endif
-
-#if 0 /* These definitions normally have no effect because
-        MIPS systems define USE_COLLECT2, so
-        assemble_constructor does nothing anyway.  */
-
-/* Don't use the default definitions, because we don't have gld.
-   Also, we don't want stabs when generating ECOFF output.
-   Instead we depend on collect to handle these.  */
-
-#define ASM_OUTPUT_CONSTRUCTOR(file, name)
-#define ASM_OUTPUT_DESTRUCTOR(file, name)
-
-#endif /* 0 */
 \f
 /* Target machine storage layout */
 
-/* Define in order to support both big and little endian float formats
-   in the same gcc binary.  */
-#define REAL_ARITHMETIC
-
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.
 */
 #define BITS_BIG_ENDIAN 0
 
-/* Define this if most significant byte of a word is the lowest numbered. */
+/* Define this if most significant byte of a word is the lowest numbered.  */
 #define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
 
-/* Define this if most significant word of a multiword number is the lowest. */
+/* Define this if most significant word of a multiword number is the lowest.  */
 #define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
 
 /* Define this to set the endianness to use in libgcc2.c, which can
@@ -1351,14 +1581,6 @@ do {                                                     \
 #define LIBGCC2_WORDS_BIG_ENDIAN 0
 #endif
 
-/* Number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
-   Note that this is not necessarily the width of data type `int';
-   if using 16-bit ints on a 68000, this would still be 32.
-   But on a machine with 16-bit registers, this would be 16.  */
-#define BITS_PER_WORD (TARGET_64BIT ? 64 : 32)
 #define MAX_BITS_PER_WORD 64
 
 /* Width of a word, in units (bytes).  */
@@ -1368,16 +1590,22 @@ do {                                                    \
 /* For MIPS, width of a floating point register.  */
 #define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
 
+/* If register $f0 holds a floating-point value, $f(0 + FP_INC) is
+   the next available register.  */
+#define FP_INC (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT ? 1 : 2)
+
+/* The largest size of value that can be held in floating-point registers.  */
+#define UNITS_PER_FPVALUE (FP_INC * UNITS_PER_FPREG)
+
 /* A C expression for the size in bits of the type `int' on the
    target machine.  If you don't define this, the default is one
    word.  */
 #define INT_TYPE_SIZE (TARGET_INT64 ? 64 : 32)
-#define MAX_INT_TYPE_SIZE 64
 
 /* Tell the preprocessor the maximum size of wchar_t.  */
 #ifndef MAX_WCHAR_TYPE_SIZE
 #ifndef WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE MAX_INT_TYPE_SIZE
+#define MAX_WCHAR_TYPE_SIZE 64
 #endif
 #endif
 
@@ -1398,12 +1626,6 @@ do {                                                     \
    words.  */
 #define LONG_LONG_TYPE_SIZE 64
 
-/* A C expression for the size in bits of the type `char' on the
-   target machine.  If you don't define this, the default is one
-   quarter of a word.  (If this would be less than one storage unit,
-   it is rounded up to one unit.)  */
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-
 /* A C expression for the size in bits of the type `float' on the
    target machine.  If you don't define this, the default is one
    word.  */
@@ -1429,7 +1651,9 @@ do {                                                      \
 #define POINTER_BOUNDARY (Pmode == DImode ? 64 : 32)
 
 /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
-#define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
+#define PARM_BOUNDARY ((mips_abi == ABI_O64 || mips_abi == ABI_N32 \
+                       || mips_abi == ABI_64 \
+                       || (mips_abi == ABI_EABI && TARGET_64BIT)) ? 64 : 32)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
 #define FUNCTION_BOUNDARY 32
@@ -1508,12 +1732,14 @@ do {                                                    \
 
 /* Force right-alignment for small varargs in 32 bit little_endian mode */
 
-#define PAD_VARARGS_DOWN (TARGET_64BIT ? BYTES_BIG_ENDIAN : !BYTES_BIG_ENDIAN)
+#define PAD_VARARGS_DOWN (TARGET_64BIT                                  \
+                         || mips_abi == ABI_MEABI                      \
+                            ? BYTES_BIG_ENDIAN : !BYTES_BIG_ENDIAN)
 
 /* Define this macro if an argument declared as `char' or `short' in a
    prototype should actually be passed as an `int'.  In addition to
    avoiding errors in certain cases of mismatch, it also makes for
-   better code on certain machines. */
+   better code on certain machines.  */
 
 #define PROMOTE_PROTOTYPES 1
 
@@ -1608,6 +1834,25 @@ do {                                                     \
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1                                   \
 }
 
+/* Like `CALL_USED_REGISTERS' but used to overcome a historical
+   problem which makes CALL_USED_REGISTERS *always* include
+   all the FIXED_REGISTERS.  Until this problem has been
+   resolved this macro can be used to overcome this situation.
+   In particular, block_propagate() requires this list
+   be acurate, or we can remove registers which should be live.
+   This macro is used in regs_invalidated_by_call.  */
+
+
+#define CALL_REALLY_USED_REGISTERS                                      \
+{ /* General registers.  */                                             \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                       \
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1,                       \
+  /* Floating-point registers.  */                                      \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                      \
+  1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                      \
+  /* Others.  */                                                        \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1                                   \
+}
 
 /* Internal macros to classify a register number as to whether it's a
    general purpose register, a floating point register, a
@@ -1663,10 +1908,7 @@ do {                                                     \
    the R4000 with the FR bit set, the floating point uses register
    pairs, with the second register not being allocable.  */
 
-#define HARD_REGNO_NREGS(REGNO, MODE)                                  \
-  (! FP_REG_P (REGNO)                                                  \
-       ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) \
-       : ((GET_MODE_SIZE (MODE) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG))
+#define HARD_REGNO_NREGS(REGNO, MODE) mips_hard_regno_nregs (REGNO, MODE)
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode
    MODE.  In 32 bit mode, require that DImode and DFmode be in even
@@ -1773,15 +2015,6 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
 #define PIC_OFFSET_TABLE_REGNUM (GP_REG_FIRST + 28)
 
 #define PIC_FUNCTION_ADDR_REGNUM (GP_REG_FIRST + 25)
-
-/* Initialize embedded_pic_fnaddr_rtx before RTL generation for
-   each function.  We used to do this in FINALIZE_PIC, but FINALIZE_PIC
-   isn't always called for static inline functions.  */
-#define INIT_EXPANDERS                 \
-do {                                   \
-  embedded_pic_fnaddr_rtx = NULL;      \
-  mips16_gp_pseudo_rtx = NULL;         \
-} while (0)
 \f
 /* Define the classes of registers for register constraints in the
    machine description.  Also define ranges of constants.
@@ -1819,6 +2052,7 @@ enum reg_class
   HI_AND_GR_REGS,              /* union classes */
   LO_AND_GR_REGS,
   HILO_AND_GR_REGS,
+  HI_AND_FP_REGS,
   ST_REGS,                     /* status registers (fp status) */
   ALL_REGS,                    /* all registers */
   LIM_REG_CLASSES              /* max value + 1 */
@@ -1848,6 +2082,7 @@ enum reg_class
   "HI_AND_GR_REGS",                                                    \
   "LO_AND_GR_REGS",                                                    \
   "HILO_AND_GR_REGS",                                                  \
+  "HI_AND_FP_REGS",                                                    \
   "ST_REGS",                                                           \
   "ALL_REGS"                                                           \
 }
@@ -1879,6 +2114,7 @@ enum reg_class
   { 0xffffffff, 0x00000000, 0x00000001 },      /* union classes */     \
   { 0xffffffff, 0x00000000, 0x00000002 },                              \
   { 0xffffffff, 0x00000000, 0x00000004 },                              \
+  { 0x00000000, 0xffffffff, 0x00000001 },                              \
   { 0x00000000, 0x00000000, 0x000007f8 },      /* status registers */  \
   { 0xffffffff, 0xffffffff, 0x000007ff }       /* all registers */     \
 }
@@ -1889,7 +2125,7 @@ enum reg_class
    choose a class which is "minimal", meaning that no smaller class
    also contains the register.  */
 
-extern enum reg_class mips_regno_to_class[];
+extern const enum reg_class mips_regno_to_class[];
 
 #define REGNO_REG_CLASS(REGNO) mips_regno_to_class[ (REGNO) ]
 
@@ -1910,7 +2146,7 @@ extern enum reg_class mips_regno_to_class[];
 /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
-   registers. */
+   registers.  */
 
 #define SMALL_REGISTER_CLASSES (TARGET_MIPS16)
 
@@ -1959,7 +2195,7 @@ extern enum reg_class mips_regno_to_class[];
    'z' FP Status register
    'b' All registers */
 
-extern enum reg_class mips_char_to_class[];
+extern enum reg_class mips_char_to_class[256];
 
 #define REG_CLASS_FROM_LETTER(C) mips_char_to_class[(unsigned char)(C)]
 
@@ -2106,10 +2342,18 @@ extern enum reg_class mips_char_to_class[];
    : CLASS_UNITS (MODE, UNITS_PER_WORD))
 
 /* 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.  */
+   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.  */
 
-#define CLASS_CANNOT_CHANGE_MODE \
-  (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS)
+#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))
 
 /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
 
@@ -2312,6 +2556,8 @@ extern struct mips_frame_info current_frame_info;
               + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))      \
                  * (BYTES_BIG_ENDIAN != 0));                            \
   }                                                                     \
+  else                                                                  \
+    abort();                                                            \
 }
 
 /* If we generate an insn to push BYTES bytes,
@@ -2494,11 +2740,8 @@ extern struct mips_frame_info current_frame_info;
    to give us MIPS cc compatibility.  */
 
 #define RETURN_IN_MEMORY(TYPE) \
-  (TYPE_MODE (TYPE) == BLKmode)
+       mips_return_in_memory (TYPE)
 \f
-/* A code distinguishing the floating point format of the target
-   machine.  There are three defined values: IEEE_FLOAT_FORMAT,
-   VAX_FLOAT_FORMAT, and UNKNOWN_FLOAT_FORMAT.  */
 
 #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
 
@@ -2533,6 +2776,7 @@ typedef struct mips_args {
                                /* ??? The size is doubled to work around a
                                   bug in the code that sets the adjustments
                                   in function_arg.  */
+  int prototype;                /* True if the function has a prototype.  */
   struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS*2];
 } CUMULATIVE_ARGS;
 
@@ -2570,7 +2814,7 @@ typedef struct mips_args {
 
 /* For an arg passed partly in registers and partly in memory,
    this is the number of registers used.
-   For args passed entirely in registers or entirely in memory, zero. */
+   For args passed entirely in registers or entirely in memory, zero.  */
 
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
   function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
@@ -2621,18 +2865,16 @@ typedef struct mips_args {
 {                                                                      \
   if (TARGET_MIPS16)                                                   \
     sorry ("mips16 function profiling");                               \
-  fprintf (FILE, "\t.set\tnoreorder\n");                               \
   fprintf (FILE, "\t.set\tnoat\n");                                    \
   fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n",   \
           reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]);  \
-  fprintf (FILE, "\tjal\t_mcount\n");                                  \
   fprintf (FILE,                                                       \
           "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from  stack\n",    \
           TARGET_64BIT ? "dsubu" : "subu",                             \
           reg_names[STACK_POINTER_REGNUM],                             \
           reg_names[STACK_POINTER_REGNUM],                             \
           Pmode == DImode ? 16 : 8);                                   \
-  fprintf (FILE, "\t.set\treorder\n");                                 \
+  fprintf (FILE, "\tjal\t_mcount\n");                                   \
   fprintf (FILE, "\t.set\tat\n");                                      \
 }
 
@@ -2724,10 +2966,11 @@ typedef struct mips_args {
   /* Flush both caches.  We need to flush the data cache in case           \
      the system has a write-back cache.  */                                \
   /* ??? Should check the return value for errors.  */                     \
-  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, CACHE_FLUSH_FUNC),         \
-                    0, VOIDmode, 3, addr, Pmode,                           \
-                    GEN_INT (TRAMPOLINE_SIZE), TYPE_MODE (integer_type_node),\
-                    GEN_INT (3), TYPE_MODE (integer_type_node));           \
+  if (mips_cache_flush_func && mips_cache_flush_func[0])                   \
+    emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func),   \
+                      0, VOIDmode, 3, addr, Pmode,                         \
+                      GEN_INT (TRAMPOLINE_SIZE), TYPE_MODE (integer_type_node),\
+                      GEN_INT (3), TYPE_MODE (integer_type_node));         \
 }
 \f
 /* Addressing modes, and classification of registers for them.  */
@@ -2754,7 +2997,7 @@ typedef struct mips_args {
    : GP_REG_P (regno))
 
 #define GP_REG_OR_PSEUDO_STRICT_P(regno, mode)                             \
-  BASE_REG_P((regno < FIRST_PSEUDO_REGISTER) ? regno : reg_renumber[regno], \
+  BASE_REG_P((regno < FIRST_PSEUDO_REGISTER) ? (int) regno : reg_renumber[regno], \
             (mode))
 
 #define GP_REG_OR_PSEUDO_NONSTRICT_P(regno, mode) \
@@ -3099,12 +3342,12 @@ typedef struct mips_args {
    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)                                      \
+#define ENCODE_SECTION_INFO(DECL, FIRST)                               \
 do                                                                     \
   {                                                                    \
     if (TARGET_MIPS16)                                                 \
       {                                                                        \
-       if (TREE_CODE (DECL) == STRING_CST                              \
+       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     \
@@ -3171,7 +3414,8 @@ do                                                                        \
                                                                        \
     else if (HALF_PIC_P ())                                            \
       {                                                                        \
-        HALF_PIC_ENCODE (DECL);                                                \
+       if (FIRST)                                                      \
+          HALF_PIC_ENCODE (DECL);                                      \
       }                                                                        \
   }                                                                    \
 while (0)
@@ -3211,15 +3455,9 @@ while (0)
 /* Define as C expression which evaluates to nonzero if the tablejump
    instruction expects the table to contain offsets from the address of the
    table.
-   Do not define this if the table should contain absolute addresses. */
+   Do not define this if the table should contain absolute addresses.  */
 #define CASE_VECTOR_PC_RELATIVE (TARGET_MIPS16)
 
-/* Specify the tree operation to be used to convert reals to integers.  */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case.  */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #ifndef DEFAULT_SIGNED_CHAR
 #define DEFAULT_SIGNED_CHAR 1
@@ -3245,11 +3483,8 @@ while (0)
 
 #define STORE_FLAG_VALUE 1
 
-/* Define this if zero-extension is slow (more than one real instruction).  */
-#define SLOW_ZERO_EXTEND
-
 /* Define this to be nonzero if shift instructions ignore all but the low-order
-   few bits. */
+   few bits.  */
 #define SHIFT_COUNT_TRUNCATED 1
 
 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
@@ -3267,7 +3502,7 @@ while (0)
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.
 
-   For MIPS we make pointers are the smaller of longs and gp-registers. */
+   For MIPS we make pointers are the smaller of longs and gp-registers.  */
 
 #ifndef Pmode
 #define Pmode ((TARGET_LONG64 && TARGET_64BIT) ? DImode : SImode)
@@ -3386,7 +3621,7 @@ while (0)
       if (GET_CODE (symref) != SYMBOL_REF)                             \
        return COSTS_N_INSNS (4);                                       \
                                                                        \
-      /* let's be paranoid.... */                                      \
+      /* let's be paranoid....  */                                     \
       if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)         \
        return COSTS_N_INSNS (2);                                       \
                                                                        \
@@ -3625,7 +3860,7 @@ while (0)
    different numbers of registers on machines with lots of registers.
 
    This macro will normally either not be defined or be defined as
-   a constant. */
+   a constant.  */
 
 #define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : mips_address_cost (ADDR))
 
@@ -3658,7 +3893,7 @@ while (0)
    all values except -1.  We could handle that case by using a signed
    divide, e.g.  -1 / 2 (or maybe 1 / -2?).  We'd have to emit a
    compare/branch to test the input value to see which instruction we
-   need to use.  This gets pretty messy, but it is feasible. */
+   need to use.  This gets pretty messy, but it is feasible.  */
 
 #define REGISTER_MOVE_COST(MODE, FROM, TO)     \
   ((FROM) == M16_REGS && GR_REG_CLASS_P (TO) ? 2                       \
@@ -3700,16 +3935,6 @@ while (0)
     && (TUNE_MIPS4000 || TUNE_MIPS6000))       \
    ? 2 : 1)
 
-/* A C statement (sans semicolon) to update the integer variable COST
-   based on the relationship between INSN that is dependent on
-   DEP_INSN through the dependence LINK.  The default is to make no
-   adjustment to COST.  On the MIPS, ignore the cost of anti- and
-   output-dependencies.  */
-
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST)                           \
-  if (REG_NOTE_KIND (LINK) != 0)                                       \
-    (COST) = 0; /* Anti or output dependence.  */
-
 /* If defined, modifies the length assigned to instruction INSN as a
    function of the context in which it is used.  LENGTH is an lvalue
    that contains the initially computed length of the insn and should
@@ -4135,7 +4360,7 @@ while (0)
        $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. */
+       $Lp\..+         Half-pic labels.  */
 
 /* 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.
@@ -4228,32 +4453,27 @@ while (0)
 #define ASM_FILE_END(STREAM) mips_asm_file_end(STREAM)
 
 
+/* Play switch file games if we're optimizing the global pointer.  */
+
+#undef TEXT_SECTION
+#define TEXT_SECTION()                                 \
+do {                                                   \
+  extern FILE *asm_out_text_file;                      \
+  if (TARGET_FILE_SWITCHING)                           \
+    asm_out_file = asm_out_text_file;                  \
+  fputs (TEXT_SECTION_ASM_OP, asm_out_file);           \
+  fputc ('\n', asm_out_file);                          \
+} while (0)
+
+
 /* 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.
-
-   Also, switch files if we are optimizing the global pointer.  */
+   and after any .file directives.  */
 
 #undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL)                    \
-{                                                                      \
-  extern FILE *asm_out_text_file;                                      \
-  if (TARGET_GP_OPT && ! TARGET_MIPS16)                                        \
-    {                                                                  \
-      STREAM = asm_out_text_file;                                      \
-      /* ??? text_section gets called too soon.  If the previous       \
-        function is in a special section and we're not, we have        \
-        to switch back to the text section.  We can't call             \
-        text_section again as gcc thinks we're already there.  */      \
-      /* ??? See varasm.c.  There are other things that get output     \
-        too early, like alignment (before we've switched STREAM).  */  \
-      if (DECL_SECTION_NAME (DECL) == NULL_TREE)                       \
-       fprintf (STREAM, "%s\n", TEXT_SECTION_ASM_OP);                  \
-    }                                                                  \
-                                                                       \
-  HALF_PIC_DECLARE (NAME);                                             \
-}
+#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL)    \
+  HALF_PIC_DECLARE (NAME)
 
 /* This is how to output an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.  */
@@ -4271,81 +4491,6 @@ while (0)
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)                  \
   sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
 
-/* This is how to output an assembler line defining a `double' constant.  */
-
-#define ASM_OUTPUT_DOUBLE(STREAM,VALUE)                                        \
-  mips_output_double (STREAM, VALUE)
-
-
-/* This is how to output an assembler line defining a `float' constant.  */
-
-#define ASM_OUTPUT_FLOAT(STREAM,VALUE)                                 \
-  mips_output_float (STREAM, VALUE)
-
-
-/* This is how to output an assembler line defining an `int' constant.  */
-
-#define ASM_OUTPUT_INT(STREAM,VALUE)                                   \
-do {                                                                   \
-  fprintf (STREAM, "\t.word\t");                                       \
-  output_addr_const (STREAM, (VALUE));                                 \
-  fprintf (STREAM, "\n");                                              \
-} while (0)
-
-/* Likewise for 64 bit, `char' and `short' constants.
-
-   FIXME: operand_subword can't handle some complex constant expressions
-   that output_addr_const can (for example it does not call
-   simplify_subtraction).  Since GAS can handle dword, even for mipsII,
-   rely on that to avoid operand_subword for most of the cases where this
-   matters.  Try gcc.c-torture/compile/930326-1.c with -mips2 -mlong64,
-   or the same case with the type of 'i' changed to long long.
-
-*/
-
-#define ASM_OUTPUT_DOUBLE_INT(STREAM,VALUE)                            \
-do {                                                                   \
-  if (TARGET_64BIT || TARGET_GAS)                                      \
-    {                                                                  \
-      fprintf (STREAM, "\t.dword\t");                                  \
-      if (HOST_BITS_PER_WIDE_INT < 64 || GET_CODE (VALUE) != CONST_INT)        \
-       /* We can't use 'X' for negative numbers, because then we won't \
-          get the right value for the upper 32 bits.  */               \
-        output_addr_const (STREAM, VALUE);                             \
-      else                                                             \
-       /* We must use 'X', because otherwise LONG_MIN will print as    \
-          a number that the Irix 6 assembler won't accept.  */         \
-        print_operand (STREAM, VALUE, 'X');                            \
-      fprintf (STREAM, "\n");                                          \
-    }                                                                  \
-  else                                                                 \
-    {                                                                  \
-      assemble_integer (operand_subword ((VALUE), 0, 0, DImode),       \
-                       UNITS_PER_WORD, 1);                             \
-      assemble_integer (operand_subword ((VALUE), 1, 0, DImode),       \
-                       UNITS_PER_WORD, 1);                             \
-    }                                                                  \
-} while (0)
-
-#define ASM_OUTPUT_SHORT(STREAM,VALUE)                                 \
-{                                                                      \
-  fprintf (STREAM, "\t.half\t");                                       \
-  output_addr_const (STREAM, (VALUE));                                 \
-  fprintf (STREAM, "\n");                                              \
-}
-
-#define ASM_OUTPUT_CHAR(STREAM,VALUE)                                  \
-{                                                                      \
-  fprintf (STREAM, "\t.byte\t");                                       \
-  output_addr_const (STREAM, (VALUE));                                 \
-  fprintf (STREAM, "\n");                                              \
-}
-
-/* This is how to output an assembler line for a numeric constant byte.  */
-
-#define ASM_OUTPUT_BYTE(STREAM,VALUE)                                  \
-  fprintf (STREAM, "\t.byte\t0x%x\n", (VALUE))
-
 /* This is how to output an element of a case-vector that is absolute.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                         \
@@ -4413,8 +4558,8 @@ do {                                                                      \
 /* Handle certain cpp directives used in header files on sysV.  */
 #define SCCS_DIRECTIVE
 
-#ifndef ASM_OUTPUT_IDENT
 /* Output #ident as a in the read-only data section.  */
+#undef  ASM_OUTPUT_IDENT
 #define ASM_OUTPUT_IDENT(FILE, STRING)                                 \
 {                                                                      \
   const char *p = STRING;                                              \
@@ -4422,7 +4567,6 @@ do {                                                                      \
   rdata_section ();                                                    \
   assemble_string (p, size);                                           \
 }
-#endif
 \f
 /* Default to -G 8 */
 #ifndef MIPS_DEFAULT_GVALUE
@@ -4451,7 +4595,7 @@ do {                                                                      \
    address with faster (gp) register relative addressing, which can
    only get at sdata and sbss items (there is no stext !!)  However,
    if the constant is too large for sdata, and it's readonly, it
-   will go into the .rdata section. */
+   will go into the .rdata section.  */
 
 #undef EXTRA_SECTION_FUNCTIONS
 #define EXTRA_SECTION_FUNCTIONS                                                \
@@ -4479,10 +4623,12 @@ rdata_section ()                                                        \
    and select that section.  */
 
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)   mips_select_rtx_section (MODE, RTX)
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
+  mips_select_rtx_section (MODE, RTX)
 
 #undef SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC)    mips_select_section (DECL, RELOC)
+#define SELECT_SECTION(DECL, RELOC, ALIGN) \
+  mips_select_section (DECL, RELOC)
 
 \f
 /* Store in OUTPUT a string (made with alloca) containing
@@ -4538,7 +4684,7 @@ while (0)
    and mips-tdump.c to print them out.
 
    These must match the corresponding definitions in gdb/mipsread.c.
-   Unfortunately, gcc and gdb do not currently share any directories. */
+   Unfortunately, gcc and gdb do not currently share any directories.  */
 
 #define CODE_MASK 0x8F300
 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
@@ -4589,7 +4735,7 @@ do                                                                        \
          init_one_libfunc ("__mips16_subsf3");                         \
        smul_optab->handlers[(int) SFmode].libfunc =                    \
          init_one_libfunc ("__mips16_mulsf3");                         \
-       flodiv_optab->handlers[(int) SFmode].libfunc =                  \
+       sdiv_optab->handlers[(int) SFmode].libfunc =                    \
          init_one_libfunc ("__mips16_divsf3");                         \
                                                                        \
        eqsf2_libfunc = init_one_libfunc ("__mips16_eqsf2");            \
@@ -4612,7 +4758,7 @@ do                                                                        \
              init_one_libfunc ("__mips16_subdf3");                     \
            smul_optab->handlers[(int) DFmode].libfunc =                \
              init_one_libfunc ("__mips16_muldf3");                     \
-           flodiv_optab->handlers[(int) DFmode].libfunc =              \
+           sdiv_optab->handlers[(int) DFmode].libfunc =                \
              init_one_libfunc ("__mips16_divdf3");                     \
                                                                        \
            extendsfdf2_libfunc =                                       \