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 106026b..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
@@ -119,7 +119,7 @@ enum block_move_type {
 };
 
 extern char mips_reg_names[][8];       /* register names (a0 vs. $4).  */
-extern char mips_print_operand_punct[];        /* print_operand punctuation chars */
+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 */
@@ -166,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));
@@ -577,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                                             \
@@ -679,7 +660,7 @@ 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                         \
@@ -867,47 +848,14 @@ while (0)
 #define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
 
 
-/* We use the o32 abi as default for mips1 and mips2.  SGI uses n32/n64 for
-   mips3 and mips4 by default, however, this is unsupported at this point in
-   binutils so we use o64. This should change when n32/n64 is supported.  */
-
 extern int mips_abi;
 
 #ifndef MIPS_ABI_DEFAULT
 #define MIPS_ABI_DEFAULT ABI_32
 #endif
 
-#if MIPS_ABI_DEFAULT == ABI_32
-#define ABI_GAS_ASM_SPEC "%{mabi=*} \
-%{!mabi=*:%{mips3|mips4|mips5|mips64:-mabi=o64} %{!mips3:%{!mips4:%{!mips5:%{!mips64:-mabi=32}}}}}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_N32
-#define ABI_GAS_ASM_SPEC "%{mabi=*} %{!mabi=*:-mabi=n32}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_64
-#define ABI_GAS_ASM_SPEC "%{mabi=*} %{!mabi=*:-mabi=64}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define ABI_GAS_ASM_SPEC "%{mabi=*} %{!mabi=*:-mabi=eabi}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_O64
-#define ABI_GAS_ASM_SPEC "\
-%{mabi=*} \
-%{!mabi=*:%{mips1|mips2|mips32:-mabi=32} %{!mips1:%{!mips2:%{!mips3:%{!mips32:-mabi=o64}}}}}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_MEABI
-#define ABI_GAS_ASM_SPEC "\
-%{mabi=*} \
-%{!mabi=*:-mabi=meabi }"
-#endif
-
 #ifndef ABI_GAS_ASM_SPEC
- #error "Unhandled MIPS_ABI_DEFAULT"
+#define ABI_GAS_ASM_SPEC ""
 #endif
 
 /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
@@ -1070,25 +1018,205 @@ extern int mips_abi;
    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 "\
-%{mlong64:%{!mips1:%{!mips2:%{!mips32:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}} \
-%{!mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}"
+%{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
 
-/* SUBTARGET_CPP_SPEC is passed to the preprocessor.  It may be
-   overridden by subtargets.  */
-#ifndef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC ""
+#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
 
-/* 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}"
 #else
-#define LONG_MAX_SPEC "%{mlong64:-D__LONG_MAX__=9223372036854775807L}"
+
+/* 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 "\
+%{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
+   overridden by subtargets.  */
+#ifndef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC ""
 #endif
 
 /* Define appropriate macros for fpr register size.  */
@@ -1257,7 +1385,7 @@ extern int mips_abi;
 #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.
@@ -1434,10 +1562,6 @@ do {                                                     \
 \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.
 */
@@ -1457,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).  */
@@ -1474,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
 
@@ -1504,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.  */
@@ -1535,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
@@ -1716,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
@@ -1878,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.
@@ -1924,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 */
@@ -1953,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"                                                           \
 }
@@ -1984,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 */     \
 }
@@ -2064,7 +2195,7 @@ extern const 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)]
 
@@ -2211,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?
 
-#define CLASS_CANNOT_CHANGE_MODE \
-  (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS)
+   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_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.  */
 
@@ -2601,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
 
@@ -2729,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");                                      \
 }
 
@@ -3208,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     \
@@ -3280,7 +3414,8 @@ do                                                                        \
                                                                        \
     else if (HALF_PIC_P ())                                            \
       {                                                                        \
-        HALF_PIC_ENCODE (DECL);                                                \
+       if (FIRST)                                                      \
+          HALF_PIC_ENCODE (DECL);                                      \
       }                                                                        \
   }                                                                    \
 while (0)
@@ -3323,12 +3458,6 @@ while (0)
    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
@@ -3354,9 +3483,6 @@ 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.  */
 #define SHIFT_COUNT_TRUNCATED 1
@@ -4365,81 +4491,6 @@ do {                                                     \
 #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, BITS_PER_WORD, 1);              \
-      assemble_integer (operand_subword ((VALUE), 1, 0, DImode),       \
-                       UNITS_PER_WORD, BITS_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", (int)(VALUE))
-
 /* This is how to output an element of a case-vector that is absolute.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                         \